From 75641f54024b2e182572385cb2e714c519fbe20d Mon Sep 17 00:00:00 2001 From: Dimitri Berthault <160850597+dberthault@users.noreply.github.com> Date: Wed, 15 May 2024 16:19:43 +0200 Subject: [PATCH] Update to Pyo3 0.21 (#556) * wip * almost there * save before mass replace * save before mass replace * it compiles * Update qoqo to pyo3 0.21 * format test like the others * version, dependencies and changelog * toml patch * git patch * clippy * compatibility test patch * remove useless binds * from_bound_pyany * cargo clippy * use bound * toml * unstable features fix * cargo clippy * remove patches * remove useless lines * remove empty line * PR review * pr review * rm unused import * cargo update * compatibility --- .../compatibility_test_1_0/Cargo.toml | 17 +- .../compatibility_test_1_10/Cargo.toml | 15 +- .../tests/integration/compatibility_1_10.rs | 28 +- .../compatibility_test_1_11/Cargo.toml | 34 + .../compatibility_test_1_11/src/lib.rs | 14 + .../tests/integration/compatibility_1_11.rs | 200 + .../tests/integration/main.rs | 13 + .../compatibility_test_1_2/Cargo.toml | 17 +- .../compatibility_test_1_3/Cargo.toml | 17 +- .../compatibility_test_1_4/Cargo.toml | 17 +- .../compatibility_test_1_5/Cargo.toml | 17 +- .../compatibility_test_1_6/Cargo.toml | 17 +- .../compatibility_test_1_7/Cargo.toml | 17 +- .../compatibility_test_1_8/Cargo.toml | 17 +- .../compatibility_test_1_9/Cargo.toml | 17 +- .../compatibility_test_sim/Cargo.toml | 16 +- CHANGELOG.md | 5 +- Cargo.lock | 404 +- Cargo.toml | 10 +- qoqo-macros/Cargo.toml | 4 +- qoqo-macros/src/devices.rs | 13 +- qoqo-macros/src/lib.rs | 64 +- qoqo-macros/src/noise_models.rs | 11 +- qoqo-macros/src/operate.rs | 20 +- qoqo/Cargo.toml | 39 +- qoqo/build.rs | 22 +- qoqo/pyproject.toml | 25 +- qoqo/qoqo/DEPENDENCIES | 3341 +++++++++++------ qoqo/src/circuit.rs | 133 +- qoqo/src/circuitdag.rs | 56 +- qoqo/src/devices/all_to_all.rs | 25 +- qoqo/src/devices/generic_device.rs | 29 +- qoqo/src/devices/mod.rs | 40 +- qoqo/src/devices/square_lattice.rs | 33 +- qoqo/src/lib.rs | 7 +- .../basis_rotation_measurement.rs | 116 +- .../cheated_basis_rotation_measurement.rs | 115 +- qoqo/src/measurements/cheated_measurement.rs | 120 +- .../classical_register_measurement.rs | 86 +- .../measurement_auxiliary_data_input.rs | 118 +- qoqo/src/measurements/mod.rs | 2 +- .../noise_models/continuous_decoherence.rs | 6 +- qoqo/src/noise_models/decoherence_on_gate.rs | 12 +- qoqo/src/noise_models/decoherence_on_idle.rs | 6 +- qoqo/src/noise_models/imperfect_readout.rs | 4 +- qoqo/src/noise_models/mod.rs | 2 +- qoqo/src/noise_models/overrotation.rs | 74 +- qoqo/src/operations/analog_operations.rs | 8 +- qoqo/src/operations/mod.rs | 2 +- qoqo/src/operations/pragma_operations.rs | 310 +- qoqo/src/quantum_program.rs | 78 +- qoqo/tests/integration/circuit.rs | 320 +- qoqo/tests/integration/circuitdag.rs | 156 +- qoqo/tests/integration/devices.rs | 139 +- .../basis_rotation_measurement.rs | 404 +- .../cheated_basis_rotation_measurement.rs | 379 +- .../measurements/cheated_measurement.rs | 357 +- .../classical_register_measurement.rs | 171 +- .../noise_models/continuous_decoherence.rs | 140 +- .../noise_models/decoherence_on_gate.rs | 129 +- .../noise_models/decoherence_on_idle.rs | 140 +- .../noise_models/imperfect_readout.rs | 88 +- .../integration/noise_models/overrotation.rs | 172 +- .../operations/analog_operations.rs | 160 +- .../operations/bosonic_operations.rs | 317 +- .../operations/define_operations.rs | 198 +- .../operations/measurement_operations.rs | 214 +- qoqo/tests/integration/operations/mod.rs | 14 +- .../operations/multi_qubit_gate_operations.rs | 173 +- .../operations/operation_conversions.rs | 4 +- .../operations/pragma_operations.rs | 827 ++-- .../single_qubit_gate_operations.rs | 660 ++-- .../operations/spin_boson_operations.rs | 275 +- .../operations/three_qubit_gate_operations.rs | 169 +- .../operations/two_qubit_gate_operations.rs | 719 ++-- qoqo/tests/integration/quantum_program.rs | 435 +-- roqoqo-derive/Cargo.toml | 2 +- roqoqo-test/Cargo.toml | 6 +- roqoqo/Cargo.toml | 53 +- roqoqo/build.rs | 2 +- roqoqo/src/circuitdag.rs | 8 +- roqoqo/src/devices/generic_device.rs | 6 +- .../src/operations/measurement_operations.rs | 2 +- roqoqo/src/operations/mod.rs | 22 +- 84 files changed, 6486 insertions(+), 6188 deletions(-) create mode 100644 .compatibility_tests/compatibility_test_1_11/Cargo.toml create mode 100644 .compatibility_tests/compatibility_test_1_11/src/lib.rs create mode 100644 .compatibility_tests/compatibility_test_1_11/tests/integration/compatibility_1_11.rs create mode 100644 .compatibility_tests/compatibility_test_1_11/tests/integration/main.rs diff --git a/.compatibility_tests/compatibility_test_1_0/Cargo.toml b/.compatibility_tests/compatibility_test_1_0/Cargo.toml index c54be9a2..1bb96234 100644 --- a/.compatibility_tests/compatibility_test_1_0/Cargo.toml +++ b/.compatibility_tests/compatibility_test_1_0/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "compatibility_test_1_0" -version ="1.11.0" +version = "1.12.0" authors = ["HQS Quantum Simulations "] license = "Apache-2.0" edition = "2021" @@ -19,12 +19,15 @@ publish = false [workspace] [dependencies] -test_roqoqo_1_0 = {package = "roqoqo", version="=1.0.0"} -test_roqoqo_derive_1_0 = {package = "roqoqo-derive", version="=1.0.0"} -qoqo_calculator = { version="1.1" } -roqoqo = {version="1.11.0", path="../../roqoqo", features=["serialize", "overrotate"]} -bincode = {version="1.3"} +test_roqoqo_1_0 = { package = "roqoqo", version = "=1.0.0" } +test_roqoqo_derive_1_0 = { package = "roqoqo-derive", version = "=1.0.0" } +qoqo_calculator = { version = "1.2" } +roqoqo = { version = "1.12.0", path = "../../roqoqo", features = [ + "serialize", + "overrotate", +] } +bincode = { version = "1.3" } ndarray = "0.15" [dev-dependencies] -test-case = "3.0" \ No newline at end of file +test-case = "3.0" diff --git a/.compatibility_tests/compatibility_test_1_10/Cargo.toml b/.compatibility_tests/compatibility_test_1_10/Cargo.toml index 7a6aef79..4b93c9ef 100644 --- a/.compatibility_tests/compatibility_test_1_10/Cargo.toml +++ b/.compatibility_tests/compatibility_test_1_10/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "compatibility_test_1_10" -version ="1.11.0" +version = "1.12.0" authors = ["HQS Quantum Simulations "] license = "Apache-2.0" edition = "2021" @@ -19,11 +19,14 @@ publish = false [workspace] [dependencies] -test_roqoqo_1_10 = {package = "roqoqo", version="=1.10.0"} -test_roqoqo_derive_1_10 = {package = "roqoqo-derive", version="=1.10.0"} -qoqo_calculator = { version="1.1" } -roqoqo = {version="1.11.0", path="../../roqoqo", features=["serialize", "overrotate"]} -bincode = {version="1.3"} +test_roqoqo_1_10 = { package = "roqoqo", version = "=1.10.0" } +test_roqoqo_derive_1_10 = { package = "roqoqo-derive", version = "=1.10.0" } +qoqo_calculator = { version = "1.2" } +roqoqo = { version = "1.12.0", path = "../../roqoqo", features = [ + "serialize", + "overrotate", +] } +bincode = { version = "1.3" } ndarray = "0.15" [dev-dependencies] diff --git a/.compatibility_tests/compatibility_test_1_10/tests/integration/compatibility_1_10.rs b/.compatibility_tests/compatibility_test_1_10/tests/integration/compatibility_1_10.rs index 45de8813..2186bc08 100644 --- a/.compatibility_tests/compatibility_test_1_10/tests/integration/compatibility_1_10.rs +++ b/.compatibility_tests/compatibility_test_1_10/tests/integration/compatibility_1_10.rs @@ -112,10 +112,11 @@ use test_roqoqo_1_10; #[test_case(test_roqoqo_1_10::operations::EchoCrossResonance::new(0, 1).into(); "EchoCrossResonance")] #[test_case(test_roqoqo_1_10::operations::PragmaAnnotatedOp::new(test_roqoqo_1_10::operations::PauliX::new(0).into(), "test".to_string()).into(); "PragmaAnnotatedOp")] // Operations from 1.9 - nothing was added -// Operations from 1.10 +// Operations from 1.10 // QuantumRabi, LongitudinalCoupling, JaynesCummings, SingleExcitationLoad, SingleExcitationStore and CZQubitResonator were all added // as unstable, but have been added as stable in 1.11 // Operations from 1.11 - uncomment for next unittests +// ApplyConstantSpinHamiltonian and ApplyTimeDependentHamiltonian are unstable in 1.11 // #[test_case(test_roqoqo_1_10::operations::QuantumRabi::new(0, 1, 0.1.into()).into(); "QuantumRabi")] // #[test_case(test_roqoqo_1_10::operations::LongitudinalCoupling::new(0, 1, 0.1.into()).into(); "LongitudinalCoupling")] // #[test_case(test_roqoqo_1_10::operations::JaynesCummings::new(0, 1, 0.1.into()).into(); "JaynesCummings")] @@ -165,28 +166,3 @@ fn test_device_compat() { ); assert_eq!(test_deserialisation, comparsion_device); } - -// Operations from 1.11 -// use struqture; -// use struqture::prelude::*; -// fn create_apply_constant_spin_hamiltonian() -> test_roqoqo_1_10::operations::ApplyConstantSpinHamiltonian -// { -// let pp = struqture::spins::PauliProduct::new().z(0); -// let mut hamiltonian = struqture::spins::SpinHamiltonian::new(); -// hamiltonian -// .add_operator_product(pp.clone(), 1.0.into()) -// .unwrap(); -// return test_roqoqo_1_10::operations::ApplyConstantSpinHamiltonian::new(hamiltonian, 1.0.into()); -// } - -// fn create_apply_timedependent_spin_hamiltonian() -> test_roqoqo_1_10::operations::ApplyTimeDependentSpinHamiltonian -// { -// let pp = struqture::spins::PauliProduct::new().z(0); -// let mut hamiltonian = struqture::spins::SpinHamiltonian::new(); -// hamiltonian -// .add_operator_product(pp.clone(), "omega".into()) -// .unwrap(); -// let mut values = HashMap::new(); -// values.insert("omega".to_string(), vec![1.0]); -// return test_roqoqo_1_10::operations::ApplyTimeDependentSpinHamiltonian::new(hamiltonian, vec![1.0], values.clone()); -// } \ No newline at end of file diff --git a/.compatibility_tests/compatibility_test_1_11/Cargo.toml b/.compatibility_tests/compatibility_test_1_11/Cargo.toml new file mode 100644 index 00000000..203ff892 --- /dev/null +++ b/.compatibility_tests/compatibility_test_1_11/Cargo.toml @@ -0,0 +1,34 @@ +[package] +name = "compatibility_test_1_11" +version = "1.12.0" +authors = ["HQS Quantum Simulations "] +license = "Apache-2.0" +edition = "2021" +rust-version = "1.56" +categories = ["science", "simulation"] +homepage = "https://github.com/HQSquantumsimulations/qoqo" +repository = "https://github.com/HQSquantumsimulations/qoqo" +documentation = "https://docs.rs/roqoqo/" +readme = "../README.md" +description = "Compatibility tests for roqoqo" +include = ["src*", "build.rs", "LICENSE", "README.md"] +publish = false + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[workspace] + +[dependencies] +test_roqoqo_1_11 = { package = "roqoqo", version = "=1.11.0" } +test_roqoqo_derive_1_11 = { package = "roqoqo-derive", version = "=1.11.0" } +qoqo_calculator = { version = "1.2" } +roqoqo = { version = "1.12.0", path = "../../roqoqo", features = [ + "serialize", + "overrotate", +] } +struqture = { version = "1.7" } +bincode = { version = "1.3" } +ndarray = "0.15" + +[dev-dependencies] +test-case = "3.0" diff --git a/.compatibility_tests/compatibility_test_1_11/src/lib.rs b/.compatibility_tests/compatibility_test_1_11/src/lib.rs new file mode 100644 index 00000000..7d12d9af --- /dev/null +++ b/.compatibility_tests/compatibility_test_1_11/src/lib.rs @@ -0,0 +1,14 @@ +pub fn add(left: usize, right: usize) -> usize { + left + right +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn it_works() { + let result = add(2, 2); + assert_eq!(result, 4); + } +} diff --git a/.compatibility_tests/compatibility_test_1_11/tests/integration/compatibility_1_11.rs b/.compatibility_tests/compatibility_test_1_11/tests/integration/compatibility_1_11.rs new file mode 100644 index 00000000..9fe98694 --- /dev/null +++ b/.compatibility_tests/compatibility_test_1_11/tests/integration/compatibility_1_11.rs @@ -0,0 +1,200 @@ +// Copyright © 2023 HQS Quantum Simulations GmbH. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software distributed under the +// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +// express or implied. See the License for the specific language governing permissions and +// limitations under the License. + +use std::collections::HashMap; + +use test_case::test_case; +use test_roqoqo_1_11; + +// 1.0 version +#[test_case(test_roqoqo_1_11::operations::SingleQubitGate::new(0, 1.0.into(), 0.0.into(), 0.0.into(), 0.0.into(), 0.0.into(),).into(); "SingleQubitGate")] +#[test_case(test_roqoqo_1_11::operations::RotateZ::new(0, 0.1.into()).into(); "RotateZ")] +#[test_case(test_roqoqo_1_11::operations::RotateY::new(0, 0.1.into()).into(); "RotateY")] +#[test_case(test_roqoqo_1_11::operations::RotateX::new(0, 0.1.into()).into(); "RotateX")] +#[test_case(test_roqoqo_1_11::operations::RotateXY::new(0,1.0.into(), 0.1.into()).into(); "RotateXY")] +#[test_case(test_roqoqo_1_11::operations::RotateAroundSphericalAxis::new(0, 1.0.into(), 1.0.into(), 1.0.into()).into(); "RotateAroundSphericalAxis")] +#[test_case(test_roqoqo_1_11::operations::PauliZ::new(0).into(); "PauliZ")] +#[test_case(test_roqoqo_1_11::operations::PauliY::new(0).into(); "PauliY")] +#[test_case(test_roqoqo_1_11::operations::PauliX::new(0).into(); "PauliX")] +#[test_case(test_roqoqo_1_11::operations::SqrtPauliX::new(0).into(); "SqrtPauliX")] +#[test_case(test_roqoqo_1_11::operations::InvSqrtPauliX::new(0).into(); "InvSqrtPauliX")] +#[test_case(test_roqoqo_1_11::operations::Hadamard::new(0).into(); "Hadamard")] +#[test_case(test_roqoqo_1_11::operations::TGate::new(0).into(); "TGate")] +#[test_case(test_roqoqo_1_11::operations::SGate::new(0).into(); "SGate")] +#[test_case(test_roqoqo_1_11::operations::DefinitionBit::new("ro".to_string(), 1, false).into(); "DefinitionBit")] +#[test_case(test_roqoqo_1_11::operations::DefinitionComplex::new("ro".to_string(), 1, true).into(); "DefinitionComplex")] +#[test_case(test_roqoqo_1_11::operations::DefinitionUsize::new("ro".to_string(), 1, true).into(); "DefinitionUsize")] +#[test_case(test_roqoqo_1_11::operations::DefinitionFloat::new("ro".to_string(), 1, true).into(); "DefinitionFloat")] +#[test_case(test_roqoqo_1_11::operations::InputSymbolic::new("ro".to_string(), 1.0).into(); "InputSymbolic")] +#[test_case(test_roqoqo_1_11::operations::MeasureQubit::new(0,"ro".to_string(), 1).into(); "MeasureQubit")] +#[test_case(test_roqoqo_1_11::operations::PragmaGetStateVector::new("ro".to_string(), None).into(); "PragmaGetStateVector")] +#[test_case(test_roqoqo_1_11::operations::PragmaGetDensityMatrix::new("ro".to_string(), None).into(); "PragmaGetDensityMatrix")] +#[test_case(test_roqoqo_1_11::operations::PragmaGetOccupationProbability::new("ro".to_string(), None).into(); "PragmaGetOccupationProbability")] +#[test_case(test_roqoqo_1_11::operations::PragmaGetPauliProduct::new(std::collections::HashMap::new(),"ro".to_string(), test_roqoqo_1_11::Circuit::new()).into(); "PragmaGetPauliProduct")] +#[test_case(test_roqoqo_1_11::operations::PragmaRepeatedMeasurement::new("ro".to_string(), 10, None).into(); "PragmaRepeatedMeasurement")] +#[test_case(test_roqoqo_1_11::operations::PragmaSetNumberOfMeasurements::new(10, "ro".to_string()).into(); "PragmaSetNumberOfMeasurements")] +#[test_case(test_roqoqo_1_11::operations::PragmaSetStateVector::new(ndarray::array![1.0.into(), 0.0.into(), 0.0.into()]).into(); "PragmaSetStateVector")] +#[test_case(test_roqoqo_1_11::operations::PragmaSetDensityMatrix::new(ndarray::array![[1.0.into(), 0.0.into(), 0.0.into()]]).into(); "PragmaSetDensityMatrix")] +#[test_case(test_roqoqo_1_11::operations::PragmaRepeatGate::new(10).into(); "PragmaRepeatGate")] +#[test_case(test_roqoqo_1_11::operations::PragmaOverrotation::new("RotateZ".to_string(), vec![0], 1.0, 1.0).into(); "PragmaOverrotation")] +#[test_case(test_roqoqo_1_11::operations::PragmaBoostNoise::new(1.0.into()).into(); "PragmaBoostNoise")] +#[test_case(test_roqoqo_1_11::operations::PragmaStopParallelBlock::new(vec![0], 1.0.into()).into(); "PragmaStopParallelBlock")] +#[test_case(test_roqoqo_1_11::operations::PragmaGlobalPhase::new(1.0.into()).into(); "PragmaGlobalPhase")] +#[test_case(test_roqoqo_1_11::operations::PragmaSleep::new(vec![0], 1.0.into()).into(); "PragmaSleep")] +#[test_case(test_roqoqo_1_11::operations::PragmaActiveReset::new(0).into(); "PragmaActiveReset")] +#[test_case(test_roqoqo_1_11::operations::PragmaStartDecompositionBlock::new(vec![0], HashMap::new()).into(); "PragmaStartDecompositionBlock")] +#[test_case(test_roqoqo_1_11::operations::PragmaStopDecompositionBlock::new(vec![0]).into(); "PragmaStopDecompositionBlock")] +#[test_case(test_roqoqo_1_11::operations::PragmaDamping::new(0,1.0.into(), 1.0.into()).into(); "PragmaDamping")] +#[test_case(test_roqoqo_1_11::operations::PragmaDepolarising::new(0,1.0.into(), 1.0.into()).into(); "PragmaDepolarising")] +#[test_case(test_roqoqo_1_11::operations::PragmaDephasing::new(0,1.0.into(), 1.0.into()).into(); "PragmaDephasing")] +#[test_case(test_roqoqo_1_11::operations::PragmaRandomNoise::new(0,1.0.into(), 1.0.into(), 1.0.into()).into(); "PragmaRandomNoise")] +#[test_case(test_roqoqo_1_11::operations::PragmaGeneralNoise::new(0, 0.1.into(), ndarray::array![[1.0.into(), 0.0.into()], [1.0.into(), 2.0.into()]]).into(); "PragmaGeneralNoise")] +#[test_case(test_roqoqo_1_11::operations::PragmaConditional::new("ro".to_string(),0, test_roqoqo_1_11::Circuit::new()).into(); "PragmaConditional")] +// #[test_case(test_roqoqo_1_11::operations::PragmaChangeDevice::new(&"PragmaTest".into()).unwrap().into(); "PragmaChangeDevice")] +#[test_case(test_roqoqo_1_11::operations::CNOT::new(0,1).into(); "CNOT")] +#[test_case(test_roqoqo_1_11::operations::SWAP::new(0,1).into(); "SWAP")] +#[test_case(test_roqoqo_1_11::operations::FSwap::new(0,1).into(); "FSwap")] +#[test_case(test_roqoqo_1_11::operations::ISwap::new(0,1).into(); "ISwap")] +#[test_case(test_roqoqo_1_11::operations::SqrtISwap::new(0,1).into(); "SqrtISWAP")] +#[test_case(test_roqoqo_1_11::operations::InvSqrtISwap::new(0,1).into(); "InvSqrtISWAP")] +#[test_case(test_roqoqo_1_11::operations::XY::new(0,1, 0.1.into()).into(); "XY")] +#[test_case(test_roqoqo_1_11::operations::ControlledPhaseShift::new(0,1, 0.1.into()).into(); "ControlledPhase")] +#[test_case(test_roqoqo_1_11::operations::ControlledPauliY::new(0,1).into(); "ControlledPauliY")] +#[test_case(test_roqoqo_1_11::operations::ControlledPauliZ::new(0,1).into(); "ControlledPauliZ")] +#[test_case(test_roqoqo_1_11::operations::MolmerSorensenXX::new(0,1).into(); "MolmerSorensenXX")] +#[test_case(test_roqoqo_1_11::operations::VariableMSXX::new(0,1, 0.1.into()).into(); "VariableMSXX")] +#[test_case(test_roqoqo_1_11::operations::GivensRotation::new(0,1, 0.1.into(), 0.1.into()).into(); "GivensRotation")] +#[test_case(test_roqoqo_1_11::operations::GivensRotationLittleEndian::new(0,1, 0.1.into(), 0.1.into()).into(); "GivensRotationLittleEndian")] +#[test_case(test_roqoqo_1_11::operations::Qsim::new(0,1, 0.1.into(), 0.1.into(), 0.1.into()).into(); "Qsim")] +#[test_case(test_roqoqo_1_11::operations::Fsim::new(0,1, 0.1.into(), 0.1.into(), 0.1.into()).into(); "Fsim")] +#[test_case(test_roqoqo_1_11::operations::SpinInteraction::new(0,1, 0.1.into(), 0.1.into(), 0.1.into()).into(); "SpinInteraction")] +#[test_case(test_roqoqo_1_11::operations::Bogoliubov::new(0,1, 0.1.into(), 0.1.into()).into(); "Bogoliubov")] +#[test_case(test_roqoqo_1_11::operations::PMInteraction::new(0,1, 0.1.into()).into(); "PMInteraction")] +#[test_case(test_roqoqo_1_11::operations::ComplexPMInteraction::new(0,1, 0.1.into(), 0.1.into()).into(); "ComplexPMInteraction")] +#[test_case(test_roqoqo_1_11::operations::PhaseShiftedControlledZ::new(0,1, 1.0.into()).into(); "PhaseShiftedControlledZ")] +#[test_case(test_roqoqo_1_11::operations::PhaseShiftState1::new(0, 1.0.into()).into(); "PhaseShiftState1")] +#[test_case(test_roqoqo_1_11::operations::PhaseShiftState0::new(0, 1.0.into()).into(); "PhaseShiftState0")] +#[test_case(test_roqoqo_1_11::operations::MultiQubitMS::new(vec![0,2,3], 1.0.into()).into(); "MultiQubitMS")] +#[test_case(test_roqoqo_1_11::operations::MultiQubitZZ::new(vec![0,2,3], 1.0.into()).into(); "MultiQubitZZ")] +// 1.1 and 1.2 +#[test_case(test_roqoqo_1_11::operations::InputBit::new("input".to_string(), 1, true).into(); "InputBit")] +#[test_case(test_roqoqo_1_11::operations::PragmaLoop::new(2.0.into(), test_roqoqo_1_11::Circuit::new()).into(); "PragmaLoop")] +#[test_case(test_roqoqo_1_11::operations::PhaseShiftedControlledPhase::new(0,1, 1.0.into(), 1.0.into()).into(); "PhaseShiftedControlledPhase")] +// 1.3 +#[test_case(test_roqoqo_1_11::operations::ControlledRotateX::new(0,1, 1.0.into()).into(); "ControlledRotateX")] +#[test_case(test_roqoqo_1_11::operations::ControlledRotateXY::new(0,1, 1.0.into(), 1.0.into()).into(); "ControlledRotateXY")] +#[test_case(test_roqoqo_1_11::operations::ControlledControlledPauliZ::new(0,1,2).into(); "ControlledControlledPauliZ")] +#[test_case(test_roqoqo_1_11::operations::ControlledControlledPhaseShift::new(0,1,2, 1.0.into()).into(); "ControlledControlledPhaseShift")] +#[test_case(test_roqoqo_1_11::operations::Toffoli::new(0,1,2).into(); "Toffoli")] +// 1.4 +#[test_case(test_roqoqo_1_11::operations::GPi::new(0, 0.1.into()).into(); "GPi")] +#[test_case(test_roqoqo_1_11::operations::GPi2::new(0, 0.1.into()).into(); "GPi2")] +// 1.5 +#[test_case(test_roqoqo_1_11::operations::PragmaControlledCircuit::new(0, test_roqoqo_1_11::Circuit::new()).into(); "PragmaControlledCircuit")] +// Operations from 1.6 +#[test_case(test_roqoqo_1_11::operations::Squeezing::new(0, 0.1.into(), 0.1.into()).into(); "Squeezing")] +#[test_case(test_roqoqo_1_11::operations::PhaseShift::new(0, 0.1.into()).into(); "PhaseShift")] +#[test_case(test_roqoqo_1_11::operations::BeamSplitter::new(0, 1, 0.1.into(), 0.2.into()).into(); "BeamSplitter")] +#[test_case(test_roqoqo_1_11::operations::PhotonDetection::new(0, "ro".into(), 0).into(); "PhotonDetection")] +// Operations from 1.7 +#[test_case(test_roqoqo_1_11::operations::Identity::new(0).into(); "Identity")] +// Operations from 1.8 +#[test_case(test_roqoqo_1_11::operations::PhaseDisplacement::new(0, 0.1.into(), 0.1.into()).into(); "PhaseDisplacement")] +#[test_case(test_roqoqo_1_11::operations::EchoCrossResonance::new(0, 1).into(); "EchoCrossResonance")] +#[test_case(test_roqoqo_1_11::operations::PragmaAnnotatedOp::new(test_roqoqo_1_11::operations::PauliX::new(0).into(), "test".to_string()).into(); "PragmaAnnotatedOp")] +// Operations from 1.9 - nothing was added +// Operations from 1.10 +// QuantumRabi, LongitudinalCoupling, JaynesCummings, SingleExcitationLoad, SingleExcitationStore and CZQubitResonator were all added +// as unstable, but have been added as stable in 1.11 +// Operations from 1.11 +#[test_case(test_roqoqo_1_11::operations::QuantumRabi::new(0, 1, 0.1.into()).into(); "QuantumRabi")] +#[test_case(test_roqoqo_1_11::operations::LongitudinalCoupling::new(0, 1, 0.1.into()).into(); "LongitudinalCoupling")] +#[test_case(test_roqoqo_1_11::operations::JaynesCummings::new(0, 1, 0.1.into()).into(); "JaynesCummings")] +#[test_case(test_roqoqo_1_11::operations::SingleExcitationLoad::new(0, 1).into(); "SingleExcitationLoad")] +#[test_case(test_roqoqo_1_11::operations::SingleExcitationStore::new(0, 1).into(); "SingleExcitationStore")] +#[test_case(test_roqoqo_1_11::operations::CZQubitResonator::new(0, 1).into(); "CZQubitResonator")] +// Operations from 1.11 - ApplyConstantSpinHamiltonian and ApplyTimeDependentHamiltonian are unstable in 1.11 +// #[test_case(create_apply_constant_spin_hamiltonian(); "ApplyConstantSpinHamiltonian")] +// #[test_case(create_apply_timedependent_spin_hamiltonian(); "ApplyTimeDependentHamiltonian")] +fn test_bincode_compatibility_1_10(operation: test_roqoqo_1_11::operations::Operation) { + let mut test_circuit = test_roqoqo_1_11::Circuit::new(); + test_circuit += operation; + + let test_measurement_input = test_roqoqo_1_11::measurements::PauliZProductInput::new(3, false); + let test_measurement = test_roqoqo_1_11::measurements::PauliZProduct { + constant_circuit: Some(test_circuit.clone()), + circuits: vec![test_circuit], + input: test_measurement_input, + }; + let test_program = test_roqoqo_1_11::QuantumProgram::PauliZProduct { + measurement: test_measurement, + input_parameter_names: vec!["test".to_string()], + }; + let test_serialisation: Vec = bincode::serialize(&test_program).unwrap(); + + let _test_deserialisation: roqoqo::QuantumProgram = + bincode::deserialize(&test_serialisation).unwrap(); +} + +#[test] +fn test_device_compat() { + let test_device = test_roqoqo_1_11::devices::AllToAllDevice::new( + 3, + &["RotateZ".to_string()], + &["CNOT".to_string()], + 1.0, + ); + let test_serialisation: Vec = bincode::serialize(&test_device).unwrap(); + + let test_deserialisation: roqoqo::devices::AllToAllDevice = + bincode::deserialize(&test_serialisation).unwrap(); + + let comparsion_device = roqoqo::devices::AllToAllDevice::new( + 3, + &["RotateZ".to_string()], + &["CNOT".to_string()], + 1.0, + ); + assert_eq!(test_deserialisation, comparsion_device); +} + +// Operations from 1.11 - ApplyConstantSpinHamiltonian and ApplyTimeDependentHamiltonian are unstable in 1.11 +// use struqture; +// use struqture::prelude::*; +// fn create_apply_constant_spin_hamiltonian( +// ) -> test_roqoqo_1_11::operations::ApplyConstantSpinHamiltonian { +// let pp = struqture::spins::PauliProduct::new().z(0); +// let mut hamiltonian = struqture::spins::SpinHamiltonian::new(); +// hamiltonian +// .add_operator_product(pp.clone(), 1.0.into()) +// .unwrap(); +// return test_roqoqo_1_11::operations::ApplyConstantSpinHamiltonian::new( +// hamiltonian, +// 1.0.into(), +// ); +// } + +// fn create_apply_timedependent_spin_hamiltonian( +// ) -> test_roqoqo_1_11::operations::ApplyTimeDependentSpinHamiltonian { +// let pp = struqture::spins::PauliProduct::new().z(0); +// let mut hamiltonian = struqture::spins::SpinHamiltonian::new(); +// hamiltonian +// .add_operator_product(pp.clone(), "omega".into()) +// .unwrap(); +// let mut values = HashMap::new(); +// values.insert("omega".to_string(), vec![1.0]); +// return test_roqoqo_1_11::operations::ApplyTimeDependentSpinHamiltonian::new( +// hamiltonian, +// vec![1.0], +// values.clone(), +// ); +// } diff --git a/.compatibility_tests/compatibility_test_1_11/tests/integration/main.rs b/.compatibility_tests/compatibility_test_1_11/tests/integration/main.rs new file mode 100644 index 00000000..e0bad880 --- /dev/null +++ b/.compatibility_tests/compatibility_test_1_11/tests/integration/main.rs @@ -0,0 +1,13 @@ +// Copyright © 2021-2023 HQS Quantum Simulations GmbH. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software distributed under the +// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +// express or implied. See the License for the specific language governing permissions and +// limitations under the License. +#[cfg(test)] +mod compatibility_1_11; diff --git a/.compatibility_tests/compatibility_test_1_2/Cargo.toml b/.compatibility_tests/compatibility_test_1_2/Cargo.toml index 41b13599..af5d5d2f 100644 --- a/.compatibility_tests/compatibility_test_1_2/Cargo.toml +++ b/.compatibility_tests/compatibility_test_1_2/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "compatibility_test_1_2" -version ="1.11.0" +version = "1.12.0" authors = ["HQS Quantum Simulations "] license = "Apache-2.0" edition = "2021" @@ -19,12 +19,15 @@ publish = false [workspace] [dependencies] -test_roqoqo_1_2 = {package = "roqoqo", version="=1.2.5"} -test_roqoqo_derive_1_2 = {package = "roqoqo-derive", version="=1.2.5"} -qoqo_calculator = { version="1.1" } -roqoqo = {version="1.11.0", path="../../roqoqo", features=["serialize", "overrotate"]} -bincode = {version="1.3"} +test_roqoqo_1_2 = { package = "roqoqo", version = "=1.2.5" } +test_roqoqo_derive_1_2 = { package = "roqoqo-derive", version = "=1.2.5" } +qoqo_calculator = { version = "1.2" } +roqoqo = { version = "1.12.0", path = "../../roqoqo", features = [ + "serialize", + "overrotate", +] } +bincode = { version = "1.3" } ndarray = "0.15" [dev-dependencies] -test-case = "3.0" \ No newline at end of file +test-case = "3.0" diff --git a/.compatibility_tests/compatibility_test_1_3/Cargo.toml b/.compatibility_tests/compatibility_test_1_3/Cargo.toml index 65e2ad6d..26e51224 100644 --- a/.compatibility_tests/compatibility_test_1_3/Cargo.toml +++ b/.compatibility_tests/compatibility_test_1_3/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "compatibility_test_1_3" -version ="1.11.0" +version = "1.12.0" authors = ["HQS Quantum Simulations "] license = "Apache-2.0" edition = "2021" @@ -19,12 +19,15 @@ publish = false [workspace] [dependencies] -test_roqoqo_1_3 = {package = "roqoqo", version="=1.3.2"} -test_roqoqo_derive_1_3 = {package = "roqoqo-derive", version="=1.3.2"} -qoqo_calculator = { version="1.1" } -roqoqo = {version="1.11.0", path="../../roqoqo", features=["serialize", "overrotate"]} -bincode = {version="1.3"} +test_roqoqo_1_3 = { package = "roqoqo", version = "=1.3.2" } +test_roqoqo_derive_1_3 = { package = "roqoqo-derive", version = "=1.3.2" } +qoqo_calculator = { version = "1.2" } +roqoqo = { version = "1.12.0", path = "../../roqoqo", features = [ + "serialize", + "overrotate", +] } +bincode = { version = "1.3" } ndarray = "0.15" [dev-dependencies] -test-case = "3.0" \ No newline at end of file +test-case = "3.0" diff --git a/.compatibility_tests/compatibility_test_1_4/Cargo.toml b/.compatibility_tests/compatibility_test_1_4/Cargo.toml index 8692b60d..86ba4ec6 100644 --- a/.compatibility_tests/compatibility_test_1_4/Cargo.toml +++ b/.compatibility_tests/compatibility_test_1_4/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "compatibility_test_1_4" -version ="1.11.0" +version = "1.12.0" authors = ["HQS Quantum Simulations "] license = "Apache-2.0" edition = "2021" @@ -19,12 +19,15 @@ publish = false [workspace] [dependencies] -test_roqoqo_1_4 = {package = "roqoqo", version="=1.4.0"} -test_roqoqo_derive_1_4 = {package = "roqoqo-derive", version="=1.4.0"} -qoqo_calculator = { version="1.1" } -roqoqo = {version="1.11.0", path="../../roqoqo", features=["serialize", "overrotate"]} -bincode = {version="1.3"} +test_roqoqo_1_4 = { package = "roqoqo", version = "=1.4.0" } +test_roqoqo_derive_1_4 = { package = "roqoqo-derive", version = "=1.4.0" } +qoqo_calculator = { version = "1.2" } +roqoqo = { version = "1.12.0", path = "../../roqoqo", features = [ + "serialize", + "overrotate", +] } +bincode = { version = "1.3" } ndarray = "0.15" [dev-dependencies] -test-case = "3.0" \ No newline at end of file +test-case = "3.0" diff --git a/.compatibility_tests/compatibility_test_1_5/Cargo.toml b/.compatibility_tests/compatibility_test_1_5/Cargo.toml index 7872c9cf..bf7c5195 100644 --- a/.compatibility_tests/compatibility_test_1_5/Cargo.toml +++ b/.compatibility_tests/compatibility_test_1_5/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "compatibility_test_1_5" -version ="1.11.0" +version = "1.12.0" authors = ["HQS Quantum Simulations "] license = "Apache-2.0" edition = "2021" @@ -19,12 +19,15 @@ publish = false [workspace] [dependencies] -test_roqoqo_1_5 = {package = "roqoqo", version="=1.5.0"} -test_roqoqo_derive_1_5 = {package = "roqoqo-derive", version="=1.5.0"} -qoqo_calculator = { version="1.1" } -roqoqo = {version="1.11.0", path="../../roqoqo", features=["serialize", "overrotate"]} -bincode = {version="1.3"} +test_roqoqo_1_5 = { package = "roqoqo", version = "=1.5.0" } +test_roqoqo_derive_1_5 = { package = "roqoqo-derive", version = "=1.5.0" } +qoqo_calculator = { version = "1.2" } +roqoqo = { version = "1.12.0", path = "../../roqoqo", features = [ + "serialize", + "overrotate", +] } +bincode = { version = "1.3" } ndarray = "0.15" [dev-dependencies] -test-case = "3.0" \ No newline at end of file +test-case = "3.0" diff --git a/.compatibility_tests/compatibility_test_1_6/Cargo.toml b/.compatibility_tests/compatibility_test_1_6/Cargo.toml index 8ff3cc96..48bb4046 100644 --- a/.compatibility_tests/compatibility_test_1_6/Cargo.toml +++ b/.compatibility_tests/compatibility_test_1_6/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "compatibility_test_1_6" -version ="1.11.0" +version = "1.12.0" authors = ["HQS Quantum Simulations "] license = "Apache-2.0" edition = "2021" @@ -19,12 +19,15 @@ publish = false [workspace] [dependencies] -test_roqoqo_1_6 = {package = "roqoqo", version="=1.6.1"} -test_roqoqo_derive_1_6 = {package = "roqoqo-derive", version="=1.6.1"} -qoqo_calculator = { version="1.1" } -roqoqo = {version="1.11.0", path="../../roqoqo", features=["serialize", "overrotate"]} -bincode = {version="1.3"} +test_roqoqo_1_6 = { package = "roqoqo", version = "=1.6.1" } +test_roqoqo_derive_1_6 = { package = "roqoqo-derive", version = "=1.6.1" } +qoqo_calculator = { version = "1.2" } +roqoqo = { version = "1.12.0", path = "../../roqoqo", features = [ + "serialize", + "overrotate", +] } +bincode = { version = "1.3" } ndarray = "0.15" [dev-dependencies] -test-case = "3.0" \ No newline at end of file +test-case = "3.0" diff --git a/.compatibility_tests/compatibility_test_1_7/Cargo.toml b/.compatibility_tests/compatibility_test_1_7/Cargo.toml index a7085cfa..295cc54d 100644 --- a/.compatibility_tests/compatibility_test_1_7/Cargo.toml +++ b/.compatibility_tests/compatibility_test_1_7/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "compatibility_test_1_7" -version ="1.11.0" +version = "1.12.0" authors = ["HQS Quantum Simulations "] license = "Apache-2.0" edition = "2021" @@ -19,12 +19,15 @@ publish = false [workspace] [dependencies] -test_roqoqo_1_7 = {package = "roqoqo", version="=1.7.1"} -test_roqoqo_derive_1_7 = {package = "roqoqo-derive", version="=1.7.1"} -qoqo_calculator = { version="1.1" } -roqoqo = {version="1.11.0", path="../../roqoqo", features=["serialize", "overrotate"]} -bincode = {version="1.3"} +test_roqoqo_1_7 = { package = "roqoqo", version = "=1.7.1" } +test_roqoqo_derive_1_7 = { package = "roqoqo-derive", version = "=1.7.1" } +qoqo_calculator = { version = "1.2" } +roqoqo = { version = "1.12.0", path = "../../roqoqo", features = [ + "serialize", + "overrotate", +] } +bincode = { version = "1.3" } ndarray = "0.15" [dev-dependencies] -test-case = "3.0" \ No newline at end of file +test-case = "3.0" diff --git a/.compatibility_tests/compatibility_test_1_8/Cargo.toml b/.compatibility_tests/compatibility_test_1_8/Cargo.toml index 264a6823..e19365e7 100644 --- a/.compatibility_tests/compatibility_test_1_8/Cargo.toml +++ b/.compatibility_tests/compatibility_test_1_8/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "compatibility_test_1_8" -version ="1.11.0" +version = "1.12.0" authors = ["HQS Quantum Simulations "] license = "Apache-2.0" edition = "2021" @@ -19,12 +19,15 @@ publish = false [workspace] [dependencies] -test_roqoqo_1_8 = {package = "roqoqo", version="=1.8.0"} -test_roqoqo_derive_1_8 = {package = "roqoqo-derive", version="=1.8.0"} -qoqo_calculator = { version="1.1" } -roqoqo = {version="1.11.0", path="../../roqoqo", features=["serialize", "overrotate"]} -bincode = {version="1.3"} +test_roqoqo_1_8 = { package = "roqoqo", version = "=1.8.0" } +test_roqoqo_derive_1_8 = { package = "roqoqo-derive", version = "=1.8.0" } +qoqo_calculator = { version = "1.2" } +roqoqo = { version = "1.12.0", path = "../../roqoqo", features = [ + "serialize", + "overrotate", +] } +bincode = { version = "1.3" } ndarray = "0.15" [dev-dependencies] -test-case = "3.0" \ No newline at end of file +test-case = "3.0" diff --git a/.compatibility_tests/compatibility_test_1_9/Cargo.toml b/.compatibility_tests/compatibility_test_1_9/Cargo.toml index bcada1ad..4cb00a7c 100644 --- a/.compatibility_tests/compatibility_test_1_9/Cargo.toml +++ b/.compatibility_tests/compatibility_test_1_9/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "compatibility_test_1_9" -version ="1.11.0" +version = "1.12.0" authors = ["HQS Quantum Simulations "] license = "Apache-2.0" edition = "2021" @@ -19,12 +19,15 @@ publish = false [workspace] [dependencies] -test_roqoqo_1_9 = {package = "roqoqo", version="=1.9.0"} -test_roqoqo_derive_1_9 = {package = "roqoqo-derive", version="=1.9.0"} -qoqo_calculator = { version="1.1" } -roqoqo = {version="1.11.0", path="../../roqoqo", features=["serialize", "overrotate"]} -bincode = {version="1.3"} +test_roqoqo_1_9 = { package = "roqoqo", version = "=1.9.0" } +test_roqoqo_derive_1_9 = { package = "roqoqo-derive", version = "=1.9.0" } +qoqo_calculator = { version = "1.2" } +roqoqo = { version = "1.12.0", path = "../../roqoqo", features = [ + "serialize", + "overrotate", +] } +bincode = { version = "1.3" } ndarray = "0.15" [dev-dependencies] -test-case = "3.0" \ No newline at end of file +test-case = "3.0" diff --git a/.compatibility_tests/compatibility_test_sim/Cargo.toml b/.compatibility_tests/compatibility_test_sim/Cargo.toml index ef3cfaeb..69fa097e 100644 --- a/.compatibility_tests/compatibility_test_sim/Cargo.toml +++ b/.compatibility_tests/compatibility_test_sim/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "compatibility_test_sim" -version = "1.11.0" +version = "1.12.0" authors = ["HQS Quantum Simulations "] license = "Apache-2.0" edition = "2021" @@ -19,13 +19,15 @@ publish = false [workspace] [dependencies] -test_roqoqo_1_2 = {package = "roqoqo", features=["serialize"], version="=1.2.5"} -qoqo_calculator = { version="1.1" } -roqoqo = {path="../../roqoqo", features=["serialize", "overrotate"]} -num-complex = {version="0.4"} -ndarray="0.15" +test_roqoqo_1_2 = { package = "roqoqo", features = [ + "serialize", +], version = "=1.2.5" } +qoqo_calculator = { version = "1.2" } +roqoqo = { path = "../../roqoqo", features = ["serialize", "overrotate"] } +num-complex = { version = "0.4" } +ndarray = "0.15" [dev-dependencies] test-case = "3.0" -roqoqo-quest = {version="=0.9.1"} +roqoqo-quest = { version = "=0.9.1" } serde_json = "1.0" diff --git a/CHANGELOG.md b/CHANGELOG.md index dde76d90..6879e406 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,8 +2,11 @@ This changelog track changes to the qoqo project starting at version v0.5.0 -## Not yet released +## 1.12.0 +### Added in 1.12.0 + +* Updated to pyo3 0.21. * Fix typo in name of RoqoqoBackendError::AuthenticationError ## 1.11.0 diff --git a/Cargo.lock b/Cargo.lock index 101998f1..75a7ef4a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -42,47 +42,48 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.13" +version = "0.6.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb" +checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", + "is_terminal_polyfill", "utf8parse", ] [[package]] name = "anstyle" -version = "1.0.6" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" +checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" [[package]] name = "anstyle-parse" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" +checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" +checksum = "a64c907d4e79225ac72e2a354c9ce84d50ebb4586dee56c82b3ee73004f537f5" dependencies = [ "windows-sys 0.52.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.2" +version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" +checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" dependencies = [ "anstyle", "windows-sys 0.52.0", @@ -90,9 +91,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.81" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247" +checksum = "25bdb32cbbdce2b519a9cd7df3a678443100e265d5e25ca763b7572a5104f5f3" [[package]] name = "approx" @@ -105,20 +106,20 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.79" +version = "0.1.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507401cad91ec6a857ed5513a2073c82a9b9048762b885bb98655b306964681" +checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.63", ] [[package]] name = "autocfg" -version = "1.2.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "backtrace" @@ -171,23 +172,29 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitflags" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" + [[package]] name = "bumpalo" -version = "3.15.4" +version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ff69b9dd49fd426c69a0db9fc04dd934cdb6645ff000864d98f7e2af8830eaa" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "bytecount" -version = "0.6.7" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1e5f035d16fc623ae5f74981db80a439803888314e3a555fd6f04acd51a3205" +checksum = "5ce89b21cab1437276d2650d57e971f9d548a2d9037cc231abdc0562b97498ce" [[package]] name = "bytemuck" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d6d68c57235a3a081186990eca2867354726650f42f7516ca50c28d6281fd15" +checksum = "78834c15cb5d5efe3452d58b1e8ba890dd62d21907f867f383358198e56ebca5" [[package]] name = "bytes" @@ -197,9 +204,9 @@ checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" [[package]] name = "cc" -version = "1.0.90" +version = "1.0.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5" +checksum = "099a5357d84c4c61eb35fc8eafa9a79a902c2f76911e5747ced4e032edd8d9b4" [[package]] name = "cfg-if" @@ -238,7 +245,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.63", ] [[package]] @@ -249,9 +256,9 @@ checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" [[package]] name = "colorchoice" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" [[package]] name = "core-foundation" @@ -286,15 +293,15 @@ checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" [[package]] name = "either" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" +checksum = "a47c1c47d2f5964e29c61246e81db715514cd532db6b5116a25ea3c03d6780a2" [[package]] name = "encoding_rs" -version = "0.8.33" +version = "0.8.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" dependencies = [ "cfg-if", ] @@ -307,11 +314,12 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "erased-serde" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b73807008a3c7f171cc40312f37d95ef0396e048b5848d775f54b1a4dd4a0d3" +checksum = "24e2389d65ab4fab27dc2a5de7b191e1f6617d1f1c8855c0dc569c94a4cbb18d" dependencies = [ "serde", + "typeid", ] [[package]] @@ -411,7 +419,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.63", ] [[package]] @@ -446,9 +454,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.12" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "js-sys", @@ -484,9 +492,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.14.3" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" [[package]] name = "heck" @@ -596,6 +604,12 @@ version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" +[[package]] +name = "is_terminal_polyfill" +version = "1.70.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" + [[package]] name = "iso8601" version = "0.6.1" @@ -667,9 +681,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.153" +version = "0.2.154" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +checksum = "ae743338b92ff9146ce83992f766a31066a91a8c84a45e0e9f21e7cf6de6d346" [[package]] name = "libm" @@ -679,9 +693,9 @@ checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" [[package]] name = "lock_api" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" dependencies = [ "autocfg", "scopeguard", @@ -803,9 +817,9 @@ dependencies = [ [[package]] name = "num" -version = "0.4.1" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b05180d69e3da0e530ba2a1dae5110317e49e3b7f3d41be227dc5f92e49ee7af" +checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23" dependencies = [ "num-bigint", "num-complex", @@ -817,11 +831,10 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +checksum = "c165a9ab64cf766f73521c0dd2cfdff64f488b8f0b3e621face3462d3db536d7" dependencies = [ - "autocfg", "num-integer", "num-traits", ] @@ -834,9 +847,9 @@ checksum = "63335b2e2c34fae2fb0aa2cecfd9f0832a1e24b3b32ecec612c3426d46dc8aaa" [[package]] name = "num-complex" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23c6602fda94a57c990fe0df199a035d83576b496aa29f4e634a8ac6004e68a6" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" dependencies = [ "num-traits", "serde", @@ -859,9 +872,9 @@ dependencies = [ [[package]] name = "num-iter" -version = "0.1.44" +version = "0.1.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d869c01cc0c455284163fd0092f1f93835385ccab5a98a0dcc497b2f8bf055a9" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" dependencies = [ "autocfg", "num-integer", @@ -870,11 +883,10 @@ dependencies = [ [[package]] name = "num-rational" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" dependencies = [ - "autocfg", "num-bigint", "num-integer", "num-traits", @@ -882,9 +894,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.18" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", "libm", @@ -892,9 +904,9 @@ dependencies = [ [[package]] name = "numpy" -version = "0.20.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef41cbb417ea83b30525259e30ccef6af39b31c240bda578889494c5392d331" +checksum = "ec170733ca37175f5d75a5bea5911d6ff45d2cd52849ce98b685394e4f2f37f4" dependencies = [ "libc", "ndarray", @@ -922,9 +934,9 @@ checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "parking_lot" -version = "0.12.1" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +checksum = "7e4af0ca4f6caed20e900d564c242b8e5d4903fdacf31d3daf527b66fe6f42fb" dependencies = [ "lock_api", "parking_lot_core", @@ -932,22 +944,22 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.9" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", "redox_syscall", "smallvec", - "windows-targets 0.48.5", + "windows-targets 0.52.5", ] [[package]] name = "paste" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" [[package]] name = "percent-encoding" @@ -957,9 +969,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "petgraph" -version = "0.6.4" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" +checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" dependencies = [ "fixedbitset", "indexmap", @@ -999,18 +1011,18 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "proc-macro2" -version = "1.0.79" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "pyo3" -version = "0.20.3" +version = "0.21.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53bdbb96d49157e65d45cc287af5f32ffadd5f4761438b527b055fb0d4bb8233" +checksum = "a5e00b96a521718e08e03b1a622f01c8a8deb50719335de3f60b3b3950f069d8" dependencies = [ "cfg-if", "indoc", @@ -1020,7 +1032,7 @@ dependencies = [ "num-complex", "parking_lot", "portable-atomic", - "pyo3-build-config", + "pyo3-build-config 0.21.2", "pyo3-ffi", "pyo3-macros", "unindent", @@ -1036,44 +1048,54 @@ dependencies = [ "target-lexicon", ] +[[package]] +name = "pyo3-build-config" +version = "0.21.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7883df5835fafdad87c0d888b266c8ec0f4c9ca48a5bed6bbb592e8dedee1b50" +dependencies = [ + "once_cell", + "target-lexicon", +] + [[package]] name = "pyo3-ffi" -version = "0.20.3" +version = "0.21.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b42531d03e08d4ef1f6e85a2ed422eb678b8cd62b762e53891c05faf0d4afa" +checksum = "01be5843dc60b916ab4dad1dca6d20b9b4e6ddc8e15f50c47fe6d85f1fb97403" dependencies = [ "libc", - "pyo3-build-config", + "pyo3-build-config 0.21.2", ] [[package]] name = "pyo3-macros" -version = "0.20.3" +version = "0.21.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7305c720fa01b8055ec95e484a6eca7a83c841267f0dd5280f0c8b8551d2c158" +checksum = "77b34069fc0682e11b31dbd10321cbf94808394c56fd996796ce45217dfac53c" dependencies = [ "proc-macro2", "pyo3-macros-backend", "quote", - "syn 2.0.58", + "syn 2.0.63", ] [[package]] name = "pyo3-macros-backend" -version = "0.20.3" +version = "0.21.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c7e9b68bb9c3149c5b0cade5d07f953d6d125eb4337723c4ccdb665f1f96185" +checksum = "08260721f32db5e1a5beae69a55553f56b99bd0e1c3e6e0a5e8851a9d0f5a85c" dependencies = [ "heck 0.4.1", "proc-macro2", - "pyo3-build-config", + "pyo3-build-config 0.21.2", "quote", - "syn 2.0.58", + "syn 2.0.63", ] [[package]] name = "qoqo" -version = "1.11.0" +version = "1.12.0" dependencies = [ "bincode", "nalgebra", @@ -1082,7 +1104,7 @@ dependencies = [ "numpy", "proc-macro2", "pyo3", - "pyo3-build-config", + "pyo3-build-config 0.21.2", "qoqo-macros", "qoqo_calculator", "qoqo_calculator_pyo3", @@ -1093,26 +1115,26 @@ dependencies = [ "serde_json", "struqture", "struqture-py", - "syn 2.0.58", + "syn 2.0.63", "test-case", "thiserror", ] [[package]] name = "qoqo-macros" -version = "1.11.0" +version = "1.12.0" dependencies = [ "proc-macro2", "quote", "struqture", - "syn 2.0.58", + "syn 2.0.63", ] [[package]] name = "qoqo_calculator" -version = "1.1.5" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67110647e68fb28b7afaec29245b7a40d2908635065df84361d99dbd4c75053e" +checksum = "6fa8b27bb34103af09afcca6d21ccb52dfa66a34c0ffa0f8103003bb1afd9d53" dependencies = [ "num-complex", "schemars", @@ -1122,13 +1144,13 @@ dependencies = [ [[package]] name = "qoqo_calculator_pyo3" -version = "1.1.5" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e973e62b55ef8196012cba19711688d4ff11c7929792043faba13fe8fbd7b2c" +checksum = "76c7ab3901e5e23a81517803d3cecc9e3de2fe0fbf1355726ff9df6e7ff1b4fd" dependencies = [ "num-complex", "pyo3", - "pyo3-build-config", + "pyo3-build-config 0.21.2", "qoqo_calculator", "serde", "thiserror", @@ -1136,9 +1158,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -1191,11 +1213,11 @@ checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" [[package]] name = "redox_syscall" -version = "0.4.1" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +checksum = "469052894dcb553421e483e4209ee581a45100d31b4018de03e5a7ad86374a7e" dependencies = [ - "bitflags", + "bitflags 2.5.0", ] [[package]] @@ -1265,7 +1287,7 @@ dependencies = [ [[package]] name = "roqoqo" -version = "1.11.0" +version = "1.12.0" dependencies = [ "async-trait", "bincode", @@ -1287,7 +1309,7 @@ dependencies = [ "serde_json", "serde_test", "struqture", - "syn 2.0.58", + "syn 2.0.63", "test-case", "thiserror", "typetag", @@ -1295,16 +1317,16 @@ dependencies = [ [[package]] name = "roqoqo-derive" -version = "1.11.0" +version = "1.12.0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.63", ] [[package]] name = "roqoqo-test" -version = "1.11.0" +version = "1.12.0" dependencies = [ "nalgebra", "ndarray", @@ -1313,14 +1335,14 @@ dependencies = [ "quote", "rand", "roqoqo", - "syn 2.0.58", + "syn 2.0.63", ] [[package]] name = "rustc-demangle" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustc-hash" @@ -1330,9 +1352,9 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] name = "ryu" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "safe_arch" @@ -1345,9 +1367,9 @@ dependencies = [ [[package]] name = "schemars" -version = "0.8.16" +version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45a28f4c49489add4ce10783f7911893516f15afe45d015608d41faca6bc4d29" +checksum = "fc6e7ed6919cb46507fb01ff1654309219f62b4d603822501b0b80d42f6f21ef" dependencies = [ "dyn-clone", "schemars_derive", @@ -1357,14 +1379,14 @@ dependencies = [ [[package]] name = "schemars_derive" -version = "0.8.16" +version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c767fd6fa65d9ccf9cf026122c1b555f2ef9a4f0cea69da4d7dbc3e258d30967" +checksum = "185f2b7aa7e02d418e453790dde16890256bbd2bcd04b7dc5348811052b53f49" dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn 1.0.109", + "syn 2.0.63", ] [[package]] @@ -1375,40 +1397,40 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "serde" -version = "1.0.197" +version = "1.0.202" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +checksum = "226b61a0d411b2ba5ff6d7f73a476ac4f8bb900373459cd00fab8512828ba395" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.197" +version = "1.0.202" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +checksum = "6048858004bcff69094cd972ed40a32500f153bd3be9f716b2eed2e8217c4838" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.63", ] [[package]] name = "serde_derive_internals" -version = "0.26.0" +version = "0.29.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85bf8229e7920a9f636479437026331ce11aa132b4dde37d121944a44d6e5f3c" +checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.63", ] [[package]] name = "serde_json" -version = "1.0.115" +version = "1.0.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12dc5c46daa8e9fdf4f5e71b6cf9a53f2487da0e86e55808e2d35539666497dd" +checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" dependencies = [ "itoa", "ryu", @@ -1466,9 +1488,9 @@ checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "socket2" -version = "0.5.6" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" dependencies = [ "libc", "windows-sys 0.52.0", @@ -1482,9 +1504,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "struqture" -version = "1.6.1" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6a6fae203fb8098042ab51364cf5ff79020312e68b63038371d627029ab08" +checksum = "d2fe3b5ee158db81a424c6194639a689b67a37b133578ffd8fc9e07e3b6a1f57" dependencies = [ "itertools", "ndarray", @@ -1499,16 +1521,16 @@ dependencies = [ [[package]] name = "struqture-py" -version = "1.6.1" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd549b80a7e8a929b9125c37c8ec8f74916df3ed2fbc427462ee93812c1f450e" +checksum = "a608a0a151196d275cdead34c1a804da410a20abde8f8047e3b3603ab2b4271a" dependencies = [ "bincode", "num-complex", "numpy", "proc-macro2", "pyo3", - "pyo3-build-config", + "pyo3-build-config 0.20.3", "qoqo_calculator", "qoqo_calculator_pyo3", "quote", @@ -1517,20 +1539,20 @@ dependencies = [ "serde_json", "struqture", "struqture-py-macros", - "syn 2.0.58", + "syn 2.0.63", "thiserror", ] [[package]] name = "struqture-py-macros" -version = "1.6.1" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3215f75379ad75b4847b3166e5fd39de65ae2723a9cdd382ad92966925a8f48e" +checksum = "577cbc9755cc3e7c83fbaa31b9c869d90ccd20c23cd36f5561c32454ea6d4e73" dependencies = [ "num-complex", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.63", ] [[package]] @@ -1546,9 +1568,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.58" +version = "2.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44cfb93f38070beee36b3fef7d4f5a16f27751d94b187b666a5cc5e9b0d30687" +checksum = "bf5be731623ca1a1fb7d8be6f261a3be6d3e2337b8a1f97be944d020c8fcb704" dependencies = [ "proc-macro2", "quote", @@ -1567,7 +1589,7 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" dependencies = [ - "bitflags", + "bitflags 1.3.2", "core-foundation", "system-configuration-sys", ] @@ -1606,7 +1628,7 @@ dependencies = [ "cfg-if", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.63", ] [[package]] @@ -1617,35 +1639,35 @@ checksum = "5c89e72a01ed4c579669add59014b9a524d609c0c88c6a585ce37485879f6ffb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.63", "test-case-core", ] [[package]] name = "thiserror" -version = "1.0.58" +version = "1.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297" +checksum = "579e9083ca58dd9dcf91a9923bb9054071b9ebbd800b342194c9feb0ee89fc18" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.58" +version = "1.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" +checksum = "e2470041c06ec3ac1ab38d0356a6119054dedaea53e12fbefc0de730a1c08524" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.63", ] [[package]] name = "time" -version = "0.3.34" +version = "0.3.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8248b6521bb14bc45b4067159b9b6ad792e2d6d754d6c41fb50e29fefe38749" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" dependencies = [ "deranged", "num-conv", @@ -1663,9 +1685,9 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.17" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ba3a3ef41e6672a2f0f001392bb5dcd3ff0a9992d618ca761a11c3121547774" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" dependencies = [ "num-conv", "time-core", @@ -1704,16 +1726,15 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.10" +version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" dependencies = [ "bytes", "futures-core", "futures-sink", "pin-project-lite", "tokio", - "tracing", ] [[package]] @@ -1747,6 +1768,12 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" +[[package]] +name = "typeid" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "059d83cc991e7a42fc37bd50941885db0888e34209f8cfd9aab07ddec03bc9cf" + [[package]] name = "typenum" version = "1.17.0" @@ -1774,7 +1801,7 @@ checksum = "ac73887f47b9312552aa90ef477927ff014d63d1920ca8037c6c1951eab64bb1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.63", ] [[package]] @@ -1869,7 +1896,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.63", "wasm-bindgen-shared", ] @@ -1903,7 +1930,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.63", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -1926,9 +1953,9 @@ dependencies = [ [[package]] name = "wide" -version = "0.7.15" +version = "0.7.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89beec544f246e679fc25490e3f8e08003bc4bf612068f325120dad4cea02c1c" +checksum = "aab6594190de06d718a5dbc5fa781ab62f8903797056480e549ca74add6b7065" dependencies = [ "bytemuck", "safe_arch", @@ -1949,7 +1976,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.4", + "windows-targets 0.52.5", ] [[package]] @@ -1969,17 +1996,18 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" +checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" dependencies = [ - "windows_aarch64_gnullvm 0.52.4", - "windows_aarch64_msvc 0.52.4", - "windows_i686_gnu 0.52.4", - "windows_i686_msvc 0.52.4", - "windows_x86_64_gnu 0.52.4", - "windows_x86_64_gnullvm 0.52.4", - "windows_x86_64_msvc 0.52.4", + "windows_aarch64_gnullvm 0.52.5", + "windows_aarch64_msvc 0.52.5", + "windows_i686_gnu 0.52.5", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.5", + "windows_x86_64_gnu 0.52.5", + "windows_x86_64_gnullvm 0.52.5", + "windows_x86_64_msvc 0.52.5", ] [[package]] @@ -1990,9 +2018,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" +checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" [[package]] name = "windows_aarch64_msvc" @@ -2002,9 +2030,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" +checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" [[package]] name = "windows_i686_gnu" @@ -2014,9 +2042,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.4" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" +checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" [[package]] name = "windows_i686_msvc" @@ -2026,9 +2060,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" +checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" [[package]] name = "windows_x86_64_gnu" @@ -2038,9 +2072,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" +checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" [[package]] name = "windows_x86_64_gnullvm" @@ -2050,9 +2084,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" +checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" [[package]] name = "windows_x86_64_msvc" @@ -2062,9 +2096,9 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" +checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" [[package]] name = "winreg" @@ -2078,20 +2112,20 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.7.32" +version = "0.7.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +checksum = "ae87e3fcd617500e5d106f0380cf7b77f3c6092aae37191433159dda23cfb087" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.32" +version = "0.7.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.63", ] diff --git a/Cargo.toml b/Cargo.toml index 6f953ce2..77fc9e66 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,11 +1,5 @@ [workspace] -members = [ - "roqoqo", - "roqoqo-derive", - "roqoqo-test", - "qoqo", - "qoqo-macros", -] +members = ["roqoqo", "roqoqo-derive", "roqoqo-test", "qoqo", "qoqo-macros"] resolver = "2" @@ -13,4 +7,4 @@ resolver = "2" lto = true [profile.bench] -lto = true \ No newline at end of file +lto = true diff --git a/qoqo-macros/Cargo.toml b/qoqo-macros/Cargo.toml index 912dc162..e5bfa662 100644 --- a/qoqo-macros/Cargo.toml +++ b/qoqo-macros/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "qoqo-macros" -version = "1.11.0" +version = "1.12.0" authors = ["HQS Quantum Simulations "] license = "Apache-2.0" readme = "../README.md" @@ -19,7 +19,7 @@ doctest = false proc-macro2 = "1.0" syn = { version = "2.0", features = ["full", "visit"] } quote = "1.0" -struqture = {version="1.5"} +struqture = { version = "1.7" } [features] unstable_chain_with_environment = [] diff --git a/qoqo-macros/src/devices.rs b/qoqo-macros/src/devices.rs index 39ee713b..538ec1de 100644 --- a/qoqo-macros/src/devices.rs +++ b/qoqo-macros/src/devices.rs @@ -220,10 +220,10 @@ pub fn device_wrapper_def( fn qubit_decoherence_rates(&self, qubit: usize) -> Py> { Python::with_gil(|py| -> Py> { match self.internal.qubit_decoherence_rates(&qubit) { - Some(matrix) => matrix.to_pyarray(py).to_owned(), + Some(matrix) => matrix.to_pyarray_bound(py).to_owned().into(), None => { let matrix = Array2::::zeros((3, 3)); - matrix.to_pyarray(py).to_owned() + matrix.to_pyarray_bound(py).to_owned().into() } } }) @@ -341,7 +341,7 @@ pub fn device_wrapper_def( /// Returns: /// A deep copy of self. /// - pub fn __deepcopy__(&self, _memodict: Py) -> Self { + pub fn __deepcopy__(&self, _memodict: &Bound) -> Self { self.clone() } @@ -357,7 +357,7 @@ pub fn device_wrapper_def( let serialized = serialize(&self.internal) .map_err(|_| PyValueError::new_err("Cannot serialize Device to bytes"))?; let b: Py = Python::with_gil(|py| -> Py { - PyByteArray::new(py, &serialized[..]).into() + PyByteArray::new_bound(py, &serialized[..]).into() }); Ok(b) } @@ -389,8 +389,9 @@ pub fn device_wrapper_def( /// ValueError: Input cannot be deserialized to selected Device. #[staticmethod] #[pyo3(text_signature = "(input)")] - pub fn from_bincode(input: &PyAny) -> PyResult<#ident> { + pub fn from_bincode(input: &Bound) -> PyResult<#ident> { let bytes = input + .as_gil_ref() .extract::>() .map_err(|_| PyTypeError::new_err("Input cannot be converted to byte array"))?; @@ -438,7 +439,7 @@ pub fn device_wrapper_def( /// Raises: /// NotImplementedError: Other comparison not implemented. /// - fn __richcmp__(&self, other: Py, op: pyo3::class::basic::CompareOp) -> PyResult { + fn __richcmp__(&self, other: &Bound, op: pyo3::class::basic::CompareOp) -> PyResult { let other = #ident::from_pyany(other); match op { pyo3::class::basic::CompareOp::Eq => match other { diff --git a/qoqo-macros/src/lib.rs b/qoqo-macros/src/lib.rs index b72513b7..a014ab42 100644 --- a/qoqo-macros/src/lib.rs +++ b/qoqo-macros/src/lib.rs @@ -153,7 +153,7 @@ pub fn wrap( /// pub fn superoperator(&self) -> PyResult>>{ Python::with_gil(|py| -> PyResult>> { - Ok(self.internal.superoperator().unwrap().to_pyarray(py).to_owned()) + Ok(self.internal.superoperator().unwrap().to_pyarray_bound(py).as_gil_ref().into()) }) } /// Return the power of the noise gate @@ -297,20 +297,17 @@ pub fn wrap( /// print("Multiplied gate: ", multiplied) /// ``` /// - pub fn mul(&self, other: Py) -> PyResult { - Python::with_gil(|py| -> PyResult { - let other_ref = other.as_ref(py); - let other: Operation = crate::operations::convert_pyany_to_operation(other_ref).map_err(|x| { - pyo3::exceptions::PyTypeError::new_err(format!("Right hand side cannot be converted to Operation {:?}",x)) - })?; - let other_converted: SingleQubitGateOperation = other.clone().try_into().map_err(|x| { - pyo3::exceptions::PyRuntimeError::new_err(format!("Conversion to SingleQubitGateOperation failed {:?}",x)) - })?; - let multiplied = self.internal.mul(&other_converted).map_err(|x| { - pyo3::exceptions::PyRuntimeError::new_err(format!("Multiplication failed {:?}",x)) - })?; - Ok(SingleQubitGateWrapper{ internal: multiplied}) - }) + pub fn mul(&self, other: &Bound) -> PyResult { + let other: Operation = crate::operations::convert_pyany_to_operation(other).map_err(|x| { + pyo3::exceptions::PyTypeError::new_err(format!("Right hand side cannot be converted to Operation {:?}",x)) + })?; + let other_converted: SingleQubitGateOperation = other.clone().try_into().map_err(|x| { + pyo3::exceptions::PyRuntimeError::new_err(format!("Conversion to SingleQubitGateOperation failed {:?}",x)) + })?; + let multiplied = self.internal.mul(&other_converted).map_err(|x| { + pyo3::exceptions::PyRuntimeError::new_err(format!("Multiplication failed {:?}",x)) + })?; + Ok(SingleQubitGateWrapper{ internal: multiplied}) } } } else { @@ -382,7 +379,10 @@ pub fn wrap( /// ValueError: Error symbolic operation cannot return float unitary matrix pub fn unitary_matrix(&self) -> PyResult>>{ Python::with_gil(|py| -> PyResult>> { - Ok(self.internal.unitary_matrix().map_err(|x| PyValueError::new_err(format!("Error symbolic operation cannot return float unitary matrix {:?}",x)))?.to_pyarray(py).to_owned()) + Ok(self.internal.unitary_matrix().map_err(|x| PyValueError::new_err(format!("Error symbolic operation cannot return float unitary matrix {:?}",x)))? + .to_pyarray_bound(py) + .as_gil_ref() + .into()) }) } } @@ -453,12 +453,12 @@ pub fn wrap( let involved = self.internal.involved_modes(); match involved { InvolvedModes::All => { - let pyref: &PySet = PySet::new(py, &["All"]).unwrap(); + let pyref: &Bound = &PySet::new_bound(py, &["All"]).unwrap(); let pyobject: PyObject = pyref.to_object(py); pyobject }, InvolvedModes::None => { - let pyref: &PySet = PySet::empty(py).unwrap(); + let pyref: &Bound = &PySet::empty_bound(py).unwrap(); let pyobject: PyObject = pyref.to_object(py); pyobject }, @@ -467,7 +467,7 @@ pub fn wrap( for mode in x { vector.push(mode) } - let pyref: &PySet = PySet::new(py, &vector[..]).unwrap(); + let pyref: &Bound = &PySet::new_bound(py, &vector[..]).unwrap(); let pyobject: PyObject = pyref.to_object(py); pyobject }, @@ -662,22 +662,18 @@ pub fn wrap( /// /// `PyResult` - whether the two operations compared evaluated to True or False /// - fn __richcmp__(&self, other: Py, op: pyo3::class::basic::CompareOp) -> PyResult { - Python::with_gil(|py| -> PyResult { - let other_ref = other.as_ref(py); - let other: Operation = crate::operations::convert_pyany_to_operation(other_ref).map_err(|x| { - pyo3::exceptions::PyTypeError::new_err(format!("Right hand side cannot be converted to Operation {:?}",x)) - })?; - match op { - pyo3::class::basic::CompareOp::Eq => Ok(Operation::from(self.internal.clone()) == other), - pyo3::class::basic::CompareOp::Ne => Ok(Operation::from(self.internal.clone()) != other), - _ => Err(pyo3::exceptions::PyNotImplementedError::new_err( - "Other comparison not implemented.", - )), - } - }) + fn __richcmp__(&self, other: &Bound, op: pyo3::class::basic::CompareOp) -> PyResult { + let other: Operation = crate::operations::convert_pyany_to_operation(other).map_err(|x| { + pyo3::exceptions::PyTypeError::new_err(format!("Right hand side cannot be converted to Operation {:?}",x)) + })?; + match op { + pyo3::class::basic::CompareOp::Eq => Ok(Operation::from(self.internal.clone()) == other), + pyo3::class::basic::CompareOp::Ne => Ok(Operation::from(self.internal.clone()) != other), + _ => Err(pyo3::exceptions::PyNotImplementedError::new_err( + "Other comparison not implemented.", + )), + } } - } }; q.into() diff --git a/qoqo-macros/src/noise_models.rs b/qoqo-macros/src/noise_models.rs index d3c67150..b24a18a0 100644 --- a/qoqo-macros/src/noise_models.rs +++ b/qoqo-macros/src/noise_models.rs @@ -40,7 +40,7 @@ pub fn noise_model_wrapper_def( /// Returns: /// A deep copy of self. /// - pub fn __deepcopy__(&self, _memodict: Py) -> Self { + pub fn __deepcopy__(&self, _memodict: &Bound) -> Self { self.clone() } @@ -57,7 +57,7 @@ pub fn noise_model_wrapper_def( let serialized = bincode::serialize(&noise_model) .map_err(|_| pyo3::exceptions::PyValueError::new_err("Cannot serialize Noise-Model to bytes"))?; let b: Py = Python::with_gil(|py| -> Py { - pyo3::types::PyByteArray::new(py, &serialized[..]).into() + pyo3::types::PyByteArray::new_bound(py, &serialized[..]).into() }); Ok(b) } @@ -110,7 +110,7 @@ pub fn noise_model_wrapper_def( /// Raises: /// NotImplementedError: Other comparison not implemented. /// - fn __richcmp__(&self, other: Py, op: pyo3::class::basic::CompareOp) -> PyResult { + fn __richcmp__(&self, other: &Bound, op: pyo3::class::basic::CompareOp) -> PyResult { let other = #ident::from_pyany(other); match op { @@ -131,9 +131,7 @@ pub fn noise_model_wrapper_def( impl #ident { /// Fallible conversion of generic python object.. - pub fn from_pyany(input: Py) -> PyResult { - Python::with_gil(|py| -> PyResult { - let input = input.as_ref(py); + pub fn from_pyany(input: &Bound) -> PyResult { if let Ok(try_downcast) = input.extract::<#ident>() { Ok(try_downcast.internal.into()) } else { @@ -146,7 +144,6 @@ pub fn noise_model_wrapper_def( )) }) } - }) } } }; diff --git a/qoqo-macros/src/operate.rs b/qoqo-macros/src/operate.rs index 2c91694e..715e2979 100644 --- a/qoqo-macros/src/operate.rs +++ b/qoqo-macros/src/operate.rs @@ -34,10 +34,10 @@ fn operate_struct(ds: DataStruct, ident: Ident) -> TokenStream { .clone() .map(|(id, type_string, ty)| match type_string { Some(s) => match s.as_str() { - "CalculatorFloat" => quote! {#id: &pyo3::PyAny}, - "Circuit" => quote! {#id: &pyo3::PyAny}, - "Option" => quote! {#id: &pyo3::PyAny}, - "SpinHamiltonian" => quote! {#id: pyo3::Py}, + "CalculatorFloat" => quote! {#id: &pyo3::Bound}, + "Circuit" => quote! {#id: &pyo3::Bound}, + "Option" => quote! {#id: &pyo3::Bound}, + "SpinHamiltonian" => quote! {#id: &pyo3::Bound}, _ => quote! {#id: #ty}, }, _ => quote! {#id: #ty}, @@ -101,7 +101,7 @@ fn operate_struct(ds: DataStruct, ident: Ident) -> TokenStream { pyo3::exceptions::PyTypeError::new_err(format!("Argument cannot be converted to Circuit {:?}",x)) })?; let #id_extracted: Option = match tmp{ - Some(cw) => Some(convert_into_circuit(cw).map_err(|x| { + Some(cw) => Some(convert_into_circuit(&cw.as_borrowed()).map_err(|x| { pyo3::exceptions::PyTypeError::new_err(format!("Argument cannot be converted to Circuit {:?}",x)) })?), _ => None }; @@ -237,7 +237,7 @@ fn operate_struct(ds: DataStruct, ident: Ident) -> TokenStream { /// /// Raises: /// RuntimeError: Parameter Substitution failed - fn substitute_parameters(&self, substitution_parameters: std::collections::HashMap<&str, f64>) -> PyResult { + fn substitute_parameters(&self, substitution_parameters: std::collections::HashMap) -> PyResult { let mut calculator = qoqo_calculator::Calculator::new(); for (key, val) in substitution_parameters.iter(){ calculator.set_variable(key, *val); @@ -273,12 +273,12 @@ fn operate_struct(ds: DataStruct, ident: Ident) -> TokenStream { let involved = self.internal.involved_qubits(); match involved { InvolvedQubits::All => { - let pyref: &PySet = PySet::new(py, &["All"]).unwrap(); + let pyref: &Bound = &PySet::new_bound(py, &["All"]).unwrap(); let pyobject: PyObject = pyref.to_object(py); pyobject }, InvolvedQubits::None => { - let pyref: &PySet = PySet::empty(py).unwrap(); + let pyref: &Bound = &PySet::empty_bound(py).unwrap(); let pyobject: PyObject = pyref.to_object(py); pyobject }, @@ -287,7 +287,7 @@ fn operate_struct(ds: DataStruct, ident: Ident) -> TokenStream { for qubit in x { vector.push(qubit) } - let pyref: &PySet = PySet::new(py, &vector[..]).unwrap(); + let pyref: &Bound = &PySet::new_bound(py, &vector[..]).unwrap(); let pyobject: PyObject = pyref.to_object(py); pyobject }, @@ -303,7 +303,7 @@ fn operate_struct(ds: DataStruct, ident: Ident) -> TokenStream { } /// Creates deep copy of Operation - fn __deepcopy__(&self, _memodict: Py) -> Self { + fn __deepcopy__(&self, _memodict: &Bound) -> Self { self.clone() } } diff --git a/qoqo/Cargo.toml b/qoqo/Cargo.toml index e9800dd6..104383d0 100644 --- a/qoqo/Cargo.toml +++ b/qoqo/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "qoqo" -version = "1.11.0" +version = "1.12.0" authors = ["HQS Quantum Simulations "] license = "Apache-2.0" homepage = "https://github.com/HQSquantumsimulations/qoqo" @@ -9,9 +9,16 @@ documentation = "https://docs.rs/qoqo/" readme = "README.md" edition = "2021" rust-version = "1.56" -categories = ["science", "simulation","ffi"] +categories = ["science", "simulation", "ffi"] description = "Quantum computing circuit toolkit. Python interface of roqoqo" -include = ["src*", "build.rs", "qoqo*", "LICENSE", "README.md", "pyproject.toml"] +include = [ + "src*", + "build.rs", + "qoqo*", + "LICENSE", + "README.md", + "pyproject.toml", +] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -22,7 +29,7 @@ doctest = false crate-type = ["cdylib", "rlib"] [dependencies.pyo3] -version = "0.20" +version = "0.21" features = ["num-complex", "multiple-pymethods"] [dependencies] @@ -30,13 +37,16 @@ serde = { version = "1.0", features = ["derive"] } ndarray = "0.15" num-complex = "0.4" thiserror = "1.0" -qoqo_calculator = { version="1.1" } -qoqo_calculator_pyo3 = {version="1.1", default-features=false} -qoqo-macros = {version="1.11.0", path="../qoqo-macros"} -roqoqo = {version="1.11.0", path="../roqoqo", features=["serialize", "overrotate"]} -struqture = {version="1.5"} -struqture-py = {version = "1.5", default-features = false} -numpy = "0.20" +qoqo_calculator = { version = "1.2" } +qoqo_calculator_pyo3 = { version = "1.2", default-features = false } +qoqo-macros = { version = "1.12.0", path = "../qoqo-macros" } +roqoqo = { version = "1.12.0", path = "../roqoqo", features = [ + "serialize", + "overrotate", +] } +struqture = { version = "1.7" } +struqture-py = { version = "1.7", default-features = false } +numpy = "0.21" bincode = "1.3" serde_json = "1.0" schemars = "0.8" @@ -49,7 +59,7 @@ nalgebra = "0.32" quote = "1.0" syn = { version = "2.0", features = ["full", "visit"] } proc-macro2 = "1.0" -pyo3-build-config = "0.20" +pyo3-build-config = "0.21" [package.metadata.docs.rs] no-default-features = true @@ -59,5 +69,8 @@ extension-module = ["pyo3/extension-module", "circuitdag"] default = ["extension-module", "json_schema"] circuitdag = ["roqoqo/circuitdag"] json_schema = ["roqoqo/json_schema"] -unstable_chain_with_environment = ["roqoqo/unstable_chain_with_environment", "qoqo-macros/unstable_chain_with_environment"] +unstable_chain_with_environment = [ + "roqoqo/unstable_chain_with_environment", + "qoqo-macros/unstable_chain_with_environment", +] unstable_analog_operations = ["roqoqo/unstable_analog_operations"] diff --git a/qoqo/build.rs b/qoqo/build.rs index 0a55e905..f4e35d2e 100644 --- a/qoqo/build.rs +++ b/qoqo/build.rs @@ -160,41 +160,41 @@ fn main() { Some(type_str) => match type_str.as_str(){ "CalculatorFloat" => {quote!{ - let #pyobject_name = op + let #pyobject_name = &op .call_method0(#ident_string) .map_err(|_| QoqoError::ConversionError)?; let #ident = convert_into_calculator_float(#pyobject_name).map_err(|_| QoqoError::ConversionError)?; }}, "Circuit" => {quote!{ - let #pyobject_name = op + let #pyobject_name = &op .call_method0(#ident_string) .map_err(|_| QoqoError::ConversionError)?; let #ident = convert_into_circuit(#pyobject_name).map_err(|_| QoqoError::ConversionError)?; }}, "Option" => {quote!{ - let #pyobject_name = op + let #pyobject_name = &op .call_method0(#ident_string) .map_err(|_| QoqoError::ConversionError)?; let tmp: Option<&PyAny> = #pyobject_name.extract().map_err(|_| QoqoError::ConversionError)?; let #ident = match tmp{ - Some(cw) => Some(convert_into_circuit(cw) + Some(cw) => Some(convert_into_circuit(&cw.as_borrowed()) .map_err(|_| QoqoError::ConversionError)?), _ => None }; }}, "SpinHamiltonian" => {quote!{ - let #pyobject_name = op + let #pyobject_name = &op .call_method0(#ident_string) .map_err(|_| QoqoError::ConversionError)?; - let temp_op: struqture::spins::SpinHamiltonianSystem = struqture_py::spins::SpinHamiltonianSystemWrapper::from_pyany(#pyobject_name.into()).map_err(|_| QoqoError::ConversionError)?; + let temp_op: struqture::spins::SpinHamiltonianSystem = struqture_py::spins::SpinHamiltonianSystemWrapper::from_pyany(#pyobject_name).map_err(|_| QoqoError::ConversionError)?; let #ident = temp_op.hamiltonian().clone(); }}, _ => { quote!{ - let #pyobject_name = op + let #pyobject_name = &op .call_method0(#ident_string) .map_err(|_| QoqoError::ConversionError)?; let #ident: #ty = #pyobject_name.extract() @@ -203,7 +203,7 @@ fn main() { }, None => { quote!{ - let #pyobject_name = op + let #pyobject_name = &op .call_method0(#ident_string) .map_err(|_| QoqoError::ConversionError)?; let #ident: #ty = #pyobject_name.extract() @@ -262,11 +262,11 @@ fn main() { } /// Tries to convert any python object to a [roqoqo::operations::Operation] - pub fn convert_pyany_to_operation(op: &PyAny) -> Result { - let hqslang_pyobject = op + pub fn convert_pyany_to_operation(op: &Bound) -> Result { + let hqslang_pyobject = &op .call_method0("hqslang") .map_err(|_| QoqoError::ConversionError)?; - let hqslang: String = String::extract(hqslang_pyobject) + let hqslang: String = String::extract_bound(hqslang_pyobject) .map_err(|_| QoqoError::ConversionError)?; match hqslang.as_str() { #(#pyany_to_operation_quotes),* diff --git a/qoqo/pyproject.toml b/qoqo/pyproject.toml index d622d281..8374a1b5 100644 --- a/qoqo/pyproject.toml +++ b/qoqo/pyproject.toml @@ -1,12 +1,11 @@ [project] name = "qoqo" -version = "1.11.0" -dependencies = [ - 'numpy', - 'qoqo_calculator_pyo3>=1.1', +version = "1.12.0" +dependencies = ['numpy', 'qoqo_calculator_pyo3>=1.2'] +license = { text = "Apache-2.0 AND Apache-2.0 with LLVM-exception AND MIT AND Unicode-DFS-2016 AND BSD-2-Clause AND BSD-3-CLause" } +maintainers = [ + { name = "HQS Quantum Simulations GmbH", email = "info@quantumsimulations.de" }, ] -license = {text="Apache-2.0 AND Apache-2.0 with LLVM-exception AND MIT AND Unicode-DFS-2016 AND BSD-2-Clause AND BSD-3-CLause"} -maintainers = [{name = "HQS Quantum Simulations GmbH", email = "info@quantumsimulations.de"}] requires-python = ">=3.7" readme = "README.md" @@ -23,11 +22,11 @@ profile = "release" [project.optional-dependencies] docs = [ - "sphinx >= 2.1", - "nbsphinx", - "pygments", - "recommonmark", - "myst_parser", - "sphinx_rtd_theme", - "tomli" + "sphinx >= 2.1", + "nbsphinx", + "pygments", + "recommonmark", + "myst_parser", + "sphinx_rtd_theme", + "tomli", ] diff --git a/qoqo/qoqo/DEPENDENCIES b/qoqo/qoqo/DEPENDENCIES index a8cfa0c8..266a01cf 100644 --- a/qoqo/qoqo/DEPENDENCIES +++ b/qoqo/qoqo/DEPENDENCIES @@ -245,6 +245,22 @@ https://github.com/jonas-schievink/adler.git by Jonas Schievink A simple clean-room implementation of the Adler-32 checksum License: 0BSD OR MIT OR Apache-2.0 +---------------------------------------------------- +LICENSE-0BSD: + +Copyright (C) Jonas Schievink + +Permission to use, copy, modify, and/or distribute this software for +any purpose with or without fee is hereby granted. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN +AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ---------------------------------------------------- LICENSE-MIT: @@ -272,22 +288,6 @@ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ----------------------------------------------------- -LICENSE-0BSD: - -Copyright (C) Jonas Schievink - -Permission to use, copy, modify, and/or distribute this software for -any purpose with or without fee is hereby granted. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN -AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT -OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - ---------------------------------------------------- LICENSE-APACHE: @@ -741,31 +741,6 @@ https://github.com/BurntSushi/aho-corasick by Andrew Gallant Fast multiple substring searching. License: Unlicense OR MIT ----------------------------------------------------- -LICENSE-MIT: - -The MIT License (MIT) - -Copyright (c) 2015 Andrew Gallant - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - ---------------------------------------------------- UNLICENSE: @@ -794,24 +769,12 @@ OTHER DEALINGS IN THE SOFTWARE. For more information, please refer to ----------------------------------------------------- -COPYING: - -This project is dual-licensed under the Unlicense and MIT licenses. - -You may use this code under the terms of either license. - - -==================================================== -anstream 0.6.13 -https://github.com/rust-cli/anstyle -by -A simple cross platform library for writing colored text to a terminal. -License: MIT OR Apache-2.0 ---------------------------------------------------- LICENSE-MIT: -Copyright (c) Individual contributors +The MIT License (MIT) + +Copyright (c) 2015 Andrew Gallant Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -820,234 +783,35 @@ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. ---------------------------------------------------- -LICENSE-APACHE: - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright {yyyy} {name of copyright owner} - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 +COPYING: - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. +This project is dual-licensed under the Unlicense and MIT licenses. +You may use this code under the terms of either license. ==================================================== -anstyle 1.0.6 +anstream 0.6.14 https://github.com/rust-cli/anstyle by -ANSI text styling +A simple cross platform library for writing colored text to a terminal. License: MIT OR Apache-2.0 ---------------------------------------------------- LICENSE-MIT: -Copyright (c) 2022 The rust-cli Developers +Copyright (c) Individual contributors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -1275,7 +1039,243 @@ LICENSE-APACHE: ==================================================== -anstyle-parse 0.2.3 +anstyle 1.0.7 +https://github.com/rust-cli/anstyle +by +ANSI text styling +License: MIT OR Apache-2.0 +---------------------------------------------------- +LICENSE-MIT: + +Copyright (c) 2022 The rust-cli Developers + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +---------------------------------------------------- +LICENSE-APACHE: + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + +==================================================== +anstyle-parse 0.2.4 https://github.com/rust-cli/anstyle by Parse ANSI Style Escapes @@ -1516,7 +1516,7 @@ LICENSE-APACHE: ==================================================== -anstyle-query 1.0.2 +anstyle-query 1.0.3 https://github.com/rust-cli/anstyle by Look up colored console capabilities @@ -1752,7 +1752,7 @@ LICENSE-APACHE: ==================================================== -anstyle-wincon 3.0.2 +anstyle-wincon 3.0.3 https://github.com/rust-cli/anstyle by Styling legacy Windows terminals @@ -1988,7 +1988,7 @@ LICENSE-APACHE: ==================================================== -anyhow 1.0.81 +anyhow 1.0.83 https://github.com/dtolnay/anyhow by David Tolnay Flexible concrete Error type built on std::error::Error @@ -2415,7 +2415,7 @@ LICENSE: ==================================================== -autocfg 1.2.0 +autocfg 1.3.0 https://github.com/cuviper/autocfg by Josh Stone Automatic cfg for Rust compiler features @@ -3891,7 +3891,249 @@ limitations under the License. ==================================================== -bumpalo 3.15.4 +bitflags 2.5.0 +https://github.com/bitflags/bitflags +by The Rust Project Developers +A macro to generate structures which behave like bitflags. + +License: MIT OR Apache-2.0 +---------------------------------------------------- +LICENSE-MIT: + +Copyright (c) 2014 The Rust Project Developers + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +---------------------------------------------------- +LICENSE-APACHE: + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + + +==================================================== +bumpalo 3.16.0 https://github.com/fitzgen/bumpalo by Nick Fitzgerald A fast bump allocation arena for Rust. @@ -4132,11 +4374,34 @@ limitations under the License. ==================================================== -bytecount 0.6.7 +bytecount 0.6.8 https://github.com/llogiq/bytecount by Andre Bogus , Joshua Landau count occurrences of a given byte, or the number of UTF-8 code points, in a byte slice, fast License: Apache-2.0/MIT +---------------------------------------------------- +LICENSE.MIT: + +Copyright (c) 2017 The bytecount Developers + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + ---------------------------------------------------- LICENSE.Apache2: @@ -4342,32 +4607,9 @@ LICENSE.Apache2: See the License for the specific language governing permissions and limitations under the License. ----------------------------------------------------- -LICENSE.MIT: - -Copyright (c) 2017 The bytecount Developers - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - ==================================================== -bytemuck 1.15.0 +bytemuck 1.16.0 https://github.com/Lokathor/bytemuck by Lokathor A crate for mucking around with piles of bytes. @@ -4385,21 +4627,6 @@ The above copyright notice and this permission notice (including the next paragr THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ----------------------------------------------------- -LICENSE-ZLIB: - -Copyright (c) 2019 Daniel "Lokathor" Gee. - -This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. - -Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: - -1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. - -2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. - -3. This notice may not be removed or altered from any source distribution. - ---------------------------------------------------- LICENSE-APACHE: @@ -4465,6 +4692,21 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +---------------------------------------------------- +LICENSE-ZLIB: + +Copyright (c) 2019 Daniel "Lokathor" Gee. + +This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source distribution. + ==================================================== bytes 1.6.0 @@ -4503,7 +4745,7 @@ DEALINGS IN THE SOFTWARE. ==================================================== -cc 1.0.90 +cc 1.0.97 https://github.com/rust-lang/cc-rs by Alex Crichton A build-time dependency for Cargo build scripts to assist in invoking the native @@ -5938,7 +6180,7 @@ LICENSE-APACHE: ==================================================== -colorchoice 1.0.0 +colorchoice 1.0.1 https://github.com/rust-cli/anstyle by Global override of color control @@ -6661,6 +6903,212 @@ https://github.com/jhpratt/deranged by Jacob Pratt Ranged integers License: MIT OR Apache-2.0 +---------------------------------------------------- +LICENSE-Apache: + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2022 Jacob Pratt et al. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ---------------------------------------------------- LICENSE-MIT: @@ -6684,212 +7132,6 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ----------------------------------------------------- -LICENSE-Apache: - - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2022 Jacob Pratt et al. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - ==================================================== dyn-clone 1.0.17 @@ -7106,7 +7348,7 @@ END OF TERMS AND CONDITIONS ==================================================== -either 1.10.0 +either 1.11.0 https://github.com/rayon-rs/either by bluss The enum `Either` with variants `Left` and `Right` is a general purpose sum type with two cases. @@ -7348,7 +7590,7 @@ limitations under the License. ==================================================== -encoding_rs 0.8.33 +encoding_rs 0.8.34 https://docs.rs/encoding_rs/ by Henri Sivonen A Gecko-oriented implementation of the Encoding Standard @@ -7382,36 +7624,6 @@ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ----------------------------------------------------- -LICENSE-WHATWG: - -Copyright © WHATWG (Apple, Google, Mozilla, Microsoft). - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -3. Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ---------------------------------------------------- LICENSE-APACHE: @@ -7618,6 +7830,36 @@ LICENSE-APACHE: See the License for the specific language governing permissions and limitations under the License. +---------------------------------------------------- +LICENSE-WHATWG: + +Copyright © WHATWG (Apple, Google, Mozilla, Microsoft). + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ==================================================== equivalent 1.0.1 @@ -10321,7 +10563,7 @@ limitations under the License. ==================================================== -getrandom 0.2.12 +getrandom 0.2.15 https://github.com/rust-random/getrandom by The Rand Project Developers A small cross-platform library for retrieving random data from system source @@ -10840,7 +11082,7 @@ DEALINGS IN THE SOFTWARE. ==================================================== -hashbrown 0.14.3 +hashbrown 0.14.5 https://github.com/rust-lang/hashbrown by Amanieu d'Antras A Rust port of Google's SwissTable hash map @@ -13475,6 +13717,242 @@ LICENSE-APACHE: limitations under the License. +==================================================== +is_terminal_polyfill 1.70.0 +https://github.com/polyfill-rs/is_terminal_polyfill +by +Polyfill for `is_terminal` stdlib feature for use with older MSRVs +License: MIT OR Apache-2.0 +---------------------------------------------------- +LICENSE-MIT: + +Copyright (c) Individual contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +---------------------------------------------------- +LICENSE-APACHE: + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + ==================================================== iso8601 0.6.1 https://github.com/badboy/iso8601 @@ -14453,7 +14931,7 @@ limitations under the License. ==================================================== -libc 0.2.153 +libc 0.2.154 https://github.com/rust-lang/libc by The Rust Project Developers Raw FFI bindings to platform libraries like libc. @@ -14911,7 +15389,7 @@ limitations under the License. ==================================================== -lock_api 0.4.11 +lock_api 0.4.12 https://github.com/Amanieu/parking_lot by Amanieu d'Antras Wrappers to create fully-featured Mutex and RwLock types. Compatible with no_std. @@ -15646,31 +16124,6 @@ Provides extremely fast (uses SIMD on x86_64, aarch64 and wasm32) routines for 1, 2 or 3 byte search and single substring search. License: Unlicense OR MIT ----------------------------------------------------- -LICENSE-MIT: - -The MIT License (MIT) - -Copyright (c) 2015 Andrew Gallant - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - ---------------------------------------------------- UNLICENSE: @@ -15699,6 +16152,31 @@ OTHER DEALINGS IN THE SOFTWARE. For more information, please refer to +---------------------------------------------------- +LICENSE-MIT: + +The MIT License (MIT) + +Copyright (c) 2015 Andrew Gallant + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + ---------------------------------------------------- COPYING: @@ -15978,6 +16456,33 @@ https://github.com/Alexhuszagh/minimal-lexical by Alex Huszagh Fast float parsing conversion routines. License: MIT/Apache-2.0 +---------------------------------------------------- +LICENSE-MIT: + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + ---------------------------------------------------- LICENSE.md: @@ -16019,33 +16524,6 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----------------------------------------------------- -LICENSE-MIT: - -Permission is hereby granted, free of charge, to any -person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the -Software without restriction, including without -limitation the rights to use, copy, modify, merge, -publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software -is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice -shall be included in all copies or substantial portions -of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF -ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED -TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT -SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR -IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. - ---------------------------------------------------- LICENSE-APACHE: @@ -16259,19 +16737,54 @@ by Frommi , oyvindln PyO3-based Rust bindings of the NumPy C-API @@ -19874,7 +20352,7 @@ limitations under the License. ==================================================== -parking_lot 0.12.1 +parking_lot 0.12.2 https://github.com/Amanieu/parking_lot by Amanieu d'Antras More compact and efficient implementations of the standard synchronization primitives. @@ -20115,7 +20593,7 @@ limitations under the License. ==================================================== -parking_lot_core 0.9.9 +parking_lot_core 0.9.10 https://github.com/Amanieu/parking_lot by Amanieu d'Antras An advanced API for creating custom synchronization primitives. @@ -20356,7 +20834,7 @@ limitations under the License. ==================================================== -paste 1.0.14 +paste 1.0.15 https://github.com/dtolnay/paste by David Tolnay Macros for all your token pasting needs @@ -20811,7 +21289,7 @@ limitations under the License. ==================================================== -petgraph 0.6.4 +petgraph 0.6.5 https://github.com/petgraph/petgraph by bluss, mitchmindtree Graph data structure library. Provides graph types and graph algorithms. @@ -21734,29 +22212,6 @@ by Jacob Pratt allocation, and avoid repetitive calculations. License: MIT OR Apache-2.0 ----------------------------------------------------- -LICENSE-MIT: - -Copyright (c) 2023 Jacob Pratt et al. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - ---------------------------------------------------- LICENSE-Apache: @@ -21963,6 +22418,29 @@ LICENSE-Apache: See the License for the specific language governing permissions and limitations under the License. +---------------------------------------------------- +LICENSE-MIT: + +Copyright (c) 2023 Jacob Pratt et al. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + ==================================================== ppv-lite86 0.2.17 @@ -22206,7 +22684,7 @@ limitations under the License. ==================================================== -proc-macro2 1.0.79 +proc-macro2 1.0.82 https://github.com/dtolnay/proc-macro2 by David Tolnay , Alex Crichton A substitute implementation of the compiler's `proc_macro` API to decouple token-based libraries from the procedural macro use case. @@ -22420,7 +22898,7 @@ END OF TERMS AND CONDITIONS ==================================================== -pyo3 0.20.3 +pyo3 0.21.2 https://github.com/pyo3/pyo3 by PyO3 Project and Contributors Bindings to Python interpreter @@ -22878,7 +23356,236 @@ LICENSE-APACHE: ==================================================== -pyo3-ffi 0.20.3 +pyo3-build-config 0.21.2 +https://github.com/pyo3/pyo3 +by PyO3 Project and Contributors +Build configuration for the PyO3 ecosystem +License: MIT OR Apache-2.0 +---------------------------------------------------- +LICENSE-MIT: + +Copyright (c) 2023-present PyO3 Project and Contributors. https://github.com/PyO3 + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +---------------------------------------------------- +LICENSE-APACHE: + + Copyright (c) 2017-present PyO3 Project and Contributors. https://github.com/PyO3 + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + +==================================================== +pyo3-ffi 0.21.2 https://github.com/pyo3/pyo3 by PyO3 Project and Contributors Python-API bindings for the PyO3 ecosystem @@ -23107,7 +23814,7 @@ LICENSE-APACHE: ==================================================== -pyo3-macros 0.20.3 +pyo3-macros 0.21.2 https://github.com/pyo3/pyo3 by PyO3 Project and Contributors Proc macros for PyO3 package @@ -23336,7 +24043,7 @@ LICENSE-APACHE: ==================================================== -pyo3-macros-backend 0.20.3 +pyo3-macros-backend 0.21.2 https://github.com/pyo3/pyo3 by PyO3 Project and Contributors Code generation for PyO3 package @@ -23565,7 +24272,7 @@ LICENSE-APACHE: ==================================================== -qoqo 1.11.0 +qoqo 1.12.0 https://github.com/HQSquantumsimulations/qoqo by HQS Quantum Simulations Quantum computing circuit toolkit. Python interface of roqoqo @@ -23777,7 +24484,7 @@ LICENSE: ==================================================== -qoqo-macros 1.11.0 +qoqo-macros 1.12.0 by HQS Quantum Simulations Macros for the qoqo crate License: Apache-2.0 @@ -23988,7 +24695,7 @@ LICENSE: ==================================================== -qoqo_calculator 1.1.5 +qoqo_calculator 1.2.2 https://github.com/HQSquantumsimulations/qoqo_calculator by HQS Quantum Simulations qoqo-calculator is the calculator backend of the qoqo quantum computing toolkit by HQS Quantum Simulations @@ -24200,7 +24907,7 @@ LICENSE: ==================================================== -qoqo_calculator_pyo3 1.1.5 +qoqo_calculator_pyo3 1.2.2 https://github.com/HQSquantumsimulations/qoqo_calculator_pyo3 by HQS Quantum Simulations Python interface to qoqo calculator, the calculator backend of the qoqo quantum computing toolkit by HQS Quantum Simulations @@ -24412,7 +25119,7 @@ LICENSE: ==================================================== -quote 1.0.35 +quote 1.0.36 https://github.com/dtolnay/quote by David Tolnay Quasi-quoting macro quote!(...) @@ -25789,7 +26496,7 @@ limitations under the License. ==================================================== -redox_syscall 0.4.1 +redox_syscall 0.5.1 https://gitlab.redox-os.org/redox-os/syscall by Jeremy Soller A Rust library to access raw Redox system calls @@ -26783,7 +27490,7 @@ limitations under the License. ==================================================== -roqoqo 1.11.0 +roqoqo 1.12.0 https://github.com/HQSquantumsimulations/qoqo by HQS Quantum Simulations Rust Quantum Computing Toolkit by HQS @@ -26995,7 +27702,7 @@ LICENSE: ==================================================== -roqoqo-derive 1.11.0 +roqoqo-derive 1.12.0 by HQS Quantum Simulations Macros for the roqoqo crate License: Apache-2.0 @@ -27206,7 +27913,7 @@ LICENSE: ==================================================== -roqoqo-test 1.11.0 +roqoqo-test 1.12.0 https://github.com/HQSquantumsimulations/qoqo by HQS Quantum Simulations Testing helper functions for roqoqo toolkit @@ -27418,8 +28125,8 @@ LICENSE: ==================================================== -rustc-demangle 0.1.23 -https://github.com/alexcrichton/rustc-demangle +rustc-demangle 0.1.24 +https://github.com/rust-lang/rustc-demangle by Alex Crichton Rust compiler symbol demangling. @@ -27899,7 +28606,7 @@ limitations under the License. ==================================================== -ryu 1.0.17 +ryu 1.0.18 https://github.com/dtolnay/ryu by David Tolnay Fast floating point to string conversion @@ -28119,19 +28826,17 @@ by Lokathor Crate that exposes `core::arch` safely via `#[cfg()]`. License: Zlib OR Apache-2.0 OR MIT ---------------------------------------------------- -LICENSE-ZLIB.md: +LICENSE-MIT.md: -Copyright (c) 2020 Daniel "Lokathor" Gee. - -This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. +MIT License -Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +Copyright (c) 2023 Daniel "Lokathor" Gee. -1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: -2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software. -3. This notice may not be removed or altered from any source distribution. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------- LICENSE-APACHE.md: @@ -28199,21 +28904,23 @@ See the License for the specific language governing permissions and limitations under the License. ---------------------------------------------------- -LICENSE-MIT.md: +LICENSE-ZLIB.md: -MIT License +Copyright (c) 2020 Daniel "Lokathor" Gee. -Copyright (c) 2023 Daniel "Lokathor" Gee. +This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: +Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: -The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software. +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source distribution. ==================================================== -schemars 0.8.16 +schemars 0.8.19 https://graham.cool/schemars/ by Graham Esau Generate JSON Schemas from Rust code @@ -28245,7 +28952,7 @@ SOFTWARE. ==================================================== -schemars_derive 0.8.16 +schemars_derive 0.8.19 https://graham.cool/schemars/ by Graham Esau Macros for #[derive(JsonSchema)], for use with schemars @@ -28496,251 +29203,37 @@ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION END OF TERMS AND CONDITIONS -APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - -Copyright [yyyy] [name of copyright owner] - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - - -==================================================== -serde 1.0.197 -https://serde.rs -by Erick Tryzelaar , David Tolnay -A generic serialization/deserialization framework -License: MIT OR Apache-2.0 ----------------------------------------------------- -LICENSE-MIT: - -Permission is hereby granted, free of charge, to any -person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the -Software without restriction, including without -limitation the rights to use, copy, modify, merge, -publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software -is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice -shall be included in all copies or substantial portions -of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF -ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED -TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT -SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR -IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. - ----------------------------------------------------- -LICENSE-APACHE: - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - -2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - -3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - -4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - -5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - -6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - -8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS - +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + ==================================================== -serde_derive 1.0.197 +serde 1.0.202 https://serde.rs by Erick Tryzelaar , David Tolnay -Macros 1.1 implementation of #[derive(Serialize, Deserialize)] +A generic serialization/deserialization framework License: MIT OR Apache-2.0 ---------------------------------------------------- LICENSE-MIT: @@ -28951,10 +29444,10 @@ END OF TERMS AND CONDITIONS ==================================================== -serde_derive_internals 0.26.0 +serde_derive 1.0.202 https://serde.rs by Erick Tryzelaar , David Tolnay -AST representation used by Serde derive macros. Unstable. +Macros 1.1 implementation of #[derive(Serialize, Deserialize)] License: MIT OR Apache-2.0 ---------------------------------------------------- LICENSE-MIT: @@ -29163,34 +29656,223 @@ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION END OF TERMS AND CONDITIONS -APPENDIX: How to apply the Apache License to your work. - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. +==================================================== +serde_derive_internals 0.29.1 +https://serde.rs +by Erick Tryzelaar , David Tolnay +AST representation used by Serde derive macros. Unstable. +License: MIT OR Apache-2.0 +---------------------------------------------------- +LICENSE-MIT: -Copyright [yyyy] [name of copyright owner] +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. - http://www.apache.org/licenses/LICENSE-2.0 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. +---------------------------------------------------- +LICENSE-APACHE: + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS ==================================================== -serde_json 1.0.115 +serde_json 1.0.117 https://github.com/serde-rs/json by Erick Tryzelaar , David Tolnay A JSON serialization file format @@ -30323,7 +31005,7 @@ limitations under the License. ==================================================== -socket2 0.5.6 +socket2 0.5.7 https://github.com/rust-lang/socket2 by Alex Crichton , Thomas de Zeeuw Utilities for handling networking sockets with a maximal amount of configuration @@ -30602,7 +31284,7 @@ SOFTWARE. ==================================================== -struqture 1.6.1 +struqture 1.7.0 by HQS Quantum Simulations HQS tool for representing operators, Hamiltonians and open systems. License: Apache-2.0 @@ -30813,13 +31495,13 @@ LICENSE: ==================================================== -struqture-py 1.6.1 +struqture-py 1.7.0 by HQS Quantum Simulations Python interface of struqture, the HQS tool for representing operators, Hamiltonians and open systems. License: Apache-2.0 ==================================================== -struqture-py-macros 1.6.1 +struqture-py-macros 1.7.0 by HQS Quantum Simulations Macros for struqture-py crate. License: Apache-2.0 @@ -31269,7 +31951,7 @@ limitations under the License. ==================================================== -syn 2.0.58 +syn 2.0.63 https://github.com/dtolnay/syn by David Tolnay Parser for Rust source code @@ -32012,7 +32694,7 @@ SOFTWARE. ==================================================== -thiserror 1.0.58 +thiserror 1.0.60 https://github.com/dtolnay/thiserror by David Tolnay derive(Error) @@ -32226,7 +32908,7 @@ END OF TERMS AND CONDITIONS ==================================================== -thiserror-impl 1.0.58 +thiserror-impl 1.0.60 https://github.com/dtolnay/thiserror by David Tolnay Implementation detail of the `thiserror` crate @@ -32440,34 +33122,11 @@ END OF TERMS AND CONDITIONS ==================================================== -time 0.3.34 +time 0.3.36 https://time-rs.github.io by Jacob Pratt , Time contributors Date and time library. Fully interoperable with the standard library. Mostly compatible with #![no_std]. License: MIT OR Apache-2.0 ----------------------------------------------------- -LICENSE-MIT: - -Copyright (c) 2024 Jacob Pratt et al. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - ---------------------------------------------------- LICENSE-Apache: @@ -32674,17 +33333,10 @@ LICENSE-Apache: See the License for the specific language governing permissions and limitations under the License. - -==================================================== -time-core 0.1.2 -https://github.com/time-rs/time -by Jacob Pratt , Time contributors -This crate is an implementation detail and should not be relied upon directly. -License: MIT OR Apache-2.0 ---------------------------------------------------- LICENSE-MIT: -Copyright (c) 2022 Jacob Pratt et al. +Copyright (c) 2024 Jacob Pratt et al. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -32704,6 +33356,13 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +==================================================== +time-core 0.1.2 +https://github.com/time-rs/time +by Jacob Pratt , Time contributors +This crate is an implementation detail and should not be relied upon directly. +License: MIT OR Apache-2.0 ---------------------------------------------------- LICENSE-Apache: @@ -32910,19 +33569,10 @@ LICENSE-Apache: See the License for the specific language governing permissions and limitations under the License. - -==================================================== -time-macros 0.2.17 -https://github.com/time-rs/time -by Jacob Pratt , Time contributors - Procedural macros for the time crate. - This crate is an implementation detail and should not be relied upon directly. - -License: MIT OR Apache-2.0 ---------------------------------------------------- LICENSE-MIT: -Copyright (c) 2024 Jacob Pratt et al. +Copyright (c) 2022 Jacob Pratt et al. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -32942,6 +33592,15 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +==================================================== +time-macros 0.2.18 +https://github.com/time-rs/time +by Jacob Pratt , Time contributors + Procedural macros for the time crate. + This crate is an implementation detail and should not be relied upon directly. + +License: MIT OR Apache-2.0 ---------------------------------------------------- LICENSE-Apache: @@ -33148,6 +33807,29 @@ LICENSE-Apache: See the License for the specific language governing permissions and limitations under the License. +---------------------------------------------------- +LICENSE-MIT: + +Copyright (c) 2024 Jacob Pratt et al. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + ==================================================== tinyvec 1.6.0 @@ -33156,19 +33838,13 @@ by Lokathor `tinyvec` provides 100% safe vec-like data structures. License: Zlib OR Apache-2.0 OR MIT ---------------------------------------------------- -LICENSE-ZLIB.md: +LICENSE-MIT.md: -Copyright (c) 2019 Daniel "Lokathor" Gee. - -This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. - -Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: - -1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: -2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -3. This notice may not be removed or altered from any source distribution. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------- LICENSE-APACHE.md: @@ -33377,13 +34053,19 @@ LICENSE-APACHE.md: limitations under the License. ---------------------------------------------------- -LICENSE-MIT.md: +LICENSE-ZLIB.md: -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: +Copyright (c) 2019 Daniel "Lokathor" Gee. -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source distribution. ==================================================== @@ -33393,28 +34075,29 @@ by Soveu Some macros for tiny containers License: MIT OR Apache-2.0 OR Zlib ---------------------------------------------------- -LICENSE-ZLIB.md: - -zlib License +LICENSE-MIT.md: -(C) 2020 Tomasz "Soveu" Marx +MIT License -This software is provided 'as-is', without any express or implied -warranty. In no event will the authors be held liable for any damages -arising from the use of this software. +Copyright (c) 2020 Soveu -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it -freely, subject to the following restrictions: +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: -1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. -2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. -3. This notice may not be removed or altered from any source distribution. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. ---------------------------------------------------- LICENSE-APACHE.md: @@ -33623,29 +34306,28 @@ LICENSE-APACHE.md: ---------------------------------------------------- -LICENSE-MIT.md: +LICENSE-ZLIB.md: -MIT License +zlib License -Copyright (c) 2020 Soveu +(C) 2020 Tomasz "Soveu" Marx -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. ==================================================== @@ -33687,7 +34369,7 @@ DEALINGS IN THE SOFTWARE. ==================================================== -tokio-util 0.7.10 +tokio-util 0.7.11 https://tokio.rs by Tokio Contributors Additional utilities for working with Tokio. @@ -33876,6 +34558,10 @@ Typenum is a Rust library for type-level numbers evaluated at implementation is incomplete. License: MIT OR Apache-2.0 ---------------------------------------------------- +LICENSE: + +MIT OR Apache-2.0 +---------------------------------------------------- LICENSE-MIT: The MIT License (MIT) @@ -34104,10 +34790,6 @@ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ----------------------------------------------------- -LICENSE: - -MIT OR Apache-2.0 ==================================================== unicode-bidi 0.3.15 @@ -34356,33 +35038,6 @@ https://github.com/dtolnay/unicode-ident by David Tolnay Determine whether characters have the XID_Start or XID_Continue properties according to Unicode Standard Annex #31 License: (MIT OR Apache-2.0) AND Unicode-DFS-2016 ----------------------------------------------------- -LICENSE-MIT: - -Permission is hereby granted, free of charge, to any -person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the -Software without restriction, including without -limitation the rights to use, copy, modify, merge, -publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software -is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice -shall be included in all copies or substantial portions -of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF -ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED -TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT -SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR -IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. - ---------------------------------------------------- LICENSE-UNICODE: @@ -34433,6 +35088,33 @@ shall not be used in advertising or otherwise to promote the sale, use or other dealings in these Data Files or Software without prior written authorization of the copyright holder. +---------------------------------------------------- +LICENSE-MIT: + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + ---------------------------------------------------- LICENSE-APACHE: @@ -36044,33 +36726,6 @@ https://github.com/bytecodealliance/wasi by The Cranelift Project Developers Experimental WASI API bindings for Rust License: Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT ----------------------------------------------------- -LICENSE-MIT: - -Permission is hereby granted, free of charge, to any -person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the -Software without restriction, including without -limitation the rights to use, copy, modify, merge, -publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software -is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice -shall be included in all copies or substantial portions -of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF -ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED -TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT -SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR -IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. - ---------------------------------------------------- LICENSE-Apache-2.0_WITH_LLVM-exception: @@ -36295,6 +36950,33 @@ the License, but only in their entirety and only with respect to the Combined Software. +---------------------------------------------------- +LICENSE-MIT: + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + ---------------------------------------------------- LICENSE-APACHE: @@ -38196,7 +38878,7 @@ limitations under the License. ==================================================== -wide 0.7.15 +wide 0.7.19 https://github.com/Lokathor/wide by Lokathor A crate to help you go wide. @@ -38929,7 +39611,7 @@ license-mit: ==================================================== -windows-targets 0.52.4 +windows-targets 0.52.5 https://github.com/microsoft/windows-rs by Microsoft Import libs for Windows @@ -39403,7 +40085,7 @@ license-mit: ==================================================== -windows_aarch64_gnullvm 0.52.4 +windows_aarch64_gnullvm 0.52.5 https://github.com/microsoft/windows-rs by Microsoft Import lib for Windows @@ -39877,7 +40559,7 @@ license-mit: ==================================================== -windows_aarch64_msvc 0.52.4 +windows_aarch64_msvc 0.52.5 https://github.com/microsoft/windows-rs by Microsoft Import lib for Windows @@ -40351,7 +41033,244 @@ license-mit: ==================================================== -windows_i686_gnu 0.52.4 +windows_i686_gnu 0.52.5 +https://github.com/microsoft/windows-rs +by Microsoft +Import lib for Windows +License: MIT OR Apache-2.0 +---------------------------------------------------- +license-apache-2.0: + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright (c) Microsoft Corporation. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +---------------------------------------------------- +license-mit: + + MIT License + + Copyright (c) Microsoft Corporation. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE + + +==================================================== +windows_i686_gnullvm 0.52.5 https://github.com/microsoft/windows-rs by Microsoft Import lib for Windows @@ -40825,7 +41744,7 @@ license-mit: ==================================================== -windows_i686_msvc 0.52.4 +windows_i686_msvc 0.52.5 https://github.com/microsoft/windows-rs by Microsoft Import lib for Windows @@ -41299,7 +42218,7 @@ license-mit: ==================================================== -windows_x86_64_gnu 0.52.4 +windows_x86_64_gnu 0.52.5 https://github.com/microsoft/windows-rs by Microsoft Import lib for Windows @@ -41773,7 +42692,7 @@ license-mit: ==================================================== -windows_x86_64_gnullvm 0.52.4 +windows_x86_64_gnullvm 0.52.5 https://github.com/microsoft/windows-rs by Microsoft Import lib for Windows @@ -42247,7 +43166,7 @@ license-mit: ==================================================== -windows_x86_64_msvc 0.52.4 +windows_x86_64_msvc 0.52.5 https://github.com/microsoft/windows-rs by Microsoft Import lib for Windows @@ -42514,11 +43433,39 @@ THE SOFTWARE. ==================================================== -zerocopy 0.7.32 +zerocopy 0.7.34 https://github.com/google/zerocopy by Joshua Liebow-Feeser Utilities for zero-copy parsing and serialization License: BSD-2-Clause OR Apache-2.0 OR MIT +---------------------------------------------------- +LICENSE-BSD: + +Copyright 2019 The Fuchsia Authors. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ---------------------------------------------------- LICENSE-MIT: @@ -42755,6 +43702,13 @@ LICENSE-APACHE: limitations under the License. + +==================================================== +zerocopy-derive 0.7.34 +https://github.com/google/zerocopy +by Joshua Liebow-Feeser +Custom derive for traits from the zerocopy crate +License: BSD-2-Clause OR Apache-2.0 OR MIT ---------------------------------------------------- LICENSE-BSD: @@ -42783,13 +43737,6 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -==================================================== -zerocopy-derive 0.7.32 -https://github.com/google/zerocopy -by Joshua Liebow-Feeser -Custom derive for traits from the zerocopy crate -License: BSD-2-Clause OR Apache-2.0 OR MIT ---------------------------------------------------- LICENSE-MIT: @@ -43026,32 +43973,4 @@ LICENSE-APACHE: limitations under the License. ----------------------------------------------------- -LICENSE-BSD: - -Copyright 2019 The Fuchsia Authors. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - diff --git a/qoqo/src/circuit.rs b/qoqo/src/circuit.rs index c1f64b49..cbe5390b 100644 --- a/qoqo/src/circuit.rs +++ b/qoqo/src/circuit.rs @@ -38,7 +38,7 @@ use crate::operations::{convert_operation_to_pyobject, convert_pyany_to_operatio /// #[pymodule] -fn circuit(_py: Python, module: &PyModule) -> PyResult<()> { +fn circuit(_py: Python, module: &Bound) -> PyResult<()> { module.add_class::()?; Ok(()) } @@ -68,26 +68,23 @@ impl CircuitWrapper { /// # Arguments: /// /// `input` - The Python object that should be casted to a [roqoqo::Circuit] - pub fn from_pyany(input: Py) -> PyResult { - Python::with_gil(|py| -> PyResult { - let input = input.as_ref(py); - if let Ok(try_downcast) = input.extract::() { - Ok(try_downcast.internal) - } else { - let get_bytes = input.call_method0("to_bincode").map_err(|_| { + pub fn from_pyany(input: &Bound) -> PyResult { + if let Ok(try_downcast) = input.extract::() { + Ok(try_downcast.internal) + } else { + let get_bytes = input.call_method0("to_bincode").map_err(|_| { PyTypeError::new_err("Python object cannot be converted to qoqo Circuit: Cast to binary representation failed".to_string()) })?; - let bytes = get_bytes.extract::>().map_err(|_| { + let bytes = get_bytes.extract::>().map_err(|_| { PyTypeError::new_err("Python object cannot be converted to qoqo Circuit: Cast to binary representation failed".to_string()) })?; - deserialize(&bytes[..]).map_err(|err| { - PyTypeError::new_err(format!( + deserialize(&bytes[..]).map_err(|err| { + PyTypeError::new_err(format!( "Python object cannot be converted to qoqo Circuit: Deserialization failed: {}", err )) - }) - } - }) + }) + } } } @@ -116,7 +113,7 @@ impl CircuitWrapper { /// RuntimeError: The parameter substitution failed. pub fn substitute_parameters( &self, - substitution_parameters: std::collections::HashMap<&str, f64>, + substitution_parameters: std::collections::HashMap, ) -> PyResult { let mut calculator = qoqo_calculator::Calculator::new(); for (key, val) in substitution_parameters.iter() { @@ -189,10 +186,10 @@ impl CircuitWrapper { /// /// Returns: /// int: The number of occurences of these operation tags. - pub fn count_occurences(&self, operations: Vec<&str>) -> usize { + pub fn count_occurences(&self, operations: Vec) -> usize { let mut counter: usize = 0; for op in self.internal.iter() { - if operations.iter().any(|x| op.tags().contains(x)) { + if operations.iter().any(|x| op.tags().contains(&x.as_str())) { counter += 1 } } @@ -223,7 +220,7 @@ impl CircuitWrapper { /// /// Returns: /// Circuit: A deep copy of self. - pub fn __deepcopy__(&self, _memodict: Py) -> CircuitWrapper { + pub fn __deepcopy__(&self, _memodict: &Bound) -> CircuitWrapper { self.clone() } @@ -258,7 +255,7 @@ impl CircuitWrapper { let serialized = serialize(&self.internal) .map_err(|_| PyValueError::new_err("Cannot serialize Circuit to bytes"))?; let b: Py = Python::with_gil(|py| -> Py { - PyByteArray::new(py, &serialized[..]).into() + PyByteArray::new_bound(py, &serialized[..]).into() }); Ok(b) } @@ -275,8 +272,9 @@ impl CircuitWrapper { /// TypeError: Input cannot be converted to byte array. /// ValueError: Input cannot be deserialized to Circuit. #[staticmethod] - pub fn from_bincode(input: &PyAny) -> PyResult { + pub fn from_bincode(input: &Bound) -> PyResult { let bytes = input + .as_gil_ref() .extract::>() .map_err(|_| PyTypeError::new_err("Input cannot be converted to byte array"))?; @@ -485,7 +483,7 @@ impl CircuitWrapper { /// /// Args: /// op (Operation): The Operation to add to the Circuit. - pub fn add(&mut self, op: &PyAny) -> PyResult<()> { + pub fn add(&mut self, op: &Bound) -> PyResult<()> { let operation = convert_pyany_to_operation(op).map_err(|x| { PyTypeError::new_err(format!("Cannot convert python object to Operation {:?}", x)) })?; @@ -521,7 +519,11 @@ impl CircuitWrapper { /// /// Raises: /// NotImplementedError: Other comparison not implemented - fn __richcmp__(&self, other: Py, op: pyo3::class::basic::CompareOp) -> PyResult { + fn __richcmp__( + &self, + other: &Bound, + op: pyo3::class::basic::CompareOp, + ) -> PyResult { let other = Self::from_pyany(other); match op { pyo3::class::basic::CompareOp::Eq => match other { @@ -584,7 +586,7 @@ impl CircuitWrapper { /// Raises: /// TypeError: Cannot convert python object to Operation. /// IndexError: Index out of range. - fn __setitem__(&mut self, index: usize, value: &PyAny) -> PyResult<()> { + fn __setitem__(&mut self, index: usize, value: &Bound) -> PyResult<()> { let operation = convert_pyany_to_operation(value) .map_err(|_| PyTypeError::new_err("Cannot convert python object to Operation"))?; let mut_reference = self @@ -602,74 +604,69 @@ impl CircuitWrapper { /// /// Raises: /// TypeError: Right hand side cannot be converted to Operation or Circuit. - fn __iadd__(&mut self, other: Py) -> PyResult<()> { - Python::with_gil(|py| -> PyResult<()> { - let other_ref = other.as_ref(py); - match convert_pyany_to_operation(other_ref) { - Ok(x) => { - self.internal += x; - Ok(()) - } - Err(_) => { - let other = convert_into_circuit(other_ref).map_err(|x| { - pyo3::exceptions::PyTypeError::new_err(format!( - "Right hand side cannot be converted to Operation or Circuit {:?}", - x - )) - }); - match other { - Ok(x) => { - self.internal += x; - Ok(()) - } - Err(y) => Err(y), + fn __iadd__(&mut self, other: &Bound) -> PyResult<()> { + match convert_pyany_to_operation(other) { + Ok(x) => { + self.internal += x; + Ok(()) + } + Err(_) => { + let other = convert_into_circuit(other).map_err(|x| { + pyo3::exceptions::PyTypeError::new_err(format!( + "Right hand side cannot be converted to Operation or Circuit {:?}", + x + )) + }); + match other { + Ok(x) => { + self.internal += x; + Ok(()) } + Err(y) => Err(y), } } - }) + } } /// Implement the `+` (__add__) magic method to add two Circuits. /// /// Args: - /// lhs (Circuit): The first Circuit object in this operation. + /// self (CircuitWrapper): The first Circuit object in this operation. /// rhs (Circuit): The second Circuit object in this operation. /// /// Returns: - /// lhs + rhs (Circuit): the two Circuits added together. + /// self + rhs (Circuit): the two Circuits added together. /// /// Raises: /// TypeError: Left hand side can not be converted to Circuit. /// TypeError: Right hand side cannot be converted to Operation or Circuit. - fn __add__(lhs: Py, rhs: Py) -> PyResult { - Python::with_gil(|py| -> PyResult { - let (lhs_ref, rhs_ref) = (lhs.as_ref(py), rhs.as_ref(py)); - let self_circ = convert_into_circuit(lhs_ref).map_err(|_| { - PyTypeError::new_err("Left hand side can not be converted to Circuit") - })?; - match convert_pyany_to_operation(rhs_ref) { - Ok(x) => Ok(CircuitWrapper { - internal: self_circ + x, - }), - Err(_) => { - let other = convert_into_circuit(rhs_ref).map_err(|_| { - pyo3::exceptions::PyTypeError::new_err( - "Right hand side cannot be converted to Operation or Circuit", - ) - })?; - Ok(CircuitWrapper { - internal: self_circ + other, - }) + fn __add__(&mut self, other: &Bound) -> PyResult { + match convert_pyany_to_operation(other) { + Ok(x) => Ok(CircuitWrapper { + internal: self.internal.clone() + x, + }), + Err(_) => { + let other = convert_into_circuit(other).map_err(|x| { + pyo3::exceptions::PyTypeError::new_err(format!( + "Right hand side cannot be converted to Operation or Circuit {:?}", + x + )) + }); + match other { + Ok(x) => Ok(CircuitWrapper { + internal: self.internal.clone() + x, + }), + Err(y) => Err(y), } } - }) + } } } /// Convert generic python object to [roqoqo::Circuit]. /// /// Fallible conversion of generic python object to [roqoqo::Circuit]. -pub fn convert_into_circuit(input: &PyAny) -> Result { +pub fn convert_into_circuit(input: &Bound) -> Result { if let Ok(try_downcast) = input.extract::() { return Ok(try_downcast.internal); } diff --git a/qoqo/src/circuitdag.rs b/qoqo/src/circuitdag.rs index 70af900f..3c298c8f 100644 --- a/qoqo/src/circuitdag.rs +++ b/qoqo/src/circuitdag.rs @@ -29,7 +29,7 @@ use crate::CircuitWrapper; /// of a quantum circuit in qoqo. /// #[pymodule] -fn circuitdag(_py: Python, module: &PyModule) -> PyResult<()> { +fn circuitdag(_py: Python, module: &Bound) -> PyResult<()> { module.add_class::()?; Ok(()) } @@ -60,26 +60,23 @@ impl CircuitDagWrapper { /// # Arguments: /// /// `input` - The Python object that should be casted to a [roqoqo::Circuit] - pub fn from_pyany(input: Py) -> PyResult { - Python::with_gil(|py| -> PyResult { - let input = input.as_ref(py); - if let Ok(try_downcast) = input.extract::() { - Ok(try_downcast.internal) - } else { - let get_bytes = input.call_method0("to_bincode").map_err(|_| { + pub fn from_pyany(input: &Bound) -> PyResult { + if let Ok(try_downcast) = input.extract::() { + Ok(try_downcast.internal) + } else { + let get_bytes = input.call_method0("to_bincode").map_err(|_| { PyTypeError::new_err("Python object cannot be converted to qoqo CircuitDag: Cast to binary representation failed".to_string()) })?; - let bytes = get_bytes.extract::>().map_err(|_| { + let bytes = get_bytes.extract::>().map_err(|_| { PyTypeError::new_err("Python object cannot be converted to qoqo CircuitDag: Cast to binary representation failed".to_string()) })?; - deserialize(&bytes[..]).map_err(|err| { + deserialize(&bytes[..]).map_err(|err| { PyTypeError::new_err(format!( "Python object cannot be converted to qoqo CircuitDag: Deserialization failed: {}", err ))} ) - } - }) + } } } @@ -109,13 +106,8 @@ impl CircuitDagWrapper { /// Returns: /// self: The new CircuitDag. #[pyo3(text_signature = "(circuit)")] - pub fn from_circuit(&self, circuit: Py) -> PyResult { - let circuit = Python::with_gil(|py| -> Result { - let circ_ref = circuit.as_ref(py); - crate::convert_into_circuit(circ_ref) - }) - .unwrap(); - + pub fn from_circuit(&self, circuit: &Bound) -> PyResult { + let circuit = crate::convert_into_circuit(circuit).unwrap(); Ok(Self { internal: CircuitDag::from(circuit), }) @@ -138,7 +130,7 @@ impl CircuitDagWrapper { /// Raises: /// TypeError: The Python Object cannot be converted to Operation. #[pyo3(text_signature = "($self, op)")] - pub fn add_to_back(&mut self, op: &PyAny) -> PyResult> { + pub fn add_to_back(&mut self, op: &Bound) -> PyResult> { let operation = convert_pyany_to_operation(op).map_err(|x| { PyTypeError::new_err(format!("Cannot convert python object to Operation {:?}", x)) })?; @@ -153,7 +145,7 @@ impl CircuitDagWrapper { /// Raises: /// TypeError: The Python Object cannot be converted to Operation. #[pyo3(text_signature = "($self, op)")] - pub fn add_to_front(&mut self, op: &PyAny) -> PyResult> { + pub fn add_to_front(&mut self, op: &Bound) -> PyResult> { let operation = convert_pyany_to_operation(op).map_err(|x| { PyTypeError::new_err(format!("Cannot convert python object to Operation {:?}", x)) })?; @@ -187,7 +179,7 @@ impl CircuitDagWrapper { /// /// Args: /// already_executed (list[int]): List of NodeIndices of Nodes that have already been executed in the Circuit. - /// to_be_executed(int): NodeIndex of the Operation that should be executed next. + /// to_be_executed (int): NodeIndex of the Operation that should be executed next. /// /// Returns: /// list[int]: List containing the sorted blocking elements. @@ -286,11 +278,12 @@ impl CircuitDagWrapper { /// /// Raises: /// NotImplementedError: Other comparison not implemented. - fn __richcmp__(&self, other: Py, op: pyo3::class::basic::CompareOp) -> PyResult { - let other = Python::with_gil(|py| -> Result { - let other_ref = other.as_ref(py); - crate::convert_into_circuitdag(other_ref) - }); + fn __richcmp__( + &self, + other: &Bound, + op: pyo3::class::basic::CompareOp, + ) -> PyResult { + let other = crate::convert_into_circuitdag(other); match op { pyo3::class::basic::CompareOp::Eq => match other { Ok(dag) => Ok(self.internal == dag), @@ -339,7 +332,7 @@ impl CircuitDagWrapper { let serialized = serialize(&self.internal) .map_err(|_| PyValueError::new_err("Cannot serialize CircuitDag to bytes"))?; let b: Py = Python::with_gil(|py| -> Py { - PyByteArray::new(py, &serialized[..]).into() + PyByteArray::new_bound(py, &serialized[..]).into() }); Ok(b) } @@ -357,8 +350,9 @@ impl CircuitDagWrapper { /// ValueError: Input cannot be deserialized to CircuitDag. #[staticmethod] #[pyo3(text_signature = "(input)")] - pub fn from_bincode(input: &PyAny) -> PyResult { + pub fn from_bincode(input: &Bound) -> PyResult { let bytes = input + .as_gil_ref() .extract::>() .map_err(|_| PyTypeError::new_err("Input cannot be converted to byte array"))?; @@ -461,8 +455,8 @@ impl CircuitDagWrapper { /// Convert generic python object to [roqoqo::CircuitDag]. /// /// Fallible conversion of generic python object to [roqoqo::CircuitDag]. -pub fn convert_into_circuitdag(input: &PyAny) -> Result { - if let Ok(try_downcast) = input.extract::() { +pub fn convert_into_circuitdag(input: &Bound) -> Result { + if let Ok(try_downcast) = input.as_gil_ref().extract::() { return Ok(try_downcast.internal); } // Everything that follows tries to extract the circuitdag when two separately diff --git a/qoqo/src/devices/all_to_all.rs b/qoqo/src/devices/all_to_all.rs index e05daac2..0766968b 100644 --- a/qoqo/src/devices/all_to_all.rs +++ b/qoqo/src/devices/all_to_all.rs @@ -110,7 +110,7 @@ impl AllToAllDeviceWrapper { /// Function to set the decoherence rates for all qubits in the AllToAllDevice device. /// /// Args: - /// rates[2d array]: Decoherence rates provided as (3x3)-matrix for all qubits in the device. + /// rates (2darray):: Decoherence rates provided as (3x3)-matrix for all qubits in the device. /// /// Returns: /// AllToAllDevice @@ -208,18 +208,15 @@ impl AllToAllDeviceWrapper { impl AllToAllDeviceWrapper { /// Fallible conversion of generic python object. - pub fn from_pyany(input: Py) -> PyResult { - Python::with_gil(|py| -> PyResult { - let input = input.as_ref(py); - if let Ok(try_downcast) = input.extract::() { - Ok(try_downcast.internal) - } else { - let get_bytes = input.call_method0("to_bincode")?; - let bytes = get_bytes.extract::>()?; - deserialize(&bytes[..]).map_err(|err| { - PyValueError::new_err(format!("Cannot treat input as AllToAllDevice: {}", err)) - }) - } - }) + pub fn from_pyany(input: &Bound) -> PyResult { + if let Ok(try_downcast) = input.extract::() { + Ok(try_downcast.internal) + } else { + let get_bytes = input.call_method0("to_bincode")?; + let bytes = get_bytes.extract::>()?; + deserialize(&bytes[..]).map_err(|err| { + PyValueError::new_err(format!("Cannot treat input as AllToAllDevice: {}", err)) + }) + } } } diff --git a/qoqo/src/devices/generic_device.rs b/qoqo/src/devices/generic_device.rs index fdc93a2c..43349bd4 100644 --- a/qoqo/src/devices/generic_device.rs +++ b/qoqo/src/devices/generic_device.rs @@ -82,21 +82,18 @@ impl GenericDeviceWrapper { } impl GenericDeviceWrapper { - /// Fallible conversion of generic python object.. - pub fn from_pyany(input: Py) -> PyResult { - Python::with_gil(|py| -> PyResult { - let input = input.as_ref(py); - if let Ok(try_downcast) = input.extract::() { - Ok(try_downcast.internal) - } else { - // This allows all devices to be imported as generic device - let generic_device_candidate = input.call_method0("generic_device")?; - let get_bytes = generic_device_candidate.call_method0("to_bincode")?; - let bytes = get_bytes.extract::>()?; - deserialize(&bytes[..]).map_err(|err| { - PyValueError::new_err(format!("Cannot treat input as GenericDevice: {}", err)) - }) - } - }) + /// Fallible conversion of generic python object. + pub fn from_pyany(input: &Bound) -> PyResult { + if let Ok(try_downcast) = input.extract::() { + Ok(try_downcast.internal) + } else { + // This allows all devices to be imported as generic device + let generic_device_candidate = input.call_method0("generic_device")?; + let get_bytes = generic_device_candidate.call_method0("to_bincode")?; + let bytes = get_bytes.extract::>()?; + deserialize(&bytes[..]).map_err(|err| { + PyValueError::new_err(format!("Cannot treat input as GenericDevice: {}", err)) + }) + } } } diff --git a/qoqo/src/devices/mod.rs b/qoqo/src/devices/mod.rs index 5c5f5b6e..60349338 100644 --- a/qoqo/src/devices/mod.rs +++ b/qoqo/src/devices/mod.rs @@ -48,29 +48,25 @@ impl ChainWithEnvironmentCapsule { /// # Arguments /// /// * `python_device` - The python object that should implement the - pub fn new(python_device: Py) -> Result { - let implements_protocol = Python::with_gil(|py| -> bool { - let __implements_environment_with_chains = - python_device.call_method0(py, "__implements_environment_chains"); - if __implements_environment_with_chains.is_err() { - return false; - } - let __implements_environment_with_chains = __implements_environment_with_chains - .unwrap() - .extract::(py); - if __implements_environment_with_chains.is_err() { - return false; + pub fn new(python_device: &Bound) -> Result { + let __implements_environment_with_chains = + python_device.call_method0("__implements_environment_chains"); + let implements_protocol = + __implements_environment_with_chains.map(|implement| implement.extract::()); + + match implements_protocol { + Ok(Ok(true)) => Python::with_gil(|py| -> Result { + Ok(Self { + internal: python_device.into_py(py), + }) + }), + _ => { + return Err(RoqoqoError::GenericError { + msg: "Python device does not implement `environment_chains` method." + .to_string(), + }) } - __implements_environment_with_chains.unwrap() - }); - if !implements_protocol { - return Err(RoqoqoError::GenericError { - msg: "Python device does not implement `environment_chains` method.".to_string(), - }); } - Ok(Self { - internal: python_device, - }) } } @@ -124,7 +120,7 @@ impl ChainWithEnvironmentDevice for ChainWithEnvironmentCapsule { /// SquareLatticeDevice #[pymodule] -pub fn devices(_py: Python, module: &PyModule) -> PyResult<()> { +pub fn devices(_py: Python, module: &Bound) -> PyResult<()> { module.add_class::()?; module.add_class::()?; module.add_class::()?; diff --git a/qoqo/src/devices/square_lattice.rs b/qoqo/src/devices/square_lattice.rs index 5aca01ad..6fbf1c81 100644 --- a/qoqo/src/devices/square_lattice.rs +++ b/qoqo/src/devices/square_lattice.rs @@ -132,7 +132,7 @@ impl SquareLatticeDeviceWrapper { /// Set the decoherence rates for all qubits in the SquareLatticeDevice device. /// /// Args: - /// rates[2d array]: Decoherence rates provided as (3x3)-matrix for all qubits in the device. + /// rates (2darray):: Decoherence rates provided as (3x3)-matrix for all qubits in the device. /// /// Returns: /// SquareLatticeDevice @@ -229,22 +229,19 @@ impl SquareLatticeDeviceWrapper { } impl SquareLatticeDeviceWrapper { - /// Fallible conversion of generic python object.. - pub fn from_pyany(input: Py) -> PyResult { - Python::with_gil(|py| -> PyResult { - let input = input.as_ref(py); - if let Ok(try_downcast) = input.extract::() { - Ok(try_downcast.internal) - } else { - let get_bytes = input.call_method0("to_bincode")?; - let bytes = get_bytes.extract::>()?; - deserialize(&bytes[..]).map_err(|err| { - PyValueError::new_err(format!( - "Cannot treat input as SquareLatticeDevice: {}", - err - )) - }) - } - }) + /// Fallible conversion of generic python object. + pub fn from_pyany(input: &Bound) -> PyResult { + if let Ok(try_downcast) = input.extract::() { + Ok(try_downcast.internal) + } else { + let get_bytes = input.call_method0("to_bincode")?; + let bytes = get_bytes.extract::>()?; + deserialize(&bytes[..]).map_err(|err| { + PyValueError::new_err(format!( + "Cannot treat input as SquareLatticeDevice: {}", + err + )) + }) + } } } diff --git a/qoqo/src/lib.rs b/qoqo/src/lib.rs index 0498a2bd..898e8c5a 100644 --- a/qoqo/src/lib.rs +++ b/qoqo/src/lib.rs @@ -108,7 +108,7 @@ pub enum QoqoBackendError { /// #[pymodule] -fn qoqo(_py: Python, module: &PyModule) -> PyResult<()> { +fn qoqo(_py: Python, module: &Bound) -> PyResult<()> { module.add_class::()?; module.add_class::()?; #[cfg(feature = "circuitdag")] @@ -122,8 +122,9 @@ fn qoqo(_py: Python, module: &PyModule) -> PyResult<()> { let wrapper4 = wrap_pymodule!(noise_models::noise_models); module.add_wrapped(wrapper4)?; // Adding nice imports corresponding to maturin example - let system = PyModule::import(_py, "sys")?; - let system_modules: &PyDict = system.getattr("modules")?.downcast()?; + let system = PyModule::import_bound(_py, "sys")?; + let binding = system.getattr("modules")?; + let system_modules: &Bound = binding.downcast()?; system_modules.set_item("qoqo.operations", module.getattr("operations")?)?; system_modules.set_item("qoqo.measurements", module.getattr("measurements")?)?; system_modules.set_item("qoqo.devices", module.getattr("devices")?)?; diff --git a/qoqo/src/measurements/basis_rotation_measurement.rs b/qoqo/src/measurements/basis_rotation_measurement.rs index 3691f76e..c97b8739 100644 --- a/qoqo/src/measurements/basis_rotation_measurement.rs +++ b/qoqo/src/measurements/basis_rotation_measurement.rs @@ -29,6 +29,14 @@ use std::collections::HashMap; #[pyclass(name = "PauliZProduct", module = "qoqo.measurements")] #[derive(Clone, Debug)] /// Collected information for executing a measurement of PauliZ product. +/// +/// Args: +/// constant_circuit (Optional[Circuit]): The constant Circuit that is executed before each Circuit in circuits. +/// circuits (list[Circuit]): The collection of quantum circuits for the separate basis rotations. +/// input (PauliZProductInput): The additional input information required for measurement. +/// +/// Returns: +/// PauliZProduct: The PauliZProduct containing the new PauliZ product measurement. pub struct PauliZProductWrapper { /// Internal storage of [roqoqo::PauliZProduct]. pub internal: PauliZProduct, @@ -52,40 +60,42 @@ impl PauliZProductWrapper { circuits: Vec>, input: Py, ) -> PyResult { - let mut new_circuits: Vec = Vec::new(); - for c in circuits.into_iter() { - let tmp_c = CircuitWrapper::from_pyany(c).map_err(|err| { - PyTypeError::new_err(format!( - "`circuits` argument is not a list of qoqo Circuits: {}", - err - )) - })?; - new_circuits.push(tmp_c) - } - let new_constant: Option = match constant_circuit { - None => None, - Some(c) => { - let tmp_c = CircuitWrapper::from_pyany(c).map_err(|err| { + Python::with_gil(|py| -> PyResult { + let mut new_circuits: Vec = Vec::new(); + for c in circuits.into_iter() { + let tmp_c = CircuitWrapper::from_pyany(c.bind(py)).map_err(|err| { PyTypeError::new_err(format!( - "`constant_circuit` argument is not None or a qoqo Circuit: {}", + "`circuits` argument is not a list of qoqo Circuits: {}", err )) })?; - Some(tmp_c) + new_circuits.push(tmp_c) } - }; - let input = PauliZProductInputWrapper::from_pyany(input).map_err(|err| { - PyTypeError::new_err(format!( - "`input` argument is not a qoqo CheatedInput: {}", - err - )) - })?; - Ok(Self { - internal: PauliZProduct { - input, - constant_circuit: new_constant, - circuits: new_circuits, - }, + let new_constant: Option = match constant_circuit { + None => None, + Some(c) => { + let tmp_c = CircuitWrapper::from_pyany(c.bind(py)).map_err(|err| { + PyTypeError::new_err(format!( + "`constant_circuit` argument is not None or a qoqo Circuit: {}", + err + )) + })?; + Some(tmp_c) + } + }; + let input = PauliZProductInputWrapper::from_pyany(input.bind(py)).map_err(|err| { + PyTypeError::new_err(format!( + "`input` argument is not a qoqo CheatedInput: {}", + err + )) + })?; + Ok(Self { + internal: PauliZProduct { + input, + constant_circuit: new_constant, + circuits: new_circuits, + }, + }) }) } @@ -93,8 +103,8 @@ impl PauliZProductWrapper { /// /// Args: /// input_bit_registers (dict[str, Union[list[list[int]], list[list[bool]]]]): The classical bit registers with the register name as key - /// float_registers (dict[str, list[list[float]]): The classical float registers as a dictionary with the register name as key - /// complex_registers (dict[str, list[list[complex]]): The classical complex registers as a dictionary with the register name as key + /// float_registers (Dict[str, List[List[float]]]): The classical float registers as a dictionary with the register name as key + /// complex_registers (Dict[str, List[List[complex]]]): The classical complex registers as a dictionary with the register name as key /// /// Returns: /// Optional[dict[str, float]]: The evaluated measurement. @@ -104,26 +114,18 @@ impl PauliZProductWrapper { /// RuntimeError: Error evaluating PauliZ product measurement. pub fn evaluate( &mut self, - input_bit_registers: Py, + input_bit_registers: &Bound, float_registers: HashMap, complex_registers: HashMap, ) -> PyResult>> { let mut bit_registers: HashMap = HashMap::new(); let bit_registers_bool: PyResult>>> = - Python::with_gil(|py| -> PyResult>>> { - input_bit_registers - .as_ref(py) - .extract::>() - }); + input_bit_registers.extract::>(); if let Ok(try_downcast) = bit_registers_bool { bit_registers = try_downcast } else { let tmp_bit_registers = - Python::with_gil(|py| -> PyResult>>> { - input_bit_registers - .as_ref(py) - .extract::>>>() - })?; + input_bit_registers.extract::>>>()?; for (name, output_reg) in tmp_bit_registers { let mut tmp_output_reg: Vec> = Vec::with_capacity(output_reg.len()); for reg in output_reg { @@ -221,7 +223,7 @@ impl PauliZProductWrapper { PyValueError::new_err("Cannot serialize PauliZProductMeasurement to bytes") })?; let b: Py = Python::with_gil(|py| -> Py { - PyByteArray::new(py, &serialized[..]).into() + PyByteArray::new_bound(py, &serialized[..]).into() }); Ok(("PauliZProduct", b)) } @@ -237,7 +239,7 @@ impl PauliZProductWrapper { let serialized = serialize(&self.internal) .map_err(|_| PyValueError::new_err("Cannot serialize PauliZProduct to bytes"))?; let b: Py = Python::with_gil(|py| -> Py { - PyByteArray::new(py, &serialized[..]).into() + PyByteArray::new_bound(py, &serialized[..]).into() }); Ok(b) } @@ -254,8 +256,9 @@ impl PauliZProductWrapper { /// TypeError: Input cannot be converted to byte array. /// ValueError: Input cannot be deserialized to PauliZProduct. #[staticmethod] - pub fn from_bincode(input: &PyAny) -> PyResult { + pub fn from_bincode(input: &Bound) -> PyResult { let bytes = input + .as_gil_ref() .extract::>() .map_err(|_| PyTypeError::new_err("Input cannot be converted to byte array"))?; @@ -304,7 +307,7 @@ impl PauliZProductWrapper { } /// Return a deep copy of the Object. - pub fn __deepcopy__(&self, _memodict: Py) -> Self { + pub fn __deepcopy__(&self, _memodict: &Bound) -> Self { self.clone() } @@ -367,7 +370,7 @@ impl PauliZProductWrapper { } impl PauliZProductWrapper { - /// Extracts a PauliZProduct from a PauliZProductWrapper python object. + /// Extracts a PauliZProduct from a PauliZProductWrapper python object. /// /// When working with qoqo and other rust based python packages compiled separately /// a downcast will not detect that two PauliZProductWrapper objects are compatible. @@ -376,25 +379,22 @@ impl PauliZProductWrapper { /// # Arguments: /// /// `input` - The Python object that should be casted to a [roqoqo::PauliZProduct] - pub fn from_pyany(input: Py) -> PyResult { - Python::with_gil(|py| -> PyResult { - let input = input.as_ref(py); - if let Ok(try_downcast) = input.extract::() { - Ok(try_downcast.internal) - } else { - let get_bytes = input.call_method0("to_bincode").map_err(|_| { + pub fn from_pyany(input: &Bound) -> PyResult { + if let Ok(try_downcast) = input.extract::() { + Ok(try_downcast.internal) + } else { + let get_bytes = input.call_method0("to_bincode").map_err(|_| { PyTypeError::new_err("Python object cannot be converted to qoqo PauliZProduct: Cast to binary representation failed".to_string()) })?; - let bytes = get_bytes.extract::>().map_err(|_| { + let bytes = get_bytes.extract::>().map_err(|_| { PyTypeError::new_err("Python object cannot be converted to qoqo PauliZProduct: Cast to binary representation failed".to_string()) })?; - deserialize(&bytes[..]).map_err(|err| { + deserialize(&bytes[..]).map_err(|err| { PyTypeError::new_err(format!( "Python object cannot be converted to qoqo PauliZProduct: Deserialization failed: {}", err )) }) - } - }) + } } } diff --git a/qoqo/src/measurements/cheated_basis_rotation_measurement.rs b/qoqo/src/measurements/cheated_basis_rotation_measurement.rs index 4be28c78..10d50967 100644 --- a/qoqo/src/measurements/cheated_basis_rotation_measurement.rs +++ b/qoqo/src/measurements/cheated_basis_rotation_measurement.rs @@ -29,6 +29,14 @@ use std::collections::HashMap; #[pyclass(name = "CheatedPauliZProduct", module = "qoqo.measurements")] #[derive(Clone, Debug)] /// Collected information for executing a cheated measurement of PauliZ product. +/// +/// Args: +/// constant_circuit (Optional[Circuit]): The constant Circuit that is executed before each Circuit in circuits. +/// circuits (list[Circuit]): The collection of quantum circuits for the separate basis rotations. +/// input (CheatedPauliZProductInput): The additional input information required for measurement. +/// +/// Returns: +/// self: The CheatedPauliZProduct containing the new cheated PauliZ product measurement. pub struct CheatedPauliZProductWrapper { /// Internal storage of [roqoqo::PauliZProduct]. pub internal: CheatedPauliZProduct, @@ -52,40 +60,43 @@ impl CheatedPauliZProductWrapper { circuits: Vec>, input: Py, ) -> PyResult { - let mut new_circuits: Vec = Vec::new(); - for c in circuits.into_iter() { - let tmp_c = CircuitWrapper::from_pyany(c).map_err(|err| { - PyTypeError::new_err(format!( - "`circuits` argument is not a list of qoqo Circuits: {}", - err - )) - })?; - new_circuits.push(tmp_c) - } - let new_constant: Option = match constant_circuit { - None => None, - Some(c) => { - let tmp_c = CircuitWrapper::from_pyany(c).map_err(|err| { + Python::with_gil(|py| -> PyResult { + let mut new_circuits: Vec = Vec::new(); + for c in circuits.into_iter() { + let tmp_c = CircuitWrapper::from_pyany(c.bind(py)).map_err(|err| { PyTypeError::new_err(format!( - "`constant_circuit` argument is not None or a qoqo Circuit: {}", + "`circuits` argument is not a list of qoqo Circuits: {}", err )) })?; - Some(tmp_c) + new_circuits.push(tmp_c) } - }; - let input = CheatedPauliZProductInputWrapper::from_pyany(input).map_err(|err| { - PyTypeError::new_err(format!( - "`input` argument is not a qoqo CheatedInput: {}", - err - )) - })?; - Ok(Self { - internal: CheatedPauliZProduct { - input, - constant_circuit: new_constant, - circuits: new_circuits, - }, + let new_constant: Option = match constant_circuit { + None => None, + Some(c) => { + let tmp_c = CircuitWrapper::from_pyany(c.bind(py)).map_err(|err| { + PyTypeError::new_err(format!( + "`constant_circuit` argument is not None or a qoqo Circuit: {}", + err + )) + })?; + Some(tmp_c) + } + }; + let input = + CheatedPauliZProductInputWrapper::from_pyany(input.bind(py)).map_err(|err| { + PyTypeError::new_err(format!( + "`input` argument is not a qoqo CheatedInput: {}", + err + )) + })?; + Ok(Self { + internal: CheatedPauliZProduct { + input, + constant_circuit: new_constant, + circuits: new_circuits, + }, + }) }) } @@ -93,8 +104,8 @@ impl CheatedPauliZProductWrapper { /// /// Args: /// input_bit_registers (dict[str, Union[list[list[int]], list[list[bool]]]]): The classical bit registers with the register name as key - /// float_registers (dict[str, list[list[float]]): The classical float registers as a dictionary with the register name as key - /// complex_registers (dict[str, list[list[complex]]): The classical complex registers as a dictionary with the register name as key + /// float_registers (Dict[str, List[List[float]]]): The classical float registers as a dictionary with the register name as key + /// complex_registers (Dict[str, List[List[complex]]]): The classical complex registers as a dictionary with the register name as key /// /// Returns: /// Optional[dict[str, float]]: The evaluated measurement. @@ -104,26 +115,18 @@ impl CheatedPauliZProductWrapper { /// RuntimeError: Error evaluating cheated PauliZ product measurement. pub fn evaluate( &mut self, - input_bit_registers: Py, + input_bit_registers: &Bound, float_registers: HashMap, complex_registers: HashMap, ) -> PyResult>> { let mut bit_registers: HashMap = HashMap::new(); let bit_registers_bool: PyResult>>> = - Python::with_gil(|py| -> PyResult>>> { - input_bit_registers - .as_ref(py) - .extract::>() - }); + input_bit_registers.extract::>(); if let Ok(try_downcast) = bit_registers_bool { bit_registers = try_downcast } else { let tmp_bit_registers = - Python::with_gil(|py| -> PyResult>>> { - input_bit_registers - .as_ref(py) - .extract::>>>() - })?; + input_bit_registers.extract::>>>()?; for (name, output_reg) in tmp_bit_registers { let mut tmp_output_reg: Vec> = Vec::with_capacity(output_reg.len()); for reg in output_reg { @@ -220,7 +223,7 @@ impl CheatedPauliZProductWrapper { PyValueError::new_err("Cannot serialize CheatedPauliZProductMeasurement to bytes") })?; let b: Py = Python::with_gil(|py| -> Py { - PyByteArray::new(py, &serialized[..]).into() + PyByteArray::new_bound(py, &serialized[..]).into() }); Ok(("CheatedPauliZProduct", b)) } @@ -236,7 +239,7 @@ impl CheatedPauliZProductWrapper { let serialized = serialize(&self.internal) .map_err(|_| PyValueError::new_err("Cannot serialize CheatedPauliZProduct to bytes"))?; let b: Py = Python::with_gil(|py| -> Py { - PyByteArray::new(py, &serialized[..]).into() + PyByteArray::new_bound(py, &serialized[..]).into() }); Ok(b) } @@ -253,8 +256,9 @@ impl CheatedPauliZProductWrapper { /// TypeError: Input cannot be converted to byte array. /// ValueError: Input cannot be deserialized to CheatedPauliZProduct. #[staticmethod] - pub fn from_bincode(input: &PyAny) -> PyResult { + pub fn from_bincode(input: &Bound) -> PyResult { let bytes = input + .as_gil_ref() .extract::>() .map_err(|_| PyTypeError::new_err("Input cannot be converted to byte array"))?; @@ -303,7 +307,7 @@ impl CheatedPauliZProductWrapper { } /// Return a deep copy of the Object. - pub fn __deepcopy__(&self, _memodict: Py) -> Self { + pub fn __deepcopy__(&self, _memodict: &Bound) -> Self { self.clone() } @@ -375,25 +379,22 @@ impl CheatedPauliZProductWrapper { /// # Arguments: /// /// `input` - The Python object that should be casted to a [roqoqo::CheatedPauliZProduct] - pub fn from_pyany(input: Py) -> PyResult { - Python::with_gil(|py| -> PyResult { - let input = input.as_ref(py); - if let Ok(try_downcast) = input.extract::() { - Ok(try_downcast.internal) - } else { - let get_bytes = input.call_method0("to_bincode").map_err(|_| { + pub fn from_pyany(input: &Bound) -> PyResult { + if let Ok(try_downcast) = input.extract::() { + Ok(try_downcast.internal) + } else { + let get_bytes = input.call_method0("to_bincode").map_err(|_| { PyTypeError::new_err("Python object cannot be converted to qoqo CheatedPauliZProduct: Cast to binary representation failed".to_string()) })?; - let bytes = get_bytes.extract::>().map_err(|_| { + let bytes = get_bytes.extract::>().map_err(|_| { PyTypeError::new_err("Python object cannot be converted to qoqo CheatedPauliZProduct: Cast to binary representation failed".to_string()) })?; - deserialize(&bytes[..]).map_err(|err| { + deserialize(&bytes[..]).map_err(|err| { PyTypeError::new_err(format!( "Python object cannot be converted to qoqo CheatedPauliZProduct: Deserialization failed: {}", err )) }) - } - }) + } } } diff --git a/qoqo/src/measurements/cheated_measurement.rs b/qoqo/src/measurements/cheated_measurement.rs index aafa0c67..2b44551a 100644 --- a/qoqo/src/measurements/cheated_measurement.rs +++ b/qoqo/src/measurements/cheated_measurement.rs @@ -29,6 +29,14 @@ use std::collections::HashMap; #[pyclass(name = "Cheated", module = "qoqo.measurements")] #[derive(Clone, Debug)] /// Collected information for executing a cheated measurement. +/// +/// Args: +/// constant_circuit (Optional[Circuit]): The constant Circuit that is executed before each Circuit in circuits. +/// circuits (list[Circuit]): The collection of quantum circuits executed for the measurement. +/// input (CheatedInput): The additional input information required for measurement. +/// +/// Returns: +/// Cheated: The new measurement. pub struct CheatedWrapper { /// Internal storage of [roqoqo::Cheated] pub internal: Cheated, @@ -52,40 +60,42 @@ impl CheatedWrapper { circuits: Vec>, input: Py, ) -> PyResult { - let mut new_circuits: Vec = Vec::new(); - for c in circuits.into_iter() { - let tmp_c = CircuitWrapper::from_pyany(c).map_err(|err| { - PyTypeError::new_err(format!( - "`circuits` argument is not a list of qoqo Circuits: {}", - err - )) - })?; - new_circuits.push(tmp_c) - } - let new_constant: Option = match constant_circuit { - None => None, - Some(c) => { - let tmp_c = CircuitWrapper::from_pyany(c).map_err(|err| { + Python::with_gil(|py| -> PyResult { + let mut new_circuits: Vec = Vec::new(); + for c in circuits.into_iter() { + let tmp_c = CircuitWrapper::from_pyany(c.bind(py)).map_err(|err| { PyTypeError::new_err(format!( - "`constant_circuit` argument is not None or a qoqo Circuit: {}", + "`circuits` argument is not a list of qoqo Circuits: {}", err )) })?; - Some(tmp_c) + new_circuits.push(tmp_c) } - }; - let input = CheatedInputWrapper::from_pyany(input).map_err(|err| { - PyTypeError::new_err(format!( - "`input` argument is not a qoqo CheatedInput: {}", - err - )) - })?; - Ok(Self { - internal: Cheated { - input, - constant_circuit: new_constant, - circuits: new_circuits, - }, + let new_constant: Option = match constant_circuit { + None => None, + Some(c) => { + let tmp_c = CircuitWrapper::from_pyany(c.bind(py)).map_err(|err| { + PyTypeError::new_err(format!( + "`constant_circuit` argument is not None or a qoqo Circuit: {}", + err + )) + })?; + Some(tmp_c) + } + }; + let input = CheatedInputWrapper::from_pyany(input.bind(py)).map_err(|err| { + PyTypeError::new_err(format!( + "`input` argument is not a qoqo CheatedInput: {}", + err + )) + })?; + Ok(Self { + internal: Cheated { + input, + constant_circuit: new_constant, + circuits: new_circuits, + }, + }) }) } @@ -93,37 +103,29 @@ impl CheatedWrapper { /// /// Args: /// input_bit_registers (dict[str, Union[list[list[int]], list[list[bool]]]]): The classical bit registers with the register name as key. - /// float_registers (dict[str, list[list[float]]): The classical float registers as a dictionary with the register name as key. - /// complex_registers (dict[str, list[list[complex]]): The classical complex registers as a dictionary with the register name as key. + /// float_registers (Dict[str, List[List[float]]]): The classical float registers as a dictionary with the register name as key. + /// complex_registers (Dict[str, List[List[complex]]]): The classical complex registers as a dictionary with the register name as key. /// /// Returns: - /// Optional[dict[str, float]: The evaluated expectation values. + /// Optional[dict[str, float]]: The evaluated expectation values. /// /// Raises: /// RuntimeError: Unexpected repetition of key in bit_register. /// RuntimeError: Error evaluating cheated measurement. pub fn evaluate( &mut self, - input_bit_registers: Py, + input_bit_registers: &Bound, float_registers: HashMap, complex_registers: HashMap, ) -> PyResult>> { let mut bit_registers: HashMap = HashMap::new(); let bit_registers_bool: PyResult>>> = - Python::with_gil(|py| -> PyResult>>> { - input_bit_registers - .as_ref(py) - .extract::>() - }); + input_bit_registers.extract::>(); if let Ok(try_downcast) = bit_registers_bool { bit_registers = try_downcast } else { let tmp_bit_registers = - Python::with_gil(|py| -> PyResult>>> { - input_bit_registers - .as_ref(py) - .extract::>>>() - })?; + input_bit_registers.extract::>>>()?; for (name, output_reg) in tmp_bit_registers { let mut tmp_output_reg: Vec> = Vec::with_capacity(output_reg.len()); for reg in output_reg { @@ -220,7 +222,7 @@ impl CheatedWrapper { let serialized = serialize(&self.internal) .map_err(|_| PyValueError::new_err("Cannot serialize CheatedMeasurement to bytes"))?; let b: Py = Python::with_gil(|py| -> Py { - PyByteArray::new(py, &serialized[..]).into() + PyByteArray::new_bound(py, &serialized[..]).into() }); Ok(("Cheated", b)) } @@ -236,7 +238,7 @@ impl CheatedWrapper { let serialized = serialize(&self.internal) .map_err(|_| PyValueError::new_err("Cannot serialize Cheated to bytes"))?; let b: Py = Python::with_gil(|py| -> Py { - PyByteArray::new(py, &serialized[..]).into() + PyByteArray::new_bound(py, &serialized[..]).into() }); Ok(b) } @@ -253,8 +255,9 @@ impl CheatedWrapper { /// TypeError: Input cannot be converted to byte array. /// ValueError: Input cannot be deserialized to Cheated. #[staticmethod] - pub fn from_bincode(input: &PyAny) -> PyResult { + pub fn from_bincode(input: &Bound) -> PyResult { let bytes = input + .as_gil_ref() .extract::>() .map_err(|_| PyTypeError::new_err("Input cannot be converted to byte array"))?; @@ -302,7 +305,7 @@ impl CheatedWrapper { } /// Return a deep copy of the Object. - pub fn __deepcopy__(&self, _memodict: Py) -> Self { + pub fn __deepcopy__(&self, _memodict: &Bound) -> Self { self.clone() } @@ -374,25 +377,22 @@ impl CheatedWrapper { /// # Arguments: /// /// `input` - The Python object that should be casted to a [roqoqo::Cheated] - pub fn from_pyany(input: Py) -> PyResult { - Python::with_gil(|py| -> PyResult { - let input = input.as_ref(py); - if let Ok(try_downcast) = input.extract::() { - Ok(try_downcast.internal) - } else { - let get_bytes = input.call_method0("to_bincode").map_err(|_| { + pub fn from_pyany(input: &Bound) -> PyResult { + if let Ok(try_downcast) = input.extract::() { + Ok(try_downcast.internal) + } else { + let get_bytes = input.call_method0("to_bincode").map_err(|_| { PyTypeError::new_err("Python object cannot be converted to qoqo Cheated: Cast to binary representation failed".to_string()) })?; - let bytes = get_bytes.extract::>().map_err(|_| { + let bytes = get_bytes.extract::>().map_err(|_| { PyTypeError::new_err("Python object cannot be converted to qoqo Cheated: Cast to binary representation failed".to_string()) })?; - deserialize(&bytes[..]).map_err(|err| { - PyTypeError::new_err(format!( + deserialize(&bytes[..]).map_err(|err| { + PyTypeError::new_err(format!( "Python object cannot be converted to qoqo Cheated: Deserialization failed: {}", err )) - }) - } - }) + }) + } } } diff --git a/qoqo/src/measurements/classical_register_measurement.rs b/qoqo/src/measurements/classical_register_measurement.rs index 0da0d615..39ddef02 100644 --- a/qoqo/src/measurements/classical_register_measurement.rs +++ b/qoqo/src/measurements/classical_register_measurement.rs @@ -27,6 +27,13 @@ use std::collections::HashMap; #[pyclass(name = "ClassicalRegister", module = "qoqo.measurements")] #[derive(Clone, Debug)] /// Collected information for executing a classical register. +/// +/// Args: +/// constant_circuit (Optional[Circuit]): The constant Circuit that is executed before each Circuit in circuits. +/// circuits (list[Circuit]): The collection of quantum circuits executed for the measurement. +/// +/// Returns: +/// ClassicalRegister: The new register. pub struct ClassicalRegisterWrapper { /// Internal storage of [roqoqo::ClassicalRegister]. pub internal: ClassicalRegister, @@ -44,34 +51,39 @@ impl ClassicalRegisterWrapper { /// ClassicalRegister: The new register. #[new] #[pyo3(signature=(constant_circuit, circuits))] - pub fn new(constant_circuit: Option>, circuits: Vec>) -> PyResult { - let mut new_circuits: Vec = Vec::new(); - for c in circuits.into_iter() { - let tmp_c = CircuitWrapper::from_pyany(c).map_err(|err| { - PyTypeError::new_err(format!( - "`circuits` argument is not a list of qoqo Circuits: {}", - err - )) - })?; - new_circuits.push(tmp_c) - } - let new_constant: Option = match constant_circuit { - None => None, - Some(c) => { - let tmp_c = CircuitWrapper::from_pyany(c).map_err(|err| { + pub fn new( + constant_circuit: Option<&Bound>, + circuits: Vec>, + ) -> PyResult { + Python::with_gil(|py| -> PyResult { + let mut new_circuits: Vec = Vec::new(); + for c in circuits.into_iter() { + let tmp_c = CircuitWrapper::from_pyany(c.bind(py)).map_err(|err| { PyTypeError::new_err(format!( - "`constant_circuit` argument is not None or a qoqo Circuit: {}", + "`circuits` argument is not a list of qoqo Circuits: {}", err )) })?; - Some(tmp_c) + new_circuits.push(tmp_c) } - }; - Ok(Self { - internal: ClassicalRegister { - constant_circuit: new_constant, - circuits: new_circuits, - }, + let new_constant: Option = match constant_circuit { + None => None, + Some(c) => { + let tmp_c = CircuitWrapper::from_pyany(c).map_err(|err| { + PyTypeError::new_err(format!( + "`constant_circuit` argument is not None or a qoqo Circuit: {}", + err + )) + })?; + Some(tmp_c) + } + }; + Ok(Self { + internal: ClassicalRegister { + constant_circuit: new_constant, + circuits: new_circuits, + }, + }) }) } @@ -142,7 +154,7 @@ impl ClassicalRegisterWrapper { let serialized = serialize(&self.internal) .map_err(|_| PyValueError::new_err("Cannot serialize ClassicalRegister to bytes"))?; let b: Py = Python::with_gil(|py| -> Py { - PyByteArray::new(py, &serialized[..]).into() + PyByteArray::new_bound(py, &serialized[..]).into() }); Ok(("ClassicalRegister", b)) } @@ -158,7 +170,7 @@ impl ClassicalRegisterWrapper { let serialized = serialize(&self.internal) .map_err(|_| PyValueError::new_err("Cannot serialize ClassicalRegister to bytes"))?; let b: Py = Python::with_gil(|py| -> Py { - PyByteArray::new(py, &serialized[..]).into() + PyByteArray::new_bound(py, &serialized[..]).into() }); Ok(b) } @@ -175,8 +187,9 @@ impl ClassicalRegisterWrapper { /// TypeError: Input cannot be converted to byte array. /// ValueError: Input cannot be deserialized to ClassicalRegister. #[staticmethod] - pub fn from_bincode(input: &PyAny) -> PyResult { + pub fn from_bincode(input: &Bound) -> PyResult { let bytes = input + .as_gil_ref() .extract::>() .map_err(|_| PyTypeError::new_err("Input cannot be converted to byte array"))?; @@ -226,7 +239,7 @@ impl ClassicalRegisterWrapper { } /// Return a deep copy of the Object. - pub fn __deepcopy__(&self, _memodict: Py) -> Self { + pub fn __deepcopy__(&self, _memodict: &Bound) -> Self { self.clone() } /// Return the __richcmp__ magic method to perform rich comparison operations on QuantumProgram. @@ -297,25 +310,22 @@ impl ClassicalRegisterWrapper { /// # Arguments: /// /// `input` - The Python object that should be casted to a [roqoqo::ClassicalRegister] - pub fn from_pyany(input: Py) -> PyResult { - Python::with_gil(|py| -> PyResult { - let input = input.as_ref(py); - if let Ok(try_downcast) = input.extract::() { - Ok(try_downcast.internal) - } else { - let get_bytes = input.call_method0("to_bincode").map_err(|_| { + pub fn from_pyany(input: &Bound) -> PyResult { + if let Ok(try_downcast) = input.extract::() { + Ok(try_downcast.internal) + } else { + let get_bytes = input.call_method0("to_bincode").map_err(|_| { PyTypeError::new_err("Python object cannot be converted to qoqo ClassicalRegister: Cast to binary representation failed".to_string()) })?; - let bytes = get_bytes.extract::>().map_err(|_| { + let bytes = get_bytes.extract::>().map_err(|_| { PyTypeError::new_err("Python object cannot be converted to qoqo ClassicalRegister: Cast to binary representation failed".to_string()) })?; - deserialize(&bytes[..]).map_err(|err| { + deserialize(&bytes[..]).map_err(|err| { PyTypeError::new_err(format!( "Python object cannot be converted to qoqo ClassicalRegister: Deserialization failed: {}", err )) }) - } - }) + } } } diff --git a/qoqo/src/measurements/measurement_auxiliary_data_input.rs b/qoqo/src/measurements/measurement_auxiliary_data_input.rs index 8ba9761e..1b5f07ac 100644 --- a/qoqo/src/measurements/measurement_auxiliary_data_input.rs +++ b/qoqo/src/measurements/measurement_auxiliary_data_input.rs @@ -27,6 +27,20 @@ use std::collections::HashMap; #[pyclass(name = "PauliZProductInput", module = "qoqo.measurements")] #[derive(Clone, Debug)] /// Provides Necessary Information to run a [roqoqo::measurements::PauliZProduct] measurement. +/// +/// The PauliZProductInput starts with just the number of qubtis and flipped measurements set. +/// The pauli_poduct_qubit_masks and measured_exp_vals start empty +/// and can be extended with [PauliZProductInput::add_pauliz_product] +/// [PauliZProductInput::add_linear_exp_val] and [PauliZProductInput::add_symbolic_exp_val] +/// +/// Args: +/// number_qubits (int): The number of qubits in the PauliZProduct measurement. +/// use_flipped_measurement (bool): Whether or not to use flipped measurements. +/// +/// Returns: +/// self: The new instance of PauliZProductInput with pauli_product_qubit_masks = an empty dictionary, the +/// specified number of qubits in input, number_pauli_products = 0, measured_exp_vals = an empty +/// dictionary, and whether to use flipped measurements as specified in input. pub struct PauliZProductInputWrapper { /// Internal storage of [roqoqo::PauliZProductInput]. pub internal: PauliZProductInput, @@ -163,7 +177,7 @@ impl PauliZProductInputWrapper { let serialized = serialize(&self.internal) .map_err(|_| PyValueError::new_err("Cannot serialize PauliZProductInput to bytes"))?; let b: Py = Python::with_gil(|py| -> Py { - PyByteArray::new(py, &serialized[..]).into() + PyByteArray::new_bound(py, &serialized[..]).into() }); Ok(b) } @@ -180,8 +194,9 @@ impl PauliZProductInputWrapper { /// TypeError: Input cannot be converted to byte array. /// ValueError: Input cannot be deserialized to PauliZProductInput. #[staticmethod] - pub fn from_bincode(input: &PyAny) -> PyResult { + pub fn from_bincode(input: &Bound) -> PyResult { let bytes = input + .as_gil_ref() .extract::>() .map_err(|_| PyTypeError::new_err("Input cannot be converted to byte array"))?; @@ -217,7 +232,7 @@ impl PauliZProductInputWrapper { } /// Return a deep copy of the Object. - pub fn __deepcopy__(&self, _memodict: Py) -> Self { + pub fn __deepcopy__(&self, _memodict: &Bound) -> Self { self.clone() } @@ -257,6 +272,15 @@ impl PauliZProductInputWrapper { #[pyclass(name = "CheatedPauliZProductInput", module = "qoqo.measurements")] #[derive(Clone, Debug)] /// Collected information for executing a cheated basis rotation measurement. +/// +/// The CheatedPauliZProductInput starts with just the number of qubtis and flipped measurements set. +/// The pauli_poduct_qubit_masks and measured_exp_vals start empty +/// and can be extended with [CheatedPauliZProductInput::add_linear_exp_val] and +/// [CheatedPauliZProductInput::add_symbolic_exp_val]. +/// +/// Returns: +/// self: The new instance of CheatedPauliZProductInput with measured_exp_vals = an empty +/// HashMap and pauli_product_keys = an empty HashMap. pub struct CheatedPauliZProductInputWrapper { /// Internal storage of [roqoqo::CheatedPauliZProductInput]. pub internal: CheatedPauliZProductInput, @@ -278,9 +302,8 @@ impl CheatedPauliZProductInputWrapper { /// [CheatedPauliZProductInput::add_symbolic_exp_val]. /// /// Returns: - /// self: The new instance of PauliZProductInput with pauli_product_qubit_masks = an empty dictionary, the - /// specified number of qubits in input, number_pauli_products = 0, measured_exp_vals = an empty - /// dictionary, and whether to use flipped measurements as specified in input. + /// self: The new instance of CheatedPauliZProductInput with measured_exp_vals = an empty + /// HashMap and pauli_product_keys = an empty HashMap. #[new] pub fn new() -> Self { Self { @@ -387,7 +410,7 @@ impl CheatedPauliZProductInputWrapper { PyValueError::new_err("Cannot serialize CheatedPauliZProductInput to bytes") })?; let b: Py = Python::with_gil(|py| -> Py { - PyByteArray::new(py, &serialized[..]).into() + PyByteArray::new_bound(py, &serialized[..]).into() }); Ok(b) } @@ -404,8 +427,9 @@ impl CheatedPauliZProductInputWrapper { /// TypeError: Input cannot be converted to byte array. /// ValueError: Input cannot be deserialized to CheatedPauliZProductInput. #[staticmethod] - pub fn from_bincode(input: &PyAny) -> PyResult { + pub fn from_bincode(input: &Bound) -> PyResult { let bytes = input + .as_gil_ref() .extract::>() .map_err(|_| PyTypeError::new_err("Input cannot be converted to byte array"))?; @@ -427,7 +451,7 @@ impl CheatedPauliZProductInputWrapper { } /// Return a deep copy of the Object. - pub fn __deepcopy__(&self, _memodict: Py) -> Self { + pub fn __deepcopy__(&self, _memodict: &Bound) -> Self { self.clone() } @@ -481,6 +505,18 @@ impl CheatedPauliZProductInputWrapper { #[pyclass(name = "CheatedInput", module = "qoqo.measurements")] #[derive(Clone, Debug)] /// Provides Necessary Information to run a cheated measurement. +/// +/// The CheatedInput stores the number of qubits that are measured +/// and a dictionary mapping expectation value names to operators on the Hilbert space +/// of the qubits. The operators are represented by sparse lists of non-zero entry triples +/// of an operator matrix. +/// +/// Args: +/// number_qubits (int): The number of qubits in the PauliZProduct measurement. +/// +/// Returns: +/// CheatedInput: The new instance of CheatedInput with the specified number of qubits in input, +/// and an empty dictionay of expectation values. pub struct CheatedInputWrapper { /// Internal storage of [roqoqo::CheatedInput]. pub internal: CheatedInput, @@ -575,7 +611,7 @@ impl CheatedInputWrapper { let serialized = serialize(&self.internal) .map_err(|_| PyValueError::new_err("Cannot serialize CheatedInput to bytes"))?; let b: Py = Python::with_gil(|py| -> Py { - PyByteArray::new(py, &serialized[..]).into() + PyByteArray::new_bound(py, &serialized[..]).into() }); Ok(b) } @@ -592,8 +628,9 @@ impl CheatedInputWrapper { /// TypeError: Input cannot be converted to byte array. /// ValueError: Input cannot be deserialized to CheatedInput. #[staticmethod] - pub fn from_bincode(input: &PyAny) -> PyResult { + pub fn from_bincode(input: &Bound) -> PyResult { let bytes = input + .as_gil_ref() .extract::>() .map_err(|_| PyTypeError::new_err("Input cannot be converted to byte array"))?; @@ -615,7 +652,7 @@ impl CheatedInputWrapper { } /// Return a deep copy of the Object. - pub fn __deepcopy__(&self, _memodict: Py) -> Self { + pub fn __deepcopy__(&self, _memodict: &Bound) -> Self { self.clone() } fn __richcmp__( @@ -675,26 +712,23 @@ impl CheatedPauliZProductInputWrapper { /// # Arguments: /// /// `input` - The Python object that should be casted to a [roqoqo::CheatedPauliZProductInput] - pub fn from_pyany(input: Py) -> PyResult { - Python::with_gil(|py| -> PyResult { - let input = input.as_ref(py); - if let Ok(try_downcast) = input.extract::() { - Ok(try_downcast.internal) - } else { - let get_bytes = input.call_method0("to_bincode").map_err(|_| { + pub fn from_pyany(input: &Bound) -> PyResult { + if let Ok(try_downcast) = input.extract::() { + Ok(try_downcast.internal) + } else { + let get_bytes = input.call_method0("to_bincode").map_err(|_| { PyTypeError::new_err("Python object cannot be converted to qoqo CheatedPauliZInput: Cast to binary representation failed".to_string()) })?; - let bytes = get_bytes.extract::>().map_err(|_| { + let bytes = get_bytes.extract::>().map_err(|_| { PyTypeError::new_err("Python object cannot be converted to qoqo CheatedPauliZInput: Cast to binary representation failed".to_string()) })?; - bincode::deserialize(&bytes[..]).map_err(|err| { + bincode::deserialize(&bytes[..]).map_err(|err| { PyTypeError::new_err(format!( "Python object cannot be converted to qoqo CheatedPauliZInput: Deserialization failed: {}", err )) }) - } - }) + } } } @@ -708,26 +742,23 @@ impl PauliZProductInputWrapper { /// # Arguments: /// /// `input` - The Python object that should be casted to a [roqoqo::PauliZProductInput] - pub fn from_pyany(input: Py) -> PyResult { - Python::with_gil(|py| -> PyResult { - let input = input.as_ref(py); - if let Ok(try_downcast) = input.extract::() { - Ok(try_downcast.internal) - } else { - let get_bytes = input.call_method0("to_bincode").map_err(|_| { + pub fn from_pyany(input: &Bound) -> PyResult { + if let Ok(try_downcast) = input.extract::() { + Ok(try_downcast.internal) + } else { + let get_bytes = input.call_method0("to_bincode").map_err(|_| { PyTypeError::new_err("Python object cannot be converted to qoqo PauliZInput: Cast to binary representation failed".to_string()) })?; - let bytes = get_bytes.extract::>().map_err(|_| { + let bytes = get_bytes.extract::>().map_err(|_| { PyTypeError::new_err("Python object cannot be converted to qoqo PauliZInput: Cast to binary representation failed".to_string()) })?; - bincode::deserialize(&bytes[..]).map_err(|err| { + bincode::deserialize(&bytes[..]).map_err(|err| { PyTypeError::new_err(format!( "Python object cannot be converted to qoqo PauliZInput: Deserialization failed: {}", err )) }) - } - }) + } } } @@ -741,25 +772,22 @@ impl CheatedInputWrapper { /// # Arguments: /// /// `input` - The Python object that should be casted to a [roqoqo::CheatedInput] - pub fn from_pyany(input: Py) -> PyResult { - Python::with_gil(|py| -> PyResult { - let input = input.as_ref(py); - if let Ok(try_downcast) = input.extract::() { - Ok(try_downcast.internal) - } else { - let get_bytes = input.call_method0("to_bincode").map_err(|_| { + pub fn from_pyany(input: &Bound) -> PyResult { + if let Ok(try_downcast) = input.extract::() { + Ok(try_downcast.internal) + } else { + let get_bytes = input.call_method0("to_bincode").map_err(|_| { PyTypeError::new_err("Python object cannot be converted to qoqo CheatedInput: Cast to binary representation failed".to_string()) })?; - let bytes = get_bytes.extract::>().map_err(|_| { + let bytes = get_bytes.extract::>().map_err(|_| { PyTypeError::new_err("Python object cannot be converted to qoqo CheatedInput: Cast to binary representation failed".to_string()) })?; - bincode::deserialize(&bytes[..]).map_err(|err| { + bincode::deserialize(&bytes[..]).map_err(|err| { PyTypeError::new_err(format!( "Python object cannot be converted to qoqo CheatedInput: Deserialization failed: {}", err )) }) - } - }) + } } } diff --git a/qoqo/src/measurements/mod.rs b/qoqo/src/measurements/mod.rs index 96c94645..d2146d1c 100644 --- a/qoqo/src/measurements/mod.rs +++ b/qoqo/src/measurements/mod.rs @@ -40,7 +40,7 @@ pub use classical_register_measurement::ClassicalRegisterWrapper; /// Cheated /// ClassicalRegister #[pymodule] -pub fn measurements(_py: Python, m: &PyModule) -> PyResult<()> { +pub fn measurements(_py: Python, m: &Bound) -> PyResult<()> { m.add_class::()?; m.add_class::()?; m.add_class::()?; diff --git a/qoqo/src/noise_models/continuous_decoherence.rs b/qoqo/src/noise_models/continuous_decoherence.rs index 817cd56d..1bcc4d15 100644 --- a/qoqo/src/noise_models/continuous_decoherence.rs +++ b/qoqo/src/noise_models/continuous_decoherence.rs @@ -54,7 +54,7 @@ pub struct ContinuousDecoherenceModelWrapper { impl ContinuousDecoherenceModelWrapper { /// Create a new ContinuousDecoherenceModel #[new] - pub fn new(noise_operator: Option>) -> PyResult { + pub fn new(noise_operator: Option<&Bound>) -> PyResult { if let Some(lindblad_operator) = noise_operator { let noise_operator = struqture_py::spins::PlusMinusLindbladNoiseOperatorWrapper::from_pyany( @@ -93,8 +93,8 @@ impl ContinuousDecoherenceModelWrapper { /// ValueError: Input cannot be deserialized to selected Noise-Model. #[staticmethod] #[pyo3(text_signature = "(input)")] - pub fn from_bincode(input: &PyAny) -> PyResult { - let bytes = input.extract::>().map_err(|_| { + pub fn from_bincode(input: &Bound) -> PyResult { + let bytes = input.as_gil_ref().extract::>().map_err(|_| { pyo3::exceptions::PyTypeError::new_err("Input cannot be converted to byte array") })?; let noise_model: NoiseModel = bincode::deserialize(&bytes[..]).map_err(|_| { diff --git a/qoqo/src/noise_models/decoherence_on_gate.rs b/qoqo/src/noise_models/decoherence_on_gate.rs index 2abfde13..4d76ac27 100644 --- a/qoqo/src/noise_models/decoherence_on_gate.rs +++ b/qoqo/src/noise_models/decoherence_on_gate.rs @@ -75,7 +75,7 @@ impl DecoherenceOnGateModelWrapper { &self, gate: &str, qubit: usize, - noise_operator: Py, + noise_operator: &Bound, ) -> PyResult { let noise_operator = struqture_py::spins::PlusMinusLindbladNoiseOperatorWrapper::from_pyany(noise_operator)?; @@ -128,7 +128,7 @@ impl DecoherenceOnGateModelWrapper { gate: &str, control: usize, target: usize, - noise_operator: Py, + noise_operator: &Bound, ) -> PyResult { let noise_operator = struqture_py::spins::PlusMinusLindbladNoiseOperatorWrapper::from_pyany(noise_operator)?; @@ -186,7 +186,7 @@ impl DecoherenceOnGateModelWrapper { control0: usize, control1: usize, target: usize, - noise_operator: Py, + noise_operator: &Bound, ) -> PyResult { let noise_operator = struqture_py::spins::PlusMinusLindbladNoiseOperatorWrapper::from_pyany(noise_operator)?; @@ -243,7 +243,7 @@ impl DecoherenceOnGateModelWrapper { &self, gate: &str, qubits: Vec, - noise_operator: Py, + noise_operator: &Bound, ) -> PyResult { let noise_operator = struqture_py::spins::PlusMinusLindbladNoiseOperatorWrapper::from_pyany(noise_operator)?; @@ -291,8 +291,8 @@ impl DecoherenceOnGateModelWrapper { /// ValueError: Input cannot be deserialized to selected Noise-Model. #[staticmethod] #[pyo3(text_signature = "(input)")] - pub fn from_bincode(input: &PyAny) -> PyResult { - let bytes = input.extract::>().map_err(|_| { + pub fn from_bincode(input: &Bound) -> PyResult { + let bytes = input.as_gil_ref().extract::>().map_err(|_| { pyo3::exceptions::PyTypeError::new_err("Input cannot be converted to byte array") })?; let noise_model: NoiseModel = bincode::deserialize(&bytes[..]).map_err(|_| { diff --git a/qoqo/src/noise_models/decoherence_on_idle.rs b/qoqo/src/noise_models/decoherence_on_idle.rs index 0f6f3f25..61a9cb4b 100644 --- a/qoqo/src/noise_models/decoherence_on_idle.rs +++ b/qoqo/src/noise_models/decoherence_on_idle.rs @@ -53,7 +53,7 @@ pub struct DecoherenceOnIdleModelWrapper { impl DecoherenceOnIdleModelWrapper { /// Create a new DecoherenceOnIdleModel #[new] - pub fn new(noise_operator: Option>) -> PyResult { + pub fn new(noise_operator: Option<&Bound>) -> PyResult { if let Some(lindblad_operator) = noise_operator { let noise_operator = struqture_py::spins::PlusMinusLindbladNoiseOperatorWrapper::from_pyany( @@ -92,8 +92,8 @@ impl DecoherenceOnIdleModelWrapper { /// ValueError: Input cannot be deserialized to selected Noise-Model. #[staticmethod] #[pyo3(text_signature = "(input)")] - pub fn from_bincode(input: &PyAny) -> PyResult { - let bytes = input.extract::>().map_err(|_| { + pub fn from_bincode(input: &Bound) -> PyResult { + let bytes = input.as_gil_ref().extract::>().map_err(|_| { pyo3::exceptions::PyTypeError::new_err("Input cannot be converted to byte array") })?; let noise_model: NoiseModel = bincode::deserialize(&bytes[..]).map_err(|_| { diff --git a/qoqo/src/noise_models/imperfect_readout.rs b/qoqo/src/noise_models/imperfect_readout.rs index 08c5cbd3..77893189 100644 --- a/qoqo/src/noise_models/imperfect_readout.rs +++ b/qoqo/src/noise_models/imperfect_readout.rs @@ -92,8 +92,8 @@ impl ImperfectReadoutModelWrapper { /// ValueError: Input cannot be deserialized to selected Noise-Model. #[staticmethod] #[pyo3(text_signature = "(input)")] - pub fn from_bincode(input: &PyAny) -> PyResult { - let bytes = input.extract::>().map_err(|_| { + pub fn from_bincode(input: &Bound) -> PyResult { + let bytes = input.as_gil_ref().extract::>().map_err(|_| { pyo3::exceptions::PyTypeError::new_err("Input cannot be converted to byte array") })?; let noise_model: NoiseModel = bincode::deserialize(&bytes[..]).map_err(|_| { diff --git a/qoqo/src/noise_models/mod.rs b/qoqo/src/noise_models/mod.rs index ccb6aecc..fbe824d8 100644 --- a/qoqo/src/noise_models/mod.rs +++ b/qoqo/src/noise_models/mod.rs @@ -40,7 +40,7 @@ use pyo3::prelude::*; /// SingleQubitOverrotationOnGate /// DecoherenceOnIdleModel #[pymodule] -pub fn noise_models(_py: Python, module: &PyModule) -> PyResult<()> { +pub fn noise_models(_py: Python, module: &Bound) -> PyResult<()> { module.add_class::()?; module.add_class::()?; module.add_class::()?; diff --git a/qoqo/src/noise_models/overrotation.rs b/qoqo/src/noise_models/overrotation.rs index 70730cc7..38b335c4 100644 --- a/qoqo/src/noise_models/overrotation.rs +++ b/qoqo/src/noise_models/overrotation.rs @@ -85,7 +85,7 @@ impl SingleQubitOverrotationDescriptionWrapper { /// /// Returns: /// A deep copy of self. - pub fn __deepcopy__(&self, _memodict: Py) -> Self { + pub fn __deepcopy__(&self, _memodict: &Bound) -> Self { self.clone() } @@ -105,7 +105,7 @@ impl SingleQubitOverrotationDescriptionWrapper { })?; let b: Py = Python::with_gil(|py| -> Py { - pyo3::types::PyByteArray::new(py, &serialized[..]).into() + pyo3::types::PyByteArray::new_bound(py, &serialized[..]).into() }); Ok(b) } @@ -140,8 +140,10 @@ impl SingleQubitOverrotationDescriptionWrapper { /// ValueError: Input cannot be deserialized to selected Noise-Model. #[staticmethod] #[pyo3(text_signature = "(input)")] - pub fn from_bincode(input: &PyAny) -> PyResult { - let bytes = input.extract::>().map_err(|_| { + pub fn from_bincode( + input: &Bound, + ) -> PyResult { + let bytes = input.as_gil_ref().extract::>().map_err(|_| { pyo3::exceptions::PyTypeError::new_err("Input cannot be converted to byte array") })?; let noise_description: SingleQubitOverrotationDescription = @@ -192,7 +194,11 @@ impl SingleQubitOverrotationDescriptionWrapper { /// Raises: /// NotImplementedError: Other comparison not implemented. /// - fn __richcmp__(&self, other: Py, op: pyo3::class::basic::CompareOp) -> PyResult { + fn __richcmp__( + &self, + other: &Bound, + op: pyo3::class::basic::CompareOp, + ) -> PyResult { let other = SingleQubitOverrotationDescriptionWrapper::from_pyany(other); match op { @@ -247,24 +253,22 @@ impl SingleQubitOverrotationDescriptionWrapper { impl SingleQubitOverrotationDescriptionWrapper { /// Fallible conversion of generic python object.. - pub fn from_pyany(input: Py) -> PyResult { - Python::with_gil(|py| -> PyResult { - let input = input.as_ref(py); - if let Ok(try_downcast) = input.extract::() { - Ok(try_downcast.internal) - } else { - let get_bytes = input.call_method0("to_bincode")?; - let bytes = get_bytes.extract::>()?; - bincode::deserialize(&bytes[..]).map_err(|err| { - pyo3::exceptions::PyValueError::new_err(format!( - "Cannot treat input as Overrotation Description: {}", - err - )) - }) - } - }) + pub fn from_pyany(input: &Bound) -> PyResult { + if let Ok(try_downcast) = input.extract::() { + Ok(try_downcast.internal) + } else { + let get_bytes = input.call_method0("to_bincode")?; + let bytes = get_bytes.extract::>()?; + bincode::deserialize(&bytes[..]).map_err(|err| { + pyo3::exceptions::PyValueError::new_err(format!( + "Cannot treat input as Overrotation Description: {}", + err + )) + }) + } } } + /// Single qubit overrotation noise model on gate. /// /// Adds a rotation gate with a randomly distributed rotation angle after specified gates in a quantum circuit. @@ -315,7 +319,7 @@ impl SingleQubitOverrotationOnGateWrapper { &self, gate: &str, qubit: usize, - noise_description: Py, + noise_description: &Bound, ) -> PyResult { let noise_description = SingleQubitOverrotationDescriptionWrapper::from_pyany(noise_description)?; @@ -368,16 +372,20 @@ impl SingleQubitOverrotationOnGateWrapper { target: usize, noise_operator: (Py, Py), ) -> PyResult { - let noise1 = SingleQubitOverrotationDescriptionWrapper::from_pyany(noise_operator.0)?; - let noise2 = SingleQubitOverrotationDescriptionWrapper::from_pyany(noise_operator.1)?; + Python::with_gil(|py| -> PyResult { + let noise1 = + SingleQubitOverrotationDescriptionWrapper::from_pyany(noise_operator.0.bind(py))?; + let noise2 = + SingleQubitOverrotationDescriptionWrapper::from_pyany(noise_operator.1.bind(py))?; - Ok(Self { - internal: self.internal.clone().set_two_qubit_overrotation( - gate, - control, - target, - (noise1, noise2), - ), + Ok(Self { + internal: self.internal.clone().set_two_qubit_overrotation( + gate, + control, + target, + (noise1, noise2), + ), + }) }) } @@ -426,8 +434,8 @@ impl SingleQubitOverrotationOnGateWrapper { /// ValueError: Input cannot be deserialized to selected Noise-Model. #[staticmethod] #[pyo3(text_signature = "(input)")] - pub fn from_bincode(input: &PyAny) -> PyResult { - let bytes = input.extract::>().map_err(|_| { + pub fn from_bincode(input: &Bound) -> PyResult { + let bytes = input.as_gil_ref().extract::>().map_err(|_| { pyo3::exceptions::PyTypeError::new_err("Input cannot be converted to byte array") })?; let noise_model: NoiseModel = bincode::deserialize(&bytes[..]).map_err(|_| { diff --git a/qoqo/src/operations/analog_operations.rs b/qoqo/src/operations/analog_operations.rs index 4a84a87f..b20beed7 100644 --- a/qoqo/src/operations/analog_operations.rs +++ b/qoqo/src/operations/analog_operations.rs @@ -18,14 +18,14 @@ use qoqo_calculator::CalculatorFloat; use qoqo_calculator_pyo3::{convert_into_calculator_float, CalculatorFloatWrapper}; use qoqo_macros::*; use roqoqo::operations::*; +#[cfg(feature = "json_schema")] +use roqoqo::ROQOQO_VERSION; use struqture::spins::SpinHamiltonian; use struqture_py::spins::SpinHamiltonianSystemWrapper; -#[cfg(feature = "json_schema")] -use roqoqo::ROQOQO_VERSION; use std::collections::HashMap; -#[wrap(Operate, OperateSpinsAnalog)] +#[wrap(Operate, OperateSpinsAnalog, JsonSchema)] /// Constant Hamiltonian operation on analog quantum device (PASQAL) /// /// Args: @@ -36,7 +36,7 @@ pub struct ApplyConstantSpinHamiltonian { time: CalculatorFloat, } -#[wrap(Operate, OperateSpinsAnalog)] +#[wrap(Operate, OperateSpinsAnalog, JsonSchema)] /// Constant Hamiltonian operation on analog quantum device (PASCAL) /// /// Args: diff --git a/qoqo/src/operations/mod.rs b/qoqo/src/operations/mod.rs index 975cc96c..defb2ad4 100644 --- a/qoqo/src/operations/mod.rs +++ b/qoqo/src/operations/mod.rs @@ -57,7 +57,7 @@ use pyo3::prelude::*; /// #[pymodule] -pub fn operations(_py: Python, m: &PyModule) -> PyResult<()> { +pub fn operations(_py: Python, m: &Bound) -> PyResult<()> { // 1.0 m.add_class::()?; m.add_class::()?; diff --git a/qoqo/src/operations/pragma_operations.rs b/qoqo/src/operations/pragma_operations.rs index f15a4b85..776cdd6e 100644 --- a/qoqo/src/operations/pragma_operations.rs +++ b/qoqo/src/operations/pragma_operations.rs @@ -58,7 +58,7 @@ pub struct PragmaLoop { /// Module containing the PragmaSetStateVector class. #[pymodule] -fn pragma_set_statevector(_py: Python, module: &PyModule) -> PyResult<()> { +fn pragma_set_statevector(_py: Python, module: &Bound) -> PyResult<()> { module.add_class::()?; Ok(()) } @@ -84,7 +84,7 @@ insert_pyany_to_operation!( "PragmaSetStateVector" =>{ let array = op.call_method0("statevector").expect("error extracting"); let statevec_casted: PyReadonlyArray1 = array.extract().unwrap(); - let statevec_array: Array1 = statevec_casted.to_owned_array(); + let statevec_array: Array1 = statevec_casted.as_array().to_owned();; // let statevec_array: Array1 = Array1::from(statevec_casted); Ok(PragmaSetStateVector::new(statevec_array).into()) } @@ -110,44 +110,34 @@ impl PragmaSetStateVectorWrapper { /// Returns: /// self: The new PragmaSetStateVector. #[new] - fn new(statevector: Py) -> PyResult { - let try_cast: PyResult> = - Python::with_gil(|py| -> PyResult> { - let extracted: PyReadonlyArray1 = statevector.as_ref(py).extract()?; - let statevec: Array1 = extracted.to_owned_array(); - Ok(statevec) - }); - let try_cast = try_cast.or_else(|_| { - Python::with_gil(|py| -> PyResult> { - let extracted: PyReadonlyArray1 = statevector.as_ref(py).extract()?; - let statevec: Array1 = extracted.to_owned_array(); - let statevec: Array1 = statevec - .into_iter() - .map(|f| Complex64::new(f, 0.0)) - .collect(); - Ok(statevec) - }) + fn new(statevector: &Bound) -> PyResult { + let extracted: PyReadonlyArray1 = statevector.extract()?; + let statevec: Array1 = extracted.as_array().to_owned(); + let try_cast: PyResult> = Ok(statevec); + let try_cast: PyResult> = try_cast.or_else(|_| { + let extracted: PyReadonlyArray1 = statevector.extract()?; + let statevec: Array1 = extracted.as_array().to_owned(); + let statevec: Array1 = statevec + .into_iter() + .map(|f| Complex64::new(f, 0.0)) + .collect(); + Ok(statevec) }); - let try_cast = try_cast.or_else(|_| { - Python::with_gil(|py| -> PyResult> { - let extracted: PyReadonlyArray1 = statevector.as_ref(py).extract()?; - let statevec: Array1 = extracted.to_owned_array(); - let statevec: Array1 = statevec - .into_iter() - .map(|f| Complex64::new(f as f64, 0.0)) - .collect(); - Ok(statevec) - }) + let try_cast: PyResult> = try_cast.or_else(|_| { + let extracted: PyReadonlyArray1 = statevector.extract()?; + let statevec: Array1 = extracted.as_array().to_owned(); + let statevec: Array1 = statevec + .into_iter() + .map(|f| Complex64::new(f as f64, 0.0)) + .collect(); + Ok(statevec) }); match try_cast { Ok(array) => Ok(Self { internal: PragmaSetStateVector::new(array), }), Err(_) => { - let statevec_casted: Vec = - Python::with_gil(|py| -> PyResult> { - Vec::extract(statevector.as_ref(py)) - })?; + let statevec_casted: Vec = Vec::extract_bound(statevector)?; let statevec_array: Array1 = Array1::from(statevec_casted); Ok(Self { internal: PragmaSetStateVector::new(statevec_array), @@ -162,7 +152,7 @@ impl PragmaSetStateVectorWrapper { /// np.ndarray: The statevector representing the qubit register. fn statevector(&self) -> Py> { Python::with_gil(|py| -> Py> { - self.internal.statevector().to_pyarray(py).to_owned() + self.internal.statevector().to_pyarray_bound(py).unbind() }) } @@ -171,8 +161,9 @@ impl PragmaSetStateVectorWrapper { /// Returns: /// set[int]: The involved qubits of the PRAGMA operation. fn involved_qubits(&self) -> PyObject { - let pyobject: PyObject = - Python::with_gil(|py| -> PyObject { PySet::new(py, &["All"]).unwrap().to_object(py) }); + let pyobject: PyObject = Python::with_gil(|py| -> PyObject { + PySet::new_bound(py, &["All"]).unwrap().to_object(py) + }); pyobject } @@ -214,7 +205,7 @@ impl PragmaSetStateVectorWrapper { /// RuntimeError: The parameter substitution failed. fn substitute_parameters( &self, - substitution_parameters: std::collections::HashMap<&str, f64>, + substitution_parameters: std::collections::HashMap, ) -> PyResult { let mut calculator = qoqo_calculator::Calculator::new(); for (key, val) in substitution_parameters.iter() { @@ -265,7 +256,7 @@ impl PragmaSetStateVectorWrapper { /// /// Returns: /// PragmaSetStateVector: A deep copy of self. - fn __deepcopy__(&self, _memodict: Py) -> PragmaSetStateVectorWrapper { + fn __deepcopy__(&self, _memodict: &Bound) -> PragmaSetStateVectorWrapper { self.clone() } @@ -294,15 +285,15 @@ impl PragmaSetStateVectorWrapper { /// /// Returns: /// bool: Whether the two operations compared evaluated to True or False. - fn __richcmp__(&self, other: Py, op: pyo3::class::basic::CompareOp) -> PyResult { - let other: Operation = Python::with_gil(|py| -> PyResult { - let other_ref = other.as_ref(py); - - crate::operations::convert_pyany_to_operation(other_ref).map_err(|_| { - pyo3::exceptions::PyTypeError::new_err( - "Right hand side cannot be converted to Operation", - ) - }) + fn __richcmp__( + &self, + other: &Bound, + op: pyo3::class::basic::CompareOp, + ) -> PyResult { + let other = crate::operations::convert_pyany_to_operation(other).map_err(|_| { + pyo3::exceptions::PyTypeError::new_err( + "Right hand side cannot be converted to Operation", + ) })?; match op { pyo3::class::basic::CompareOp::Eq => { @@ -352,7 +343,7 @@ impl PragmaSetStateVectorWrapper { /// Module containing the PragmaSetDensityMatrix class. #[pymodule] -fn pragma_set_density_matrix(_py: Python, module: &PyModule) -> PyResult<()> { +fn pragma_set_density_matrix(_py: Python, module: &Bound) -> PyResult<()> { module.add_class::()?; Ok(()) } @@ -378,7 +369,7 @@ insert_pyany_to_operation!( .map_err(|_| QoqoError::ConversionError)?; let density_matrix_op = density_matrix.downcast::>().unwrap(); - let densmat_array = density_matrix_op.readonly().as_array().to_owned(); + let densmat_array = density_matrix_op.as_gil_ref().readonly().as_array().to_owned(); Ok(PragmaSetDensityMatrix::new(densmat_array).into()) } ); @@ -417,7 +408,7 @@ impl PragmaSetDensityMatrixWrapper { fn density_matrix(&self) -> Py> { Python::with_gil(|py| -> Py> { - self.internal.density_matrix().to_pyarray(py).to_owned() + self.internal.density_matrix().to_pyarray_bound(py).unbind() }) } @@ -426,8 +417,9 @@ impl PragmaSetDensityMatrixWrapper { /// Returns: /// set[int]: The involved qubits of the PRAGMA operation. fn involved_qubits(&self) -> PyObject { - let pyobject: PyObject = - Python::with_gil(|py| -> PyObject { PySet::new(py, &["All"]).unwrap().to_object(py) }); + let pyobject: PyObject = Python::with_gil(|py| -> PyObject { + PySet::new_bound(py, &["All"]).unwrap().to_object(py) + }); pyobject } @@ -469,7 +461,7 @@ impl PragmaSetDensityMatrixWrapper { /// RuntimeError: The parameter substitution failed. fn substitute_parameters( &self, - substitution_parameters: std::collections::HashMap<&str, f64>, + substitution_parameters: std::collections::HashMap, ) -> PyResult { let mut calculator = qoqo_calculator::Calculator::new(); for (key, val) in substitution_parameters.iter() { @@ -520,7 +512,7 @@ impl PragmaSetDensityMatrixWrapper { /// /// Returns: /// PragmaSetDensityMatrix: A deep copy of self. - fn __deepcopy__(&self, _memodict: Py) -> PragmaSetDensityMatrixWrapper { + fn __deepcopy__(&self, _memodict: &Bound) -> PragmaSetDensityMatrixWrapper { self.clone() } @@ -549,14 +541,15 @@ impl PragmaSetDensityMatrixWrapper { /// /// Returns: /// bool: Whether the two operations compared evaluated to True or False. - fn __richcmp__(&self, other: Py, op: pyo3::class::basic::CompareOp) -> PyResult { - let other: Operation = Python::with_gil(|py| -> PyResult { - let other_ref = other.as_ref(py); - crate::operations::convert_pyany_to_operation(other_ref).map_err(|_| { - pyo3::exceptions::PyTypeError::new_err( - "Right hand side cannot be converted to Operation", - ) - }) + fn __richcmp__( + &self, + other: &Bound, + op: pyo3::class::basic::CompareOp, + ) -> PyResult { + let other = crate::operations::convert_pyany_to_operation(other).map_err(|_| { + pyo3::exceptions::PyTypeError::new_err( + "Right hand side cannot be converted to Operation", + ) })?; match op { pyo3::class::basic::CompareOp::Eq => { @@ -703,7 +696,7 @@ pub struct PragmaActiveReset { /// /// Args: /// qubits (list[int]): The qubits involved in the decomposition block. -/// reordering_dictionary dict[int, int]): The reordering dictionary of the block. +/// reordering_dictionary (dict[int, int]): The reordering dictionary of the block. pub struct PragmaStartDecompositionBlock { qubits: Vec, reordering_dictionary: HashMap, @@ -970,7 +963,7 @@ pub struct PragmaRandomNoise { /// Module containing the PragmaGeneralNoise class. #[pymodule] -fn pragma_general_noise(_py: Python, module: &PyModule) -> PyResult<()> { +fn pragma_general_noise(_py: Python, module: &Bound) -> PyResult<()> { module.add_class::()?; Ok(()) } @@ -998,7 +991,7 @@ insert_pyany_to_operation!( let qubit: usize = qbt.extract() .map_err(|_| QoqoError::ConversionError)?; - let gatetm = op.call_method0("gate_time") + let gatetm = &op.call_method0("gate_time") .map_err(|_| QoqoError::ConversionError)?; let gate_time: CalculatorFloat = convert_into_calculator_float(gatetm).map_err(|_| { QoqoError::ConversionError @@ -1007,7 +1000,7 @@ insert_pyany_to_operation!( let array = op.call_method0("rates") .map_err(|_| QoqoError::ConversionError)?; let rates_array = array.downcast::>().unwrap(); - let rates = rates_array.readonly().as_array().to_owned(); + let rates = rates_array.as_gil_ref().readonly().as_array().to_owned(); Ok(PragmaGeneralNoise::new(qubit, gate_time, rates).into()) } @@ -1056,14 +1049,12 @@ impl PragmaGeneralNoiseWrapper { /// Returns: /// self: The new PragmaGeneralNoise. #[new] - fn new(qubit: usize, gate_time: Py, rates: PyReadonlyArray2) -> PyResult { + fn new(qubit: usize, gate_time: &Bound, rates: PyReadonlyArray2) -> PyResult { let rates_array = rates.as_array().to_owned(); - let gate_time_cf = Python::with_gil(|py| -> PyResult { - convert_into_calculator_float(gate_time.as_ref(py)).map_err(|_| { - pyo3::exceptions::PyTypeError::new_err( - "Argument gate time cannot be converted to CalculatorFloat", - ) - }) + let gate_time_cf = convert_into_calculator_float(gate_time).map_err(|_| { + pyo3::exceptions::PyTypeError::new_err( + "Argument gate time cannot be converted to CalculatorFloat", + ) })?; Ok(Self { @@ -1095,7 +1086,7 @@ impl PragmaGeneralNoiseWrapper { /// np.ndarray: The rates of the PRAGMA operation. fn rates(&self) -> Py> { Python::with_gil(|py| -> Py> { - self.internal.rates().to_pyarray(py).to_owned() + self.internal.rates().to_pyarray_bound(py).unbind() }) } @@ -1106,7 +1097,7 @@ impl PragmaGeneralNoiseWrapper { fn superoperator(&self) -> PyResult>> { Python::with_gil(|py| -> PyResult>> { match self.internal.superoperator() { - Ok(x) => Ok(x.to_pyarray(py).to_owned()), + Ok(x) => Ok(x.to_pyarray_bound(py).unbind()), Err(err) => Err(PyRuntimeError::new_err(format!("{:?}", err))), } }) @@ -1118,7 +1109,7 @@ impl PragmaGeneralNoiseWrapper { /// set[int]: The involved qubits of the PRAGMA operation. fn involved_qubits(&self) -> PyObject { let pyobject: PyObject = Python::with_gil(|py| -> PyObject { - PySet::new(py, &[*self.internal.qubit()]) + PySet::new_bound(py, &[*self.internal.qubit()]) .unwrap() .to_object(py) }); @@ -1163,7 +1154,7 @@ impl PragmaGeneralNoiseWrapper { /// RuntimeError: The parameter substitution failed. fn substitute_parameters( &self, - substitution_parameters: std::collections::HashMap<&str, f64>, + substitution_parameters: std::collections::HashMap, ) -> PyResult { let mut calculator = qoqo_calculator::Calculator::new(); for (key, val) in substitution_parameters.iter() { @@ -1214,7 +1205,7 @@ impl PragmaGeneralNoiseWrapper { /// /// Returns: /// PragmaGeneralNoise: A deep copy of self. - fn __deepcopy__(&self, _memodict: Py) -> PragmaGeneralNoiseWrapper { + fn __deepcopy__(&self, _memodict: &Bound) -> PragmaGeneralNoiseWrapper { self.clone() } @@ -1243,14 +1234,15 @@ impl PragmaGeneralNoiseWrapper { /// /// Returns: /// bool: Whether the two operations compared evaluated to True or False. - fn __richcmp__(&self, other: Py, op: pyo3::class::basic::CompareOp) -> PyResult { - let other: Operation = Python::with_gil(|py| -> PyResult { - let other_ref = other.as_ref(py); - crate::operations::convert_pyany_to_operation(other_ref).map_err(|_| { - pyo3::exceptions::PyTypeError::new_err( - "Right hand side cannot be converted to Operation", - ) - }) + fn __richcmp__( + &self, + other: &Bound, + op: pyo3::class::basic::CompareOp, + ) -> PyResult { + let other = crate::operations::convert_pyany_to_operation(other).map_err(|_| { + pyo3::exceptions::PyTypeError::new_err( + "Right hand side cannot be converted to Operation", + ) })?; match op { pyo3::class::basic::CompareOp::Eq => { @@ -1403,7 +1395,7 @@ impl PragmaChangeDeviceWrapper { fn wrapped_operation(&self) -> PyResult> { let serialized: Vec = self.internal.wrapped_operation.clone(); let b: Py = Python::with_gil(|py| -> Py { - PyByteArray::new(py, &serialized[..]).into() + PyByteArray::new_bound(py, &serialized[..]).into() }); Ok(b) } @@ -1413,8 +1405,9 @@ impl PragmaChangeDeviceWrapper { /// Returns: /// set[int]: The involved qubits of the PRAGMA operation. fn involved_qubits(&self) -> PyObject { - let pyobject: PyObject = - Python::with_gil(|py| -> PyObject { PySet::new(py, &["All"]).unwrap().to_object(py) }); + let pyobject: PyObject = Python::with_gil(|py| -> PyObject { + PySet::new_bound(py, &["All"]).unwrap().to_object(py) + }); pyobject } @@ -1456,7 +1449,7 @@ impl PragmaChangeDeviceWrapper { /// RuntimeError: The parameter substitution failed. fn substitute_parameters( &self, - substitution_parameters: std::collections::HashMap<&str, f64>, + substitution_parameters: std::collections::HashMap, ) -> PyResult { let mut calculator = qoqo_calculator::Calculator::new(); for (key, val) in substitution_parameters.iter() { @@ -1507,7 +1500,7 @@ impl PragmaChangeDeviceWrapper { /// /// Returns: /// PragmaChangeDevice: A deep copy of self. - fn __deepcopy__(&self, _memodict: Py) -> PragmaChangeDeviceWrapper { + fn __deepcopy__(&self, _memodict: &Bound) -> PragmaChangeDeviceWrapper { self.clone() } @@ -1536,14 +1529,15 @@ impl PragmaChangeDeviceWrapper { /// /// Returns: /// bool: Whether the two operations compared evaluated to True or False. - fn __richcmp__(&self, other: Py, op: pyo3::class::basic::CompareOp) -> PyResult { - let other: Operation = Python::with_gil(|py| -> PyResult { - let other_ref = other.as_ref(py); - crate::operations::convert_pyany_to_operation(other_ref).map_err(|_| { - pyo3::exceptions::PyTypeError::new_err( - "Right hand side cannot be converted to Operation", - ) - }) + fn __richcmp__( + &self, + other: &Bound, + op: pyo3::class::basic::CompareOp, + ) -> PyResult { + let other = crate::operations::convert_pyany_to_operation(other).map_err(|_| { + pyo3::exceptions::PyTypeError::new_err( + "Right hand side cannot be converted to Operation", + ) })?; match op { pyo3::class::basic::CompareOp::Eq => { @@ -1593,7 +1587,7 @@ impl PragmaChangeDeviceWrapper { /// Module containing the PragmaAnnotatedOp class. #[pymodule] -fn pragma_annotated_op(_py: Python, module: &PyModule) -> PyResult<()> { +fn pragma_annotated_op(_py: Python, module: &Bound) -> PyResult<()> { module.add_class::()?; Ok(()) } @@ -1612,7 +1606,7 @@ pub struct PragmaAnnotatedOpWrapper { insert_pyany_to_operation!( "PragmaAnnotatedOp" =>{ - let annot_op = op.call_method0( "operation").map_err(|_|QoqoError::ConversionError)?; + let annot_op = &op.call_method0( "operation").map_err(|_|QoqoError::ConversionError)?; let operation: Operation = convert_pyany_to_operation(annot_op) .map_err(|_| QoqoError::ConversionError)?; let annot = op.call_method0( "annotation").map_err(|_|QoqoError::ConversionError)?; @@ -1641,14 +1635,11 @@ impl PragmaAnnotatedOpWrapper { /// operation (Operation): - The Operation to be annotated. /// annotation (String): - The annotation. #[new] - fn new(operation: Py, annotation: String) -> PyResult { - let op: Operation = Python::with_gil(|py| -> PyResult { - let op_ref = operation.as_ref(py); - crate::operations::convert_pyany_to_operation(op_ref).map_err(|_| { - pyo3::exceptions::PyTypeError::new_err( - "Input operation cannot be converted to Operation", - ) - }) + fn new(operation: &Bound, annotation: String) -> PyResult { + let op = crate::operations::convert_pyany_to_operation(operation).map_err(|_| { + pyo3::exceptions::PyTypeError::new_err( + "Input operation cannot be converted to Operation", + ) })?; Ok(Self { internal: PragmaAnnotatedOp::new(op, annotation), @@ -1681,13 +1672,13 @@ impl PragmaAnnotatedOpWrapper { let involved = self.internal.involved_qubits(); match involved { InvolvedQubits::All => { - let pyref: &PySet = PySet::new(py, &["All"]).unwrap(); - let pyobject: PyObject = pyref.to_object(py); + let pyref: &Bound = &PySet::new_bound(py, &["All"]).unwrap(); + let pyobject: PyObject = pyref.as_any().to_object(py); pyobject } InvolvedQubits::None => { - let pyref: &PySet = PySet::empty(py).unwrap(); - let pyobject: PyObject = pyref.to_object(py); + let pyref: &Bound = &PySet::empty_bound(py).unwrap(); + let pyobject: PyObject = pyref.as_any().to_object(py); pyobject } InvolvedQubits::Set(x) => { @@ -1695,8 +1686,8 @@ impl PragmaAnnotatedOpWrapper { for mode in x { vector.push(mode) } - let pyref: &PySet = PySet::new(py, &vector[..]).unwrap(); - let pyobject: PyObject = pyref.to_object(py); + let pyref: &Bound = &PySet::new_bound(py, &vector[..]).unwrap(); + let pyobject: PyObject = pyref.as_any().to_object(py); pyobject } } @@ -1741,7 +1732,7 @@ impl PragmaAnnotatedOpWrapper { /// RuntimeError: The parameter substitution failed. fn substitute_parameters( &self, - substitution_parameters: std::collections::HashMap<&str, f64>, + substitution_parameters: std::collections::HashMap, ) -> PyResult { let mut calculator = qoqo_calculator::Calculator::new(); for (key, val) in substitution_parameters.iter() { @@ -1792,7 +1783,7 @@ impl PragmaAnnotatedOpWrapper { /// /// Returns: /// PragmaAnnotatedOp: A deep copy of self. - fn __deepcopy__(&self, _memodict: Py) -> PragmaAnnotatedOpWrapper { + fn __deepcopy__(&self, _memodict: &Bound) -> PragmaAnnotatedOpWrapper { self.clone() } @@ -1821,14 +1812,15 @@ impl PragmaAnnotatedOpWrapper { /// /// Returns: /// bool: Whether the two operations compared evaluated to True or False. - fn __richcmp__(&self, other: Py, op: pyo3::class::basic::CompareOp) -> PyResult { - let other: Operation = Python::with_gil(|py| -> PyResult { - let other_ref = other.as_ref(py); - crate::operations::convert_pyany_to_operation(other_ref).map_err(|_| { - pyo3::exceptions::PyTypeError::new_err( - "Right hand side cannot be converted to Operation", - ) - }) + fn __richcmp__( + &self, + other: &Bound, + op: pyo3::class::basic::CompareOp, + ) -> PyResult { + let other = crate::operations::convert_pyany_to_operation(other).map_err(|_| { + pyo3::exceptions::PyTypeError::new_err( + "Right hand side cannot be converted to Operation", + ) })?; match op { pyo3::class::basic::CompareOp::Eq => { @@ -1893,9 +1885,10 @@ mod tests { Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_definition).unwrap(); let to_involved = operation.call_method0(py, "involved_qubits").unwrap(); - let involved_op: HashSet<&str> = HashSet::extract(to_involved.as_ref(py)).unwrap(); - let mut involved_param: HashSet<&str> = HashSet::new(); - involved_param.insert("All"); + let involved_op: HashSet = + HashSet::extract_bound(to_involved.bind(py)).unwrap(); + let mut involved_param: HashSet = HashSet::new(); + involved_param.insert("All".to_owned()); assert_eq!(involved_op, involved_param); assert!(PragmaChangeDeviceWrapper::new().is_err()); @@ -1912,9 +1905,9 @@ mod tests { Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_measurement).unwrap(); let to_format = operation.call_method1(py, "__format__", ("",)).unwrap(); - let format_op: &str = <&str>::extract(to_format.as_ref(py)).unwrap(); + let format_op: String = String::extract_bound(to_format.bind(py)).unwrap(); let to_repr = operation.call_method0(py, "__repr__").unwrap(); - let repr_op: &str = <&str>::extract(to_repr.as_ref(py)).unwrap(); + let repr_op: String = String::extract_bound(to_repr.bind(py)).unwrap(); assert_eq!(format_op, format_repr); assert_eq!(repr_op, format_repr); }) @@ -1932,19 +1925,19 @@ mod tests { let deepcopy_op = operation.call_method1(py, "__deepcopy__", ("",)).unwrap(); let copy_deepcopy_param = operation; - let comparison_copy = bool::extract( + let comparison_copy = bool::extract_bound( copy_op - .as_ref(py) - .call_method1("__eq__", (copy_deepcopy_param.clone(),)) - .unwrap(), + .call_method1(py, "__eq__", (copy_deepcopy_param.clone(),)) + .unwrap() + .bind(py), ) .unwrap(); assert!(comparison_copy); - let comparison_deepcopy = bool::extract( + let comparison_deepcopy = bool::extract_bound( deepcopy_op - .as_ref(py) - .call_method1("__eq__", (copy_deepcopy_param,)) - .unwrap(), + .call_method1(py, "__eq__", (copy_deepcopy_param,)) + .unwrap() + .bind(py), ) .unwrap(); assert!(comparison_deepcopy); @@ -1960,7 +1953,7 @@ mod tests { Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_measurement).unwrap(); let to_tag = operation.call_method0(py, "tags").unwrap(); - let tags_op: &Vec<&str> = &Vec::extract(to_tag.as_ref(py)).unwrap(); + let tags_op: &Vec = &Vec::extract_bound(to_tag.bind(py)).unwrap(); let tags_param: &[&str] = &["Operation", "PragmaOperation", "PragmaChangeDevice"]; assert_eq!(tags_op, tags_param); }) @@ -1975,7 +1968,8 @@ mod tests { Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_measurement).unwrap(); let hqslang_op: String = - String::extract(operation.call_method0(py, "hqslang").unwrap().as_ref(py)).unwrap(); + String::extract_bound(operation.call_method0(py, "hqslang").unwrap().bind(py)) + .unwrap(); assert_eq!(hqslang_op, "PragmaChangeDevice".to_string()); }) } @@ -1988,11 +1982,11 @@ mod tests { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_measurement).unwrap(); - assert!(!bool::extract( + assert!(!bool::extract_bound( operation .call_method0(py, "is_parametrized") .unwrap() - .as_ref(py) + .bind(py) ) .unwrap()); }) @@ -2007,18 +2001,18 @@ mod tests { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let operation = convert_operation_to_pyobject(first_op).unwrap(); - let mut substitution_dict: HashMap<&str, f64> = HashMap::new(); - substitution_dict.insert("test", 1.0); + let mut substitution_dict: HashMap = HashMap::new(); + substitution_dict.insert("test".to_owned(), 1.0); let substitute_op = operation .call_method1(py, "substitute_parameters", (substitution_dict,)) .unwrap(); let substitute_param = convert_operation_to_pyobject(second_op).unwrap(); - let comparison = bool::extract( + let comparison = bool::extract_bound( substitute_op - .as_ref(py) - .call_method1("__eq__", (substitute_param,)) - .unwrap(), + .call_method1(py, "__eq__", (substitute_param,)) + .unwrap() + .bind(py), ) .unwrap(); assert!(comparison); @@ -2042,11 +2036,11 @@ mod tests { .unwrap(); let comparison_op = convert_operation_to_pyobject(second_op).unwrap(); - let comparison = bool::extract( + let comparison = bool::extract_bound( remapped_op .call_method1(py, "__eq__", (comparison_op,)) .unwrap() - .as_ref(py), + .bind(py), ) .unwrap(); assert!(comparison); @@ -2081,20 +2075,20 @@ mod tests { let operation_one = convert_operation_to_pyobject(definition_1).unwrap(); let operation_two = convert_operation_to_pyobject(definition_2).unwrap(); - let comparison = bool::extract( + let comparison = bool::extract_bound( operation_one - .as_ref(py) - .call_method1("__eq__", (operation_two.clone(),)) - .unwrap(), + .call_method1(py, "__eq__", (operation_two.clone(),)) + .unwrap() + .bind(py), ) .unwrap(); assert!(!comparison); - let comparison = bool::extract( + let comparison = bool::extract_bound( operation_one - .as_ref(py) - .call_method1("__ne__", (operation_two.clone(),)) - .unwrap(), + .call_method1(py, "__ne__", (operation_two.clone(),)) + .unwrap() + .bind(py), ) .unwrap(); assert!(comparison); diff --git a/qoqo/src/quantum_program.rs b/qoqo/src/quantum_program.rs index 8d7c3305..08f3462a 100644 --- a/qoqo/src/quantum_program.rs +++ b/qoqo/src/quantum_program.rs @@ -56,26 +56,23 @@ impl QuantumProgramWrapper { /// # Arguments: /// /// `input` - The Python object that should be casted to a [roqoqo::QuantumProgram] - pub fn from_pyany(input: Py) -> PyResult { - Python::with_gil(|py| -> PyResult { - let input = input.as_ref(py); - if let Ok(try_downcast) = input.extract::() { - Ok(try_downcast.internal) - } else { - let get_bytes = input.call_method0("to_bincode").map_err(|_| { + pub fn from_pyany(input: &Bound) -> PyResult { + if let Ok(try_downcast) = input.extract::() { + Ok(try_downcast.internal) + } else { + let get_bytes = input.call_method0("to_bincode").map_err(|_| { PyTypeError::new_err("Python object cannot be converted to qoqo QuantumProgram: Cast to binary representation failed".to_string()) })?; - let bytes = get_bytes.extract::>().map_err(|_| { + let bytes = get_bytes.extract::>().map_err(|_| { PyTypeError::new_err("Python object cannot be converted to qoqo QuantumProgram: Cast to binary representation failed".to_string()) })?; - deserialize(&bytes[..]).map_err(|err| { + deserialize(&bytes[..]).map_err(|err| { PyTypeError::new_err(format!( "Python object cannot be converted to qoqo QuantumProgram: Deserialization failed: {}", err )) }) - } - }) + } } } @@ -90,8 +87,8 @@ impl QuantumProgramWrapper { /// Returns: /// self: The new . #[new] - pub fn new(measurement: &PyAny, input_parameter_names: Vec) -> PyResult { - if let Ok(try_downcast) = PauliZProductWrapper::from_pyany(measurement.into()) { + pub fn new(measurement: &Bound, input_parameter_names: Vec) -> PyResult { + if let Ok(try_downcast) = PauliZProductWrapper::from_pyany(measurement) { return Ok(Self { internal: QuantumProgram::PauliZProduct { measurement: try_downcast, @@ -99,7 +96,7 @@ impl QuantumProgramWrapper { }, }); } - if let Ok(try_downcast) = CheatedPauliZProductWrapper::from_pyany(measurement.into()) { + if let Ok(try_downcast) = CheatedPauliZProductWrapper::from_pyany(measurement) { return Ok(Self { internal: QuantumProgram::CheatedPauliZProduct { measurement: try_downcast, @@ -107,7 +104,7 @@ impl QuantumProgramWrapper { }, }); } - if let Ok(try_downcast) = CheatedWrapper::from_pyany(measurement.into()) { + if let Ok(try_downcast) = CheatedWrapper::from_pyany(measurement) { return Ok(Self { internal: QuantumProgram::Cheated { measurement: try_downcast, @@ -115,7 +112,7 @@ impl QuantumProgramWrapper { }, }); } - if let Ok(try_downcast) = ClassicalRegisterWrapper::from_pyany(measurement.into()) { + if let Ok(try_downcast) = ClassicalRegisterWrapper::from_pyany(measurement) { return Ok(Self { internal: QuantumProgram::ClassicalRegister { measurement: try_downcast, @@ -225,8 +222,8 @@ impl QuantumProgramWrapper { /// /// Args: /// backend (Backend): The backend the program is executed on. - /// parameters (Optional[List[float]): List of float parameters of the function call in order of `input_parameter_names` - pub fn run(&self, backend: Py, parameters: Option>) -> PyResult> { + /// parameters (Optional[List[float]]): List of float parameters of the function call in order of `input_parameter_names` + pub fn run(&self, backend: &Bound, parameters: Option>) -> PyResult> { let parameters = parameters.unwrap_or_default(); match &self.internal{ QuantumProgram::PauliZProduct{measurement, input_parameter_names } => { @@ -235,18 +232,15 @@ impl QuantumProgramWrapper { let substituted_measurement = measurement.substitute_parameters( substituted_parameters ).map_err(|err| PyRuntimeError::new_err(format!("Applying parameters failed {:?}", err)))?; - Python::with_gil(|py| -> PyResult> { - backend.call_method1(py, "run_measurement", (PauliZProductWrapper{internal: substituted_measurement}, )) - }) } + backend.call_method1("run_measurement", (PauliZProductWrapper{internal: substituted_measurement}, )).map(|bound| bound.as_gil_ref().into()) + } QuantumProgram::CheatedPauliZProduct{measurement, input_parameter_names } => { if parameters.len() != input_parameter_names.len() { return Err(PyValueError::new_err( format!("Wrong number of parameters {} parameters expected {} parameters given", input_parameter_names.len(), parameters.len())))}; let substituted_parameters: HashMap = input_parameter_names.iter().zip(parameters.iter()).map(|(key, value)| (key.clone(), *value)).collect(); let substituted_measurement = measurement.substitute_parameters( substituted_parameters ).map_err(|err| PyRuntimeError::new_err(format!("Applying parameters failed {:?}", err)))?; - Python::with_gil(|py| -> PyResult> { - backend.call_method1(py, "run_measurement", (CheatedPauliZProductWrapper{internal: substituted_measurement}, )) - }) + backend.call_method1("run_measurement", (CheatedPauliZProductWrapper{internal: substituted_measurement}, )).map(|bound| bound.as_gil_ref().into()) } QuantumProgram::Cheated{measurement, input_parameter_names } => { if parameters.len() != input_parameter_names.len() { return Err(PyValueError::new_err( format!("Wrong number of parameters {} parameters expected {} parameters given", input_parameter_names.len(), parameters.len())))}; @@ -254,9 +248,8 @@ impl QuantumProgramWrapper { let substituted_measurement = measurement.substitute_parameters( substituted_parameters ).map_err(|err| PyRuntimeError::new_err(format!("Applying parameters failed {:?}", err)))?; - Python::with_gil(|py| -> PyResult> { - backend.call_method1(py, "run_measurement", (CheatedWrapper{internal: substituted_measurement}, )) - }) } + backend.call_method1("run_measurement", (CheatedWrapper{internal: substituted_measurement}, )).map(|bound| bound.as_gil_ref().into()) + } _ => Err(PyTypeError::new_err("A quantum programm returning classical registeres cannot be executed by `run` use `run_registers` instead".to_string())) } } @@ -271,10 +264,10 @@ impl QuantumProgramWrapper { /// /// Args: /// backend (Backend): The backend the program is executed on. - /// parameters (Optional[List[float]): List of float parameters of the function call in order of `input_parameter_names` + /// parameters (Optional[List[float]]): List of float parameters of the function call in order of `input_parameter_names` pub fn run_registers( &self, - backend: Py, + backend: &Bound, parameters: Option>, ) -> PyResult> { let parameters = parameters.unwrap_or_default(); @@ -285,9 +278,8 @@ impl QuantumProgramWrapper { let substituted_measurement = measurement.substitute_parameters( substituted_parameters ).map_err(|err| PyRuntimeError::new_err(format!("Applying parameters failed {:?}", err)))?; - Python::with_gil(|py| -> PyResult> { - backend.call_method1(py, "run_measurement_registers", (ClassicalRegisterWrapper{internal: substituted_measurement}, )) - }) }, + backend.call_method1("run_measurement_registers", (ClassicalRegisterWrapper{internal: substituted_measurement}, )).map(|bound| bound.as_gil_ref().into()) + }, _ => Err(PyTypeError::new_err("A quantum programm returning expectation values cannot be executed by `run_registers` use `run` instead".to_string())) } } @@ -304,7 +296,7 @@ impl QuantumProgramWrapper { /// /// Returns: /// QuantumProgram: A deep copy of self. - pub fn __deepcopy__(&self, _memodict: Py) -> QuantumProgramWrapper { + pub fn __deepcopy__(&self, _memodict: &Bound) -> QuantumProgramWrapper { self.clone() } @@ -339,7 +331,7 @@ impl QuantumProgramWrapper { let serialized = serialize(&self.internal) .map_err(|_| PyValueError::new_err("Cannot serialize QuantumProgram to bytes"))?; let b: Py = Python::with_gil(|py| -> Py { - PyByteArray::new(py, &serialized[..]).into() + PyByteArray::new_bound(py, &serialized[..]).into() }); Ok(b) } @@ -356,8 +348,9 @@ impl QuantumProgramWrapper { /// TypeError: Input cannot be converted to byte array. /// ValueError: Input cannot be deserialized to QuantumProgram. #[staticmethod] - pub fn from_bincode(input: &PyAny) -> PyResult { + pub fn from_bincode(input: &Bound) -> PyResult { let bytes = input + .as_gil_ref() .extract::>() .map_err(|_| PyTypeError::new_err("Input cannot be converted to byte array"))?; @@ -443,11 +436,12 @@ impl QuantumProgramWrapper { /// /// Raises: /// NotImplementedError: Other comparison not implemented - fn __richcmp__(&self, other: Py, op: pyo3::class::basic::CompareOp) -> PyResult { - let other = Python::with_gil(|py| -> Result { - let other_ref = other.as_ref(py); - convert_into_quantum_program(other_ref) - }); + fn __richcmp__( + &self, + other: &Bound, + op: pyo3::class::basic::CompareOp, + ) -> PyResult { + let other = convert_into_quantum_program(other); match op { pyo3::class::basic::CompareOp::Eq => match other { Ok(qp) => Ok(self.internal == qp), @@ -467,8 +461,8 @@ impl QuantumProgramWrapper { /// Convert generic python object to [roqoqo::QuantumProgram]. /// /// Fallible conversion of generic python object to [roqoqo::QuantumProgram]. -pub fn convert_into_quantum_program(input: &PyAny) -> Result { - if let Ok(try_downcast) = input.extract::() { +pub fn convert_into_quantum_program(input: &Bound) -> Result { + if let Ok(try_downcast) = input.as_gil_ref().extract::() { return Ok(try_downcast.internal); } // Everything that follows tries to extract the quantum program when two separately diff --git a/qoqo/tests/integration/circuit.rs b/qoqo/tests/integration/circuit.rs index fb2736ad..802d73ab 100644 --- a/qoqo/tests/integration/circuit.rs +++ b/qoqo/tests/integration/circuit.rs @@ -27,29 +27,30 @@ use std::collections::{HashMap, HashSet}; use test_case::test_case; // helper functions -fn new_circuit(py: Python) -> &PyCell { - let circuit_type = py.get_type::(); +fn new_circuit(py: Python) -> Bound { + let circuit_type = py.get_type_bound::(); circuit_type .call0() .unwrap() - .downcast::>() + .downcast::() .unwrap() + .to_owned() } fn populate_circuit_rotatex( py: Python, - circuit: &PyCell, + circuit: &Bound, start: usize, stop: usize, ) { - let rotatex_type = py.get_type::(); + let rotatex_type = py.get_type_bound::(); for i in start..stop { let new_rotatex_0 = rotatex_type.call1((i, i)).unwrap(); circuit.call_method1("add", (new_rotatex_0,)).unwrap(); } } -fn add_circuit_measurement_operation(circuit: &PyCell) { +fn add_circuit_measurement_operation(circuit: &Bound) { let mut qubit_mapping: HashMap = HashMap::new(); qubit_mapping.insert(0, 1); let input_measurement: Operation = Operation::from(PragmaRepeatedMeasurement::new( @@ -96,8 +97,8 @@ fn test_substitute_parameters() { let circuit = new_circuit(py); circuit.call_method1("add", (operation,)).unwrap(); - let mut substitution_dict: HashMap<&str, f64> = HashMap::new(); - substitution_dict.insert("test", 1.0); + let mut substitution_dict: HashMap = HashMap::new(); + substitution_dict.insert("test".to_owned(), 1.0); let substitute_circ = circuit .call_method1("substitute_parameters", (substitution_dict,)) .unwrap(); @@ -107,7 +108,8 @@ fn test_substitute_parameters() { let comp_op = substitute_circ.call_method1("__getitem__", (0,)).unwrap(); let comparison = - bool::extract(comp_op.call_method1("__eq__", (subbed_operation,)).unwrap()).unwrap(); + bool::extract_bound(&comp_op.call_method1("__eq__", (subbed_operation,)).unwrap()) + .unwrap(); assert!(comparison); let mut substitution_dict_error = HashMap::new(); @@ -139,8 +141,8 @@ fn test_remap_qubits() { let remapped_operation = convert_operation_to_pyobject(to_remap).unwrap(); let comp_op = remap_circ.call_method1("__getitem__", (0,)).unwrap(); - let comparison = bool::extract( - comp_op + let comparison = bool::extract_bound( + &comp_op .call_method1("__eq__", (remapped_operation,)) .unwrap(), ) @@ -170,36 +172,36 @@ fn test_count_occurences() { circuit.call_method1("add", (operation2.clone(),)).unwrap(); circuit.call_method1("add", (operation3.clone(),)).unwrap(); - let comp_op = usize::extract( - circuit + let comp_op = usize::extract_bound( + &circuit .call_method1("count_occurences", (vec!["Definition"],)) .unwrap(), ) .unwrap(); assert_eq!(comp_op, 1_usize); - let comp_op = usize::extract( - circuit + let comp_op = usize::extract_bound( + &circuit .call_method1("count_occurences", (vec!["Operation"],)) .unwrap(), ) .unwrap(); assert_eq!(comp_op, 3_usize); - let comp_op = usize::extract( - circuit + let comp_op = usize::extract_bound( + &circuit .call_method1("count_occurences", (vec!["RotateX"],)) .unwrap(), ) .unwrap(); assert_eq!(comp_op, 1_usize); - let comp_op = usize::extract( - circuit + let comp_op = usize::extract_bound( + &circuit .call_method1("count_occurences", (vec!["SingleQubitGateOperation"],)) .unwrap(), ) .unwrap(); assert_eq!(comp_op, 2_usize); - let comp_op = usize::extract( - circuit + let comp_op = usize::extract_bound( + &circuit .call_method1("count_occurences", (vec!["MadeUp"],)) .unwrap(), ) @@ -224,13 +226,13 @@ fn test_get_operation_types() { circuit.call_method1("add", (operation2.clone(),)).unwrap(); circuit.call_method1("add", (operation3.clone(),)).unwrap(); - let mut op_types: HashSet<&str> = HashSet::new(); - op_types.insert("DefinitionBit"); - op_types.insert("RotateX"); - op_types.insert("PauliX"); + let mut op_types: HashSet = HashSet::new(); + op_types.insert("DefinitionBit".to_owned()); + op_types.insert("RotateX".to_owned()); + op_types.insert("PauliX".to_owned()); let comp_op = - HashSet::extract(circuit.call_method0("get_operation_types").unwrap()).unwrap(); + HashSet::extract_bound(&circuit.call_method0("get_operation_types").unwrap()).unwrap(); assert_eq!(comp_op, op_types); }) } @@ -241,22 +243,22 @@ fn test_copy_deepcopy() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let circuit = new_circuit(py); - populate_circuit_rotatex(py, circuit, 0, 3); + populate_circuit_rotatex(py, &circuit, 0, 3); let copy_circ = circuit.call_method0("__copy__").unwrap(); let deepcopy_circ = circuit.call_method1("__deepcopy__", ("",)).unwrap(); let copy_deepcopy_param = circuit; - let comparison_copy = bool::extract( - copy_circ - .call_method1("__eq__", (copy_deepcopy_param,)) + let comparison_copy = bool::extract_bound( + ©_circ + .call_method1("__eq__", (©_deepcopy_param,)) .unwrap(), ) .unwrap(); assert!(comparison_copy); - let comparison_deepcopy = bool::extract( - deepcopy_circ - .call_method1("__eq__", (copy_deepcopy_param,)) + let comparison_deepcopy = bool::extract_bound( + &deepcopy_circ + .call_method1("__eq__", (©_deepcopy_param,)) .unwrap(), ) .unwrap(); @@ -270,7 +272,7 @@ fn test_qoqo_versions() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let circuit = new_circuit(py); - populate_circuit_rotatex(py, circuit, 0, 3); + populate_circuit_rotatex(py, &circuit, 0, 3); let mut rsplit = ROQOQO_VERSION.split('.').take(2); let mut qsplit = QOQO_VERSION.split('.').take(2); let rver = format!( @@ -284,8 +286,8 @@ fn test_qoqo_versions() { qsplit.next().expect("QOQO_VERSION badly formatted") ); - let comparison_copy: Vec<&str> = - Vec::extract(circuit.call_method0("_qoqo_versions").unwrap()).unwrap(); + let comparison_copy: Vec = + Vec::extract_bound(&circuit.call_method0("_qoqo_versions").unwrap()).unwrap(); assert_eq!(comparison_copy, vec![rver.as_str(), qver.as_str()]); }) } @@ -296,14 +298,15 @@ fn test_to_from_bincode() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let circuit = new_circuit(py); - populate_circuit_rotatex(py, circuit, 0, 3); + populate_circuit_rotatex(py, &circuit, 0, 3); // testing 'to_bincode' and 'from_bincode' functions let serialised = circuit.call_method0("to_bincode").unwrap(); let new = new_circuit(py); - let deserialised = new.call_method1("from_bincode", (serialised,)).unwrap(); + let deserialised = new.call_method1("from_bincode", (&serialised,)).unwrap(); let comparison = - bool::extract(deserialised.call_method1("__eq__", (circuit,)).unwrap()).unwrap(); + bool::extract_bound(&deserialised.call_method1("__eq__", (&circuit,)).unwrap()) + .unwrap(); assert!(comparison); let deserialised_error = @@ -321,13 +324,14 @@ fn test_to_from_bincode() { assert!(serialised_error.is_err()); // testing that 'from_bincode' can be called directly on a circuit (python staticmethod) - let circuit_type = py.get_type::(); + let circuit_type = py.get_type_bound::(); let deserialised_py = circuit_type - .call_method1("from_bincode", (serialised,)) + .call_method1("from_bincode", (&serialised,)) .unwrap(); let comparison = - bool::extract(deserialised_py.call_method1("__eq__", (circuit,)).unwrap()).unwrap(); + bool::extract_bound(&deserialised_py.call_method1("__eq__", (&circuit,)).unwrap()) + .unwrap(); assert!(comparison); }) } @@ -336,12 +340,9 @@ fn test_to_from_bincode() { fn test_value_error_bincode() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let input_type = py.get_type::(); - let input = input_type - .call1((3, false)) - .unwrap() - .downcast::>() - .unwrap(); + let input_type = py.get_type_bound::(); + let binding = input_type.call1((3, false)).unwrap(); + let input = binding.downcast::().unwrap(); let tmp_vec: Vec = Vec::new(); let _ = input .call_method1("add_pauliz_product", ("ro", tmp_vec)) @@ -349,20 +350,16 @@ fn test_value_error_bincode() { let circs: Vec = vec![CircuitWrapper::new()]; - let br_type = py.get_type::(); - let br = br_type + let br_type = py.get_type_bound::(); + let binding = br_type .call1((Some(CircuitWrapper::new()), circs, input)) - .unwrap() - .downcast::>() .unwrap(); + let br = binding.downcast::().unwrap(); let new_br = br; let serialised = br.call_method0("to_json").unwrap(); - let deserialised = new_br - .call_method1("from_json", (serialised,)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = &new_br.call_method1("from_json", (&serialised,)).unwrap(); + let deserialised = binding.downcast::().unwrap(); let new = new_circuit(py); let deserialised_error = new.call_method1("from_bincode", (deserialised,)); @@ -376,16 +373,17 @@ fn test_to_from_json() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let circuit = new_circuit(py); - populate_circuit_rotatex(py, circuit, 0, 3); - add_circuit_measurement_operation(circuit); + populate_circuit_rotatex(py, &circuit, 0, 3); + add_circuit_measurement_operation(&circuit); // testing 'from_json' and 'to_json' functions - let serialised = circuit.call_method0("to_json").unwrap(); + let serialised = &circuit.call_method0("to_json").unwrap(); let new = new_circuit(py); let deserialised = new.call_method1("from_json", (serialised,)).unwrap(); let comparison = - bool::extract(deserialised.call_method1("__eq__", (circuit,)).unwrap()).unwrap(); + bool::extract_bound(&deserialised.call_method1("__eq__", (&circuit,)).unwrap()) + .unwrap(); assert!(comparison); let deserialised_error = @@ -403,13 +401,14 @@ fn test_to_from_json() { assert!(deserialised_error.is_err()); // testing that 'from_json' can be called directly on a circuit (python staticmethod) - let circuit_type = py.get_type::(); + let circuit_type = py.get_type_bound::(); let deserialised_py = circuit_type .call_method1("from_json", (serialised,)) .unwrap(); let comparison = - bool::extract(deserialised_py.call_method1("__eq__", (circuit,)).unwrap()).unwrap(); + bool::extract_bound(&deserialised_py.call_method1("__eq__", (circuit,)).unwrap()) + .unwrap(); assert!(comparison); }) } @@ -421,16 +420,17 @@ fn test_json_schema() { pyo3::prepare_freethreaded_python(); pyo3::Python::with_gil(|py| { let circuit = new_circuit(py); - populate_circuit_rotatex(py, circuit, 0, 4); + populate_circuit_rotatex(py, &circuit, 0, 4); - let schema: String = String::extract(circuit.call_method0("json_schema").unwrap()).unwrap(); + let schema: String = + String::extract_bound(&circuit.call_method0("json_schema").unwrap()).unwrap(); let rust_schema = serde_json::to_string_pretty(&schemars::schema_for!(Circuit)).unwrap(); assert_eq!(schema, rust_schema); let current_version_string = - String::extract(circuit.call_method0("current_version").unwrap()).unwrap(); + String::extract_bound(&circuit.call_method0("current_version").unwrap()).unwrap(); let minimum_supported_version_string = - String::extract(circuit.call_method0("min_supported_version").unwrap()).unwrap(); + String::extract_bound(&circuit.call_method0("min_supported_version").unwrap()).unwrap(); assert_eq!(current_version_string, ROQOQO_VERSION); assert_eq!(minimum_supported_version_string, "1.0.0"); @@ -443,7 +443,7 @@ fn test_single_index_access_get() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let circuit = new_circuit(py); - populate_circuit_rotatex(py, circuit, 0, 3); + populate_circuit_rotatex(py, &circuit, 0, 3); // test access at index 1 let comp_op = circuit.call_method1("get", (1,)).unwrap(); @@ -453,7 +453,7 @@ fn test_single_index_access_get() { ))) .unwrap(); let comparison = - bool::extract(comp_op.call_method1("__eq__", (operation,)).unwrap()).unwrap(); + bool::extract_bound(&comp_op.call_method1("__eq__", (operation,)).unwrap()).unwrap(); assert!(comparison); // test setting new operation at index 1 @@ -469,7 +469,7 @@ fn test_single_index_access_get() { let comp_op = circuit.call_method1("get", (1,)).unwrap(); let comparison = - bool::extract(comp_op.call_method1("__eq__", (operation2,)).unwrap()).unwrap(); + bool::extract_bound(&comp_op.call_method1("__eq__", (operation2,)).unwrap()).unwrap(); assert!(comparison); let comparison = circuit.call_method1("get", (20,)); @@ -483,20 +483,20 @@ fn test_get_slice() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let circuit = new_circuit(py); - populate_circuit_rotatex(py, circuit, 0, 4); + populate_circuit_rotatex(py, &circuit, 0, 4); let circuit2 = new_circuit(py); - populate_circuit_rotatex(py, circuit2, 1, 3); + populate_circuit_rotatex(py, &circuit2, 1, 3); let circuit3 = new_circuit(py); - populate_circuit_rotatex(py, circuit3, 0, 3); + populate_circuit_rotatex(py, &circuit3, 0, 3); let circuit4 = new_circuit(py); - populate_circuit_rotatex(py, circuit4, 2, 4); + populate_circuit_rotatex(py, &circuit4, 2, 4); let new_circuit_slice = circuit.call_method1("get_slice", (1, 2)).unwrap(); - let comparison = bool::extract( - new_circuit_slice + let comparison = bool::extract_bound( + &new_circuit_slice .call_method1("__eq__", (circuit2,)) .unwrap(), ) @@ -506,8 +506,8 @@ fn test_get_slice() { let new_circuit_slice = circuit .call_method1("get_slice", (Option::::None, 2)) .unwrap(); - let comparison = bool::extract( - new_circuit_slice + let comparison = bool::extract_bound( + &new_circuit_slice .call_method1("__eq__", (circuit3,)) .unwrap(), ) @@ -517,8 +517,8 @@ fn test_get_slice() { let new_circuit_slice = circuit .call_method1("get_slice", (2, Option::::None)) .unwrap(); - let comparison = bool::extract( - new_circuit_slice + let comparison = bool::extract_bound( + &new_circuit_slice .call_method1("__eq__", (circuit4,)) .unwrap(), ) @@ -556,8 +556,8 @@ fn test_definitions() { circuit.call_method1("add", (operation2.clone(),)).unwrap(); let comp_op = circuit.call_method0("definitions").unwrap(); - let comparison = bool::extract( - comp_op + let comparison = bool::extract_bound( + &comp_op .call_method1("__eq__", (vec![operation1, operation2],)) .unwrap(), ) @@ -580,8 +580,8 @@ fn test_operations() { circuit.call_method1("add", (operation2.clone(),)).unwrap(); let comp_op = circuit.call_method0("operations").unwrap(); - let comparison = bool::extract( - comp_op + let comparison = bool::extract_bound( + &comp_op .call_method1("__eq__", (vec![operation1, operation2],)) .unwrap(), ) @@ -602,34 +602,28 @@ fn test_filter_by_tag() { let circuit = new_circuit(py); circuit.call_method1("add", (operation1.clone(),)).unwrap(); circuit.call_method1("add", (operation2.clone(),)).unwrap(); - populate_circuit_rotatex(py, circuit, 0, 2); + populate_circuit_rotatex(py, &circuit, 0, 2); let comp_op = circuit .call_method1("filter_by_tag", ("Definition",)) .unwrap(); - let comparison = bool::extract( - comp_op + let comparison = bool::extract_bound( + &comp_op .call_method1("__eq__", (vec![operation1, operation2],)) .unwrap(), ) .unwrap(); assert!(comparison); - let rotatex_type = py.get_type::(); - let rotatex_0 = rotatex_type - .call1((0, 0)) - .unwrap() - .downcast::>() - .unwrap(); - let rotatex_1 = rotatex_type - .call1((1, 1)) - .unwrap() - .downcast::>() - .unwrap(); + let rotatex_type = py.get_type_bound::(); + let binding = rotatex_type.call1((0, 0)).unwrap(); + let rotatex_0 = binding.downcast::().unwrap(); + let binding = rotatex_type.call1((1, 1)).unwrap(); + let rotatex_1 = binding.downcast::().unwrap(); let comp_op = circuit.call_method1("filter_by_tag", ("RotateX",)).unwrap(); - let comparison = bool::extract( - comp_op + let comparison = bool::extract_bound( + &comp_op .call_method1("__eq__", (vec![rotatex_0, rotatex_1],)) .unwrap(), ) @@ -651,7 +645,7 @@ fn test_circuit_add_function(added_operation: Operation) { let comp_op = circuit.call_method1("__getitem__", (0,)).unwrap(); let comparison = - bool::extract(comp_op.call_method1("__eq__", (operation,)).unwrap()).unwrap(); + bool::extract_bound(&comp_op.call_method1("__eq__", (operation,)).unwrap()).unwrap(); assert!(comparison); let comparison = circuit.call_method1("add", (vec!["fails"],)); @@ -664,14 +658,14 @@ fn test_circuit_add_function(added_operation: Operation) { fn test_format_repr() { Python::with_gil(|py| { let circuit = new_circuit(py); - populate_circuit_rotatex(py, circuit, 0, 2); + populate_circuit_rotatex(py, &circuit, 0, 2); let format_repr = "RotateX(RotateX { qubit: 0, theta: Float(0.0) })\nRotateX(RotateX { qubit: 1, theta: Float(1.0) })\n"; let to_format = circuit.call_method1("__format__", ("",)).unwrap(); - let format_op: &str = <&str>::extract(to_format).unwrap(); + let format_op: String = String::extract_bound(&to_format).unwrap(); let to_repr = circuit.call_method0("__repr__").unwrap(); - let repr_op: &str = <&str>::extract(to_repr).unwrap(); + let repr_op: String = String::extract_bound(&to_repr).unwrap(); assert_eq!(format_op, format_repr); assert_eq!(repr_op, format_repr); @@ -684,16 +678,13 @@ fn test_fmt_circuititerator() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let new_circuit = new_circuit(py); - populate_circuit_rotatex(py, new_circuit, 0, 2); - let circuit_iter = new_circuit - .call_method0("__iter__") - .unwrap() - .downcast::>() - .unwrap(); + populate_circuit_rotatex(py, &new_circuit, 0, 2); + let binding = &new_circuit.call_method0("__iter__").unwrap(); + let circuit_iter = binding.downcast::().unwrap(); let fmt = "RefCell { value: OperationIteratorWrapper { internal: OperationIterator { definition_iter: IntoIter([]), operation_iter: IntoIter([RotateX(RotateX { qubit: 0, theta: Float(0.0) }), RotateX(RotateX { qubit: 1, theta: Float(1.0) })]) } } }"; - assert_eq!(format!("{:?}", circuit_iter), fmt); + assert_eq!(format!("{:?}", circuit_iter.as_gil_ref()), fmt); }) } @@ -703,16 +694,17 @@ fn test_richcmp() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let circuit_one = new_circuit(py); - populate_circuit_rotatex(py, circuit_one, 0, 2); + populate_circuit_rotatex(py, &circuit_one, 0, 2); let circuit_two = new_circuit(py); - populate_circuit_rotatex(py, circuit_two, 0, 3); + populate_circuit_rotatex(py, &circuit_two, 0, 3); let operation1 = convert_operation_to_pyobject(Operation::from(PauliX::new(0))).unwrap(); let comparison = - bool::extract(circuit_one.call_method1("__eq__", (circuit_two,)).unwrap()).unwrap(); + bool::extract_bound(&circuit_one.call_method1("__eq__", (&circuit_two,)).unwrap()) + .unwrap(); assert!(!comparison); - let comparison = bool::extract( - circuit_one + let comparison = bool::extract_bound( + &circuit_one .call_method1("__eq__", (operation1.clone(),)) .unwrap(), ) @@ -720,10 +712,11 @@ fn test_richcmp() { assert!(!comparison); let comparison = - bool::extract(circuit_one.call_method1("__ne__", (circuit_two,)).unwrap()).unwrap(); + bool::extract_bound(&circuit_one.call_method1("__ne__", (&circuit_two,)).unwrap()) + .unwrap(); assert!(comparison); - let comparison = bool::extract( - circuit_one + let comparison = bool::extract_bound( + &circuit_one .call_method1("__ne__", (operation1.clone(),)) .unwrap(), ) @@ -759,17 +752,17 @@ fn test_circuit_iadd_magic_method() { let comp_op = circuit.call_method1("__getitem__", (0,)).unwrap(); let comparison = - bool::extract(comp_op.call_method1("__eq__", (operation1,)).unwrap()).unwrap(); + bool::extract_bound(&comp_op.call_method1("__eq__", (operation1,)).unwrap()).unwrap(); assert!(comparison); let comp_op = circuit.call_method1("__getitem__", (1,)).unwrap(); let comparison = - bool::extract(comp_op.call_method1("__eq__", (operation2,)).unwrap()).unwrap(); + bool::extract_bound(&comp_op.call_method1("__eq__", (operation2,)).unwrap()).unwrap(); assert!(comparison); let comp_op = circuit.call_method1("__getitem__", (2,)).unwrap(); let comparison = - bool::extract(comp_op.call_method1("__eq__", (operation3,)).unwrap()).unwrap(); + bool::extract_bound(&comp_op.call_method1("__eq__", (operation3,)).unwrap()).unwrap(); assert!(comparison); let comparison = circuit.call_method1("__iadd__", (vec!["fails"],)); @@ -779,13 +772,13 @@ fn test_circuit_iadd_magic_method() { #[test] fn test_circuit_add_magic_method() { + pyo3::prepare_freethreaded_python(); let added_op1 = Operation::from(DefinitionBit::new("ro".to_string(), 1, false)); let added_op2 = Operation::from(RotateX::new(0, CalculatorFloat::from(1.0))); let added_op3 = Operation::from(PauliX::new(0)); let operation1 = convert_operation_to_pyobject(added_op1).unwrap(); let operation2 = convert_operation_to_pyobject(added_op2).unwrap(); let operation3 = convert_operation_to_pyobject(added_op3).unwrap(); - pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let added_circuit = new_circuit(py); added_circuit @@ -801,17 +794,17 @@ fn test_circuit_add_magic_method() { let comp_op = circuit2.call_method1("__getitem__", (0,)).unwrap(); let comparison = - bool::extract(comp_op.call_method1("__eq__", (operation1,)).unwrap()).unwrap(); + bool::extract_bound(&comp_op.call_method1("__eq__", (operation1,)).unwrap()).unwrap(); assert!(comparison); let comp_op = circuit2.call_method1("__getitem__", (1,)).unwrap(); let comparison = - bool::extract(comp_op.call_method1("__eq__", (operation2,)).unwrap()).unwrap(); + bool::extract_bound(&comp_op.call_method1("__eq__", (operation2,)).unwrap()).unwrap(); assert!(comparison); let comp_op = circuit2.call_method1("__getitem__", (2,)).unwrap(); let comparison = - bool::extract(comp_op.call_method1("__eq__", (operation3,)).unwrap()).unwrap(); + bool::extract_bound(&comp_op.call_method1("__eq__", (operation3,)).unwrap()).unwrap(); assert!(comparison); let comparison = circuit.call_method1("__add__", (vec!["fails"],)); @@ -825,37 +818,25 @@ fn test_iter() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let new_circuit = new_circuit(py); - populate_circuit_rotatex(py, new_circuit, 0, 3); - - let rotatex_type = py.get_type::(); - let new_rotatex_0 = rotatex_type - .call1((0, 0)) - .unwrap() - .downcast::>() - .unwrap(); - let new_rotatex_1 = rotatex_type - .call1((1, 1)) - .unwrap() - .downcast::>() - .unwrap(); - let new_rotatex_2 = rotatex_type - .call1((2, 2)) - .unwrap() - .downcast::>() - .unwrap(); + populate_circuit_rotatex(py, &new_circuit, 0, 3); + + let rotatex_type = py.get_type_bound::(); + let binding = rotatex_type.call1((0, 0)).unwrap(); + let new_rotatex_0 = binding.downcast::().unwrap(); + let binding = rotatex_type.call1((1, 1)).unwrap(); + let new_rotatex_1 = binding.downcast::().unwrap(); + let binding = rotatex_type.call1((2, 2)).unwrap(); + let new_rotatex_2 = binding.downcast::().unwrap(); let comparison_vec = [new_rotatex_0, new_rotatex_1, new_rotatex_2]; - let t = new_circuit - .call_method0("__iter__") - .unwrap() - .downcast::>() - .unwrap(); + let binding = &new_circuit.call_method0("__iter__").unwrap(); + let t = binding.downcast::().unwrap(); let range = 0_usize..3_usize; for i in range { let comp_op = t.call_method0("__next__").unwrap(); - let comparison = bool::extract( - comp_op + let comparison = bool::extract_bound( + &comp_op .call_method1("__eq__", (comparison_vec[i],)) .unwrap(), ) @@ -864,7 +845,8 @@ fn test_iter() { } let iter_op = t.call_method0("__iter__").unwrap(); - let comparison = bool::extract(iter_op.call_method1("__eq__", (t,)).unwrap()).unwrap(); + let comparison = + bool::extract_bound(&iter_op.call_method1("__eq__", (t,)).unwrap()).unwrap(); assert!(comparison); }) } @@ -875,9 +857,10 @@ fn test_len() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let circuit = new_circuit(py); - populate_circuit_rotatex(py, circuit, 0, 5); + populate_circuit_rotatex(py, &circuit, 0, 5); - let len_op: usize = usize::extract(circuit.call_method0("__len__").unwrap()).unwrap(); + let len_op: usize = + usize::extract_bound(&circuit.call_method0("__len__").unwrap()).unwrap(); assert_eq!(len_op, 5_usize); }) } @@ -888,7 +871,7 @@ fn test_single_index_access_getitem() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let circuit = new_circuit(py); - populate_circuit_rotatex(py, circuit, 0, 3); + populate_circuit_rotatex(py, &circuit, 0, 3); // test access at index 1 let comp_op = circuit.call_method1("__getitem__", (1,)).unwrap(); @@ -898,7 +881,7 @@ fn test_single_index_access_getitem() { ))) .unwrap(); let comparison = - bool::extract(comp_op.call_method1("__eq__", (operation,)).unwrap()).unwrap(); + bool::extract_bound(&comp_op.call_method1("__eq__", (operation,)).unwrap()).unwrap(); assert!(comparison); // test setting new operation at index 1 @@ -913,8 +896,8 @@ fn test_single_index_access_getitem() { .unwrap(); let comp_op = circuit.call_method1("__getitem__", (1,)).unwrap(); - let comparison = bool::extract( - comp_op + let comparison = bool::extract_bound( + &comp_op .call_method1("__eq__", (operation2.clone(),)) .unwrap(), ) @@ -953,38 +936,35 @@ fn test_circuit_overrotate() { Python::with_gil(|py| { let circuit = new_circuit(py); - let overrotation_type = py.get_type::(); + let overrotation_type = py.get_type_bound::(); let _new_overrotation_1 = overrotation_type .call1(("RotateY".to_string(), vec![1], 20.0, 30.0)) .unwrap(); circuit.call_method1("add", (_new_overrotation_1,)).unwrap(); - let rotatex_type = py.get_type::(); + let rotatex_type = py.get_type_bound::(); let new_rotatex_0 = rotatex_type.call1((0, 0.0)).unwrap(); circuit.call_method1("add", (new_rotatex_0,)).unwrap(); - let rotatey_type = py.get_type::(); + let rotatey_type = py.get_type_bound::(); let new_rotatey_0 = rotatey_type.call1((0, 1.0)).unwrap(); circuit.call_method1("add", (new_rotatey_0,)).unwrap(); let new_rotatey_1 = rotatey_type.call1((1, 2.0)).unwrap(); circuit.call_method1("add", (new_rotatey_1,)).unwrap(); - let new_rotatey_1 = rotatey_type.call1((1, 3.0)).unwrap(); - circuit.call_method1("add", (new_rotatey_1,)).unwrap(); + let new_rotatey_2 = rotatey_type.call1((1, 3.0)).unwrap(); + circuit.call_method1("add", (new_rotatey_2,)).unwrap(); - let circuit_overrotated = circuit - .call_method0("overrotate") - .unwrap() - .downcast::>() - .unwrap(); + let binding = &circuit.call_method0("overrotate").unwrap(); + let circuit_overrotated = binding.downcast::().unwrap(); assert_ne!( format!("{:?}", circuit), format!("{:?}", circuit_overrotated) ); - let comparison = bool::extract( - circuit + let comparison = bool::extract_bound( + &circuit .as_ref() .call_method1("__ne__", (circuit_overrotated,)) .unwrap(), diff --git a/qoqo/tests/integration/circuitdag.rs b/qoqo/tests/integration/circuitdag.rs index ba2346b7..149147e3 100644 --- a/qoqo/tests/integration/circuitdag.rs +++ b/qoqo/tests/integration/circuitdag.rs @@ -19,22 +19,24 @@ use roqoqo::operations::*; use roqoqo::ROQOQO_VERSION; // Helper functions -fn new_circuitdag(py: Python) -> &PyCell { - let circuitdag_type = py.get_type::(); +fn new_circuitdag(py: Python) -> Bound { + let circuitdag_type = py.get_type_bound::(); circuitdag_type .call0() .unwrap() - .downcast::>() + .downcast::() .unwrap() + .to_owned() } -fn new_circuit(py: Python) -> &PyCell { - let circuit_type = py.get_type::(); +fn new_circuit(py: Python) -> Bound { + let circuit_type = py.get_type_bound::(); circuit_type .call0() .unwrap() - .downcast::>() + .downcast::() .unwrap() + .to_owned() } /// Test default @@ -87,13 +89,15 @@ fn test_get() { let comp_op = dag.call_method1("get", (0,)).unwrap(); let operation = convert_operation_to_pyobject(Operation::from(PauliX::new(0))).unwrap(); - let helper1 = bool::extract(comp_op.call_method1("__eq__", (operation,)).unwrap()).unwrap(); + let helper1 = + bool::extract_bound(&comp_op.call_method1("__eq__", (operation,)).unwrap()).unwrap(); assert!(helper1); let comp_op = dag.call_method1("get", (1,)).unwrap(); let operation = convert_operation_to_pyobject(Operation::from(PauliY::new(0))).unwrap(); - let helper2 = bool::extract(comp_op.call_method1("__eq__", (operation,)).unwrap()).unwrap(); + let helper2 = + bool::extract_bound(&comp_op.call_method1("__eq__", (operation,)).unwrap()).unwrap(); assert!(helper2); }) } @@ -116,11 +120,12 @@ fn test_copy() { let empty_dag_copy = empty_dag.call_method0("__copy__").unwrap(); let full_dag_comparison = - bool::extract(dag_copy.call_method1("__eq__", (dag,)).unwrap()).unwrap(); + bool::extract_bound(&dag_copy.call_method1("__eq__", (dag,)).unwrap()).unwrap(); assert!(full_dag_comparison); let empty_dag_comparison = - bool::extract(empty_dag_copy.call_method1("__eq__", (empty_dag,)).unwrap()).unwrap(); + bool::extract_bound(&empty_dag_copy.call_method1("__eq__", (empty_dag,)).unwrap()) + .unwrap(); assert!(empty_dag_comparison); }) } @@ -146,9 +151,11 @@ fn test_richcmp() { dag2.call_method1("add_to_back", (pauliy_0.clone(),)) .unwrap(); - let comparison = bool::extract(dag1.call_method1("__eq__", (dag2,)).unwrap()).unwrap(); + let comparison = + bool::extract_bound(&dag1.call_method1("__eq__", (&dag2,)).unwrap()).unwrap(); assert!(!comparison); - let comparison = bool::extract(dag1.call_method1("__ne__", (dag2,)).unwrap()).unwrap(); + let comparison = + bool::extract_bound(&dag1.call_method1("__ne__", (&dag2,)).unwrap()).unwrap(); assert!(comparison); let comparison = dag1.call_method1("__ge__", (dag2,)); assert!(comparison.is_err()); @@ -177,8 +184,8 @@ fn test_qoqo_versions() { qsplit.next().expect("QOQO_VERSION badly formatted") ); - let comparison_copy: Vec<&str> = - Vec::extract(dag.call_method0("_qoqo_versions").unwrap()).unwrap(); + let comparison_copy: Vec = + Vec::extract_bound(&dag.call_method0("_qoqo_versions").unwrap()).unwrap(); assert_eq!(comparison_copy, vec![rver.as_str(), qver.as_str()]); }) } @@ -196,9 +203,9 @@ fn test_to_from_bincode() { // testing 'to_bincode' and 'from_bincode' functions let serialised = dag.call_method0("to_bincode").unwrap(); let new = new_circuitdag(py); - let deserialised = new.call_method1("from_bincode", (serialised,)).unwrap(); + let deserialised = new.call_method1("from_bincode", (&serialised,)).unwrap(); let comparison = - bool::extract(deserialised.call_method1("__eq__", (dag,)).unwrap()).unwrap(); + bool::extract_bound(&deserialised.call_method1("__eq__", (&dag,)).unwrap()).unwrap(); assert!(comparison); let deserialised_error = @@ -216,13 +223,13 @@ fn test_to_from_bincode() { assert!(serialised_error.is_err()); // testing that 'from_bincode' can be called directly on a circuitdag (python staticmethod) - let circuitdag_type = py.get_type::(); + let circuitdag_type = py.get_type_bound::(); let deserialised_py = circuitdag_type - .call_method1("from_bincode", (serialised,)) + .call_method1("from_bincode", (&serialised,)) .unwrap(); let comparison = - bool::extract(deserialised_py.call_method1("__eq__", (dag,)).unwrap()).unwrap(); + bool::extract_bound(&deserialised_py.call_method1("__eq__", (dag,)).unwrap()).unwrap(); assert!(comparison); }) } @@ -241,22 +248,22 @@ fn test_from_circuit() { circuit.call_method1("add", (cnot_01.clone(),)).unwrap(); let dag = new_circuitdag(py); - let dag = dag - .call_method1("from_circuit", (circuit,)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = dag.call_method1("from_circuit", (circuit,)).unwrap(); + let dag = binding.downcast::().unwrap(); let comp_op = dag.call_method1("get", (0,)).unwrap(); - let helper1 = bool::extract(comp_op.call_method1("__eq__", (paulix_0,)).unwrap()).unwrap(); + let helper1 = + bool::extract_bound(&comp_op.call_method1("__eq__", (paulix_0,)).unwrap()).unwrap(); assert!(helper1); let comp_op = dag.call_method1("get", (1,)).unwrap(); - let helper2 = bool::extract(comp_op.call_method1("__eq__", (pauliy_0,)).unwrap()).unwrap(); + let helper2 = + bool::extract_bound(&comp_op.call_method1("__eq__", (pauliy_0,)).unwrap()).unwrap(); assert!(helper2); let comp_op = dag.call_method1("get", (2,)).unwrap(); - let helper3 = bool::extract(comp_op.call_method1("__eq__", (cnot_01,)).unwrap()).unwrap(); + let helper3 = + bool::extract_bound(&comp_op.call_method1("__eq__", (cnot_01,)).unwrap()).unwrap(); assert!(helper3); }) } @@ -283,15 +290,18 @@ fn test_to_circuit() { let new_circuit = dag.call_method0("to_circuit").unwrap(); let comp_op = new_circuit.call_method1("get", (0,)).unwrap(); - let helper1 = bool::extract(comp_op.call_method1("__eq__", (paulix_0,)).unwrap()).unwrap(); + let helper1 = + bool::extract_bound(&comp_op.call_method1("__eq__", (paulix_0,)).unwrap()).unwrap(); assert!(helper1); let comp_op = new_circuit.call_method1("get", (1,)).unwrap(); - let helper2 = bool::extract(comp_op.call_method1("__eq__", (pauliy_0,)).unwrap()).unwrap(); + let helper2 = + bool::extract_bound(&comp_op.call_method1("__eq__", (pauliy_0,)).unwrap()).unwrap(); assert!(helper2); let comp_op = new_circuit.call_method1("get", (2,)).unwrap(); - let helper3 = bool::extract(comp_op.call_method1("__eq__", (cnot_01,)).unwrap()).unwrap(); + let helper3 = + bool::extract_bound(&comp_op.call_method1("__eq__", (cnot_01,)).unwrap()).unwrap(); assert!(helper3); }) } @@ -308,17 +318,17 @@ fn test_execution_blocked() { Python::with_gil(|py| { let dag = new_circuitdag(py); - let a = dag + let a = &dag .call_method1("add_to_back", (paulix_0.clone(),)) .unwrap(); - let b = dag + let b = &dag .call_method1("add_to_back", (pauliz_0.clone(),)) .unwrap(); - let c = dag + let c = &dag .call_method1("add_to_back", (pauliy_1.clone(),)) .unwrap(); - let d = dag.call_method1("add_to_back", (cnot_01.clone(),)).unwrap(); - let e = dag + let d = &dag.call_method1("add_to_back", (cnot_01.clone(),)).unwrap(); + let e = &dag .call_method1("add_to_back", (cpauliz_12.clone(),)) .unwrap(); @@ -330,7 +340,8 @@ fn test_execution_blocked() { let comp = dag .call_method1("execution_blocked", (vec![a, b, c], e)) .unwrap(); - let helper = bool::extract(comp.call_method1("__eq__", (vec![d],)).unwrap()).unwrap(); + let helper = + bool::extract_bound(&comp.call_method1("__eq__", (vec![d],)).unwrap()).unwrap(); assert!(helper); let comp = dag @@ -346,14 +357,16 @@ fn test_execution_blocked() { let comp = dag .call_method1("execution_blocked", (vec![d, e], b)) .unwrap(); - let helper = bool::extract(comp.call_method1("__eq__", (vec![a],)).unwrap()).unwrap(); + let helper = + bool::extract_bound(&comp.call_method1("__eq__", (vec![a],)).unwrap()).unwrap(); assert!(helper); let comp = dag .call_method1("execution_blocked", (Vec::::new(), e)) .unwrap(); let helper = - bool::extract(comp.call_method1("__eq__", (vec![a, b, c, d],)).unwrap()).unwrap(); + bool::extract_bound(&comp.call_method1("__eq__", (vec![a, b, c, d],)).unwrap()) + .unwrap(); assert!(helper); }) } @@ -368,16 +381,16 @@ fn test_blocking_predecessors() { Python::with_gil(|py| { let dag = new_circuitdag(py); - let a = dag + let a = &dag .call_method1("add_to_back", (paulix_0.clone(),)) .unwrap(); - let b = dag + let b = &dag .call_method1("add_to_back", (pauliz_0.clone(),)) .unwrap(); - let c = dag + let c = &dag .call_method1("add_to_back", (pauliy_1.clone(),)) .unwrap(); - let d = dag.call_method1("add_to_back", (cnot_01.clone(),)).unwrap(); + let d = &dag.call_method1("add_to_back", (cnot_01.clone(),)).unwrap(); let comp = dag .call_method1("blocking_predecessors", (vec![a, b, c], d)) @@ -397,7 +410,8 @@ fn test_blocking_predecessors() { let comp = dag .call_method1("blocking_predecessors", (vec![a, b], d)) .unwrap(); - let helper = bool::extract(comp.call_method1("__eq__", (vec![c],)).unwrap()).unwrap(); + let helper = + bool::extract_bound(&comp.call_method1("__eq__", (vec![c],)).unwrap()).unwrap(); assert!(helper); }) } @@ -414,17 +428,17 @@ fn test_new_front_layer() { Python::with_gil(|py| { let dag = new_circuitdag(py); - let a = dag + let a = &dag .call_method1("add_to_back", (paulix_0.clone(),)) .unwrap(); - let b = dag + let b = &dag .call_method1("add_to_back", (pauliz_0.clone(),)) .unwrap(); - let c = dag + let c = &dag .call_method1("add_to_back", (pauliy_1.clone(),)) .unwrap(); - let d = dag.call_method1("add_to_back", (cnot_01.clone(),)).unwrap(); - let e = dag + let d = &dag.call_method1("add_to_back", (cnot_01.clone(),)).unwrap(); + let e = &dag .call_method1("add_to_back", (cpauliz_12.clone(),)) .unwrap(); @@ -433,28 +447,32 @@ fn test_new_front_layer() { .is_err()); let comp = dag - .call_method1("new_front_layer", (vec![a, c], vec![b], b)) + .call_method1("new_front_layer", (vec![a, c], vec![b.clone()], b)) .unwrap(); - let helper = bool::extract(comp.call_method1("__eq__", (vec![d],)).unwrap()).unwrap(); + let helper = + bool::extract_bound(&comp.call_method1("__eq__", (vec![d],)).unwrap()).unwrap(); assert!(helper); let comp = dag - .call_method1("new_front_layer", (vec![a], vec![b], b)) + .call_method1("new_front_layer", (vec![a], vec![b.clone()], b)) .unwrap(); - let helper = bool::extract(comp.call_method1("__eq__", (vec![b],)).unwrap()).unwrap(); + let helper = + bool::extract_bound(&comp.call_method1("__eq__", (vec![b],)).unwrap()).unwrap(); assert!(helper); let comp = dag - .call_method1("new_front_layer", (vec![a, b, c], vec![d], d)) + .call_method1("new_front_layer", (vec![a, b, c], vec![d.clone()], d)) .unwrap(); - let helper = bool::extract(comp.call_method1("__eq__", (vec![e],)).unwrap()).unwrap(); + let helper = + bool::extract_bound(&comp.call_method1("__eq__", (vec![e],)).unwrap()).unwrap(); assert!(helper); let comp = dag - .call_method1("new_front_layer", (vec![a, b, c, d], vec![e], e)) + .call_method1("new_front_layer", (vec![a, b, c, d], vec![e.clone()], e)) .unwrap(); let helper = - bool::extract(comp.call_method1("__eq__", (Vec::::new(),)).unwrap()).unwrap(); + bool::extract_bound(&comp.call_method1("__eq__", (Vec::::new(),)).unwrap()) + .unwrap(); assert!(helper); }) } @@ -484,15 +502,15 @@ fn test_parallel_blocks() { let vec0 = par_bl.get_item(0).unwrap(); if let Ok(el) = vec0.call0() { - let helper1 = bool::extract( - el.get_item(0) + let helper1 = bool::extract_bound( + &el.get_item(0) .unwrap() .call_method1("__eq__", (0,)) .unwrap(), ) .unwrap(); - let helper2 = bool::extract( - el.get_item(0) + let helper2 = bool::extract_bound( + &el.get_item(0) .unwrap() .call_method1("__eq__", (2,)) .unwrap(), @@ -503,15 +521,15 @@ fn test_parallel_blocks() { let vec1 = par_bl.get_item(1).unwrap(); if let Ok(el) = vec1.call0() { - let helper1 = bool::extract( - el.get_item(0) + let helper1 = bool::extract_bound( + &el.get_item(0) .unwrap() .call_method1("__eq__", (1,)) .unwrap(), ) .unwrap(); - let helper2 = bool::extract( - el.get_item(0) + let helper2 = bool::extract_bound( + &el.get_item(0) .unwrap() .call_method1("__eq__", (3,)) .unwrap(), @@ -522,8 +540,8 @@ fn test_parallel_blocks() { let vec2 = par_bl.get_item(2).unwrap(); if let Ok(el) = vec2.call0() { - let helper1 = bool::extract( - el.get_item(0) + let helper1 = bool::extract_bound( + &el.get_item(0) .unwrap() .call_method1("__eq__", (4,)) .unwrap(), @@ -553,15 +571,15 @@ fn test_successors() { let vec = dag.call_method1("successors", (a,)).unwrap(); - let len_op: usize = usize::extract(vec.call_method0("__len__").unwrap()).unwrap(); + let len_op: usize = usize::extract_bound(&vec.call_method0("__len__").unwrap()).unwrap(); assert_eq!(len_op, 2); let el = vec.call_method1("__getitem__", (0,)).unwrap(); - let comp = bool::extract(el.call_method1("__eq__", (c,)).unwrap()).unwrap(); + let comp = bool::extract_bound(&el.call_method1("__eq__", (c,)).unwrap()).unwrap(); assert!(comp); let el = vec.call_method1("__getitem__", (1,)).unwrap(); - let comp = bool::extract(el.call_method1("__eq__", (b,)).unwrap()).unwrap(); + let comp = bool::extract_bound(&el.call_method1("__eq__", (b,)).unwrap()).unwrap(); assert!(comp); }) } diff --git a/qoqo/tests/integration/devices.rs b/qoqo/tests/integration/devices.rs index be374c45..21e2209a 100644 --- a/qoqo/tests/integration/devices.rs +++ b/qoqo/tests/integration/devices.rs @@ -11,7 +11,7 @@ // limitations under the License. use ndarray::{array, Array2}; -use numpy::{pyarray, PyArray2}; +use numpy::{pyarray_bound, PyArray2}; use pyo3::prelude::*; use qoqo::devices::{AllToAllDeviceWrapper, GenericDeviceWrapper, SquareLatticeDeviceWrapper}; use roqoqo::devices::{AllToAllDevice, GenericDevice, SquareLatticeDevice}; @@ -27,7 +27,7 @@ fn new_alltoalldevice() -> Py { let two_qubit_gates = ["CNOT".to_string()]; let arguments: (usize, [String; 2], [String; 1], f64) = (number_qubits, single_qubit_gates, two_qubit_gates, 1.0); - let device_type = py.get_type::(); + let device_type = py.get_type_bound::(); device_type.call1(arguments).unwrap().into() }) } @@ -37,7 +37,7 @@ fn new_genericdevice() -> Py { Python::with_gil(|py| -> Py { let number_qubits: u32 = 4; let arguments = (number_qubits,); - let device_type = py.get_type::(); + let device_type = py.get_type_bound::(); device_type.call1(arguments).unwrap().into() }) } @@ -57,10 +57,8 @@ fn new_genericlattice() -> Py { two_qubit_gates, 1.0, ); - let device_type = py.get_type::(); + let device_type = py.get_type_bound::(); device_type.call1(arguments).unwrap().into() - // .downcast::>() - // .unwrap() }) } #[test] @@ -201,8 +199,8 @@ fn test_json_schema_all_to_all() { pyo3::prepare_freethreaded_python(); pyo3::Python::with_gil(|py| { let device = new_alltoalldevice(); - let schema: String = String::extract( - device + let schema: String = String::extract_bound( + &device .call_method0(py, "json_schema") .unwrap() .extract(py) @@ -213,16 +211,16 @@ fn test_json_schema_all_to_all() { serde_json::to_string_pretty(&schemars::schema_for!(AllToAllDevice)).unwrap(); assert_eq!(schema, rust_schema); - let current_version_string = String::extract( - device + let current_version_string = String::extract_bound( + &device .call_method0(py, "current_version") .unwrap() .extract(py) .unwrap(), ) .unwrap(); - let minimum_supported_version_string = String::extract( - device + let minimum_supported_version_string = String::extract_bound( + &device .call_method0(py, "min_supported_version") .unwrap() .extract(py) @@ -242,8 +240,8 @@ fn test_json_schema_squared() { pyo3::prepare_freethreaded_python(); pyo3::Python::with_gil(|py| { let device = new_genericlattice(); - let schema: String = String::extract( - device + let schema: String = String::extract_bound( + &device .call_method0(py, "json_schema") .unwrap() .extract(py) @@ -254,16 +252,16 @@ fn test_json_schema_squared() { serde_json::to_string_pretty(&schemars::schema_for!(SquareLatticeDevice)).unwrap(); assert_eq!(schema, rust_schema); - let current_version_string = String::extract( - device + let current_version_string = String::extract_bound( + &device .call_method0(py, "current_version") .unwrap() .extract(py) .unwrap(), ) .unwrap(); - let minimum_supported_version_string = String::extract( - device + let minimum_supported_version_string = String::extract_bound( + &device .call_method0(py, "min_supported_version") .unwrap() .extract(py) @@ -283,8 +281,8 @@ fn test_json_schema_generic() { pyo3::prepare_freethreaded_python(); pyo3::Python::with_gil(|py| { let device = new_genericdevice(); - let schema: String = String::extract( - device + let schema: String = String::extract_bound( + &device .call_method0(py, "json_schema") .unwrap() .extract(py) @@ -295,16 +293,16 @@ fn test_json_schema_generic() { serde_json::to_string_pretty(&schemars::schema_for!(GenericDevice)).unwrap(); assert_eq!(schema, rust_schema); - let current_version_string = String::extract( - device + let current_version_string = String::extract_bound( + &device .call_method0(py, "current_version") .unwrap() .extract(py) .unwrap(), ) .unwrap(); - let minimum_supported_version_string = String::extract( - device + let minimum_supported_version_string = String::extract_bound( + &device .call_method0(py, "min_supported_version") .unwrap() .extract(py) @@ -326,30 +324,31 @@ fn test_decoherence_rates_all(device: Py) { // reference matrix for an initialized deviced or a non-existing qubit // test that invalid matrix format is not accepted - let pyarray_invalid: &PyArray2 = pyarray![py, [1.0], [2.0], [3.0]]; + let pyarray_invalid: &Bound> = &pyarray_bound![py, [1.0], [2.0], [3.0]]; // let readonly_invalid = pyarray_invalid.readonly(); let error = device.call_method1(py, "set_all_qubit_decoherence_rates", (pyarray_invalid,)); assert!(error.is_err()); let pyarray_testmatrix: Array2 = array![[1.0, 0.0, 0.0], [0.0, 2.0, 0.0], [0.0, 0.0, 3.0]]; - let pyarray: &PyArray2 = - pyarray![py, [1.0, 0.0, 0.0], [0.0, 2.0, 0.0], [0.0, 0.0, 3.0]]; + let pyarray: &Bound> = + &pyarray_bound![py, [1.0, 0.0, 0.0], [0.0, 2.0, 0.0], [0.0, 0.0, 3.0]]; // let readonly = pyarray.readonly(); let device = device .call_method1(py, "set_all_qubit_decoherence_rates", (pyarray,)) .unwrap(); - // .downcast::>(py) - // .unwrap(); // proper matrix returned for the available qubit after setting decoherence rates let matrix_py2 = device .call_method1(py, "qubit_decoherence_rates", (0_i64,)) .unwrap(); let matrix_test2 = matrix_py2 - .downcast::>(py) + .downcast_bound::>(py) .unwrap() - .to_owned_array(); + .as_gil_ref() + .readonly() + .as_array() + .to_owned(); assert_eq!(matrix_test2, pyarray_testmatrix); let pyarray_testmatrix: Array2 = array![ @@ -369,9 +368,12 @@ fn test_decoherence_rates_all(device: Py) { .call_method1(py, "qubit_decoherence_rates", (0_i64,)) .unwrap(); let matrix_test2 = matrix_py2 - .downcast::>(py) + .downcast_bound::>(py) .unwrap() - .to_owned_array(); + .as_gil_ref() + .readonly() + .as_array() + .to_owned(); assert_eq!(matrix_test2, pyarray_testmatrix); }) } @@ -388,22 +390,28 @@ fn test_decoherence_rates(device: Py) { .call_method1(py, "qubit_decoherence_rates", (0_i64,)) .unwrap(); let matrix_test = matrix_py - .downcast::>(py) + .downcast_bound::>(py) .unwrap() - .to_owned_array(); + .as_gil_ref() + .readonly() + .as_array() + .to_owned(); assert_eq!(matrix_test, matrix_zeros_py); let matrix2_py = device .call_method1(py, "qubit_decoherence_rates", (100_i64,)) .unwrap(); let matrix2_test = matrix2_py - .downcast::>(py) + .downcast_bound::>(py) .unwrap() - .to_owned_array(); + .as_gil_ref() + .readonly() + .as_array() + .to_owned(); assert_eq!(matrix2_test, matrix_zeros_py); // test that invalid matrix format is not accepted - let pyarray_invalid: &PyArray2 = pyarray![py, [1.0], [2.0], [3.0]]; + let pyarray_invalid: &Bound> = &pyarray_bound![py, [1.0], [2.0], [3.0]]; // let readonly_invalid = pyarray_invalid.readonly(); let error = device.call_method1(py, "set_qubit_decoherence_rates", (0, pyarray_invalid)); assert!(error.is_err()); @@ -416,23 +424,24 @@ fn test_decoherence_rates(device: Py) { let pyarray_testmatrix: Array2 = array![[1.0, 0.0, 0.0], [0.0, 2.0, 0.0], [0.0, 0.0, 3.0]]; - let pyarray: &PyArray2 = - pyarray![py, [1.0, 0.0, 0.0], [0.0, 2.0, 0.0], [0.0, 0.0, 3.0]]; + let pyarray: &Bound> = + &pyarray_bound![py, [1.0, 0.0, 0.0], [0.0, 2.0, 0.0], [0.0, 0.0, 3.0]]; // let readonly = pyarray.readonly(); device .call_method1(py, "set_qubit_decoherence_rates", (0, pyarray)) .unwrap(); - // .downcast::>(py) - // .unwrap(); // proper matrix returned for the available qubit after setting decoherence rates let matrix_py2 = device .call_method1(py, "qubit_decoherence_rates", (0_i64,)) .unwrap(); let matrix_test2 = matrix_py2 - .downcast::>(py) + .downcast_bound::>(py) .unwrap() - .to_owned_array(); + .as_gil_ref() + .readonly() + .as_array() + .to_owned(); assert_eq!(matrix_test2, pyarray_testmatrix); // testing add_damping, add_dephasing, add_depolarising @@ -454,9 +463,12 @@ fn test_decoherence_rates(device: Py) { .call_method1(py, "qubit_decoherence_rates", (0_i64,)) .unwrap(); let matrix_test2 = matrix_py2 - .downcast::>(py) + .downcast_bound::>(py) .unwrap() - .to_owned_array(); + .as_gil_ref() + .readonly() + .as_array() + .to_owned(); assert_eq!(matrix_test2, pyarray_testmatrix); }) } @@ -474,8 +486,6 @@ fn test_gatetimes(device: Py) { device .call_method1(py, "set_single_qubit_gate_time", ("RotateZ", 0, gate_time)) .unwrap(); - // .downcast::>(py) - // .unwrap(); // get the gate time for RotateZ on qubit 0 let gate_time_rotatez = device @@ -498,8 +508,6 @@ fn test_gatetimes(device: Py) { device .call_method1(py, "set_two_qubit_gate_time", ("CNOT", 0, 1, gate_time)) .unwrap(); - // .downcast::>(py) - // .unwrap(); // get the gate time for RotateZ on qubit 0 let gate_time_cnot = device @@ -560,8 +568,6 @@ fn test_gatetimes(device: Py) { ("MultiQubitMS", vec![0, 1, 2], gate_time), ) .unwrap(); - // .downcast::>(py) - // .unwrap(); let gate_time_test = device .call_method1(py, "multi_qubit_gate_time", ("MultiQubitMS", vec![0, 1, 2])) @@ -588,8 +594,6 @@ fn test_gatetimes_all(device: Py) { ("RotateZ", gate_time), ) .unwrap(); - // .downcast::>(py) - // .unwrap(); // get the gate time for RotateZ on qubit 0 let gate_time_rotatez = device @@ -612,8 +616,6 @@ fn test_gatetimes_all(device: Py) { let device = device .call_method1(py, "set_all_two_qubit_gate_times", ("CNOT", gate_time)) .unwrap(); - // .downcast::>(py) - // .unwrap(); // get the gate time for RotateZ on qubit 0 let gate_time_cnot = device @@ -859,15 +861,12 @@ mod test_chain_with_environment { impl TestDeviceWrapper { /// Fallible conversion of generic python object.. - fn from_pyany(input: Py) -> PyResult { - Python::with_gil(|py| -> PyResult { - let input = input.as_ref(py); - if let Ok(try_downcast) = input.extract::() { - Ok(try_downcast.internal) - } else { - panic!() - } - }) + fn from_pyany(input: &Bound) -> PyResult { + if let Ok(try_downcast) = input.extract::() { + Ok(try_downcast.internal) + } else { + panic!() + } } } @@ -875,7 +874,7 @@ mod test_chain_with_environment { fn test_chain_with_environment() { pyo3::prepare_freethreaded_python(); let test_device = Python::with_gil(|py| -> Py { - let device_type = py.get_type::(); + let device_type = py.get_type_bound::(); device_type.call0().unwrap().into() }); Python::with_gil(|py| { @@ -902,11 +901,11 @@ mod test_chain_with_environment { #[test] fn test_chain_with_environment_capsule() { pyo3::prepare_freethreaded_python(); - let test_device = Python::with_gil(|py| -> Py { - let device_type = py.get_type::(); - device_type.call0().unwrap().into() + let device_capsule = Python::with_gil(|py| -> ChainWithEnvironmentCapsule { + let device_type = py.get_type_bound::(); + let test_device = device_type.call0().unwrap(); + ChainWithEnvironmentCapsule::new(&test_device).unwrap() }); - let device_capsule = ChainWithEnvironmentCapsule::new(test_device).unwrap(); let chains_with_environment = device_capsule.environment_chains(); let simple_test_device = TestDevice; let comparison = simple_test_device.environment_chains(); diff --git a/qoqo/tests/integration/measurements/basis_rotation_measurement.rs b/qoqo/tests/integration/measurements/basis_rotation_measurement.rs index e931f45d..f102a91f 100644 --- a/qoqo/tests/integration/measurements/basis_rotation_measurement.rs +++ b/qoqo/tests/integration/measurements/basis_rotation_measurement.rs @@ -31,12 +31,9 @@ use test_case::test_case; fn test_returning_circuits() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let input_type = py.get_type::(); - let input = input_type - .call1((3, false)) - .unwrap() - .downcast::>() - .unwrap(); + let input_type = py.get_type_bound::(); + let binding = input_type.call1((3, false)).unwrap(); + let input = binding.downcast::().unwrap(); let tmp_vec: Vec = Vec::new(); let _ = input .call_method1("add_pauliz_product", ("ro", tmp_vec)) @@ -52,12 +49,11 @@ fn test_returning_circuits() { let mut circ1 = CircuitWrapper::new(); circ1.internal += roqoqo::operations::RotateX::new(0, 0.0.into()); circs.push(circ1); - let br_type = py.get_type::(); - let br = br_type + let br_type = py.get_type_bound::(); + let binding = br_type .call1((Some(CircuitWrapper::new()), circs.clone(), input)) - .unwrap() - .downcast::>() .unwrap(); + let br = binding.downcast::().unwrap(); let circuits: Vec = br.call_method0("circuits").unwrap().extract().unwrap(); for (index, b) in circuits.iter().enumerate() { @@ -105,12 +101,9 @@ fn test_py03_evaluate_bool( pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let input_type = py.get_type::(); - let input = input_type - .call1((3, false)) - .unwrap() - .downcast::>() - .unwrap(); + let input_type = py.get_type_bound::(); + let binding = input_type.call1((3, false)).unwrap(); + let input = binding.downcast::().unwrap(); let tmp_vec: Vec = Vec::new(); let _ = input .call_method1("add_pauliz_product", ("ro", tmp_vec)) @@ -161,12 +154,11 @@ fn test_py03_evaluate_bool( let circs: Vec = vec![CircuitWrapper::new()]; - let br_type = py.get_type::(); - let br = br_type + let br_type = py.get_type_bound::(); + let binding = br_type .call1((Some(CircuitWrapper::new()), circs, input)) - .unwrap() - .downcast::>() .unwrap(); + let br = binding.downcast::().unwrap(); let mut measured_registers: HashMap = HashMap::new(); let new_output_register: BitOutputRegister = register; @@ -188,12 +180,13 @@ fn test_py03_evaluate_bool( let result = br .call_method1("evaluate", (measured_registers, input1, input2)) .unwrap(); - let constant_py = f64::extract(result.get_item("constant").unwrap()).unwrap(); + let constant_py = f64::extract_bound(&result.get_item("constant").unwrap()).unwrap(); let single_qubit_exp_val_py = - f64::extract(result.get_item("single_qubit_exp_val").unwrap()).unwrap(); + f64::extract_bound(&result.get_item("single_qubit_exp_val").unwrap()).unwrap(); let two_qubit_exp_val_py = - f64::extract(result.get_item("two_qubit_exp_val").unwrap()).unwrap(); - let two_pp_exp_val_py = f64::extract(result.get_item("two_pp_exp_val").unwrap()).unwrap(); + f64::extract_bound(&result.get_item("two_qubit_exp_val").unwrap()).unwrap(); + let two_pp_exp_val_py = + f64::extract_bound(&result.get_item("two_pp_exp_val").unwrap()).unwrap(); assert_eq!(&constant_py, &constant); assert_eq!(&single_qubit_exp_val_py, &single_qubit_exp_val); @@ -219,12 +212,9 @@ fn test_py03_evaluate_usize( pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let input_type = py.get_type::(); - let input = input_type - .call1((3, false)) - .unwrap() - .downcast::>() - .unwrap(); + let input_type = py.get_type_bound::(); + let binding = input_type.call1((3, false)).unwrap(); + let input = binding.downcast::().unwrap(); let tmp_vec: Vec = Vec::new(); let _ = input .call_method1("add_pauliz_product", ("ro", tmp_vec)) @@ -275,12 +265,11 @@ fn test_py03_evaluate_usize( let circs: Vec = vec![CircuitWrapper::new()]; - let br_type = py.get_type::(); - let br = br_type + let br_type = py.get_type_bound::(); + let binding = br_type .call1((Some(CircuitWrapper::new()), circs, input)) - .unwrap() - .downcast::>() .unwrap(); + let br = binding.downcast::().unwrap(); let mut measured_registers: HashMap>> = HashMap::new(); let _ = measured_registers.insert("ro".to_string(), register); @@ -297,12 +286,13 @@ fn test_py03_evaluate_usize( let result = br .call_method1("evaluate", (measured_registers, input1, input2)) .unwrap(); - let constant_py = f64::extract(result.get_item("constant").unwrap()).unwrap(); + let constant_py = f64::extract_bound(&result.get_item("constant").unwrap()).unwrap(); let single_qubit_exp_val_py = - f64::extract(result.get_item("single_qubit_exp_val").unwrap()).unwrap(); + f64::extract_bound(&result.get_item("single_qubit_exp_val").unwrap()).unwrap(); let two_qubit_exp_val_py = - f64::extract(result.get_item("two_qubit_exp_val").unwrap()).unwrap(); - let two_pp_exp_val_py = f64::extract(result.get_item("two_pp_exp_val").unwrap()).unwrap(); + f64::extract_bound(&result.get_item("two_qubit_exp_val").unwrap()).unwrap(); + let two_pp_exp_val_py = + f64::extract_bound(&result.get_item("two_pp_exp_val").unwrap()).unwrap(); assert_eq!(&constant_py, &constant); assert_eq!(&single_qubit_exp_val_py, &single_qubit_exp_val); @@ -326,12 +316,9 @@ fn test_evaluate_symbolic(register: Vec>, constant: f64) { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let input_type = py.get_type::(); - let input = input_type - .call1((3, false)) - .unwrap() - .downcast::>() - .unwrap(); + let input_type = py.get_type_bound::(); + let binding = input_type.call1((3, false)).unwrap(); + let input = binding.downcast::().unwrap(); let tmp_vec: Vec = Vec::new(); let _ = input .call_method1("add_pauliz_product", ("ro", tmp_vec)) @@ -357,12 +344,11 @@ fn test_evaluate_symbolic(register: Vec>, constant: f64) { let circs: Vec = vec![CircuitWrapper::new()]; - let br_type = py.get_type::(); - let br = br_type + let br_type = py.get_type_bound::(); + let binding = br_type .call1((Some(CircuitWrapper::new()), circs, input)) - .unwrap() - .downcast::>() .unwrap(); + let br = binding.downcast::().unwrap(); let mut measured_registers: HashMap = HashMap::new(); let new_output_register: BitOutputRegister = register; @@ -384,7 +370,7 @@ fn test_evaluate_symbolic(register: Vec>, constant: f64) { let result = br .call_method1("evaluate", (measured_registers, input1, input2)) .unwrap(); - let constant_py = f64::extract(result.get_item("constant").unwrap()).unwrap(); + let constant_py = f64::extract_bound(&result.get_item("constant").unwrap()).unwrap(); assert!((constant_py - constant).abs() < f64::EPSILON); }) } @@ -395,12 +381,9 @@ fn test_py03_evaluate_error0() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let input_type = py.get_type::(); - let input = input_type - .call1((3, false)) - .unwrap() - .downcast::>() - .unwrap(); + let input_type = py.get_type_bound::(); + let binding = input_type.call1((3, false)).unwrap(); + let input = binding.downcast::().unwrap(); let tmp_vec: Vec = Vec::new(); let _ = input .call_method1("add_pauliz_product", ("ro", tmp_vec)) @@ -417,12 +400,11 @@ fn test_py03_evaluate_error0() { let circs: Vec = vec![CircuitWrapper::new()]; - let br_type = py.get_type::(); - let br = br_type + let br_type = py.get_type_bound::(); + let binding = br_type .call1((Some(CircuitWrapper::new()), circs, input)) - .unwrap() - .downcast::>() .unwrap(); + let br = binding.downcast::().unwrap(); let measured_registers: HashMap = HashMap::new(); let input2: HashMap = @@ -448,12 +430,9 @@ fn test_pyo3_copy() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let input_type = py.get_type::(); - let input = input_type - .call1((3, false)) - .unwrap() - .downcast::>() - .unwrap(); + let input_type = py.get_type_bound::(); + let binding = input_type.call1((3, false)).unwrap(); + let input = binding.downcast::().unwrap(); let tmp_vec: Vec = Vec::new(); let _ = input .call_method1("add_pauliz_product", ("ro", tmp_vec)) @@ -469,12 +448,11 @@ fn test_pyo3_copy() { let mut circ1 = CircuitWrapper::new(); circ1.internal += roqoqo::operations::RotateX::new(0, 0.0.into()); circs.push(circ1); - let br_type = py.get_type::(); - let br = br_type + let br_type = py.get_type_bound::(); + let binding = br_type .call1((Some(CircuitWrapper::new()), circs.clone(), input)) - .unwrap() - .downcast::>() .unwrap(); + let br = binding.downcast::().unwrap(); let br_clone = br; let circuits: Vec = br.call_method0("circuits").unwrap().extract().unwrap(); @@ -505,12 +483,9 @@ fn test_pyo3_debug() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let input_type = py.get_type::(); - let input = input_type - .call1((3, false)) - .unwrap() - .downcast::>() - .unwrap(); + let input_type = py.get_type_bound::(); + let binding = input_type.call1((3, false)).unwrap(); + let input = binding.downcast::().unwrap(); let tmp_vec: Vec = Vec::new(); let _ = input .call_method1("add_pauliz_product", ("ro", tmp_vec)) @@ -518,12 +493,11 @@ fn test_pyo3_debug() { let circs: Vec = vec![CircuitWrapper::new()]; - let br_type = py.get_type::(); - let br = br_type + let br_type = py.get_type_bound::(); + let binding = br_type .call1((Some(CircuitWrapper::new()), circs, input)) - .unwrap() - .downcast::>() .unwrap(); + let br = binding.downcast::().unwrap(); let br_wrapper = br.extract::().unwrap(); #[allow(clippy::redundant_clone)] @@ -531,10 +505,10 @@ fn test_pyo3_debug() { assert_eq!(format!("{:?}", br_wrapper), format!("{:?}", br_clone)); let debug_string = "RefCell { value: PauliZProductWrapper { internal: PauliZProduct { constant_circuit: Some(Circuit { definitions: [], operations: [], _roqoqo_version: RoqoqoVersion }), circuits: [Circuit { definitions: [], operations: [], _roqoqo_version: RoqoqoVersion }], input: PauliZProductInput { pauli_product_qubit_masks: {\"ro\": {0: []}}, number_qubits: 3, number_pauli_products: 1, measured_exp_vals: {}, use_flipped_measurement: false } } } }"; - assert_eq!(format!("{:?}", br), debug_string); + assert_eq!(format!("{:?}", br.as_gil_ref()), debug_string); let debug_input_string = "RefCell { value: PauliZProductInputWrapper { internal: PauliZProductInput { pauli_product_qubit_masks: {\"ro\": {0: []}}, number_qubits: 3, number_pauli_products: 1, measured_exp_vals: {}, use_flipped_measurement: false } } }"; - assert_eq!(format!("{:?}", input), debug_input_string); + assert_eq!(format!("{:?}", input.as_gil_ref()), debug_input_string); let debug_input = input; let mut linear_map: HashMap = HashMap::new(); @@ -562,12 +536,9 @@ fn test_pyo3_debug() { fn test_internal_to_bincode() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let input_type = py.get_type::(); - let input = input_type - .call1((3, false)) - .unwrap() - .downcast::>() - .unwrap(); + let input_type = py.get_type_bound::(); + let binding = input_type.call1((3, false)).unwrap(); + let input = binding.downcast::().unwrap(); let tmp_vec: Vec = Vec::new(); let _ = input .call_method1("add_pauliz_product", ("ro", tmp_vec.clone())) @@ -575,12 +546,11 @@ fn test_internal_to_bincode() { let circs: Vec = vec![CircuitWrapper::new()]; - let br_type = py.get_type::(); - let br = br_type + let br_type = py.get_type_bound::(); + let binding = br_type .call1((Some(CircuitWrapper::new()), circs, input)) - .unwrap() - .downcast::>() .unwrap(); + let br = binding.downcast::().unwrap(); let mut roqoqo_bri = PauliZProductInput::new(3, false); roqoqo_bri @@ -594,7 +564,7 @@ fn test_internal_to_bincode() { }; let comparison_serialised = serialize(&roqoqo_br).unwrap(); - let serialised: (&str, Vec) = br + let serialised: (String, Vec) = br .call_method0("_internal_to_bincode") .unwrap() .extract() @@ -609,12 +579,9 @@ fn test_internal_to_bincode() { fn test_to_from_bincode() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let input_type = py.get_type::(); - let input = input_type - .call1((3, false)) - .unwrap() - .downcast::>() - .unwrap(); + let input_type = py.get_type_bound::(); + let binding = input_type.call1((3, false)).unwrap(); + let input = binding.downcast::().unwrap(); let tmp_vec: Vec = Vec::new(); let _ = input .call_method1("add_pauliz_product", ("ro", tmp_vec)) @@ -622,31 +589,29 @@ fn test_to_from_bincode() { let serialised = input.call_method0("to_bincode").unwrap(); let new_input = input; - let deserialised = new_input - .call_method1("from_bincode", (serialised,)) - .unwrap() - .downcast::>() + let binding = new_input + .call_method1("from_bincode", (&serialised,)) .unwrap(); + let deserialised = binding.downcast::().unwrap(); assert_eq!(format!("{:?}", input), format!("{:?}", deserialised)); let circs: Vec = vec![CircuitWrapper::new()]; - let br_type = py.get_type::(); - let br = br_type + let br_type = py.get_type_bound::(); + let binding = br_type .call1((Some(CircuitWrapper::new()), circs, input)) - .unwrap() - .downcast::>() .unwrap(); + let br = binding.downcast::().unwrap(); let new_br = br; let serialised = br.call_method0("to_bincode").unwrap(); - let deserialised = new_br - .call_method1("from_bincode", (serialised,)) - .unwrap() - .downcast::>() - .unwrap(); - assert_eq!(format!("{:?}", br), format!("{:?}", deserialised)); + let binding = new_br.call_method1("from_bincode", (&serialised,)).unwrap(); + let deserialised = binding.downcast::().unwrap(); + assert_eq!( + format!("{:?}", br.as_gil_ref()), + format!("{:?}", deserialised.as_gil_ref()) + ); let deserialised_error = new_br.call_method1("from_bincode", (bincode::serialize("fails").unwrap(),)); @@ -667,41 +632,34 @@ fn test_to_from_json() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let input_type = py.get_type::(); - let input = input_type - .call1((3, false)) - .unwrap() - .downcast::>() - .unwrap(); + let input_type = py.get_type_bound::(); + let binding = input_type.call1((3, false)).unwrap(); + let input = binding.downcast::().unwrap(); let tmp_vec: Vec = Vec::new(); let _ = input .call_method1("add_pauliz_product", ("ro", tmp_vec)) .unwrap(); let serialised = input.call_method0("to_json").unwrap(); let new_input = input; - let deserialised = new_input - .call_method1("from_json", (serialised,)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = new_input.call_method1("from_json", (&serialised,)).unwrap(); + let deserialised = binding.downcast::().unwrap(); assert_eq!(format!("{:?}", input), format!("{:?}", deserialised)); let circs: Vec = vec![CircuitWrapper::new()]; - let br_type = py.get_type::(); - let br = br_type + let br_type = py.get_type_bound::(); + let binding = br_type .call1((Some(CircuitWrapper::new()), circs, input)) - .unwrap() - .downcast::>() .unwrap(); + let br = binding.downcast::().unwrap(); let new_br = br; let serialised = br.call_method0("to_json").unwrap(); - let deserialised = new_br - .call_method1("from_json", (serialised,)) - .unwrap() - .downcast::>() - .unwrap(); - assert_eq!(format!("{:?}", br), format!("{:?}", deserialised)); + let binding = new_br.call_method1("from_json", (&serialised,)).unwrap(); + let deserialised = binding.downcast::().unwrap(); + assert_eq!( + format!("{:?}", br.as_gil_ref()), + format!("{:?}", deserialised.as_gil_ref()) + ); let deserialised_error = new_br.call_method1("from_json", (serde_json::to_string("fails").unwrap(),)); @@ -722,12 +680,9 @@ fn test_substitute_parameters() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let input_type = py.get_type::(); - let input = input_type - .call1((3, false)) - .unwrap() - .downcast::>() - .unwrap(); + let input_type = py.get_type_bound::(); + let binding = input_type.call1((3, false)).unwrap(); + let input = binding.downcast::().unwrap(); let tmp_vec: Vec = Vec::new(); let _ = input .call_method1("add_pauliz_product", ("ro", tmp_vec)) @@ -743,20 +698,16 @@ fn test_substitute_parameters() { let mut circ1 = CircuitWrapper::new(); circ1.internal += roqoqo::operations::RotateX::new(0, "theta".into()); circs.push(circ1); - let br_type = py.get_type::(); - let br = br_type + let br_type = py.get_type_bound::(); + let binding = br_type .call1((Some(CircuitWrapper::new()), circs.clone(), input)) - .unwrap() - .downcast::>() .unwrap(); + let br = binding.downcast::().unwrap(); let mut map: HashMap = HashMap::::new(); map.insert("theta".to_string(), 0.0); - let br_sub = br - .call_method1("substitute_parameters", (map,)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = br.call_method1("substitute_parameters", (map,)).unwrap(); + let br_sub = binding.downcast::().unwrap(); let br_wrapper = br.extract::().unwrap(); let br_sub_wrapper = br_sub.extract::().unwrap(); @@ -770,12 +721,9 @@ fn test_substitute_parameters_error() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let input_type = py.get_type::(); - let input = input_type - .call1((3, false)) - .unwrap() - .downcast::>() - .unwrap(); + let input_type = py.get_type_bound::(); + let binding = input_type.call1((3, false)).unwrap(); + let input = binding.downcast::().unwrap(); let tmp_vec: Vec = Vec::new(); let _ = input .call_method1("add_pauliz_product", ("ro", tmp_vec)) @@ -791,12 +739,11 @@ fn test_substitute_parameters_error() { let mut circ1 = CircuitWrapper::new(); circ1.internal += roqoqo::operations::RotateX::new(0, "theta".into()); circs.push(circ1); - let br_type = py.get_type::(); - let br = br_type + let br_type = py.get_type_bound::(); + let binding = br_type .call1((Some(CircuitWrapper::new()), circs.clone(), input)) - .unwrap() - .downcast::>() .unwrap(); + let br = binding.downcast::().unwrap(); let map: HashMap = HashMap::::new(); let br_sub = br.call_method1("substitute_parameters", (map,)); @@ -808,12 +755,9 @@ fn test_substitute_parameters_error() { #[test] fn test_measurement_type() { Python::with_gil(|py| { - let input_type = py.get_type::(); - let input = input_type - .call1((3, false)) - .unwrap() - .downcast::>() - .unwrap(); + let input_type = py.get_type_bound::(); + let binding = input_type.call1((3, false)).unwrap(); + let input = binding.downcast::().unwrap(); let tmp_vec: Vec = Vec::new(); let _ = input .call_method1("add_pauliz_product", ("ro", tmp_vec)) @@ -821,12 +765,11 @@ fn test_measurement_type() { let circs: Vec = vec![CircuitWrapper::new()]; - let br_type = py.get_type::(); - let br = br_type + let br_type = py.get_type_bound::(); + let binding = br_type .call1((Some(CircuitWrapper::new()), circs, input)) - .unwrap() - .downcast::>() .unwrap(); + let br = binding.downcast::().unwrap(); let measurement_type = br.call_method0("measurement_type").unwrap(); assert_eq!(measurement_type.to_string(), "PauliZProduct"); @@ -837,12 +780,9 @@ fn test_measurement_type() { #[test] fn test_return_input() { Python::with_gil(|py| { - let input_type = py.get_type::(); - let input = input_type - .call1((3, false)) - .unwrap() - .downcast::>() - .unwrap(); + let input_type = py.get_type_bound::(); + let binding = input_type.call1((3, false)).unwrap(); + let input = binding.downcast::().unwrap(); let tmp_vec: Vec = Vec::new(); let _ = input .call_method1("add_pauliz_product", ("ro", tmp_vec)) @@ -850,18 +790,14 @@ fn test_return_input() { let circs: Vec = vec![CircuitWrapper::new()]; - let br_type = py.get_type::(); - let br = br_type + let br_type = py.get_type_bound::(); + let binding = br_type .call1((Some(CircuitWrapper::new()), circs, input)) - .unwrap() - .downcast::>() .unwrap(); + let br = binding.downcast::().unwrap(); - let input_returned = br - .call_method0("input") - .unwrap() - .downcast::>() - .unwrap(); + let binding = br.call_method0("input").unwrap(); + let input_returned = binding.downcast::().unwrap(); assert_eq!(format!("{:?}", input_returned), format!("{:?}", input)); }) @@ -872,12 +808,9 @@ fn test_pyo3_format_repr() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let format_repr = "PauliZProduct { constant_circuit: Some(Circuit { definitions: [], operations: [], _roqoqo_version: RoqoqoVersion }), circuits: [Circuit { definitions: [], operations: [], _roqoqo_version: RoqoqoVersion }], input: PauliZProductInput { pauli_product_qubit_masks: {\"ro\": {0: []}}, number_qubits: 3, number_pauli_products: 1, measured_exp_vals: {}, use_flipped_measurement: false } }"; - let input_type = py.get_type::(); - let input = input_type - .call1((3, false)) - .unwrap() - .downcast::>() - .unwrap(); + let input_type = py.get_type_bound::(); + let binding = input_type.call1((3, false)).unwrap(); + let input = binding.downcast::().unwrap(); let tmp_vec: Vec = Vec::new(); let _ = input .call_method1("add_pauliz_product", ("ro", tmp_vec)) @@ -885,16 +818,15 @@ fn test_pyo3_format_repr() { let circs: Vec = vec![CircuitWrapper::new()]; - let br_type = py.get_type::(); - let br = br_type + let br_type = py.get_type_bound::(); + let binding = br_type .call1((Some(CircuitWrapper::new()), circs, input)) - .unwrap() - .downcast::>() .unwrap(); + let br = binding.downcast::().unwrap(); let to_format = br.call_method1("__format__", ("",)).unwrap(); - let format_op: &str = <&str>::extract(to_format).unwrap(); + let format_op: String = String::extract_bound(&to_format).unwrap(); let to_repr = br.call_method0("__repr__").unwrap(); - let repr_op: &str = <&str>::extract(to_repr).unwrap(); + let repr_op: String = String::extract_bound(&to_repr).unwrap(); assert_eq!(format_op, format_repr); assert_eq!(repr_op, format_repr); }) @@ -904,12 +836,9 @@ fn test_pyo3_format_repr() { fn test_pyo3_copy_deepcopy() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let input_type = py.get_type::(); - let input = input_type - .call1((3, false)) - .unwrap() - .downcast::>() - .unwrap(); + let input_type = py.get_type_bound::(); + let binding = input_type.call1((3, false)).unwrap(); + let input = binding.downcast::().unwrap(); let tmp_vec: Vec = Vec::new(); let _ = input .call_method1("add_pauliz_product", ("ro", tmp_vec)) @@ -917,25 +846,24 @@ fn test_pyo3_copy_deepcopy() { let circs: Vec = vec![CircuitWrapper::new()]; - let br_type = py.get_type::(); - let br = br_type + let br_type = py.get_type_bound::(); + let binding = br_type .call1((Some(CircuitWrapper::new()), circs, input)) - .unwrap() - .downcast::>() .unwrap(); + let br = binding.downcast::().unwrap(); let copy_op = br.call_method0("__copy__").unwrap(); let deepcopy_op = br.call_method1("__deepcopy__", ("",)).unwrap(); let copy_deepcopy_param = br; - let comparison_copy = bool::extract( - copy_op + let comparison_copy = bool::extract_bound( + ©_op .call_method1("__eq__", (copy_deepcopy_param,)) .unwrap(), ) .unwrap(); assert!(comparison_copy); - let comparison_deepcopy = bool::extract( - deepcopy_op + let comparison_deepcopy = bool::extract_bound( + &deepcopy_op .call_method1("__eq__", (copy_deepcopy_param,)) .unwrap(), ) @@ -948,12 +876,9 @@ fn test_pyo3_copy_deepcopy() { fn test_pyo3_richcmp() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let input_type = py.get_type::(); - let input = input_type - .call1((3, false)) - .unwrap() - .downcast::>() - .unwrap(); + let input_type = py.get_type_bound::(); + let binding = input_type.call1((3, false)).unwrap(); + let input = binding.downcast::().unwrap(); let tmp_vec: Vec = Vec::new(); let _ = input .call_method1("add_pauliz_product", ("ro", tmp_vec)) @@ -961,23 +886,21 @@ fn test_pyo3_richcmp() { let circs: Vec = vec![CircuitWrapper::new()]; - let br_type = py.get_type::(); - let br_one = br_type + let br_type = py.get_type_bound::(); + let binding = br_type .call1((Some(CircuitWrapper::new()), circs.clone(), input)) - .unwrap() - .downcast::>() .unwrap(); + let br_one = binding.downcast::().unwrap(); let arg: Option = None; - let br_two = br_type - .call1((arg, circs, input)) - .unwrap() - .downcast::>() - .unwrap(); - let comparison = bool::extract(br_one.call_method1("__eq__", (br_two,)).unwrap()).unwrap(); + let binding = br_type.call1((arg, circs, input)).unwrap(); + let br_two = binding.downcast::().unwrap(); + let comparison = + bool::extract_bound(&br_one.call_method1("__eq__", (br_two,)).unwrap()).unwrap(); assert!(!comparison); - let comparison = bool::extract(br_one.call_method1("__ne__", (br_two,)).unwrap()).unwrap(); + let comparison = + bool::extract_bound(&br_one.call_method1("__ne__", (br_two,)).unwrap()).unwrap(); assert!(comparison); let comparison = br_one.call_method1("__ge__", (br_two,)); @@ -994,12 +917,9 @@ fn test_pyo3_json_schema() { let rust_schema = serde_json::to_string_pretty(&schemars::schema_for!(PauliZProduct)).unwrap(); pyo3::prepare_freethreaded_python(); pyo3::Python::with_gil(|py| { - let input_type = py.get_type::(); - let input = input_type - .call1((3, false)) - .unwrap() - .downcast::>() - .unwrap(); + let input_type = py.get_type_bound::(); + let binding = input_type.call1((3, false)).unwrap(); + let input = binding.downcast::().unwrap(); let tmp_vec: Vec = Vec::new(); let _ = input .call_method1("add_pauliz_product", ("ro", tmp_vec)) @@ -1007,29 +927,29 @@ fn test_pyo3_json_schema() { let circs: Vec = vec![CircuitWrapper::new()]; - let br_type = py.get_type::(); + let br_type = py.get_type_bound::(); #[allow(clippy::redundant_clone)] - let br_one = br_type + let binding = br_type .call1((Some(CircuitWrapper::new()), circs.clone(), input)) - .unwrap() - .downcast::>() .unwrap(); + let br_one = binding.downcast::().unwrap(); let schema_input: String = - String::extract(input.call_method0("json_schema").unwrap()).unwrap(); - let schema: String = String::extract(br_one.call_method0("json_schema").unwrap()).unwrap(); + String::extract_bound(&input.call_method0("json_schema").unwrap()).unwrap(); + let schema: String = + String::extract_bound(&br_one.call_method0("json_schema").unwrap()).unwrap(); assert_eq!(schema_input, rust_schema_input); assert_eq!(schema, rust_schema); let current_version_string_input = - String::extract(input.call_method0("current_version").unwrap()).unwrap(); + String::extract_bound(&input.call_method0("current_version").unwrap()).unwrap(); let current_version_string = - String::extract(br_one.call_method0("current_version").unwrap()).unwrap(); + String::extract_bound(&br_one.call_method0("current_version").unwrap()).unwrap(); let minimum_supported_version_string_input = - String::extract(input.call_method0("min_supported_version").unwrap()).unwrap(); + String::extract_bound(&input.call_method0("min_supported_version").unwrap()).unwrap(); let minimum_supported_version_string = - String::extract(br_one.call_method0("min_supported_version").unwrap()).unwrap(); + String::extract_bound(&br_one.call_method0("min_supported_version").unwrap()).unwrap(); assert_eq!(current_version_string, ROQOQO_VERSION); assert_eq!(current_version_string_input, ROQOQO_VERSION); diff --git a/qoqo/tests/integration/measurements/cheated_basis_rotation_measurement.rs b/qoqo/tests/integration/measurements/cheated_basis_rotation_measurement.rs index ab647cb9..e1f7be55 100644 --- a/qoqo/tests/integration/measurements/cheated_basis_rotation_measurement.rs +++ b/qoqo/tests/integration/measurements/cheated_basis_rotation_measurement.rs @@ -31,11 +31,10 @@ fn test_returning_circuits() { Python::with_gil(|py| { pyo3::prepare_freethreaded_python(); - let input_type = py.get_type::(); - let input = input_type - .call0() - .unwrap() - .downcast::>() + let input_type = py.get_type_bound::(); + let binding = input_type.call0().unwrap(); + let input = binding + .downcast::() .unwrap(); let _ = input.call_method1("add_pauliz_product", ("ro",)).unwrap(); @@ -43,12 +42,11 @@ fn test_returning_circuits() { let mut circ1 = CircuitWrapper::new(); circ1.internal += roqoqo::operations::RotateX::new(0, 0.0.into()); circs.push(circ1); - let br_type = py.get_type::(); - let br = br_type + let br_type = py.get_type_bound::(); + let binding = br_type .call1((Some(CircuitWrapper::new()), circs.clone(), input)) - .unwrap() - .downcast::>() .unwrap(); + let br = binding.downcast::().unwrap(); let circuits: Vec = br.call_method0("circuits").unwrap().extract().unwrap(); for (index, b) in circuits.iter().enumerate() { @@ -68,11 +66,10 @@ fn test_returning_circuits() { fn test_py03_evaluate_bool() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let input_type = py.get_type::(); - let input = input_type - .call0() - .unwrap() - .downcast::>() + let input_type = py.get_type_bound::(); + let binding = input_type.call0().unwrap(); + let input = binding + .downcast::() .unwrap(); let _ = input .call_method1("add_pauliz_product", ("ro_pauli_product_0",)) @@ -99,12 +96,11 @@ fn test_py03_evaluate_bool() { let circs: Vec = vec![CircuitWrapper::new()]; - let br_type = py.get_type::(); - let br = br_type + let br_type = py.get_type_bound::(); + let binding = br_type .call1((Some(CircuitWrapper::new()), circs, input)) - .unwrap() - .downcast::>() .unwrap(); + let br = binding.downcast::().unwrap(); let mut measured_registers: HashMap = HashMap::new(); let _ = measured_registers.insert("ro_pauli_product_0".to_string(), vec![vec![1.0]]); @@ -119,8 +115,10 @@ fn test_py03_evaluate_bool() { (bit_register, measured_registers, complex_register), ) .unwrap(); - let two_qubit_exp_val_py = f64::extract(result.get_item("single_pp_val").unwrap()).unwrap(); - let two_pp_exp_val_py = f64::extract(result.get_item("multi_pp_val").unwrap()).unwrap(); + let two_qubit_exp_val_py = + f64::extract_bound(&result.get_item("single_pp_val").unwrap()).unwrap(); + let two_pp_exp_val_py = + f64::extract_bound(&result.get_item("multi_pp_val").unwrap()).unwrap(); assert_eq!(two_qubit_exp_val_py, 3.0); assert_eq!(two_pp_exp_val_py, 1.0); }) @@ -131,11 +129,10 @@ fn test_py03_evaluate_bool() { fn test_evaluate_symbolic() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let input_type = py.get_type::(); - let input = input_type - .call0() - .unwrap() - .downcast::>() + let input_type = py.get_type_bound::(); + let binding = input_type.call0().unwrap(); + let input = binding + .downcast::() .unwrap(); let _ = input .call_method1("add_pauliz_product", ("ro_pauli_product_0",)) @@ -155,12 +152,11 @@ fn test_evaluate_symbolic() { let circs: Vec = vec![CircuitWrapper::new()]; - let br_type = py.get_type::(); - let br = br_type + let br_type = py.get_type_bound::(); + let binding = br_type .call1((Some(CircuitWrapper::new()), circs, input)) - .unwrap() - .downcast::>() .unwrap(); + let br = binding.downcast::().unwrap(); let mut measured_registers: HashMap = HashMap::new(); let _ = measured_registers.insert("ro_pauli_product_0".to_string(), vec![vec![1.0]]); @@ -175,7 +171,8 @@ fn test_evaluate_symbolic() { (bit_register, measured_registers, complex_register), ) .unwrap(); - let single_pp_val_py = f64::extract(result.get_item("single_pp_val").unwrap()).unwrap(); + let single_pp_val_py = + f64::extract_bound(&result.get_item("single_pp_val").unwrap()).unwrap(); assert!((single_pp_val_py - (3.0_f64.sin() + 1.0_f64.sin())).abs() < f64::EPSILON); }) } @@ -185,11 +182,10 @@ fn test_evaluate_symbolic() { fn test_py03_evaluate_error0() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let input_type = py.get_type::(); - let input = input_type - .call0() - .unwrap() - .downcast::>() + let input_type = py.get_type_bound::(); + let binding = input_type.call0().unwrap(); + let input = binding + .downcast::() .unwrap(); let _ = input .call_method1("add_pauliz_product", ("ro_pauli_product_0",)) @@ -209,12 +205,11 @@ fn test_py03_evaluate_error0() { let circs: Vec = vec![CircuitWrapper::new()]; - let br_type = py.get_type::(); - let br = br_type + let br_type = py.get_type_bound::(); + let binding = br_type .call1((Some(CircuitWrapper::new()), circs, input)) - .unwrap() - .downcast::>() .unwrap(); + let br = binding.downcast::().unwrap(); let input2: HashMap = HashMap::::new(); @@ -236,11 +231,10 @@ fn test_py03_evaluate_error0() { fn test_pyo3_copy() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let input_type = py.get_type::(); - let input = input_type - .call0() - .unwrap() - .downcast::>() + let input_type = py.get_type_bound::(); + let binding = input_type.call0().unwrap(); + let input = binding + .downcast::() .unwrap(); let _ = input.call_method1("add_pauliz_product", ("ro",)).unwrap(); @@ -248,12 +242,11 @@ fn test_pyo3_copy() { let mut circ1 = CircuitWrapper::new(); circ1.internal += roqoqo::operations::RotateX::new(0, 0.0.into()); circs.push(circ1); - let br_type = py.get_type::(); - let br = br_type + let br_type = py.get_type_bound::(); + let binding = br_type .call1((Some(CircuitWrapper::new()), circs.clone(), input)) - .unwrap() - .downcast::>() .unwrap(); + let br = binding.downcast::().unwrap(); let br_clone = br; let circuits: Vec = br.call_method0("circuits").unwrap().extract().unwrap(); @@ -283,22 +276,20 @@ fn test_pyo3_copy() { fn test_pyo3_debug() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let input_type = py.get_type::(); - let input = input_type - .call0() - .unwrap() - .downcast::>() + let input_type = py.get_type_bound::(); + let binding = input_type.call0().unwrap(); + let input = binding + .downcast::() .unwrap(); let _ = input.call_method1("add_pauliz_product", ("ro",)).unwrap(); let circs: Vec = vec![CircuitWrapper::new()]; - let br_type = py.get_type::(); - let br = br_type + let br_type = py.get_type_bound::(); + let binding = br_type .call1((Some(CircuitWrapper::new()), circs, input)) - .unwrap() - .downcast::>() .unwrap(); + let br = binding.downcast::().unwrap(); let br_wrapper = br.extract::().unwrap(); #[allow(clippy::redundant_clone)] @@ -306,11 +297,11 @@ fn test_pyo3_debug() { assert_eq!(format!("{:?}", br_wrapper), format!("{:?}", br_clone)); let debug_string = "RefCell { value: CheatedPauliZProductWrapper { internal: CheatedPauliZProduct { constant_circuit: Some(Circuit { definitions: [], operations: [], _roqoqo_version: RoqoqoVersion }), circuits: [Circuit { definitions: [], operations: [], _roqoqo_version: RoqoqoVersion }], input: CheatedPauliZProductInput { measured_exp_vals: {}, pauli_product_keys: {\"ro\": 0} } } } }"; - assert_eq!(format!("{:?}", br), debug_string); + assert_eq!(format!("{:?}", br.as_gil_ref()), debug_string); let debug_input = input; let debug_input_string = "RefCell { value: CheatedPauliZProductInputWrapper { internal: CheatedPauliZProductInput { measured_exp_vals: {}, pauli_product_keys: {\"ro\": 0} } } }"; - assert_eq!(format!("{:?}", input), debug_input_string); + assert_eq!(format!("{:?}", input.as_gil_ref()), debug_input_string); assert_eq!( CheatedPauliZProductInputWrapper::default().internal, CheatedPauliZProductInputWrapper::new().internal @@ -337,22 +328,20 @@ fn test_pyo3_debug() { fn test_internal_to_bincode() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let input_type = py.get_type::(); - let input = input_type - .call0() - .unwrap() - .downcast::>() + let input_type = py.get_type_bound::(); + let binding = input_type.call0().unwrap(); + let input = binding + .downcast::() .unwrap(); let _ = input.call_method1("add_pauliz_product", ("ro",)).unwrap(); let circs: Vec = vec![CircuitWrapper::new()]; - let br_type = py.get_type::(); - let br = br_type + let br_type = py.get_type_bound::(); + let binding = br_type .call1((Some(CircuitWrapper::new()), circs, input)) - .unwrap() - .downcast::>() .unwrap(); + let br = binding.downcast::().unwrap(); let mut roqoqo_bri = CheatedPauliZProductInput::new(); roqoqo_bri.add_pauliz_product("ro".to_string()); @@ -364,7 +353,7 @@ fn test_internal_to_bincode() { }; let comparison_serialised = serialize(&roqoqo_br).unwrap(); - let serialised: (&str, Vec) = br + let serialised: (String, Vec) = br .call_method0("_internal_to_bincode") .unwrap() .extract() @@ -379,41 +368,40 @@ fn test_internal_to_bincode() { fn test_to_from_bincode() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let input_type = py.get_type::(); - let input = input_type - .call0() - .unwrap() - .downcast::>() + let input_type = py.get_type_bound::(); + let binding = input_type.call0().unwrap(); + let input = binding + .downcast::() .unwrap(); let _ = input.call_method1("add_pauliz_product", ("ro",)).unwrap(); let serialised = input.call_method0("to_bincode").unwrap(); let new_input = input; - let deserialised = new_input - .call_method1("from_bincode", (serialised,)) - .unwrap() - .downcast::>() + let binding = new_input + .call_method1("from_bincode", (&serialised,)) + .unwrap(); + let deserialised = binding + .downcast::() .unwrap(); assert_eq!(format!("{:?}", input), format!("{:?}", deserialised)); let circs: Vec = vec![CircuitWrapper::new()]; - let br_type = py.get_type::(); - let br = br_type + let br_type = py.get_type_bound::(); + let binding = br_type .call1((Some(CircuitWrapper::new()), circs, input)) - .unwrap() - .downcast::>() .unwrap(); + let br = binding.downcast::().unwrap(); let new_br = br; let serialised = br.call_method0("to_bincode").unwrap(); - let deserialised = new_br - .call_method1("from_bincode", (serialised,)) - .unwrap() - .downcast::>() - .unwrap(); - assert_eq!(format!("{:?}", br), format!("{:?}", deserialised)); + let binding = new_br.call_method1("from_bincode", (&serialised,)).unwrap(); + let deserialised = binding.downcast::().unwrap(); + assert_eq!( + format!("{:?}", br.as_gil_ref()), + format!("{:?}", deserialised.as_gil_ref()) + ); let deserialised_error = new_br.call_method1("from_bincode", (bincode::serialize("fails").unwrap(),)); @@ -433,40 +421,37 @@ fn test_to_from_bincode() { fn test_to_from_json() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let input_type = py.get_type::(); - let input = input_type - .call0() - .unwrap() - .downcast::>() + let input_type = py.get_type_bound::(); + let binding = input_type.call0().unwrap(); + let input = binding + .downcast::() .unwrap(); let _ = input.call_method1("add_pauliz_product", ("ro",)).unwrap(); let serialised = input.call_method0("to_json").unwrap(); let new_input = input; - let deserialised = new_input - .call_method1("from_json", (serialised,)) - .unwrap() - .downcast::>() + let binding = new_input.call_method1("from_json", (&serialised,)).unwrap(); + let deserialised = binding + .downcast::() .unwrap(); assert_eq!(format!("{:?}", input), format!("{:?}", deserialised)); let circs: Vec = vec![CircuitWrapper::new()]; - let br_type = py.get_type::(); - let br = br_type + let br_type = py.get_type_bound::(); + let binding = br_type .call1((Some(CircuitWrapper::new()), circs, input)) - .unwrap() - .downcast::>() .unwrap(); + let br = binding.downcast::().unwrap(); let new_br = br; let serialised = br.call_method0("to_json").unwrap(); - let deserialised = new_br - .call_method1("from_json", (serialised,)) - .unwrap() - .downcast::>() - .unwrap(); - assert_eq!(format!("{:?}", br), format!("{:?}", deserialised)); + let binding = new_br.call_method1("from_json", (&serialised,)).unwrap(); + let deserialised = binding.downcast::().unwrap(); + assert_eq!( + format!("{:?}", br.as_gil_ref()), + format!("{:?}", deserialised.as_gil_ref()) + ); let deserialised_error = new_br.call_method1("from_json", (serde_json::to_string("fails").unwrap(),)); @@ -486,11 +471,10 @@ fn test_to_from_json() { fn test_substitute_parameters() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let input_type = py.get_type::(); - let input = input_type - .call0() - .unwrap() - .downcast::>() + let input_type = py.get_type_bound::(); + let binding = input_type.call0().unwrap(); + let input = binding + .downcast::() .unwrap(); let _ = input.call_method1("add_pauliz_product", ("ro",)).unwrap(); @@ -498,20 +482,16 @@ fn test_substitute_parameters() { let mut circ1 = CircuitWrapper::new(); circ1.internal += roqoqo::operations::RotateX::new(0, "theta".into()); circs.push(circ1); - let br_type = py.get_type::(); - let br = br_type + let br_type = py.get_type_bound::(); + let binding = br_type .call1((Some(CircuitWrapper::new()), circs.clone(), input)) - .unwrap() - .downcast::>() .unwrap(); + let br = binding.downcast::().unwrap(); let mut map: HashMap = HashMap::::new(); map.insert("theta".to_string(), 0.0); - let br_sub = br - .call_method1("substitute_parameters", (map,)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = br.call_method1("substitute_parameters", (map,)).unwrap(); + let br_sub = binding.downcast::().unwrap(); let br_wrapper = br.extract::().unwrap(); let br_sub_wrapper = br_sub.extract::().unwrap(); @@ -524,11 +504,10 @@ fn test_substitute_parameters() { fn test_substitute_parameters_error() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let input_type = py.get_type::(); - let input = input_type - .call0() - .unwrap() - .downcast::>() + let input_type = py.get_type_bound::(); + let binding = input_type.call0().unwrap(); + let input = binding + .downcast::() .unwrap(); let _ = input.call_method1("add_pauliz_product", ("ro",)).unwrap(); @@ -536,12 +515,11 @@ fn test_substitute_parameters_error() { let mut circ1 = CircuitWrapper::new(); circ1.internal += roqoqo::operations::RotateX::new(0, "theta".into()); circs.push(circ1); - let br_type = py.get_type::(); - let br = br_type + let br_type = py.get_type_bound::(); + let binding = br_type .call1((Some(CircuitWrapper::new()), circs.clone(), input)) - .unwrap() - .downcast::>() .unwrap(); + let br = binding.downcast::().unwrap(); let map: HashMap = HashMap::::new(); let br_sub = br.call_method1("substitute_parameters", (map,)); @@ -553,11 +531,10 @@ fn test_substitute_parameters_error() { #[test] fn test_measurement_type() { Python::with_gil(|py| { - let input_type = py.get_type::(); - let input = input_type - .call0() - .unwrap() - .downcast::>() + let input_type = py.get_type_bound::(); + let binding = input_type.call0().unwrap(); + let input = binding + .downcast::() .unwrap(); let _ = input.call_method1("add_pauliz_product", ("ro",)).unwrap(); @@ -565,12 +542,11 @@ fn test_measurement_type() { let mut circ1 = CircuitWrapper::new(); circ1.internal += roqoqo::operations::RotateX::new(0, "theta".into()); circs.push(circ1); - let br_type = py.get_type::(); - let br = br_type + let br_type = py.get_type_bound::(); + let binding = br_type .call1((Some(CircuitWrapper::new()), circs.clone(), input)) - .unwrap() - .downcast::>() .unwrap(); + let br = binding.downcast::().unwrap(); let measurement_type = br.call_method0("measurement_type").unwrap(); assert_eq!(measurement_type.to_string(), "CheatedPauliZProduct"); @@ -581,11 +557,10 @@ fn test_measurement_type() { #[test] fn test_return_input() { Python::with_gil(|py| { - let input_type = py.get_type::(); - let input = input_type - .call0() - .unwrap() - .downcast::>() + let input_type = py.get_type_bound::(); + let binding = input_type.call0().unwrap(); + let input = binding + .downcast::() .unwrap(); let _ = input.call_method1("add_pauliz_product", ("ro",)).unwrap(); @@ -593,17 +568,15 @@ fn test_return_input() { let mut circ1 = CircuitWrapper::new(); circ1.internal += roqoqo::operations::RotateX::new(0, "theta".into()); circs.push(circ1); - let br_type = py.get_type::(); - let br = br_type + let br_type = py.get_type_bound::(); + let binding = br_type .call1((Some(CircuitWrapper::new()), circs.clone(), input)) - .unwrap() - .downcast::>() .unwrap(); + let br = binding.downcast::().unwrap(); - let input_returned = br - .call_method0("input") - .unwrap() - .downcast::>() + let binding = br.call_method0("input").unwrap(); + let input_returned = binding + .downcast::() .unwrap(); assert_eq!(format!("{:?}", input_returned), format!("{:?}", input)); @@ -615,25 +588,23 @@ fn test_pyo3_format_repr() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let format_repr = "CheatedPauliZProduct { constant_circuit: Some(Circuit { definitions: [], operations: [], _roqoqo_version: RoqoqoVersion }), circuits: [Circuit { definitions: [], operations: [], _roqoqo_version: RoqoqoVersion }], input: CheatedPauliZProductInput { measured_exp_vals: {}, pauli_product_keys: {\"ro\": 0} } }"; - let input_type = py.get_type::(); - let input = input_type - .call0() - .unwrap() - .downcast::>() + let input_type = py.get_type_bound::(); + let binding = input_type.call0().unwrap(); + let input = binding + .downcast::() .unwrap(); let _ = input.call_method1("add_pauliz_product", ("ro",)).unwrap(); let circs: Vec = vec![CircuitWrapper::new()]; - let br_type = py.get_type::(); - let br = br_type + let br_type = py.get_type_bound::(); + let binding = br_type .call1((Some(CircuitWrapper::new()), circs, input)) - .unwrap() - .downcast::>() .unwrap(); + let br = binding.downcast::().unwrap(); let to_format = br.call_method1("__format__", ("",)).unwrap(); - let format_op: &str = <&str>::extract(to_format).unwrap(); + let format_op: String = String::extract_bound(&to_format).unwrap(); let to_repr = br.call_method0("__repr__").unwrap(); - let repr_op: &str = <&str>::extract(to_repr).unwrap(); + let repr_op: String = String::extract_bound(&to_repr).unwrap(); assert_eq!(format_op, format_repr); assert_eq!(repr_op, format_repr); }) @@ -643,11 +614,10 @@ fn test_pyo3_format_repr() { fn test_pyo3_copy_deepcopy() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let input_type = py.get_type::(); - let input = input_type - .call0() - .unwrap() - .downcast::>() + let input_type = py.get_type_bound::(); + let binding = input_type.call0().unwrap(); + let input = binding + .downcast::() .unwrap(); let _ = input.call_method1("add_pauliz_product", ("ro",)).unwrap(); @@ -655,25 +625,24 @@ fn test_pyo3_copy_deepcopy() { let mut circ1 = CircuitWrapper::new(); circ1.internal += roqoqo::operations::RotateX::new(0, "theta".into()); circs.push(circ1); - let br_type = py.get_type::(); - let br = br_type + let br_type = py.get_type_bound::(); + let binding = br_type .call1((Some(CircuitWrapper::new()), circs.clone(), input)) - .unwrap() - .downcast::>() .unwrap(); + let br = binding.downcast::().unwrap(); let copy_op = br.call_method0("__copy__").unwrap(); let deepcopy_op = br.call_method1("__deepcopy__", ("",)).unwrap(); let copy_deepcopy_param = br; - let comparison_copy = bool::extract( - copy_op + let comparison_copy = bool::extract_bound( + ©_op .call_method1("__eq__", (copy_deepcopy_param,)) .unwrap(), ) .unwrap(); assert!(comparison_copy); - let comparison_deepcopy = bool::extract( - deepcopy_op + let comparison_deepcopy = bool::extract_bound( + &deepcopy_op .call_method1("__eq__", (copy_deepcopy_param,)) .unwrap(), ) @@ -686,11 +655,10 @@ fn test_pyo3_copy_deepcopy() { fn test_pyo3_richcmp() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let input_type = py.get_type::(); - let input = input_type - .call0() - .unwrap() - .downcast::>() + let input_type = py.get_type_bound::(); + let binding = input_type.call0().unwrap(); + let input = binding + .downcast::() .unwrap(); let _ = input.call_method1("add_pauliz_product", ("ro",)).unwrap(); @@ -698,22 +666,20 @@ fn test_pyo3_richcmp() { let mut circ1 = CircuitWrapper::new(); circ1.internal += roqoqo::operations::RotateX::new(0, "theta".into()); circs.push(circ1); - let br_type = py.get_type::(); - let br_one = br_type + let br_type = py.get_type_bound::(); + let binding = br_type .call1((Some(CircuitWrapper::new()), circs.clone(), input)) - .unwrap() - .downcast::>() .unwrap(); + let br_one = binding.downcast::().unwrap(); let arg: Option = None; - let br_two = br_type - .call1((arg, circs.clone(), input)) - .unwrap() - .downcast::>() - .unwrap(); - let comparison = bool::extract(br_one.call_method1("__eq__", (br_two,)).unwrap()).unwrap(); + let binding = br_type.call1((arg, circs.clone(), input)).unwrap(); + let br_two = binding.downcast::().unwrap(); + let comparison = + bool::extract_bound(&br_one.call_method1("__eq__", (br_two,)).unwrap()).unwrap(); assert!(!comparison); - let comparison = bool::extract(br_one.call_method1("__ne__", (br_two,)).unwrap()).unwrap(); + let comparison = + bool::extract_bound(&br_one.call_method1("__ne__", (br_two,)).unwrap()).unwrap(); assert!(comparison); let comparison = br_one.call_method1("__ge__", (br_two,)); @@ -731,11 +697,10 @@ fn test_pyo3_json_schema() { serde_json::to_string_pretty(&schemars::schema_for!(CheatedPauliZProduct)).unwrap(); pyo3::prepare_freethreaded_python(); pyo3::Python::with_gil(|py| { - let input_type = py.get_type::(); - let input = input_type - .call0() - .unwrap() - .downcast::>() + let input_type = py.get_type_bound::(); + let binding = input_type.call0().unwrap(); + let input = binding + .downcast::() .unwrap(); let _ = input.call_method1("add_pauliz_product", ("ro",)).unwrap(); @@ -743,28 +708,28 @@ fn test_pyo3_json_schema() { let mut circ1 = CircuitWrapper::new(); circ1.internal += roqoqo::operations::RotateX::new(0, "theta".into()); circs.push(circ1); - let br_type = py.get_type::(); - let br_one = br_type + let br_type = py.get_type_bound::(); + let binding = br_type .call1((Some(CircuitWrapper::new()), circs.clone(), input)) - .unwrap() - .downcast::>() .unwrap(); + let br_one = binding.downcast::().unwrap(); let schema_input: String = - String::extract(input.call_method0("json_schema").unwrap()).unwrap(); - let schema: String = String::extract(br_one.call_method0("json_schema").unwrap()).unwrap(); + String::extract_bound(&input.call_method0("json_schema").unwrap()).unwrap(); + let schema: String = + String::extract_bound(&br_one.call_method0("json_schema").unwrap()).unwrap(); assert_eq!(schema_input, rust_schema_input); assert_eq!(schema, rust_schema); let current_version_string_input = - String::extract(input.call_method0("current_version").unwrap()).unwrap(); + String::extract_bound(&input.call_method0("current_version").unwrap()).unwrap(); let current_version_string = - String::extract(br_one.call_method0("current_version").unwrap()).unwrap(); + String::extract_bound(&br_one.call_method0("current_version").unwrap()).unwrap(); let minimum_supported_version_string_input = - String::extract(input.call_method0("min_supported_version").unwrap()).unwrap(); + String::extract_bound(&input.call_method0("min_supported_version").unwrap()).unwrap(); let minimum_supported_version_string = - String::extract(br_one.call_method0("min_supported_version").unwrap()).unwrap(); + String::extract_bound(&br_one.call_method0("min_supported_version").unwrap()).unwrap(); assert_eq!(current_version_string, ROQOQO_VERSION); assert_eq!(current_version_string_input, ROQOQO_VERSION); diff --git a/qoqo/tests/integration/measurements/cheated_measurement.rs b/qoqo/tests/integration/measurements/cheated_measurement.rs index ed681f63..abc5ed30 100644 --- a/qoqo/tests/integration/measurements/cheated_measurement.rs +++ b/qoqo/tests/integration/measurements/cheated_measurement.rs @@ -32,23 +32,19 @@ use test_case::test_case; fn test_returning_circuits() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let input_type = py.get_type::(); - let input = input_type - .call1((2,)) - .unwrap() - .downcast::>() - .unwrap(); + let input_type = py.get_type_bound::(); + let binding = input_type.call1((2,)).unwrap(); + let input = binding.downcast::().unwrap(); let mut circs: Vec = vec![CircuitWrapper::new()]; let mut circ1 = CircuitWrapper::new(); circ1.internal += roqoqo::operations::RotateX::new(0, 0.0.into()); circs.push(circ1); - let br_type = py.get_type::(); - let br = br_type + let br_type = py.get_type_bound::(); + let binding = br_type .call1((Some(CircuitWrapper::new()), circs.clone(), input)) - .unwrap() - .downcast::>() .unwrap(); + let br = binding.downcast::().unwrap(); let circuits: Vec = br.call_method0("circuits").unwrap().extract().unwrap(); for (index, b) in circuits.iter().enumerate() { @@ -77,12 +73,9 @@ fn test_py03_evaluate_bool( ) { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let input_type = py.get_type::(); - let input = input_type - .call1((1,)) - .unwrap() - .downcast::>() - .unwrap(); + let input_type = py.get_type_bound::(); + let binding = input_type.call1((1,)).unwrap(); + let input = binding.downcast::().unwrap(); let test_matrix = vec![ (0, 0, Complex64::new(1.0, 0.0)), (0, 1, Complex64::new(0.0, 0.0)), @@ -107,12 +100,11 @@ fn test_py03_evaluate_bool( let circs: Vec = vec![CircuitWrapper::new()]; - let br_type = py.get_type::(); - let br = br_type + let br_type = py.get_type_bound::(); + let binding = br_type .call1((Some(CircuitWrapper::new()), circs, input)) - .unwrap() - .downcast::>() .unwrap(); + let br = binding.downcast::().unwrap(); let mut measured_registers: HashMap = HashMap::new(); let _ = measured_registers.insert("ro".to_string(), register); @@ -126,9 +118,10 @@ fn test_py03_evaluate_bool( .call_method1("evaluate", (input1, input2, measured_registers)) .unwrap(); - let test_diagonal_py = f64::extract(result.get_item("test_diagonal").unwrap()).unwrap(); + let test_diagonal_py = + f64::extract_bound(&result.get_item("test_diagonal").unwrap()).unwrap(); let test_off_diagonal_py = - f64::extract(result.get_item("test_off_diagonal").unwrap()).unwrap(); + f64::extract_bound(&result.get_item("test_off_diagonal").unwrap()).unwrap(); assert!((test_diagonal_py - value_diagonal).abs() < 1e-10); assert!((test_off_diagonal_py - value_off_diagonal).abs() < 1e-10); @@ -146,12 +139,9 @@ fn test_py03_evaluate_error0() { Complex64::new(0.0, 0.0), ]]; - let input_type = py.get_type::(); - let input = input_type - .call1((3,)) - .unwrap() - .downcast::>() - .unwrap(); + let input_type = py.get_type_bound::(); + let binding = input_type.call1((3,)).unwrap(); + let input = binding.downcast::().unwrap(); let test_matrix = vec![ (0, 0, Complex64::new(1.0, 0.0)), (0, 1, Complex64::new(0.0, 0.0)), @@ -176,12 +166,11 @@ fn test_py03_evaluate_error0() { let circs: Vec = vec![CircuitWrapper::new()]; - let br_type = py.get_type::(); - let br = br_type + let br_type = py.get_type_bound::(); + let binding = br_type .call1((Some(CircuitWrapper::new()), circs, input)) - .unwrap() - .downcast::>() .unwrap(); + let br = binding.downcast::().unwrap(); let mut measured_registers: HashMap = HashMap::new(); let _ = measured_registers.insert("ro".to_string(), register); @@ -209,12 +198,9 @@ fn test_py03_evaluate_error0() { fn test_pyo3_copy() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let input_type = py.get_type::(); - let input = input_type - .call1((3,)) - .unwrap() - .downcast::>() - .unwrap(); + let input_type = py.get_type_bound::(); + let binding = input_type.call1((3,)).unwrap(); + let input = binding.downcast::().unwrap(); let test_matrix = vec![ (0, 0, Complex64::new(1.0, 0.0)), (0, 1, Complex64::new(0.0, 0.0)), @@ -229,12 +215,11 @@ fn test_pyo3_copy() { let mut circ1 = CircuitWrapper::new(); circ1.internal += roqoqo::operations::RotateX::new(0, 0.0.into()); circs.push(circ1); - let br_type = py.get_type::(); - let br = br_type + let br_type = py.get_type_bound::(); + let binding = br_type .call1((Some(CircuitWrapper::new()), circs.clone(), input)) - .unwrap() - .downcast::>() .unwrap(); + let br = binding.downcast::().unwrap(); let br_clone = br; let circuits: Vec = br.call_method0("circuits").unwrap().extract().unwrap(); @@ -264,12 +249,9 @@ fn test_pyo3_copy() { fn test_pyo3_debug() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let input_type = py.get_type::(); - let input = input_type - .call1((3,)) - .unwrap() - .downcast::>() - .unwrap(); + let input_type = py.get_type_bound::(); + let binding = input_type.call1((3,)).unwrap(); + let input = binding.downcast::().unwrap(); let test_matrix = vec![ (0, 0, Complex64::new(1.0, 0.0)), (0, 1, Complex64::new(0.0, 0.0)), @@ -282,12 +264,11 @@ fn test_pyo3_debug() { let circs: Vec = vec![CircuitWrapper::new()]; - let br_type = py.get_type::(); - let br = br_type + let br_type = py.get_type_bound::(); + let binding = br_type .call1((Some(CircuitWrapper::new()), circs, input)) - .unwrap() - .downcast::>() .unwrap(); + let br = binding.downcast::().unwrap(); let br_wrapper = br.extract::().unwrap(); #[allow(clippy::redundant_clone)] @@ -295,10 +276,10 @@ fn test_pyo3_debug() { assert_eq!(format!("{:?}", br_wrapper), format!("{:?}", br_clone)); let debug_string = "RefCell { value: CheatedWrapper { internal: Cheated { constant_circuit: Some(Circuit { definitions: [], operations: [], _roqoqo_version: RoqoqoVersion }), circuits: [Circuit { definitions: [], operations: [], _roqoqo_version: RoqoqoVersion }], input: CheatedInput { measured_operators: {\"test_diagonal\": ([(0, 0, Complex { re: 1.0, im: 0.0 }), (0, 1, Complex { re: 0.0, im: 0.0 }), (1, 0, Complex { re: 0.0, im: 0.0 }), (1, 1, Complex { re: -1.0, im: 0.0 })], \"ro\")}, number_qubits: 3 } } } }"; - assert_eq!(format!("{:?}", br), debug_string); + assert_eq!(format!("{:?}", br.as_gil_ref()), debug_string); let debug_input_string = "RefCell { value: CheatedInputWrapper { internal: CheatedInput { measured_operators: {\"test_diagonal\": ([(0, 0, Complex { re: 1.0, im: 0.0 }), (0, 1, Complex { re: 0.0, im: 0.0 }), (1, 0, Complex { re: 0.0, im: 0.0 }), (1, 1, Complex { re: -1.0, im: 0.0 })], \"ro\")}, number_qubits: 3 } } }"; - assert_eq!(format!("{:?}", input), debug_input_string); + assert_eq!(format!("{:?}", input.as_gil_ref()), debug_input_string); let debug_input = input; let error = debug_input.call_method1( @@ -318,12 +299,9 @@ fn test_pyo3_debug() { fn test_internal_to_bincode() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let input_type = py.get_type::(); - let input = input_type - .call1((3,)) - .unwrap() - .downcast::>() - .unwrap(); + let input_type = py.get_type_bound::(); + let binding = input_type.call1((3,)).unwrap(); + let input = binding.downcast::().unwrap(); let test_matrix = vec![ (0, 0, Complex64::new(1.0, 0.0)), (0, 1, Complex64::new(0.0, 0.0)), @@ -339,12 +317,11 @@ fn test_internal_to_bincode() { let circs: Vec = vec![CircuitWrapper::new()]; - let br_type = py.get_type::(); - let br = br_type + let br_type = py.get_type_bound::(); + let binding = br_type .call1((Some(CircuitWrapper::new()), circs, input)) - .unwrap() - .downcast::>() .unwrap(); + let br = binding.downcast::().unwrap(); let mut roqoqo_bri = CheatedInput::new(3); roqoqo_bri @@ -358,7 +335,7 @@ fn test_internal_to_bincode() { }; let comparison_serialised = serialize(&roqoqo_br).unwrap(); - let serialised: (&str, Vec) = br + let serialised: (String, Vec) = br .call_method0("_internal_to_bincode") .unwrap() .extract() @@ -373,12 +350,9 @@ fn test_internal_to_bincode() { fn test_to_from_bincode() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let input_type = py.get_type::(); - let input = input_type - .call1((3,)) - .unwrap() - .downcast::>() - .unwrap(); + let input_type = py.get_type_bound::(); + let binding = input_type.call1((3,)).unwrap(); + let input = binding.downcast::().unwrap(); let test_matrix = vec![ (0, 0, Complex64::new(1.0, 0.0)), (0, 1, Complex64::new(0.0, 0.0)), @@ -391,31 +365,29 @@ fn test_to_from_bincode() { let serialised = input.call_method0("to_bincode").unwrap(); let new_input = input; - let deserialised = new_input - .call_method1("from_bincode", (serialised,)) - .unwrap() - .downcast::>() + let binding = new_input + .call_method1("from_bincode", (&serialised,)) .unwrap(); + let deserialised = binding.downcast::().unwrap(); assert_eq!(format!("{:?}", input), format!("{:?}", deserialised)); let circs: Vec = vec![CircuitWrapper::new()]; - let br_type = py.get_type::(); - let br = br_type + let br_type = py.get_type_bound::(); + let binding = br_type .call1((Some(CircuitWrapper::new()), circs, input)) - .unwrap() - .downcast::>() .unwrap(); + let br = binding.downcast::().unwrap(); let new_br = br; let serialised = br.call_method0("to_bincode").unwrap(); - let deserialised = new_br - .call_method1("from_bincode", (serialised,)) - .unwrap() - .downcast::>() - .unwrap(); - assert_eq!(format!("{:?}", br), format!("{:?}", deserialised)); + let binding = new_br.call_method1("from_bincode", (&serialised,)).unwrap(); + let deserialised = binding.downcast::().unwrap(); + assert_eq!( + format!("{:?}", br.as_gil_ref()), + format!("{:?}", deserialised.as_gil_ref()) + ); let deserialised_error = new_br.call_method1("from_bincode", (bincode::serialize("fails").unwrap(),)); @@ -435,12 +407,9 @@ fn test_to_from_bincode() { fn test_to_from_json() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let input_type = py.get_type::(); - let input = input_type - .call1((3,)) - .unwrap() - .downcast::>() - .unwrap(); + let input_type = py.get_type_bound::(); + let binding = input_type.call1((3,)).unwrap(); + let input = binding.downcast::().unwrap(); let test_matrix = vec![ (0, 0, Complex64::new(1.0, 0.0)), (0, 1, Complex64::new(0.0, 0.0)), @@ -453,30 +422,26 @@ fn test_to_from_json() { let serialised = input.call_method0("to_json").unwrap(); let new_input = input; - let deserialised = new_input - .call_method1("from_json", (serialised,)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = new_input.call_method1("from_json", (&serialised,)).unwrap(); + let deserialised = binding.downcast::().unwrap(); assert_eq!(format!("{:?}", input), format!("{:?}", deserialised)); let circs: Vec = vec![CircuitWrapper::new()]; - let br_type = py.get_type::(); - let br = br_type + let br_type = py.get_type_bound::(); + let binding = br_type .call1((Some(CircuitWrapper::new()), circs, input)) - .unwrap() - .downcast::>() .unwrap(); + let br = binding.downcast::().unwrap(); let new_br = br; let serialised = br.call_method0("to_json").unwrap(); - let deserialised = new_br - .call_method1("from_json", (serialised,)) - .unwrap() - .downcast::>() - .unwrap(); - assert_eq!(format!("{:?}", br), format!("{:?}", deserialised)); + let binding = new_br.call_method1("from_json", (&serialised,)).unwrap(); + let deserialised = binding.downcast::().unwrap(); + assert_eq!( + format!("{:?}", br.as_gil_ref()), + format!("{:?}", deserialised.as_gil_ref()) + ); let deserialised_error = new_br.call_method1("from_json", (serde_json::to_string("fails").unwrap(),)); @@ -496,12 +461,9 @@ fn test_to_from_json() { fn test_substitute_parameters() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let input_type = py.get_type::(); - let input = input_type - .call1((3,)) - .unwrap() - .downcast::>() - .unwrap(); + let input_type = py.get_type_bound::(); + let binding = input_type.call1((3,)).unwrap(); + let input = binding.downcast::().unwrap(); let test_matrix = vec![ (0, 0, Complex64::new(1.0, 0.0)), (0, 1, Complex64::new(0.0, 0.0)), @@ -516,20 +478,16 @@ fn test_substitute_parameters() { let mut circ1 = CircuitWrapper::new(); circ1.internal += roqoqo::operations::RotateX::new(0, "theta".into()); circs.push(circ1); - let br_type = py.get_type::(); - let br = br_type + let br_type = py.get_type_bound::(); + let binding = br_type .call1((Some(CircuitWrapper::new()), circs.clone(), input)) - .unwrap() - .downcast::>() .unwrap(); + let br = binding.downcast::().unwrap(); let mut map: HashMap = HashMap::::new(); map.insert("theta".to_string(), 0.0); - let br_sub = br - .call_method1("substitute_parameters", (map,)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = br.call_method1("substitute_parameters", (map,)).unwrap(); + let br_sub = binding.downcast::().unwrap(); let br_wrapper = br.extract::().unwrap(); let br_sub_wrapper = br_sub.extract::().unwrap(); @@ -542,12 +500,9 @@ fn test_substitute_parameters() { fn test_substitute_parameters_error() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let input_type = py.get_type::(); - let input = input_type - .call1((3,)) - .unwrap() - .downcast::>() - .unwrap(); + let input_type = py.get_type_bound::(); + let binding = input_type.call1((3,)).unwrap(); + let input = binding.downcast::().unwrap(); let test_matrix = vec![ (0, 0, Complex64::new(1.0, 0.0)), (0, 1, Complex64::new(0.0, 0.0)), @@ -562,12 +517,11 @@ fn test_substitute_parameters_error() { let mut circ1 = CircuitWrapper::new(); circ1.internal += roqoqo::operations::RotateX::new(0, "theta".into()); circs.push(circ1); - let br_type = py.get_type::(); - let br = br_type + let br_type = py.get_type_bound::(); + let binding = br_type .call1((Some(CircuitWrapper::new()), circs.clone(), input)) - .unwrap() - .downcast::>() .unwrap(); + let br = binding.downcast::().unwrap(); let map: HashMap = HashMap::::new(); let br_sub = br.call_method1("substitute_parameters", (map,)); @@ -579,12 +533,9 @@ fn test_substitute_parameters_error() { #[test] fn test_measurement_type() { Python::with_gil(|py| { - let input_type = py.get_type::(); - let input = input_type - .call1((3,)) - .unwrap() - .downcast::>() - .unwrap(); + let input_type = py.get_type_bound::(); + let binding = input_type.call1((3,)).unwrap(); + let input = binding.downcast::().unwrap(); let test_matrix = vec![ (0, 0, Complex64::new(1.0, 0.0)), (0, 1, Complex64::new(0.0, 0.0)), @@ -599,12 +550,11 @@ fn test_measurement_type() { let mut circ1 = CircuitWrapper::new(); circ1.internal += roqoqo::operations::RotateX::new(0, "theta".into()); circs.push(circ1); - let br_type = py.get_type::(); - let br = br_type + let br_type = py.get_type_bound::(); + let binding = br_type .call1((Some(CircuitWrapper::new()), circs.clone(), input)) - .unwrap() - .downcast::>() .unwrap(); + let br = binding.downcast::().unwrap(); let measurement_type = br.call_method0("measurement_type").unwrap(); assert_eq!(measurement_type.to_string(), "Cheated"); @@ -615,12 +565,9 @@ fn test_measurement_type() { #[test] fn test_return_input() { Python::with_gil(|py| { - let input_type = py.get_type::(); - let input = input_type - .call1((3,)) - .unwrap() - .downcast::>() - .unwrap(); + let input_type = py.get_type_bound::(); + let binding = input_type.call1((3,)).unwrap(); + let input = binding.downcast::().unwrap(); let test_matrix = vec![ (0, 0, Complex64::new(1.0, 0.0)), (0, 1, Complex64::new(0.0, 0.0)), @@ -635,18 +582,14 @@ fn test_return_input() { let mut circ1 = CircuitWrapper::new(); circ1.internal += roqoqo::operations::RotateX::new(0, "theta".into()); circs.push(circ1); - let br_type = py.get_type::(); - let br = br_type + let br_type = py.get_type_bound::(); + let binding = br_type .call1((Some(CircuitWrapper::new()), circs.clone(), input)) - .unwrap() - .downcast::>() .unwrap(); + let br = binding.downcast::().unwrap(); - let input_returned = br - .call_method0("input") - .unwrap() - .downcast::>() - .unwrap(); + let binding = br.call_method0("input").unwrap(); + let input_returned = binding.downcast::().unwrap(); assert_eq!(format!("{:?}", input_returned), format!("{:?}", input)); }) @@ -657,12 +600,9 @@ fn test_pyo3_format_repr() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let format_repr = "Cheated { constant_circuit: Some(Circuit { definitions: [], operations: [], _roqoqo_version: RoqoqoVersion }), circuits: [Circuit { definitions: [], operations: [], _roqoqo_version: RoqoqoVersion }], input: CheatedInput { measured_operators: {\"test_diagonal\": ([(0, 0, Complex { re: 1.0, im: 0.0 }), (0, 1, Complex { re: 0.0, im: 0.0 }), (1, 0, Complex { re: 0.0, im: 0.0 }), (1, 1, Complex { re: -1.0, im: 0.0 })], \"ro\")}, number_qubits: 3 } }"; - let input_type = py.get_type::(); - let input = input_type - .call1((3,)) - .unwrap() - .downcast::>() - .unwrap(); + let input_type = py.get_type_bound::(); + let binding = input_type.call1((3,)).unwrap(); + let input = binding.downcast::().unwrap(); let test_matrix = vec![ (0, 0, Complex64::new(1.0, 0.0)), (0, 1, Complex64::new(0.0, 0.0)), @@ -675,16 +615,15 @@ fn test_pyo3_format_repr() { let circs: Vec = vec![CircuitWrapper::new()]; - let br_type = py.get_type::(); - let br = br_type + let br_type = py.get_type_bound::(); + let binding = br_type .call1((Some(CircuitWrapper::new()), circs, input)) - .unwrap() - .downcast::>() .unwrap(); + let br = binding.downcast::().unwrap(); let to_format = br.call_method1("__format__", ("",)).unwrap(); - let format_op: &str = <&str>::extract(to_format).unwrap(); + let format_op: String = String::extract_bound(&to_format).unwrap(); let to_repr = br.call_method0("__repr__").unwrap(); - let repr_op: &str = <&str>::extract(to_repr).unwrap(); + let repr_op: String = String::extract_bound(&to_repr).unwrap(); assert_eq!(format_op, format_repr); assert_eq!(repr_op, format_repr); }) @@ -694,12 +633,9 @@ fn test_pyo3_format_repr() { fn test_pyo3_copy_deepcopy() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let input_type = py.get_type::(); - let input = input_type - .call1((3,)) - .unwrap() - .downcast::>() - .unwrap(); + let input_type = py.get_type_bound::(); + let binding = input_type.call1((3,)).unwrap(); + let input = binding.downcast::().unwrap(); let test_matrix = vec![ (0, 0, Complex64::new(1.0, 0.0)), (0, 1, Complex64::new(0.0, 0.0)), @@ -712,25 +648,24 @@ fn test_pyo3_copy_deepcopy() { let circs: Vec = vec![CircuitWrapper::new()]; - let br_type = py.get_type::(); - let br = br_type + let br_type = py.get_type_bound::(); + let binding = br_type .call1((Some(CircuitWrapper::new()), circs, input)) - .unwrap() - .downcast::>() .unwrap(); + let br = binding.downcast::().unwrap(); let copy_op = br.call_method0("__copy__").unwrap(); let deepcopy_op = br.call_method1("__deepcopy__", ("",)).unwrap(); let copy_deepcopy_param = br; - let comparison_copy = bool::extract( - copy_op + let comparison_copy = bool::extract_bound( + ©_op .call_method1("__eq__", (copy_deepcopy_param,)) .unwrap(), ) .unwrap(); assert!(comparison_copy); - let comparison_deepcopy = bool::extract( - deepcopy_op + let comparison_deepcopy = bool::extract_bound( + &deepcopy_op .call_method1("__eq__", (copy_deepcopy_param,)) .unwrap(), ) @@ -743,12 +678,9 @@ fn test_pyo3_copy_deepcopy() { fn test_pyo3_richcmp() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let input_type = py.get_type::(); - let input = input_type - .call1((3,)) - .unwrap() - .downcast::>() - .unwrap(); + let input_type = py.get_type_bound::(); + let binding = input_type.call1((3,)).unwrap(); + let input = binding.downcast::().unwrap(); let test_matrix = vec![ (0, 0, Complex64::new(1.0, 0.0)), (0, 1, Complex64::new(0.0, 0.0)), @@ -761,22 +693,20 @@ fn test_pyo3_richcmp() { let circs: Vec = vec![CircuitWrapper::new()]; - let br_type = py.get_type::(); - let br_one = br_type + let br_type = py.get_type_bound::(); + let binding = br_type .call1((Some(CircuitWrapper::new()), circs.clone(), input)) - .unwrap() - .downcast::>() .unwrap(); + let br_one = binding.downcast::().unwrap(); let arg: Option = None; - let br_two = br_type - .call1((arg, circs, input)) - .unwrap() - .downcast::>() - .unwrap(); - let comparison = bool::extract(br_one.call_method1("__eq__", (br_two,)).unwrap()).unwrap(); + let binding = br_type.call1((arg, circs, input)).unwrap(); + let br_two = binding.downcast::().unwrap(); + let comparison = + bool::extract_bound(&br_one.call_method1("__eq__", (br_two,)).unwrap()).unwrap(); assert!(!comparison); - let comparison = bool::extract(br_one.call_method1("__ne__", (br_two,)).unwrap()).unwrap(); + let comparison = + bool::extract_bound(&br_one.call_method1("__ne__", (br_two,)).unwrap()).unwrap(); assert!(comparison); let comparison = br_one.call_method1("__ge__", (br_two,)); @@ -793,12 +723,9 @@ fn test_pyo3_json_schema() { let rust_schema = serde_json::to_string_pretty(&schemars::schema_for!(Cheated)).unwrap(); pyo3::prepare_freethreaded_python(); pyo3::Python::with_gil(|py| { - let input_type = py.get_type::(); - let input = input_type - .call1((3,)) - .unwrap() - .downcast::>() - .unwrap(); + let input_type = py.get_type_bound::(); + let binding = input_type.call1((3,)).unwrap(); + let input = binding.downcast::().unwrap(); let test_matrix = vec![ (0, 0, Complex64::new(1.0, 0.0)), (0, 1, Complex64::new(0.0, 0.0)), @@ -811,29 +738,29 @@ fn test_pyo3_json_schema() { let circs: Vec = vec![CircuitWrapper::new()]; - let br_type = py.get_type::(); + let br_type = py.get_type_bound::(); #[allow(clippy::redundant_clone)] - let br_one = br_type + let binding = br_type .call1((Some(CircuitWrapper::new()), circs.clone(), input)) - .unwrap() - .downcast::>() .unwrap(); + let br_one = binding.downcast::().unwrap(); let schema_input: String = - String::extract(input.call_method0("json_schema").unwrap()).unwrap(); - let schema: String = String::extract(br_one.call_method0("json_schema").unwrap()).unwrap(); + String::extract_bound(&input.call_method0("json_schema").unwrap()).unwrap(); + let schema: String = + String::extract_bound(&br_one.call_method0("json_schema").unwrap()).unwrap(); assert_eq!(schema_input, rust_schema_input); assert_eq!(schema, rust_schema); let current_version_string_input = - String::extract(input.call_method0("current_version").unwrap()).unwrap(); + String::extract_bound(&input.call_method0("current_version").unwrap()).unwrap(); let current_version_string = - String::extract(br_one.call_method0("current_version").unwrap()).unwrap(); + String::extract_bound(&br_one.call_method0("current_version").unwrap()).unwrap(); let minimum_supported_version_string_input = - String::extract(input.call_method0("min_supported_version").unwrap()).unwrap(); + String::extract_bound(&input.call_method0("min_supported_version").unwrap()).unwrap(); let minimum_supported_version_string = - String::extract(br_one.call_method0("min_supported_version").unwrap()).unwrap(); + String::extract_bound(&br_one.call_method0("min_supported_version").unwrap()).unwrap(); assert_eq!(current_version_string, ROQOQO_VERSION); assert_eq!(current_version_string_input, ROQOQO_VERSION); diff --git a/qoqo/tests/integration/measurements/classical_register_measurement.rs b/qoqo/tests/integration/measurements/classical_register_measurement.rs index 4e27ce27..0120a3b1 100644 --- a/qoqo/tests/integration/measurements/classical_register_measurement.rs +++ b/qoqo/tests/integration/measurements/classical_register_measurement.rs @@ -30,12 +30,11 @@ fn test_returning_circuits() { let mut circ1 = CircuitWrapper::new(); circ1.internal += roqoqo::operations::RotateX::new(0, 0.0.into()); circs.push(circ1); - let br_type = py.get_type::(); - let br = br_type + let br_type = py.get_type_bound::(); + let binding = br_type .call1((Some(CircuitWrapper::new()), circs.clone())) - .unwrap() - .downcast::>() .unwrap(); + let br = binding.downcast::().unwrap(); let circuits: Vec = br.call_method0("circuits").unwrap().extract().unwrap(); for (index, b) in circuits.iter().enumerate() { @@ -59,12 +58,11 @@ fn test_pyo3_copy() { let mut circ1 = CircuitWrapper::new(); circ1.internal += roqoqo::operations::RotateX::new(0, 0.0.into()); circs.push(circ1); - let br_type = py.get_type::(); - let br = br_type + let br_type = py.get_type_bound::(); + let binding = br_type .call1((Some(CircuitWrapper::new()), circs.clone())) - .unwrap() - .downcast::>() .unwrap(); + let br = binding.downcast::().unwrap(); let br_clone = br; let circuits: Vec = br.call_method0("circuits").unwrap().extract().unwrap(); @@ -96,20 +94,16 @@ fn test_pyo3_debug() { Python::with_gil(|py| { let circs: Vec = vec![CircuitWrapper::new()]; - let br_type = py.get_type::(); - let br = br_type - .call1((Some(CircuitWrapper::new()), circs)) - .unwrap() - .downcast::>() - .unwrap(); + let br_type = py.get_type_bound::(); + let binding = br_type.call1((Some(CircuitWrapper::new()), circs)).unwrap(); + let br = binding.downcast::().unwrap(); let br_wrapper = br.extract::().unwrap(); #[allow(clippy::redundant_clone)] let br_clone = br_wrapper.clone(); assert_eq!(format!("{:?}", br_wrapper), format!("{:?}", br_clone)); - let debug_string = "RefCell { value: ClassicalRegisterWrapper { internal: ClassicalRegister { constant_circuit: Some(Circuit { definitions: [], operations: [], _roqoqo_version: RoqoqoVersion }), circuits: [Circuit { definitions: [], operations: [], _roqoqo_version: RoqoqoVersion }] } } }"; - assert_eq!(format!("{:?}", br), debug_string); + assert_eq!(format!("{:?}", br.as_gil_ref()), debug_string); }) } @@ -120,12 +114,9 @@ fn test_internal_to_bincode() { Python::with_gil(|py| { let circs: Vec = vec![CircuitWrapper::new()]; - let br_type = py.get_type::(); - let br = br_type - .call1((Some(CircuitWrapper::new()), circs)) - .unwrap() - .downcast::>() - .unwrap(); + let br_type = py.get_type_bound::(); + let binding = br_type.call1((Some(CircuitWrapper::new()), circs)).unwrap(); + let br = binding.downcast::().unwrap(); let circs: Vec = vec![Circuit::new()]; let roqoqo_br = ClassicalRegister { @@ -134,7 +125,7 @@ fn test_internal_to_bincode() { }; let comparison_serialised = serialize(&roqoqo_br).unwrap(); - let serialised: (&str, Vec) = br + let serialised: (String, Vec) = br .call_method0("_internal_to_bincode") .unwrap() .extract() @@ -151,21 +142,18 @@ fn test_to_from_json() { Python::with_gil(|py| { let circs: Vec = vec![CircuitWrapper::new()]; - let br_type = py.get_type::(); - let br = br_type - .call1((Some(CircuitWrapper::new()), circs)) - .unwrap() - .downcast::>() - .unwrap(); + let br_type = py.get_type_bound::(); + let binding = br_type.call1((Some(CircuitWrapper::new()), circs)).unwrap(); + let br = binding.downcast::().unwrap(); let new_br = br; let serialised = br.call_method0("to_json").unwrap(); - let deserialised = new_br - .call_method1("from_json", (serialised,)) - .unwrap() - .downcast::>() - .unwrap(); - assert_eq!(format!("{:?}", br), format!("{:?}", deserialised)); + let binding = new_br.call_method1("from_json", (&serialised,)).unwrap(); + let deserialised = binding.downcast::().unwrap(); + assert_eq!( + format!("{:?}", br.as_gil_ref()), + format!("{:?}", deserialised.as_gil_ref()) + ); let deserialised_error = new_br.call_method1("from_json", (serde_json::to_string("fails").unwrap(),)); @@ -187,21 +175,18 @@ fn test_to_from_bincode() { Python::with_gil(|py| { let circs: Vec = vec![CircuitWrapper::new()]; - let br_type = py.get_type::(); - let br = br_type - .call1((Some(CircuitWrapper::new()), circs)) - .unwrap() - .downcast::>() - .unwrap(); + let br_type = py.get_type_bound::(); + let binding = br_type.call1((Some(CircuitWrapper::new()), circs)).unwrap(); + let br = binding.downcast::().unwrap(); let new_br = br; let serialised = br.call_method0("to_bincode").unwrap(); - let deserialised = new_br - .call_method1("from_bincode", (serialised,)) - .unwrap() - .downcast::>() - .unwrap(); - assert_eq!(format!("{:?}", br), format!("{:?}", deserialised)); + let binding = new_br.call_method1("from_bincode", (&serialised,)).unwrap(); + let deserialised = binding.downcast::().unwrap(); + assert_eq!( + format!("{:?}", br.as_gil_ref()), + format!("{:?}", deserialised.as_gil_ref()) + ); let deserialised_error = new_br.call_method1("from_bincode", (bincode::serialize("fails").unwrap(),)); @@ -224,20 +209,16 @@ fn test_substitute_parameters() { let mut circ1 = CircuitWrapper::new(); circ1.internal += roqoqo::operations::RotateX::new(0, "theta".into()); circs.push(circ1); - let br_type = py.get_type::(); - let br = br_type + let br_type = py.get_type_bound::(); + let binding = br_type .call1((Some(CircuitWrapper::new()), circs.clone())) - .unwrap() - .downcast::>() .unwrap(); + let br = binding.downcast::().unwrap(); let mut map: HashMap = HashMap::::new(); map.insert("theta".to_string(), 0.0); - let br_sub = br - .call_method1("substitute_parameters", (map,)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = br.call_method1("substitute_parameters", (map,)).unwrap(); + let br_sub = binding.downcast::().unwrap(); let br_wrapper = br.extract::().unwrap(); let br_sub_wrapper = br_sub.extract::().unwrap(); @@ -254,12 +235,11 @@ fn test_substitute_parameters_error() { let mut circ1 = CircuitWrapper::new(); circ1.internal += roqoqo::operations::RotateX::new(0, "theta".into()); circs.push(circ1); - let br_type = py.get_type::(); - let br = br_type + let br_type = py.get_type_bound::(); + let binding = br_type .call1((Some(CircuitWrapper::new()), circs.clone())) - .unwrap() - .downcast::>() .unwrap(); + let br = binding.downcast::().unwrap(); let map: HashMap = HashMap::::new(); let br_sub = br.call_method1("substitute_parameters", (map,)); @@ -275,12 +255,11 @@ fn test_measurement_type() { let mut circ1 = CircuitWrapper::new(); circ1.internal += roqoqo::operations::RotateX::new(0, "theta".into()); circs.push(circ1); - let br_type = py.get_type::(); - let br = br_type + let br_type = py.get_type_bound::(); + let binding = br_type .call1((Some(CircuitWrapper::new()), circs.clone())) - .unwrap() - .downcast::>() .unwrap(); + let br = binding.downcast::().unwrap(); let measurement_type = br.call_method0("measurement_type").unwrap(); assert_eq!(measurement_type.to_string(), "ClassicalRegister"); @@ -293,16 +272,13 @@ fn test_pyo3_format_repr() { Python::with_gil(|py| { let format_repr = "ClassicalRegister { constant_circuit: Some(Circuit { definitions: [], operations: [], _roqoqo_version: RoqoqoVersion }), circuits: [Circuit { definitions: [], operations: [], _roqoqo_version: RoqoqoVersion }] }"; let circs: Vec = vec![CircuitWrapper::new()]; - let br_type = py.get_type::(); - let br = br_type - .call1((Some(CircuitWrapper::new()), circs)) - .unwrap() - .downcast::>() - .unwrap(); + let br_type = py.get_type_bound::(); + let binding = br_type.call1((Some(CircuitWrapper::new()), circs)).unwrap(); + let br = binding.downcast::().unwrap(); let to_format = br.call_method1("__format__", ("",)).unwrap(); - let format_op: &str = <&str>::extract(to_format).unwrap(); + let format_op: String = String::extract_bound(&to_format).unwrap(); let to_repr = br.call_method0("__repr__").unwrap(); - let repr_op: &str = <&str>::extract(to_repr).unwrap(); + let repr_op: String = String::extract_bound(&to_repr).unwrap(); assert_eq!(format_op, format_repr); assert_eq!(repr_op, format_repr); }) @@ -313,25 +289,22 @@ fn test_pyo3_copy_deepcopy() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let circs: Vec = vec![CircuitWrapper::new()]; - let br_type = py.get_type::(); - let br = br_type - .call1((Some(CircuitWrapper::new()), circs)) - .unwrap() - .downcast::>() - .unwrap(); + let br_type = py.get_type_bound::(); + let binding = br_type.call1((Some(CircuitWrapper::new()), circs)).unwrap(); + let br = binding.downcast::().unwrap(); let copy_op = br.call_method0("__copy__").unwrap(); let deepcopy_op = br.call_method1("__deepcopy__", ("",)).unwrap(); let copy_deepcopy_param = br; - let comparison_copy = bool::extract( - copy_op + let comparison_copy = bool::extract_bound( + ©_op .call_method1("__eq__", (copy_deepcopy_param,)) .unwrap(), ) .unwrap(); assert!(comparison_copy); - let comparison_deepcopy = bool::extract( - deepcopy_op + let comparison_deepcopy = bool::extract_bound( + &deepcopy_op .call_method1("__eq__", (copy_deepcopy_param,)) .unwrap(), ) @@ -345,22 +318,20 @@ fn test_pyo3_richcmp() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let circs: Vec = vec![CircuitWrapper::new()]; - let br_type = py.get_type::(); - let br_one = br_type + let br_type = py.get_type_bound::(); + let binding = br_type .call1((Some(CircuitWrapper::new()), circs.clone())) - .unwrap() - .downcast::>() .unwrap(); + let br_one = binding.downcast::().unwrap(); let arg: Option = None; - let br_two = br_type - .call1((arg, circs)) - .unwrap() - .downcast::>() - .unwrap(); - let comparison = bool::extract(br_one.call_method1("__eq__", (br_two,)).unwrap()).unwrap(); + let binding = br_type.call1((arg, circs)).unwrap(); + let br_two = binding.downcast::().unwrap(); + let comparison = + bool::extract_bound(&br_one.call_method1("__eq__", (br_two,)).unwrap()).unwrap(); assert!(!comparison); - let comparison = bool::extract(br_one.call_method1("__ne__", (br_two,)).unwrap()).unwrap(); + let comparison = + bool::extract_bound(&br_one.call_method1("__ne__", (br_two,)).unwrap()).unwrap(); assert!(comparison); let comparison = br_one.call_method1("__ge__", (br_two,)); @@ -377,22 +348,22 @@ fn test_pyo3_json_schema() { pyo3::prepare_freethreaded_python(); pyo3::Python::with_gil(|py| { let circs: Vec = vec![CircuitWrapper::new()]; - let br_type = py.get_type::(); + let br_type = py.get_type_bound::(); #[allow(clippy::redundant_clone)] - let br_one = br_type + let binding = br_type .call1((Some(CircuitWrapper::new()), circs.clone())) - .unwrap() - .downcast::>() .unwrap(); + let br_one = binding.downcast::().unwrap(); - let schema: String = String::extract(br_one.call_method0("json_schema").unwrap()).unwrap(); + let schema: String = + String::extract_bound(&br_one.call_method0("json_schema").unwrap()).unwrap(); assert_eq!(schema, rust_schema); let current_version_string = - String::extract(br_one.call_method0("current_version").unwrap()).unwrap(); + String::extract_bound(&br_one.call_method0("current_version").unwrap()).unwrap(); let minimum_supported_version_string = - String::extract(br_one.call_method0("min_supported_version").unwrap()).unwrap(); + String::extract_bound(&br_one.call_method0("min_supported_version").unwrap()).unwrap(); assert_eq!(current_version_string, ROQOQO_VERSION); assert_eq!(minimum_supported_version_string, "1.0.0"); diff --git a/qoqo/tests/integration/noise_models/continuous_decoherence.rs b/qoqo/tests/integration/noise_models/continuous_decoherence.rs index 83e46ec5..17277a6f 100644 --- a/qoqo/tests/integration/noise_models/continuous_decoherence.rs +++ b/qoqo/tests/integration/noise_models/continuous_decoherence.rs @@ -23,11 +23,10 @@ fn test_pyo3_init() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let plus_minus_operator = spins::PlusMinusLindbladNoiseOperatorWrapper::new(); - let br_type = py.get_type::(); - let br = br_type - .call1((plus_minus_operator.clone(),)) - .unwrap() - .downcast::>() + let br_type = py.get_type_bound::(); + let binding = br_type.call1((plus_minus_operator.clone(),)).unwrap(); + let br = binding + .downcast::() .unwrap(); let comparison = br .call_method0("get_noise_operator") @@ -53,16 +52,14 @@ fn test_add_damping() { internal: internal_plus_minus, }; - let br_type = py.get_type::(); - let br = br_type - .call0() - .unwrap() - .downcast::>() + let br_type = py.get_type_bound::(); + let binding = br_type.call0().unwrap(); + let br = binding + .downcast::() .unwrap(); - let br = br - .call_method1("add_damping_rate", ([0], 0.1)) - .unwrap() - .downcast::>() + let binding = br.call_method1("add_damping_rate", ([0], 0.1)).unwrap(); + let br = binding + .downcast::() .unwrap(); let comparison = br .call_method0("get_noise_operator") @@ -88,16 +85,14 @@ fn test_add_dephasing() { internal: internal_plus_minus, }; - let br_type = py.get_type::(); - let br = br_type - .call0() - .unwrap() - .downcast::>() + let br_type = py.get_type_bound::(); + let binding = br_type.call0().unwrap(); + let br = binding + .downcast::() .unwrap(); - let br = br - .call_method1("add_dephasing_rate", ([0], 0.1)) - .unwrap() - .downcast::>() + let binding = br.call_method1("add_dephasing_rate", ([0], 0.1)).unwrap(); + let br = binding + .downcast::() .unwrap(); let comparison = br .call_method0("get_noise_operator") @@ -137,16 +132,16 @@ fn test_add_depolarising() { internal: internal_plus_minus, }; - let br_type = py.get_type::(); - let br = br_type - .call0() - .unwrap() - .downcast::>() + let br_type = py.get_type_bound::(); + let binding = br_type.call0().unwrap(); + let br = binding + .downcast::() .unwrap(); - let br = br + let binding = br .call_method1("add_depolarising_rate", ([0], 0.2)) - .unwrap() - .downcast::>() + .unwrap(); + let br = binding + .downcast::() .unwrap(); let comparison = br .call_method0("get_noise_operator") @@ -172,16 +167,14 @@ fn test_add_excitation() { internal: internal_plus_minus, }; - let br_type = py.get_type::(); - let br = br_type - .call0() - .unwrap() - .downcast::>() + let br_type = py.get_type_bound::(); + let binding = br_type.call0().unwrap(); + let br = binding + .downcast::() .unwrap(); - let br = br - .call_method1("add_excitation_rate", ([0], 0.1)) - .unwrap() - .downcast::>() + let binding = br.call_method1("add_excitation_rate", ([0], 0.1)).unwrap(); + let br = binding + .downcast::() .unwrap(); let comparison = br .call_method0("get_noise_operator") @@ -195,11 +188,10 @@ fn test_add_excitation() { fn test_pyo3_debug() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let br_type = py.get_type::(); - let br = br_type - .call0() - .unwrap() - .downcast::>() + let br_type = py.get_type_bound::(); + let binding = br_type.call0().unwrap(); + let br = binding + .downcast::() .unwrap(); let br_wrapper = br.extract::().unwrap(); let br_copied = br @@ -221,21 +213,22 @@ fn test_pyo3_debug() { fn test_to_from_json() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let br_type = py.get_type::(); - let br = br_type - .call0() - .unwrap() - .downcast::>() + let br_type = py.get_type_bound::(); + let binding = br_type.call0().unwrap(); + let br = binding + .downcast::() .unwrap(); let new_br = br; let serialised = br.call_method0("to_json").unwrap(); - let deserialised = new_br - .call_method1("from_json", (serialised,)) - .unwrap() - .downcast::>() + let binding = new_br.call_method1("from_json", (&serialised,)).unwrap(); + let deserialised = binding + .downcast::() .unwrap(); - assert_eq!(format!("{:?}", br), format!("{:?}", deserialised)); + assert_eq!( + format!("{:?}", br.as_gil_ref()), + format!("{:?}", deserialised.as_gil_ref()) + ); let deserialised_error = new_br.call_method1("from_json", (serde_json::to_string("fails").unwrap(),)); @@ -255,20 +248,21 @@ fn test_to_from_json() { fn test_to_from_bincode() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let br_type = py.get_type::(); - let br = br_type - .call0() - .unwrap() - .downcast::>() + let br_type = py.get_type_bound::(); + let binding = br_type.call0().unwrap(); + let br = binding + .downcast::() .unwrap(); let new_br = br; let serialised = br.call_method0("to_bincode").unwrap(); - let deserialised = new_br - .call_method1("from_bincode", (serialised,)) - .unwrap() - .downcast::>() + let binding = new_br.call_method1("from_bincode", (&serialised,)).unwrap(); + let deserialised = binding + .downcast::() .unwrap(); - assert_eq!(format!("{:?}", br), format!("{:?}", deserialised)); + assert_eq!( + format!("{:?}", br.as_gil_ref()), + format!("{:?}", deserialised.as_gil_ref()) + ); let deserialised_error = new_br.call_method1("from_bincode", (bincode::serialize("fails").unwrap(),)); @@ -289,23 +283,23 @@ fn test_to_from_bincode() { fn test_json_schema() { pyo3::prepare_freethreaded_python(); pyo3::Python::with_gil(|py| { - let br_type = py.get_type::(); - let br = br_type - .call0() - .unwrap() - .downcast::>() + let br_type = py.get_type_bound::(); + let binding = br_type.call0().unwrap(); + let br = binding + .downcast::() .unwrap(); - let schema: String = String::extract(br.call_method0("json_schema").unwrap()).unwrap(); + let schema: String = + String::extract_bound(&br.call_method0("json_schema").unwrap()).unwrap(); let rust_schema = serde_json::to_string_pretty(&schemars::schema_for!(ContinuousDecoherenceModel)) .unwrap(); assert_eq!(schema, rust_schema); let current_version_string = - String::extract(br.call_method0("current_version").unwrap()).unwrap(); + String::extract_bound(&br.call_method0("current_version").unwrap()).unwrap(); let minimum_supported_version_string = - String::extract(br.call_method0("min_supported_version").unwrap()).unwrap(); + String::extract_bound(&br.call_method0("min_supported_version").unwrap()).unwrap(); assert_eq!(current_version_string, ROQOQO_VERSION); assert_eq!(minimum_supported_version_string, "1.6.0"); diff --git a/qoqo/tests/integration/noise_models/decoherence_on_gate.rs b/qoqo/tests/integration/noise_models/decoherence_on_gate.rs index ae0bc4c8..28250b28 100644 --- a/qoqo/tests/integration/noise_models/decoherence_on_gate.rs +++ b/qoqo/tests/integration/noise_models/decoherence_on_gate.rs @@ -22,12 +22,9 @@ use struqture_py::spins; fn test_pyo3_init() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let br_type = py.get_type::(); - let br = br_type - .call0() - .unwrap() - .downcast::>() - .unwrap(); + let br_type = py.get_type_bound::(); + let binding = br_type.call0().unwrap(); + let br = binding.downcast::().unwrap(); let br_copied = br .call_method0("__copy__") .unwrap() @@ -43,12 +40,9 @@ fn test_pyo3_init() { fn test_pyo3_debug() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let br_type = py.get_type::(); - let br = br_type - .call0() - .unwrap() - .downcast::>() - .unwrap(); + let br_type = py.get_type_bound::(); + let binding = br_type.call0().unwrap(); + let br = binding.downcast::().unwrap(); let br_wrapper = br.extract::().unwrap(); let br_clone = br_wrapper.clone(); @@ -64,21 +58,18 @@ fn test_pyo3_debug() { fn test_to_from_json() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let br_type = py.get_type::(); - let br = br_type - .call0() - .unwrap() - .downcast::>() - .unwrap(); + let br_type = py.get_type_bound::(); + let binding = br_type.call0().unwrap(); + let br = binding.downcast::().unwrap(); let new_br = br; let serialised = br.call_method0("to_json").unwrap(); - let deserialised = new_br - .call_method1("from_json", (serialised,)) - .unwrap() - .downcast::>() - .unwrap(); - assert_eq!(format!("{:?}", br), format!("{:?}", deserialised)); + let binding = new_br.call_method1("from_json", (&serialised,)).unwrap(); + let deserialised = binding.downcast::().unwrap(); + assert_eq!( + format!("{:?}", br.as_gil_ref()), + format!("{:?}", deserialised.as_gil_ref()) + ); let deserialised_error = new_br.call_method1("from_json", (serde_json::to_string("fails").unwrap(),)); @@ -98,20 +89,17 @@ fn test_to_from_json() { fn test_to_from_bincode() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let br_type = py.get_type::(); - let br = br_type - .call0() - .unwrap() - .downcast::>() - .unwrap(); + let br_type = py.get_type_bound::(); + let binding = br_type.call0().unwrap(); + let br = binding.downcast::().unwrap(); let new_br = br; let serialised = br.call_method0("to_bincode").unwrap(); - let deserialised = new_br - .call_method1("from_bincode", (serialised,)) - .unwrap() - .downcast::>() - .unwrap(); - assert_eq!(format!("{:?}", br), format!("{:?}", deserialised)); + let binding = new_br.call_method1("from_bincode", (&serialised,)).unwrap(); + let deserialised = binding.downcast::().unwrap(); + assert_eq!( + format!("{:?}", br.as_gil_ref()), + format!("{:?}", deserialised.as_gil_ref()) + ); let deserialised_error = new_br.call_method1("from_bincode", (bincode::serialize("fails").unwrap(),)); @@ -130,12 +118,9 @@ fn test_to_from_bincode() { fn test_singe_qubit_noise_term() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let br_type = py.get_type::(); - let br = br_type - .call0() - .unwrap() - .downcast::>() - .unwrap(); + let br_type = py.get_type_bound::(); + let binding = br_type.call0().unwrap(); + let br = binding.downcast::().unwrap(); let mut internal_plus_minus = struqture::spins::PlusMinusLindbladNoiseOperator::new(); let _ = internal_plus_minus.add_operator_product( @@ -148,14 +133,13 @@ fn test_singe_qubit_noise_term() { let plus_minus_operator = spins::PlusMinusLindbladNoiseOperatorWrapper { internal: internal_plus_minus, }; - let br = br + let binding = br .call_method1( "set_single_qubit_gate_error", ("RotateX", 0, plus_minus_operator.clone()), ) - .unwrap() - .downcast::>() .unwrap(); + let br = binding.downcast::().unwrap(); let operator = br .call_method1("get_single_qubit_gate_error", ("RotateX", 0)) .unwrap() @@ -169,12 +153,9 @@ fn test_singe_qubit_noise_term() { fn test_two_qubit_noise_term() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let br_type = py.get_type::(); - let br = br_type - .call0() - .unwrap() - .downcast::>() - .unwrap(); + let br_type = py.get_type_bound::(); + let binding = br_type.call0().unwrap(); + let br = binding.downcast::().unwrap(); let mut internal_plus_minus = struqture::spins::PlusMinusLindbladNoiseOperator::new(); let _ = internal_plus_minus.add_operator_product( @@ -192,10 +173,10 @@ fn test_two_qubit_noise_term() { "set_two_qubit_gate_error", ("CNOT", 0, 1, plus_minus_operator.clone()), ) - .unwrap() - .downcast::>() .unwrap(); let operator = br + .downcast::() + .unwrap() .call_method1("get_two_qubit_gate_error", ("CNOT", 0, 1)) .unwrap() .extract::() @@ -208,12 +189,9 @@ fn test_two_qubit_noise_term() { fn test_three_qubit_noise_term() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let br_type = py.get_type::(); - let br = br_type - .call0() - .unwrap() - .downcast::>() - .unwrap(); + let br_type = py.get_type_bound::(); + let binding = br_type.call0().unwrap(); + let br = binding.downcast::().unwrap(); let mut internal_plus_minus = struqture::spins::PlusMinusLindbladNoiseOperator::new(); let _ = internal_plus_minus.add_operator_product( @@ -237,10 +215,10 @@ fn test_three_qubit_noise_term() { plus_minus_operator.clone(), ), ) - .unwrap() - .downcast::>() .unwrap(); let operator = br + .downcast::() + .unwrap() .call_method1( "get_three_qubit_gate_error", ("ControlledControlledPauliZ", 0, 1, 2), @@ -256,12 +234,9 @@ fn test_three_qubit_noise_term() { fn test_multi_qubit_noise_term() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let br_type = py.get_type::(); - let br = br_type - .call0() - .unwrap() - .downcast::>() - .unwrap(); + let br_type = py.get_type_bound::(); + let binding = br_type.call0().unwrap(); + let br = binding.downcast::().unwrap(); let mut internal_plus_minus = struqture::spins::PlusMinusLindbladNoiseOperator::new(); let _ = internal_plus_minus.add_operator_product( @@ -279,10 +254,10 @@ fn test_multi_qubit_noise_term() { "set_multi_qubit_gate_error", ("MultiQubitMS", vec![0, 1, 2], plus_minus_operator.clone()), ) - .unwrap() - .downcast::>() .unwrap(); let operator = br + .downcast::() + .unwrap() .call_method1( "get_multi_qubit_gate_error", ("MultiQubitMS", vec![0, 1, 2]), @@ -300,22 +275,20 @@ fn test_multi_qubit_noise_term() { fn test_json_schema() { pyo3::prepare_freethreaded_python(); pyo3::Python::with_gil(|py| { - let br_type = py.get_type::(); - let br = br_type - .call0() - .unwrap() - .downcast::>() - .unwrap(); + let br_type = py.get_type_bound::(); + let binding = br_type.call0().unwrap(); + let br = binding.downcast::().unwrap(); - let schema: String = String::extract(br.call_method0("json_schema").unwrap()).unwrap(); + let schema: String = + String::extract_bound(&br.call_method0("json_schema").unwrap()).unwrap(); let rust_schema = serde_json::to_string_pretty(&schemars::schema_for!(DecoherenceOnGateModel)).unwrap(); assert_eq!(schema, rust_schema); let current_version_string = - String::extract(br.call_method0("current_version").unwrap()).unwrap(); + String::extract_bound(&br.call_method0("current_version").unwrap()).unwrap(); let minimum_supported_version_string = - String::extract(br.call_method0("min_supported_version").unwrap()).unwrap(); + String::extract_bound(&br.call_method0("min_supported_version").unwrap()).unwrap(); assert_eq!(current_version_string, ROQOQO_VERSION); assert_eq!(minimum_supported_version_string, "1.6.0"); diff --git a/qoqo/tests/integration/noise_models/decoherence_on_idle.rs b/qoqo/tests/integration/noise_models/decoherence_on_idle.rs index 80510236..0d618d1d 100644 --- a/qoqo/tests/integration/noise_models/decoherence_on_idle.rs +++ b/qoqo/tests/integration/noise_models/decoherence_on_idle.rs @@ -23,12 +23,9 @@ fn test_pyo3_init() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let plus_minus_operator = spins::PlusMinusLindbladNoiseOperatorWrapper::new(); - let br_type = py.get_type::(); - let br = br_type - .call1((plus_minus_operator.clone(),)) - .unwrap() - .downcast::>() - .unwrap(); + let br_type = py.get_type_bound::(); + let binding = br_type.call1((plus_minus_operator.clone(),)).unwrap(); + let br = binding.downcast::().unwrap(); let comparison = br .call_method0("get_noise_operator") .unwrap() @@ -53,17 +50,11 @@ fn test_add_damping() { internal: internal_plus_minus, }; - let br_type = py.get_type::(); - let br = br_type - .call0() - .unwrap() - .downcast::>() - .unwrap(); - let br = br - .call_method1("add_damping_rate", ([0], 0.1)) - .unwrap() - .downcast::>() - .unwrap(); + let br_type = py.get_type_bound::(); + let binding = br_type.call0().unwrap(); + let br = binding.downcast::().unwrap(); + let binding = br.call_method1("add_damping_rate", ([0], 0.1)).unwrap(); + let br = binding.downcast::().unwrap(); let comparison = br .call_method0("get_noise_operator") .unwrap() @@ -88,17 +79,11 @@ fn test_add_dephasing() { internal: internal_plus_minus, }; - let br_type = py.get_type::(); - let br = br_type - .call0() - .unwrap() - .downcast::>() - .unwrap(); - let br = br - .call_method1("add_dephasing_rate", ([0], 0.1)) - .unwrap() - .downcast::>() - .unwrap(); + let br_type = py.get_type_bound::(); + let binding = br_type.call0().unwrap(); + let br = binding.downcast::().unwrap(); + let binding = br.call_method1("add_dephasing_rate", ([0], 0.1)).unwrap(); + let br = binding.downcast::().unwrap(); let comparison = br .call_method0("get_noise_operator") .unwrap() @@ -137,17 +122,13 @@ fn test_add_depolarising() { internal: internal_plus_minus, }; - let br_type = py.get_type::(); - let br = br_type - .call0() - .unwrap() - .downcast::>() - .unwrap(); - let br = br + let br_type = py.get_type_bound::(); + let binding = br_type.call0().unwrap(); + let br = binding.downcast::().unwrap(); + let binding = br .call_method1("add_depolarising_rate", ([0], 0.2)) - .unwrap() - .downcast::>() .unwrap(); + let br = binding.downcast::().unwrap(); let comparison = br .call_method0("get_noise_operator") .unwrap() @@ -172,17 +153,11 @@ fn test_add_excitation() { internal: internal_plus_minus, }; - let br_type = py.get_type::(); - let br = br_type - .call0() - .unwrap() - .downcast::>() - .unwrap(); - let br = br - .call_method1("add_excitation_rate", ([0], 0.1)) - .unwrap() - .downcast::>() - .unwrap(); + let br_type = py.get_type_bound::(); + let binding = br_type.call0().unwrap(); + let br = binding.downcast::().unwrap(); + let binding = br.call_method1("add_excitation_rate", ([0], 0.1)).unwrap(); + let br = binding.downcast::().unwrap(); let comparison = br .call_method0("get_noise_operator") .unwrap() @@ -195,12 +170,9 @@ fn test_add_excitation() { fn test_pyo3_debug() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let br_type = py.get_type::(); - let br = br_type - .call0() - .unwrap() - .downcast::>() - .unwrap(); + let br_type = py.get_type_bound::(); + let binding = br_type.call0().unwrap(); + let br = binding.downcast::().unwrap(); let br_wrapper = br.extract::().unwrap(); let br_copied = br .call_method0("__copy__") @@ -221,21 +193,18 @@ fn test_pyo3_debug() { fn test_to_from_json() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let br_type = py.get_type::(); - let br = br_type - .call0() - .unwrap() - .downcast::>() - .unwrap(); + let br_type = py.get_type_bound::(); + let binding = br_type.call0().unwrap(); + let br = binding.downcast::().unwrap(); let new_br = br; let serialised = br.call_method0("to_json").unwrap(); - let deserialised = new_br - .call_method1("from_json", (serialised,)) - .unwrap() - .downcast::>() - .unwrap(); - assert_eq!(format!("{:?}", br), format!("{:?}", deserialised)); + let binding = new_br.call_method1("from_json", (&serialised,)).unwrap(); + let deserialised = binding.downcast::().unwrap(); + assert_eq!( + format!("{:?}", br.as_gil_ref()), + format!("{:?}", deserialised.as_gil_ref()) + ); let deserialised_error = new_br.call_method1("from_json", (serde_json::to_string("fails").unwrap(),)); @@ -255,20 +224,17 @@ fn test_to_from_json() { fn test_to_from_bincode() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let br_type = py.get_type::(); - let br = br_type - .call0() - .unwrap() - .downcast::>() - .unwrap(); + let br_type = py.get_type_bound::(); + let binding = br_type.call0().unwrap(); + let br = binding.downcast::().unwrap(); let new_br = br; let serialised = br.call_method0("to_bincode").unwrap(); - let deserialised = new_br - .call_method1("from_bincode", (serialised,)) - .unwrap() - .downcast::>() - .unwrap(); - assert_eq!(format!("{:?}", br), format!("{:?}", deserialised)); + let binding = new_br.call_method1("from_bincode", (&serialised,)).unwrap(); + let deserialised = binding.downcast::().unwrap(); + assert_eq!( + format!("{:?}", br.as_gil_ref()), + format!("{:?}", deserialised.as_gil_ref()) + ); let deserialised_error = new_br.call_method1("from_bincode", (bincode::serialize("fails").unwrap(),)); @@ -289,24 +255,22 @@ fn test_to_from_bincode() { fn test_json_schema() { pyo3::prepare_freethreaded_python(); pyo3::Python::with_gil(|py| { - let br_type = py.get_type::(); - let br = br_type - .call0() - .unwrap() - .downcast::>() - .unwrap(); + let br_type = py.get_type_bound::(); + let binding = br_type.call0().unwrap(); + let br = binding.downcast::().unwrap(); - let schema: String = String::extract(br.call_method0("json_schema").unwrap()).unwrap(); + let schema: String = + String::extract_bound(&br.call_method0("json_schema").unwrap()).unwrap(); let rust_schema = serde_json::to_string_pretty(&schemars::schema_for!(DecoherenceOnIdleModel)).unwrap(); assert_eq!(schema, rust_schema); let current_version_string = - String::extract(br.call_method0("current_version").unwrap()).unwrap(); + String::extract_bound(&br.call_method0("current_version").unwrap()).unwrap(); let minimum_supported_version_string = - String::extract(br.call_method0("min_supported_version").unwrap()).unwrap(); + String::extract_bound(&br.call_method0("min_supported_version").unwrap()).unwrap(); assert_eq!(current_version_string, ROQOQO_VERSION); - assert_eq!(minimum_supported_version_string, "1.6.0"); + assert_eq!(minimum_supported_version_string, "1.11.0"); }); } diff --git a/qoqo/tests/integration/noise_models/imperfect_readout.rs b/qoqo/tests/integration/noise_models/imperfect_readout.rs index af1ee772..ff8c39c2 100644 --- a/qoqo/tests/integration/noise_models/imperfect_readout.rs +++ b/qoqo/tests/integration/noise_models/imperfect_readout.rs @@ -20,12 +20,9 @@ use roqoqo::{noise_models::ImperfectReadoutModel, ROQOQO_VERSION}; fn test_pyo3_init() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let br_type = py.get_type::(); - let _br = br_type - .call0() - .unwrap() - .downcast::>() - .unwrap(); + let br_type = py.get_type_bound::(); + let binding = br_type.call0().unwrap(); + let _br = binding.downcast::().unwrap(); }) } @@ -33,17 +30,15 @@ fn test_pyo3_init() { fn test_new_with_uniform_error_init() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let br_type = py.get_type::(); - let br = br_type + let br_type = py.get_type_bound::(); + let binding = br_type .call_method1("new_with_uniform_error", (2, 0.2, 0.1)) - .unwrap() - .downcast::>() .unwrap(); - let br = br + let br = binding.downcast::().unwrap(); + let binding = br .call_method1("set_error_probabilites", (0, 0.3, 0.4)) - .unwrap() - .downcast::>() .unwrap(); + let br = binding.downcast::().unwrap(); let zero_as_1_qubit_0: f64 = br .call_method1("prob_detect_0_as_1", (0,)) .unwrap() @@ -70,12 +65,9 @@ fn test_new_with_uniform_error_init() { fn test_pyo3_debug() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let br_type = py.get_type::(); - let br = br_type - .call0() - .unwrap() - .downcast::>() - .unwrap(); + let br_type = py.get_type_bound::(); + let binding = br_type.call0().unwrap(); + let br = binding.downcast::().unwrap(); let br_copied = br .call_method0("__copy__") .unwrap() @@ -97,21 +89,18 @@ fn test_pyo3_debug() { fn test_to_from_json() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let br_type = py.get_type::(); - let br = br_type - .call0() - .unwrap() - .downcast::>() - .unwrap(); + let br_type = py.get_type_bound::(); + let binding = br_type.call0().unwrap(); + let br = binding.downcast::().unwrap(); let new_br = br; let serialised = br.call_method0("to_json").unwrap(); - let deserialised = new_br - .call_method1("from_json", (serialised,)) - .unwrap() - .downcast::>() - .unwrap(); - assert_eq!(format!("{:?}", br), format!("{:?}", deserialised)); + let binding = new_br.call_method1("from_json", (&serialised,)).unwrap(); + let deserialised = binding.downcast::().unwrap(); + assert_eq!( + format!("{:?}", br.as_gil_ref()), + format!("{:?}", deserialised.as_gil_ref()) + ); let deserialised_error = new_br.call_method1("from_json", (serde_json::to_string("fails").unwrap(),)); @@ -131,20 +120,17 @@ fn test_to_from_json() { fn test_to_from_bincode() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let br_type = py.get_type::(); - let br = br_type - .call0() - .unwrap() - .downcast::>() - .unwrap(); + let br_type = py.get_type_bound::(); + let binding = br_type.call0().unwrap(); + let br = binding.downcast::().unwrap(); let new_br = br; let serialised = br.call_method0("to_bincode").unwrap(); - let deserialised = new_br - .call_method1("from_bincode", (serialised,)) - .unwrap() - .downcast::>() - .unwrap(); - assert_eq!(format!("{:?}", br), format!("{:?}", deserialised)); + let binding = new_br.call_method1("from_bincode", (&serialised,)).unwrap(); + let deserialised = binding.downcast::().unwrap(); + assert_eq!( + format!("{:?}", br.as_gil_ref()), + format!("{:?}", deserialised.as_gil_ref()) + ); let deserialised_error = new_br.call_method1("from_bincode", (bincode::serialize("fails").unwrap(),)); @@ -165,22 +151,20 @@ fn test_to_from_bincode() { fn test_json_schema() { pyo3::prepare_freethreaded_python(); pyo3::Python::with_gil(|py| { - let br_type = py.get_type::(); - let br = br_type - .call0() - .unwrap() - .downcast::>() - .unwrap(); + let br_type = py.get_type_bound::(); + let binding = br_type.call0().unwrap(); + let br = binding.downcast::().unwrap(); - let schema: String = String::extract(br.call_method0("json_schema").unwrap()).unwrap(); + let schema: String = + String::extract_bound(&br.call_method0("json_schema").unwrap()).unwrap(); let rust_schema = serde_json::to_string_pretty(&schemars::schema_for!(ImperfectReadoutModel)).unwrap(); assert_eq!(schema, rust_schema); let current_version_string = - String::extract(br.call_method0("current_version").unwrap()).unwrap(); + String::extract_bound(&br.call_method0("current_version").unwrap()).unwrap(); let minimum_supported_version_string = - String::extract(br.call_method0("min_supported_version").unwrap()).unwrap(); + String::extract_bound(&br.call_method0("min_supported_version").unwrap()).unwrap(); assert_eq!(current_version_string, ROQOQO_VERSION); assert_eq!(minimum_supported_version_string, "1.6.0"); diff --git a/qoqo/tests/integration/noise_models/overrotation.rs b/qoqo/tests/integration/noise_models/overrotation.rs index 4a07f739..87423310 100644 --- a/qoqo/tests/integration/noise_models/overrotation.rs +++ b/qoqo/tests/integration/noise_models/overrotation.rs @@ -22,11 +22,10 @@ use roqoqo::ROQOQO_VERSION; fn test_pyo3_init() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let br_type = py.get_type::(); - let br: &PyCell = br_type - .call0() - .unwrap() - .downcast::>() + let br_type = py.get_type_bound::(); + let binding = br_type.call0().unwrap(); + let br: &Bound = binding + .downcast::() .unwrap(); let br_copied = br .call_method0("__copy__") @@ -44,11 +43,10 @@ fn test_pyo3_init() { fn test_pyo3_init_description() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let br_type = py.get_type::(); - let br: &PyCell = br_type - .call1(("RotateX", 0.0, 1.0)) - .unwrap() - .downcast::>() + let br_type = py.get_type_bound::(); + let binding = br_type.call1(("RotateX", 0.0, 1.0)).unwrap(); + let br: &Bound = binding + .downcast::() .unwrap(); let br_copied = br .call_method0("__copy__") @@ -74,16 +72,18 @@ fn test_debug_description() { fn test_debug() { Python::with_gil(|py| { // Overrotation Model Wrapper - let wrapper_description_type = py.get_type::(); - let py_wrapper_description = wrapper_description_type + let wrapper_description_type = + py.get_type_bound::(); + let binding = wrapper_description_type .call1(("RotateX", 0.0, 1.0)) - .unwrap() - .downcast::>() + .unwrap(); + let py_wrapper_description = binding + .downcast::() .unwrap(); let mut wrapper = SingleQubitOverrotationOnGateWrapper::new(); wrapper = wrapper - .set_single_qubit_overrotation("RotateZ", 0, py_wrapper_description.into()) + .set_single_qubit_overrotation("RotateZ", 0, py_wrapper_description) .unwrap(); let compare = "SingleQubitOverrotationOnGateWrapper { internal: SingleQubitOverrotationOnGate { single_qubit_overrotation: {(\"RotateZ\", 0): SingleQubitOverrotationDescription { gate: \"RotateX\", theta_mean: 0.0, theta_std: 1.0 }}, two_qubit_overrotation: {} } }"; @@ -117,21 +117,22 @@ fn test_partialeq_description() { fn test_to_from_json() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let br_type = py.get_type::(); - let br = br_type - .call0() - .unwrap() - .downcast::>() + let br_type = py.get_type_bound::(); + let binding = br_type.call0().unwrap(); + let br = binding + .downcast::() .unwrap(); let new_br = br; let serialised = br.call_method0("to_json").unwrap(); - let deserialised = new_br - .call_method1("from_json", (serialised,)) - .unwrap() - .downcast::>() + let binding = new_br.call_method1("from_json", (&serialised,)).unwrap(); + let deserialised = binding + .downcast::() .unwrap(); - assert_eq!(format!("{:?}", br), format!("{:?}", deserialised)); + assert_eq!( + format!("{:?}", br.as_gil_ref()), + format!("{:?}", deserialised.as_gil_ref()) + ); let deserialised_error = new_br.call_method1("from_json", (serde_json::to_string("fails").unwrap(),)); @@ -150,21 +151,22 @@ fn test_to_from_json() { fn test_to_from_json_description() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let br_type = py.get_type::(); - let br = br_type - .call1(("RotateX", 0.0, 1.0)) - .unwrap() - .downcast::>() + let br_type = py.get_type_bound::(); + let binding = br_type.call1(("RotateX", 0.0, 1.0)).unwrap(); + let br = binding + .downcast::() .unwrap(); let new_br = br; let serialised = br.call_method0("to_json").unwrap(); - let deserialised = new_br - .call_method1("from_json", (serialised,)) - .unwrap() - .downcast::>() + let binding = new_br.call_method1("from_json", (&serialised,)).unwrap(); + let deserialised = binding + .downcast::() .unwrap(); - assert_eq!(format!("{:?}", br), format!("{:?}", deserialised)); + assert_eq!( + format!("{:?}", br.as_gil_ref()), + format!("{:?}", deserialised.as_gil_ref()) + ); let deserialised_error = new_br.call_method1("from_json", (serde_json::to_string("fails").unwrap(),)); @@ -184,20 +186,21 @@ fn test_to_from_json_description() { fn test_to_from_bincode() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let br_type = py.get_type::(); - let br = br_type - .call0() - .unwrap() - .downcast::>() + let br_type = py.get_type_bound::(); + let binding = br_type.call0().unwrap(); + let br = binding + .downcast::() .unwrap(); let new_br = br; let serialised = br.call_method0("to_bincode").unwrap(); - let deserialised = new_br - .call_method1("from_bincode", (serialised,)) - .unwrap() - .downcast::>() + let binding = new_br.call_method1("from_bincode", (&serialised,)).unwrap(); + let deserialised = binding + .downcast::() .unwrap(); - assert_eq!(format!("{:?}", br), format!("{:?}", deserialised)); + assert_eq!( + format!("{:?}", br.as_gil_ref()), + format!("{:?}", deserialised.as_gil_ref()) + ); let deserialised_error = new_br.call_method1("from_bincode", (bincode::serialize("fails").unwrap(),)); @@ -216,20 +219,21 @@ fn test_to_from_bincode() { fn test_to_from_bincode_description() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let br_type = py.get_type::(); - let br = br_type - .call1(("RotateX", 0.0, 1.0)) - .unwrap() - .downcast::>() + let br_type = py.get_type_bound::(); + let binding = br_type.call1(("RotateX", 0.0, 1.0)).unwrap(); + let br = binding + .downcast::() .unwrap(); let new_br = br; let serialised = br.call_method0("to_bincode").unwrap(); - let deserialised = new_br - .call_method1("from_bincode", (serialised,)) - .unwrap() - .downcast::>() + let binding = new_br.call_method1("from_bincode", (&serialised,)).unwrap(); + let deserialised = binding + .downcast::() .unwrap(); - assert_eq!(format!("{:?}", br), format!("{:?}", deserialised)); + assert_eq!( + format!("{:?}", br.as_gil_ref()), + format!("{:?}", deserialised.as_gil_ref()) + ); let deserialised_error = new_br.call_method1("from_bincode", (bincode::serialize("fails").unwrap(),)); @@ -248,11 +252,10 @@ fn test_to_from_bincode_description() { fn test_single_qubit_noise_term() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let br_type = py.get_type::(); - let br = br_type - .call0() - .unwrap() - .downcast::>() + let br_type = py.get_type_bound::(); + let binding = br_type.call0().unwrap(); + let br = binding + .downcast::() .unwrap(); let desc = SingleQubitOverrotationDescriptionWrapper::new("RotateX", 1.0, 1.0); @@ -261,10 +264,10 @@ fn test_single_qubit_noise_term() { "set_single_qubit_overrotation", ("RotateX", 0, desc.clone()), ) - .unwrap() - .downcast::>() .unwrap(); let description = br + .downcast::() + .unwrap() .call_method1("get_single_qubit_overrotation", ("RotateX", 0)) .unwrap() .extract::() @@ -277,11 +280,10 @@ fn test_single_qubit_noise_term() { fn test_two_qubit_noise_term() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let br_type = py.get_type::(); - let br = br_type - .call0() - .unwrap() - .downcast::>() + let br_type = py.get_type_bound::(); + let binding = br_type.call0().unwrap(); + let br = binding + .downcast::() .unwrap(); let desc1 = SingleQubitOverrotationDescriptionWrapper::new("RotateX", 1.0, 1.0); @@ -292,10 +294,10 @@ fn test_two_qubit_noise_term() { "set_two_qubit_overrotation", ("CNOT", 0, 1, (desc1.clone(), desc2.clone())), ) - .unwrap() - .downcast::>() .unwrap(); let operator = br + .downcast::() + .unwrap() .call_method1("get_two_qubit_overrotation", ("CNOT", 0, 1)) .unwrap() .extract::<( @@ -313,23 +315,23 @@ fn test_two_qubit_noise_term() { fn test_json_schema() { pyo3::prepare_freethreaded_python(); pyo3::Python::with_gil(|py| { - let br_type = py.get_type::(); - let br = br_type - .call0() - .unwrap() - .downcast::>() + let br_type = py.get_type_bound::(); + let binding = br_type.call0().unwrap(); + let br = binding + .downcast::() .unwrap(); - let schema: String = String::extract(br.call_method0("json_schema").unwrap()).unwrap(); + let schema: String = + String::extract_bound(&br.call_method0("json_schema").unwrap()).unwrap(); let rust_schema = serde_json::to_string_pretty(&schemars::schema_for!(SingleQubitOverrotationOnGate)) .unwrap(); assert_eq!(schema, rust_schema); let current_version_string = - String::extract(br.call_method0("current_version").unwrap()).unwrap(); + String::extract_bound(&br.call_method0("current_version").unwrap()).unwrap(); let minimum_supported_version_string = - String::extract(br.call_method0("min_supported_version").unwrap()).unwrap(); + String::extract_bound(&br.call_method0("min_supported_version").unwrap()).unwrap(); assert_eq!(current_version_string, ROQOQO_VERSION); assert_eq!(minimum_supported_version_string, "1.11.0"); @@ -341,14 +343,14 @@ fn test_json_schema() { fn test_json_schema_description() { pyo3::prepare_freethreaded_python(); pyo3::Python::with_gil(|py| { - let br_type = py.get_type::(); - let br = br_type - .call1(("RotateX", 0.0, 1.0)) - .unwrap() - .downcast::>() + let br_type = py.get_type_bound::(); + let binding = br_type.call1(("RotateX", 0.0, 1.0)).unwrap(); + let br = binding + .downcast::() .unwrap(); - let schema: String = String::extract(br.call_method0("json_schema").unwrap()).unwrap(); + let schema: String = + String::extract_bound(&br.call_method0("json_schema").unwrap()).unwrap(); let rust_schema = serde_json::to_string_pretty(&schemars::schema_for!( SingleQubitOverrotationDescription )) @@ -356,9 +358,9 @@ fn test_json_schema_description() { assert_eq!(schema, rust_schema); let current_version_string = - String::extract(br.call_method0("current_version").unwrap()).unwrap(); + String::extract_bound(&br.call_method0("current_version").unwrap()).unwrap(); let minimum_supported_version_string = - String::extract(br.call_method0("min_supported_version").unwrap()).unwrap(); + String::extract_bound(&br.call_method0("min_supported_version").unwrap()).unwrap(); assert_eq!(current_version_string, ROQOQO_VERSION); assert_eq!(minimum_supported_version_string, "1.11.0"); diff --git a/qoqo/tests/integration/operations/analog_operations.rs b/qoqo/tests/integration/operations/analog_operations.rs index 29433399..77bc6146 100644 --- a/qoqo/tests/integration/operations/analog_operations.rs +++ b/qoqo/tests/integration/operations/analog_operations.rs @@ -19,7 +19,6 @@ use qoqo::operations::{ use qoqo_calculator::{Calculator, CalculatorFloat}; use roqoqo::operations::Operation; use roqoqo::operations::*; -use roqoqo::RoqoqoError; #[cfg(feature = "json_schema")] use roqoqo::ROQOQO_VERSION; @@ -79,13 +78,14 @@ fn create_apply_timedependent_spin_hamiltonian_spin_test() -> ApplyTimeDependent ApplyTimeDependentSpinHamiltonian::new(hamiltonian, vec![1.0], values.clone()) } -fn new_system(py: Python, number_spins: Option) -> &PyCell { - let system_type = py.get_type::(); +fn new_system(py: Python, number_spins: Option) -> Bound { + let system_type = py.get_type_bound::(); system_type .call1((number_spins,)) .unwrap() - .downcast::>() + .downcast::() .unwrap() + .to_owned() } /// Test new() function for ApplyConstantSpinHamiltonian @@ -105,16 +105,15 @@ fn test_new_constantspinhamiltionian() { .extract::() .unwrap(); - let operation_type = py.get_type::(); - let operation_py = operation_type - .call1((system_wrapper.clone(), 1.0)) - .unwrap() - .downcast::>() + let operation_type = py.get_type_bound::(); + let binding = operation_type.call1((system_wrapper.clone(), 1.0)).unwrap(); + let operation_py = binding + .downcast::() .unwrap(); - let comparison = bool::extract( - operation - .as_ref(py) + let comparison = bool::extract_bound( + &operation + .bind(py) .call_method1(method, (operation_py,)) .unwrap(), ) @@ -124,10 +123,9 @@ fn test_new_constantspinhamiltionian() { let def_wrapper = operation_py .extract::() .unwrap(); - let new_op_diff = operation_type - .call1((system_wrapper.clone(), 0.0)) - .unwrap() - .downcast::>() + let binding = operation_type.call1((system_wrapper.clone(), 0.0)).unwrap(); + let new_op_diff = binding + .downcast::() .unwrap(); let def_wrapper_diff = new_op_diff .extract::() @@ -164,16 +162,17 @@ fn test_new_timedependentspinhamiltionian() { let mut values = HashMap::new(); values.insert("omega".to_string(), vec![1.0]); - let operation_type = py.get_type::(); - let operation_py = operation_type + let operation_type = py.get_type_bound::(); + let binding = operation_type .call1((system_wrapper.clone(), vec![1.0], values.clone())) - .unwrap() - .downcast::>() + .unwrap(); + let operation_py = binding + .downcast::() .unwrap(); - let comparison = bool::extract( - operation - .as_ref(py) + let comparison = bool::extract_bound( + &operation + .bind(py) .call_method1(method, (operation_py,)) .unwrap(), ) @@ -186,10 +185,11 @@ fn test_new_timedependentspinhamiltionian() { let def_wrapper = operation_py .extract::() .unwrap(); - let new_op_diff = operation_type + let binding = operation_type .call1((system_wrapper.clone(), vec![0.1], values.clone())) - .unwrap() - .downcast::>() + .unwrap(); + let new_op_diff = binding + .downcast::() .unwrap(); let def_wrapper_diff = new_op_diff .extract::() @@ -213,11 +213,11 @@ fn test_pyo3_is_parametrized(input_operation: Operation) { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_operation).unwrap(); - assert!(bool::extract( - operation + assert!(bool::extract_bound( + &operation .call_method0(py, "is_parametrized") .unwrap() - .as_ref(py) + .bind(py) ) .unwrap()); }) @@ -230,11 +230,11 @@ fn test_pyo3_is_not_parametrized(input_operation: Operation) { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_operation).unwrap(); - assert!(!bool::extract( - operation + assert!(!bool::extract_bound( + &operation .call_method0(py, "is_parametrized") .unwrap() - .as_ref(py) + .bind(py) ) .unwrap()); }) @@ -248,7 +248,8 @@ fn test_pyo3_hqslang(name: &'static str, input_operation: Operation) { Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_operation).unwrap(); let name_op: String = - String::extract(operation.call_method0(py, "hqslang").unwrap().as_ref(py)).unwrap(); + String::extract_bound(&operation.call_method0(py, "hqslang").unwrap().bind(py)) + .unwrap(); assert_eq!(name_op, name.to_string()); }) } @@ -275,7 +276,8 @@ fn test_pyo3_tags(input_operation: Operation, tags: Vec<&str>) { Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_operation).unwrap(); let tags_op: Vec = - Vec::::extract(operation.call_method0(py, "tags").unwrap().as_ref(py)).unwrap(); + Vec::::extract_bound(&operation.call_method0(py, "tags").unwrap().bind(py)) + .unwrap(); assert_eq!(tags_op.len(), tags.len()); for i in 0..tags.len() { assert_eq!(tags_op[i], tags[i]); @@ -294,17 +296,17 @@ fn test_pyo3_copy_deepcopy(input_operation: Operation) { let deepcopy_op = operation.call_method1(py, "__deepcopy__", ("",)).unwrap(); let copy_deepcopy_param = operation; - let comparison_copy = bool::extract( - copy_op - .as_ref(py) + let comparison_copy = bool::extract_bound( + ©_op + .bind(py) .call_method1("__eq__", (copy_deepcopy_param.clone(),)) .unwrap(), ) .unwrap(); assert!(comparison_copy); - let comparison_deepcopy = bool::extract( - deepcopy_op - .as_ref(py) + let comparison_deepcopy = bool::extract_bound( + &deepcopy_op + .bind(py) .call_method1("__eq__", (copy_deepcopy_param,)) .unwrap(), ) @@ -327,10 +329,10 @@ fn test_pyo3_format_repr(format_repr: &str, input_operation: Operation) { Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_operation).unwrap(); let to_format = operation.call_method1(py, "__format__", ("",)).unwrap(); - let format_op: &str = <&str>::extract(to_format.as_ref(py)).unwrap(); + let format_op: String = String::extract_bound(&to_format.bind(py)).unwrap(); assert_eq!(format_op, format_repr); let to_repr = operation.call_method0(py, "__repr__").unwrap(); - let repr_op: &str = <&str>::extract(to_repr.as_ref(py)).unwrap(); + let repr_op: String = String::extract_bound(&to_repr.bind(py)).unwrap(); assert_eq!(repr_op, format_repr); }) } @@ -341,8 +343,8 @@ fn test_pyo3_substitute_parameters(input_operation: Operation) { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_operation.clone()).unwrap(); - let mut substitution_dict_py: HashMap<&str, f64> = HashMap::new(); - substitution_dict_py.insert("theta", 1.0); + let mut substitution_dict_py: HashMap = HashMap::new(); + substitution_dict_py.insert("theta".to_owned(), 1.0); let substitute_op = operation .call_method1(py, "substitute_parameters", (substitution_dict_py,)) .unwrap(); @@ -355,9 +357,9 @@ fn test_pyo3_substitute_parameters(input_operation: Operation) { let test_operation = convert_operation_to_pyobject(substitute_param).unwrap(); - let comparison = bool::extract( - substitute_op - .as_ref(py) + let comparison = bool::extract_bound( + &substitute_op + .bind(py) .call_method1("__eq__", (test_operation,)) .unwrap(), ) @@ -373,8 +375,8 @@ fn test_pyo3_substitute_params_single(input_operation: Operation) { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_operation.clone()).unwrap(); - let mut substitution_dict_py: HashMap<&str, f64> = HashMap::new(); - substitution_dict_py.insert("theta", 1.0); + let mut substitution_dict_py: HashMap = HashMap::new(); + substitution_dict_py.insert("theta".to_owned(), 1.0); let substitute_op = operation .call_method1(py, "substitute_parameters", (substitution_dict_py,)) .unwrap(); @@ -386,9 +388,9 @@ fn test_pyo3_substitute_params_single(input_operation: Operation) { .unwrap(); let test_operation = convert_operation_to_pyobject(substitute_param).unwrap(); - let comparison = bool::extract( - substitute_op - .as_ref(py) + let comparison = bool::extract_bound( + &substitute_op + .bind(py) .call_method1("__eq__", (test_operation,)) .unwrap(), ) @@ -403,12 +405,11 @@ fn test_pyo3_substitute_params_error(input_operation: Operation) { Python::with_gil(|py| { pyo3::prepare_freethreaded_python(); let operation = convert_operation_to_pyobject(input_operation).unwrap(); - let substitution_dict: HashMap<&str, f64> = HashMap::new(); + let substitution_dict: HashMap = HashMap::new(); let result = operation.call_method1(py, "substitute_parameters", (substitution_dict,)); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); let binding = result.unwrap_err(); - let e = binding.value(py); + let e = binding.value_bound(py); assert_eq!(format!("{:?}", e), "RuntimeError('Parameter Substitution failed: CalculatorError(VariableNotSet { name: \"theta\" })')"); }) } @@ -422,7 +423,7 @@ fn test_spin(input_operation: Operation, test_result: Vec) { pyo3::prepare_freethreaded_python(); let operation = convert_operation_to_pyobject(input_operation).unwrap(); let result: Vec = - Vec::::extract(operation.call_method1(py, "spin", ()).unwrap().as_ref(py)) + Vec::::extract_bound(&operation.call_method1(py, "spin", ()).unwrap().bind(py)) .unwrap(); assert_eq!(result, test_result); }) @@ -434,15 +435,15 @@ fn test_ineffective_substitute_parameters(input_operation: Operation) { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_operation.clone()).unwrap(); - let mut substitution_dict_py: HashMap<&str, f64> = HashMap::new(); - substitution_dict_py.insert("theta", 0.0); + let mut substitution_dict_py: HashMap = HashMap::new(); + substitution_dict_py.insert("theta".to_owned(), 0.0); let substitute_op = operation .call_method1(py, "substitute_parameters", (substitution_dict_py,)) .unwrap(); - let comparison = bool::extract( - substitute_op - .as_ref(py) + let comparison = bool::extract_bound( + &substitute_op + .bind(py) .call_method1("__eq__", (operation,)) .unwrap(), ) @@ -493,9 +494,9 @@ fn test_pyo3_remapqubits() { .call_method1(py, "remap_qubits", (qubit_mapping_test.clone(),)) .unwrap(); - let comparison = bool::extract( - result - .as_ref(py) + let comparison = bool::extract_bound( + &result + .bind(py) .call_method1("__eq__", (operation_2.clone(),)) .unwrap(), ) @@ -521,9 +522,9 @@ fn test_pyo3_remapqubits() { .call_method1(py, "remap_qubits", (qubit_mapping_test,)) .unwrap(); - let comparison = bool::extract( - result - .as_ref(py) + let comparison = bool::extract_bound( + &result + .bind(py) .call_method1("__eq__", (operation_2.clone(),)) .unwrap(), ) @@ -544,18 +545,18 @@ fn test_pyo3_richcmp(definition_1: Operation, definition_2: Operation) { let operation_one = convert_operation_to_pyobject(definition_1).unwrap(); let operation_two = convert_operation_to_pyobject(definition_2).unwrap(); - let comparison = bool::extract( - operation_one - .as_ref(py) + let comparison = bool::extract_bound( + &operation_one + .bind(py) .call_method1("__eq__", (operation_two.clone(),)) .unwrap(), ) .unwrap(); assert!(!comparison); - let comparison = bool::extract( - operation_one - .as_ref(py) + let comparison = bool::extract_bound( + &operation_one + .bind(py) .call_method1("__ne__", (operation_two.clone(),)) .unwrap(), ) @@ -589,17 +590,18 @@ fn test_pyo3_json_schema(operation: Operation) { pyo3::Python::with_gil(|py| { let minimum_version: String = "1.11.0".to_string(); let pyobject = convert_operation_to_pyobject(operation).unwrap(); - let operation = pyobject.as_ref(py); + let operation = pyobject.bind(py); let schema: String = - String::extract(operation.call_method0("json_schema").unwrap()).unwrap(); + String::extract_bound(&operation.call_method0("json_schema").unwrap()).unwrap(); assert_eq!(schema, rust_schema); - let current_version_string = - String::extract(operation.call_method0("current_version").unwrap()).unwrap(); let minimum_supported_version_string = - String::extract(operation.call_method0("min_supported_version").unwrap()).unwrap(); + String::extract_bound(&operation.call_method0("min_supported_version").unwrap()) + .unwrap(); + let current_version_string = + String::extract_bound(&operation.call_method0("current_version").unwrap()).unwrap(); assert_eq!(current_version_string, ROQOQO_VERSION); assert_eq!(minimum_supported_version_string, minimum_version); diff --git a/qoqo/tests/integration/operations/bosonic_operations.rs b/qoqo/tests/integration/operations/bosonic_operations.rs index beea8a48..2b8133f7 100644 --- a/qoqo/tests/integration/operations/bosonic_operations.rs +++ b/qoqo/tests/integration/operations/bosonic_operations.rs @@ -19,7 +19,6 @@ use qoqo::operations::{ }; use qoqo_calculator::Calculator; use qoqo_calculator::CalculatorFloat; -use qoqo_calculator_pyo3::CalculatorFloatWrapper; use roqoqo::operations::Operation; use roqoqo::operations::*; #[cfg(feature = "json_schema")] @@ -27,25 +26,7 @@ use roqoqo::ROQOQO_VERSION; use std::collections::{HashMap, HashSet}; use test_case::test_case; -// helper function to convert CalculatorFloat into a python object -fn convert_cf_to_pyobject( - py: Python, - parameter: CalculatorFloat, -) -> &PyCell { - let parameter_type = py.get_type::(); - match parameter { - CalculatorFloat::Float(x) => parameter_type - .call1((x,)) - .unwrap() - .downcast::>() - .unwrap(), - CalculatorFloat::Str(x) => parameter_type - .call1((x,)) - .unwrap() - .downcast::>() - .unwrap(), - } -} +use super::convert_cf_to_pyobject; /// Test new() function for Squeezing #[test_case(Operation::from(Squeezing::new(1, 0.1.into(), 0.1.into())), (1, 0.1, 0.1,), "__eq__"; "Squeezing_eq")] @@ -54,16 +35,13 @@ fn test_new_squeezing(input_operation: Operation, arguments: (u32, f64, f64), me let operation = convert_operation_to_pyobject(input_operation).unwrap(); pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let operation_type = py.get_type::(); - let operation_py = operation_type - .call1(arguments) - .unwrap() - .downcast::>() - .unwrap(); + let operation_type = py.get_type_bound::(); + let binding = operation_type.call1(arguments).unwrap(); + let operation_py = binding.downcast::().unwrap(); - let comparison = bool::extract( - operation - .as_ref(py) + let comparison = bool::extract_bound( + &operation + .bind(py) .call_method1(method, (operation_py,)) .unwrap(), ) @@ -71,11 +49,8 @@ fn test_new_squeezing(input_operation: Operation, arguments: (u32, f64, f64), me assert!(comparison); let def_wrapper = operation_py.extract::().unwrap(); - let new_op_diff = operation_type - .call1((2, 0.1, 0.0)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation_type.call1((2, 0.1, 0.0)).unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let def_wrapper_diff = new_op_diff.extract::().unwrap(); let helper_ne: bool = def_wrapper_diff != def_wrapper; assert!(helper_ne); @@ -87,11 +62,11 @@ fn test_new_squeezing(input_operation: Operation, arguments: (u32, f64, f64), me "SqueezingWrapper { internal: Squeezing { mode: 2, squeezing: Float(0.1), phase: Float(0.0) } }" ); - let comparison_copy = bool::extract( - operation + let comparison_copy = bool::extract_bound( + &operation .call_method0(py, "squeezing") .unwrap() - .as_ref(py) + .bind(py) .call_method1( "__eq__", (convert_cf_to_pyobject(py, CalculatorFloat::Float(0.1)),), @@ -101,11 +76,11 @@ fn test_new_squeezing(input_operation: Operation, arguments: (u32, f64, f64), me .unwrap(); assert!(comparison_copy); - let comparison_copy = bool::extract( - operation + let comparison_copy = bool::extract_bound( + &operation .call_method0(py, "phase") .unwrap() - .as_ref(py) + .bind(py) .call_method1( "__eq__", (convert_cf_to_pyobject(py, CalculatorFloat::Float(0.1)),), @@ -128,16 +103,13 @@ fn test_new_phasedisplacement( let operation = convert_operation_to_pyobject(input_operation).unwrap(); pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let operation_type = py.get_type::(); - let operation_py = operation_type - .call1(arguments) - .unwrap() - .downcast::>() - .unwrap(); + let operation_type = py.get_type_bound::(); + let binding = operation_type.call1(arguments).unwrap(); + let operation_py = binding.downcast::().unwrap(); - let comparison = bool::extract( - operation - .as_ref(py) + let comparison = bool::extract_bound( + &operation + .bind(py) .call_method1(method, (operation_py,)) .unwrap(), ) @@ -145,11 +117,8 @@ fn test_new_phasedisplacement( assert!(comparison); let def_wrapper = operation_py.extract::().unwrap(); - let new_op_diff = operation_type - .call1((2, 0.1, 0.1)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation_type.call1((2, 0.1, 0.1)).unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let def_wrapper_diff = new_op_diff.extract::().unwrap(); let helper_ne: bool = def_wrapper_diff != def_wrapper; assert!(helper_ne); @@ -161,11 +130,11 @@ fn test_new_phasedisplacement( "PhaseDisplacementWrapper { internal: PhaseDisplacement { mode: 2, displacement: Float(0.1), phase: Float(0.1) } }" ); - let comparison_copy = bool::extract( - operation + let comparison_copy = bool::extract_bound( + &operation .call_method0(py, "displacement") .unwrap() - .as_ref(py) + .bind(py) .call_method1( "__eq__", (convert_cf_to_pyobject(py, CalculatorFloat::Float(0.1)),), @@ -174,11 +143,11 @@ fn test_new_phasedisplacement( ) .unwrap(); assert!(comparison_copy); - let comparison_copy = bool::extract( - operation + let comparison_copy = bool::extract_bound( + &operation .call_method0(py, "phase") .unwrap() - .as_ref(py) + .bind(py) .call_method1( "__eq__", (convert_cf_to_pyobject(py, CalculatorFloat::Float(0.1)),), @@ -197,16 +166,13 @@ fn test_new_phaseshift(input_operation: Operation, arguments: (u32, f64), method let operation = convert_operation_to_pyobject(input_operation).unwrap(); pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let operation_type = py.get_type::(); - let operation_py = operation_type - .call1(arguments) - .unwrap() - .downcast::>() - .unwrap(); + let operation_type = py.get_type_bound::(); + let binding = operation_type.call1(arguments).unwrap(); + let operation_py = binding.downcast::().unwrap(); - let comparison = bool::extract( - operation - .as_ref(py) + let comparison = bool::extract_bound( + &operation + .bind(py) .call_method1(method, (operation_py,)) .unwrap(), ) @@ -214,11 +180,8 @@ fn test_new_phaseshift(input_operation: Operation, arguments: (u32, f64), method assert!(comparison); let def_wrapper = operation_py.extract::().unwrap(); - let new_op_diff = operation_type - .call1((2, 0.1)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation_type.call1((2, 0.1)).unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let def_wrapper_diff = new_op_diff.extract::().unwrap(); let helper_ne: bool = def_wrapper_diff != def_wrapper; assert!(helper_ne); @@ -230,11 +193,11 @@ fn test_new_phaseshift(input_operation: Operation, arguments: (u32, f64), method "PhaseShiftWrapper { internal: PhaseShift { mode: 2, phase: Float(0.1) } }" ); - let comparison_copy = bool::extract( - operation + let comparison_copy = bool::extract_bound( + &operation .call_method0(py, "phase") .unwrap() - .as_ref(py) + .bind(py) .call_method1( "__eq__", (convert_cf_to_pyobject(py, CalculatorFloat::Float(0.1)),), @@ -257,16 +220,13 @@ fn test_new_beamsplitter( let operation = convert_operation_to_pyobject(input_operation).unwrap(); pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let operation_type = py.get_type::(); - let operation_py = operation_type - .call1(arguments) - .unwrap() - .downcast::>() - .unwrap(); + let operation_type = py.get_type_bound::(); + let binding = operation_type.call1(arguments).unwrap(); + let operation_py = binding.downcast::().unwrap(); - let comparison = bool::extract( - operation - .as_ref(py) + let comparison = bool::extract_bound( + &operation + .bind(py) .call_method1(method, (operation_py,)) .unwrap(), ) @@ -274,11 +234,8 @@ fn test_new_beamsplitter( assert!(comparison); let def_wrapper = operation_py.extract::().unwrap(); - let new_op_diff = operation_type - .call1((2, 1, 0.1, 0.1)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation_type.call1((2, 1, 0.1, 0.1)).unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let def_wrapper_diff = new_op_diff.extract::().unwrap(); let helper_ne: bool = def_wrapper_diff != def_wrapper; assert!(helper_ne); @@ -290,11 +247,11 @@ fn test_new_beamsplitter( "BeamSplitterWrapper { internal: BeamSplitter { mode_0: 2, mode_1: 1, theta: Float(0.1), phi: Float(0.1) } }" ); - let comparison_copy: bool = bool::extract( - operation + let comparison_copy: bool = bool::extract_bound( + &operation .call_method0(py, "theta") .unwrap() - .as_ref(py) + .bind(py) .call_method1( "__eq__", (convert_cf_to_pyobject(py, CalculatorFloat::Float(0.1)),), @@ -303,11 +260,11 @@ fn test_new_beamsplitter( ) .unwrap(); assert!(comparison_copy); - let comparison_copy: bool = bool::extract( - operation + let comparison_copy: bool = bool::extract_bound( + &operation .call_method0(py, "phi") .unwrap() - .as_ref(py) + .bind(py) .call_method1( "__eq__", (convert_cf_to_pyobject(py, CalculatorFloat::Float(0.5)),), @@ -330,16 +287,13 @@ fn test_new_photondetection( let operation = convert_operation_to_pyobject(input_operation).unwrap(); pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let operation_type = py.get_type::(); - let operation_py = operation_type - .call1(arguments) - .unwrap() - .downcast::>() - .unwrap(); + let operation_type = py.get_type_bound::(); + let binding = operation_type.call1(arguments).unwrap(); + let operation_py = binding.downcast::().unwrap(); - let comparison = bool::extract( - operation - .as_ref(py) + let comparison = bool::extract_bound( + &operation + .bind(py) .call_method1(method, (operation_py,)) .unwrap(), ) @@ -347,11 +301,8 @@ fn test_new_photondetection( assert!(comparison); let def_wrapper = operation_py.extract::().unwrap(); - let new_op_diff = operation_type - .call1((2, "ro", 0)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation_type.call1((2, "ro", 0)).unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let def_wrapper_diff = new_op_diff.extract::().unwrap(); let helper_ne: bool = def_wrapper_diff != def_wrapper; assert!(helper_ne); @@ -363,22 +314,22 @@ fn test_new_photondetection( "PhotonDetectionWrapper { internal: PhotonDetection { mode: 2, readout: \"ro\", readout_index: 0 } }" ); - let comparison_copy = bool::extract( - operation + let comparison_copy = bool::extract_bound( + &operation .call_method0(py, "readout") .unwrap() - .as_ref(py) + .bind(py) .call_method1("__eq__", ("ro",)) .unwrap(), ) .unwrap(); assert!(comparison_copy); - let comparison_copy = bool::extract( - operation + let comparison_copy = bool::extract_bound( + &operation .call_method0(py, "readout_index") .unwrap() - .as_ref(py) + .bind(py) .call_method1("__eq__", (0_u32,)) .unwrap(), ) @@ -401,11 +352,11 @@ fn test_pyo3_is_parametrized(input_operation: Operation) { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_operation).unwrap(); - assert!(bool::extract( - operation + assert!(bool::extract_bound( + &operation .call_method0(py, "is_parametrized") .unwrap() - .as_ref(py) + .bind(py) ) .unwrap()); }) @@ -421,11 +372,11 @@ fn test_pyo3_is_not_parametrized(input_operation: Operation) { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_operation).unwrap(); - assert!(!bool::extract( - operation + assert!(!bool::extract_bound( + &operation .call_method0(py, "is_parametrized") .unwrap() - .as_ref(py) + .bind(py) ) .unwrap()); }) @@ -441,7 +392,7 @@ fn test_pyo3_mode(mode: usize, input_operation: Operation) { Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_operation).unwrap(); let mode_op: usize = - usize::extract(operation.call_method0(py, "mode").unwrap().as_ref(py)).unwrap(); + usize::extract_bound(&operation.call_method0(py, "mode").unwrap().bind(py)).unwrap(); assert_eq!(mode_op, mode); }) } @@ -453,10 +404,10 @@ fn test_pyo3_mode0_mode_1(mode_0: usize, mode_1: usize, input_operation: Operati Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_operation).unwrap(); let mode_op_0: usize = - usize::extract(operation.call_method0(py, "mode_0").unwrap().as_ref(py)).unwrap(); + usize::extract_bound(&operation.call_method0(py, "mode_0").unwrap().bind(py)).unwrap(); assert_eq!(mode_op_0, mode_0); let mode_op_1: usize = - usize::extract(operation.call_method0(py, "mode_1").unwrap().as_ref(py)).unwrap(); + usize::extract_bound(&operation.call_method0(py, "mode_1").unwrap().bind(py)).unwrap(); assert_eq!(mode_op_1, mode_1); }) } @@ -472,7 +423,8 @@ fn test_pyo3_hqslang(name: &'static str, input_operation: Operation) { Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_operation).unwrap(); let name_op: String = - String::extract(operation.call_method0(py, "hqslang").unwrap().as_ref(py)).unwrap(); + String::extract_bound(&operation.call_method0(py, "hqslang").unwrap().bind(py)) + .unwrap(); assert_eq!(name_op, name.to_string()); }) } @@ -527,7 +479,8 @@ fn test_pyo3_tags(input_operation: Operation, tags: Vec<&str>) { Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_operation).unwrap(); let tags_op: Vec = - Vec::::extract(operation.call_method0(py, "tags").unwrap().as_ref(py)).unwrap(); + Vec::::extract_bound(&operation.call_method0(py, "tags").unwrap().bind(py)) + .unwrap(); assert_eq!(tags_op.len(), tags.len()); for i in 0..tags.len() { assert_eq!(tags_op[i], tags[i]); @@ -546,11 +499,11 @@ fn test_pyo3_involved_modes(input_operation: Operation, modes: HashSet) { Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_operation).unwrap(); // test initial mode - let involved_modes: HashSet = HashSet::::extract( - operation + let involved_modes: HashSet = HashSet::::extract_bound( + &operation .call_method0(py, "involved_modes") .unwrap() - .as_ref(py), + .bind(py), ) .unwrap(); assert_eq!(involved_modes, modes); @@ -568,11 +521,11 @@ fn test_pyo3_remapqubits(input_operation: Operation) { Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_operation).unwrap(); // test initial qubit - let involved_qubits: HashSet = HashSet::::extract( - operation + let involved_qubits: HashSet = HashSet::::extract_bound( + &operation .call_method0(py, "involved_qubits") .unwrap() - .as_ref(py), + .bind(py), ) .unwrap(); assert_eq!(involved_qubits, HashSet::::new()); @@ -581,11 +534,8 @@ fn test_pyo3_remapqubits(input_operation: Operation) { .call_method1(py, "remap_qubits", (HashMap::::new(),)) .unwrap(); // test re-mapped qubit - let involved_qubits: HashSet = HashSet::::extract( - result - .call_method0(py, "involved_qubits") - .unwrap() - .as_ref(py), + let involved_qubits: HashSet = HashSet::::extract_bound( + &result.call_method0(py, "involved_qubits").unwrap().bind(py), ) .unwrap(); assert_eq!(involved_qubits, HashSet::::new()); @@ -603,7 +553,7 @@ fn test_pyo3_remapmodes_single(input_operation: Operation) { let operation = convert_operation_to_pyobject(input_operation).unwrap(); // test initial mode let mode: usize = - usize::extract(operation.call_method0(py, "mode").unwrap().as_ref(py)).unwrap(); + usize::extract_bound(&operation.call_method0(py, "mode").unwrap().bind(py)).unwrap(); assert_eq!(mode.clone(), 0); // remap modes let mut mode_mapping: HashMap = HashMap::new(); @@ -614,7 +564,7 @@ fn test_pyo3_remapmodes_single(input_operation: Operation) { .unwrap(); // test re-mapped mode let mode_new: usize = - usize::extract(result.call_method0(py, "mode").unwrap().as_ref(py)).unwrap(); + usize::extract_bound(&result.call_method0(py, "mode").unwrap().bind(py)).unwrap(); assert_eq!(mode_new.clone(), 1); // test that initial and rempapped modes are different assert_ne!(mode, mode_new); @@ -629,10 +579,10 @@ fn test_pyo3_remapmodes_two(input_operation: Operation) { let operation = convert_operation_to_pyobject(input_operation).unwrap(); // test initial mode let mode_0: usize = - usize::extract(operation.call_method0(py, "mode_0").unwrap().as_ref(py)).unwrap(); + usize::extract_bound(&operation.call_method0(py, "mode_0").unwrap().bind(py)).unwrap(); assert_eq!(mode_0.clone(), 0); let mode_1: usize = - usize::extract(operation.call_method0(py, "mode_1").unwrap().as_ref(py)).unwrap(); + usize::extract_bound(&operation.call_method0(py, "mode_1").unwrap().bind(py)).unwrap(); assert_eq!(mode_1.clone(), 1); // remap modes let mut mode_mapping: HashMap = HashMap::new(); @@ -643,10 +593,10 @@ fn test_pyo3_remapmodes_two(input_operation: Operation) { .unwrap(); // test re-mapped mode let mode_new_0: usize = - usize::extract(result.call_method0(py, "mode_0").unwrap().as_ref(py)).unwrap(); + usize::extract_bound(&result.call_method0(py, "mode_0").unwrap().bind(py)).unwrap(); assert_eq!(mode_new_0.clone(), 1); let mode_new_1: usize = - usize::extract(result.call_method0(py, "mode_1").unwrap().as_ref(py)).unwrap(); + usize::extract_bound(&result.call_method0(py, "mode_1").unwrap().bind(py)).unwrap(); assert_eq!(mode_new_1.clone(), 0); // test that initial and rempapped modes are different assert_ne!(mode_0, mode_new_0); @@ -669,8 +619,7 @@ fn test_pyo3_remapmodes_error(input_operation: Operation) { let mut mode_mapping: HashMap = HashMap::new(); mode_mapping.insert(2, 0); let result = operation.call_method1(py, "remap_modes", (mode_mapping,)); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); }) } @@ -688,17 +637,17 @@ fn test_pyo3_copy_deepcopy(input_operation: Operation) { let deepcopy_op = operation.call_method1(py, "__deepcopy__", ("",)).unwrap(); let copy_deepcopy_param = operation; - let comparison_copy = bool::extract( - copy_op - .as_ref(py) + let comparison_copy = bool::extract_bound( + ©_op + .bind(py) .call_method1("__eq__", (copy_deepcopy_param.clone(),)) .unwrap(), ) .unwrap(); assert!(comparison_copy); - let comparison_deepcopy = bool::extract( - deepcopy_op - .as_ref(py) + let comparison_deepcopy = bool::extract_bound( + &deepcopy_op + .bind(py) .call_method1("__eq__", (copy_deepcopy_param,)) .unwrap(), ) @@ -733,10 +682,10 @@ fn test_pyo3_format_repr(format_repr: &str, input_operation: Operation) { Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_operation).unwrap(); let to_format = operation.call_method1(py, "__format__", ("",)).unwrap(); - let format_op: &str = <&str>::extract(to_format.as_ref(py)).unwrap(); + let format_op: String = String::extract_bound(&to_format.bind(py)).unwrap(); assert_eq!(format_op, format_repr); let to_repr = operation.call_method0(py, "__repr__").unwrap(); - let repr_op: &str = <&str>::extract(to_repr.as_ref(py)).unwrap(); + let repr_op: String = String::extract_bound(&to_repr.bind(py)).unwrap(); assert_eq!(repr_op, format_repr); }) } @@ -779,9 +728,9 @@ fn test_pyo3_substitute_parameters(input_operation: Operation) { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_operation.clone()).unwrap(); - let mut substitution_dict_py: HashMap<&str, f64> = HashMap::new(); - substitution_dict_py.insert("theta", 1.0); - substitution_dict_py.insert("phi", 0.0); + let mut substitution_dict_py: HashMap = HashMap::new(); + substitution_dict_py.insert("theta".to_owned(), 1.0); + substitution_dict_py.insert("phi".to_owned(), 0.0); let substitute_op = operation .call_method1(py, "substitute_parameters", (substitution_dict_py,)) .unwrap(); @@ -794,9 +743,9 @@ fn test_pyo3_substitute_parameters(input_operation: Operation) { .unwrap(); let test_operation = convert_operation_to_pyobject(substitute_param).unwrap(); - let comparison = bool::extract( - substitute_op - .as_ref(py) + let comparison = bool::extract_bound( + &substitute_op + .bind(py) .call_method1("__eq__", (test_operation,)) .unwrap(), ) @@ -811,8 +760,8 @@ fn test_pyo3_substitute_params_single(input_operation: Operation) { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_operation.clone()).unwrap(); - let mut substitution_dict_py: HashMap<&str, f64> = HashMap::new(); - substitution_dict_py.insert("theta", 1.0); + let mut substitution_dict_py: HashMap = HashMap::new(); + substitution_dict_py.insert("theta".to_owned(), 1.0); let substitute_op = operation .call_method1(py, "substitute_parameters", (substitution_dict_py,)) .unwrap(); @@ -824,9 +773,9 @@ fn test_pyo3_substitute_params_single(input_operation: Operation) { .unwrap(); let test_operation = convert_operation_to_pyobject(substitute_param).unwrap(); - let comparison = bool::extract( - substitute_op - .as_ref(py) + let comparison = bool::extract_bound( + &substitute_op + .bind(py) .call_method1("__eq__", (test_operation,)) .unwrap(), ) @@ -844,10 +793,9 @@ fn test_pyo3_substitute_params_error(input_operation: Operation) { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_operation).unwrap(); - let substitution_dict: HashMap<&str, f64> = HashMap::new(); + let substitution_dict: HashMap = HashMap::new(); let result = operation.call_method1(py, "substitute_parameters", (substitution_dict,)); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); }) } @@ -861,15 +809,15 @@ fn test_ineffective_substitute_parameters(input_operation: Operation) { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_operation.clone()).unwrap(); - let mut substitution_dict_py: HashMap<&str, f64> = HashMap::new(); - substitution_dict_py.insert("theta", 0.0); + let mut substitution_dict_py: HashMap = HashMap::new(); + substitution_dict_py.insert("theta".to_owned(), 0.0); let substitute_op = operation .call_method1(py, "substitute_parameters", (substitution_dict_py,)) .unwrap(); - let comparison = bool::extract( - substitute_op - .as_ref(py) + let comparison = bool::extract_bound( + &substitute_op + .bind(py) .call_method1("__eq__", (operation,)) .unwrap(), ) @@ -900,18 +848,18 @@ fn test_pyo3_richcmp(definition_1: Operation, definition_2: Operation) { let operation_one = convert_operation_to_pyobject(definition_1).unwrap(); let operation_two = convert_operation_to_pyobject(definition_2).unwrap(); - let comparison = bool::extract( - operation_one - .as_ref(py) + let comparison = bool::extract_bound( + &operation_one + .bind(py) .call_method1("__eq__", (operation_two.clone(),)) .unwrap(), ) .unwrap(); assert!(!comparison); - let comparison = bool::extract( - operation_one - .as_ref(py) + let comparison = bool::extract_bound( + &operation_one + .bind(py) .call_method1("__ne__", (operation_two.clone(),)) .unwrap(), ) @@ -959,17 +907,18 @@ fn test_pyo3_json_schema(operation: Operation) { _ => "1.6.0".to_string(), }; let pyobject = convert_operation_to_pyobject(operation).unwrap(); - let operation = pyobject.as_ref(py); + let operation = pyobject.bind(py); let schema: String = - String::extract(operation.call_method0("json_schema").unwrap()).unwrap(); + String::extract_bound(&operation.call_method0("json_schema").unwrap()).unwrap(); assert_eq!(schema, rust_schema); let current_version_string = - String::extract(operation.call_method0("current_version").unwrap()).unwrap(); + String::extract_bound(&operation.call_method0("current_version").unwrap()).unwrap(); let minimum_supported_version_string = - String::extract(operation.call_method0("min_supported_version").unwrap()).unwrap(); + String::extract_bound(&operation.call_method0("min_supported_version").unwrap()) + .unwrap(); assert_eq!(current_version_string, ROQOQO_VERSION); assert_eq!(minimum_supported_version_string, minimum_version); diff --git a/qoqo/tests/integration/operations/define_operations.rs b/qoqo/tests/integration/operations/define_operations.rs index b2c102c2..99085df8 100644 --- a/qoqo/tests/integration/operations/define_operations.rs +++ b/qoqo/tests/integration/operations/define_operations.rs @@ -23,25 +23,19 @@ use test_case::test_case; fn test_pyo3_new_definition_float() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let operation = py.get_type::(); - let new_op = operation - .call1(("ro".to_string(), 1, false)) - .unwrap() - .downcast::>() - .unwrap(); + let operation = py.get_type_bound::(); + let binding = operation.call1(("ro".to_string(), 1, false)).unwrap(); + let new_op = binding.downcast::().unwrap(); let input_definition = Operation::from(DefinitionFloat::new(String::from("ro"), 1, false)); let copy_param = convert_operation_to_pyobject(input_definition).unwrap(); let comparison_copy = - bool::extract(new_op.call_method1("__eq__", (copy_param,)).unwrap()).unwrap(); + bool::extract_bound(&new_op.call_method1("__eq__", (copy_param,)).unwrap()).unwrap(); assert!(comparison_copy); let def_wrapper = new_op.extract::().unwrap(); - let new_op_diff = operation - .call1(("ro".to_string(), 1, true)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation.call1(("ro".to_string(), 1, true)).unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let def_wrapper_diff = new_op_diff.extract::().unwrap(); let helper_ne: bool = def_wrapper_diff != def_wrapper; assert!(helper_ne); @@ -60,26 +54,20 @@ fn test_pyo3_new_definition_float() { fn test_pyo3_new_definition_complex() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let operation = py.get_type::(); - let new_op = operation - .call1(("ro".to_string(), 1, false)) - .unwrap() - .downcast::>() - .unwrap(); + let operation = py.get_type_bound::(); + let binding = operation.call1(("ro".to_string(), 1, false)).unwrap(); + let new_op = binding.downcast::().unwrap(); let input_definition = Operation::from(DefinitionComplex::new(String::from("ro"), 1, false)); let copy_param = convert_operation_to_pyobject(input_definition).unwrap(); let comparison_copy = - bool::extract(new_op.call_method1("__eq__", (copy_param,)).unwrap()).unwrap(); + bool::extract_bound(&new_op.call_method1("__eq__", (copy_param,)).unwrap()).unwrap(); assert!(comparison_copy); let def_wrapper = new_op.extract::().unwrap(); - let new_op_diff = operation - .call1(("ro".to_string(), 1, true)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation.call1(("ro".to_string(), 1, true)).unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let def_wrapper_diff = new_op_diff.extract::().unwrap(); let helper_ne: bool = def_wrapper_diff != def_wrapper; assert!(helper_ne); @@ -98,25 +86,19 @@ fn test_pyo3_new_definition_complex() { fn test_pyo3_new_definition_usize() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let operation = py.get_type::(); - let new_op = operation - .call1(("ro".to_string(), 1, false)) - .unwrap() - .downcast::>() - .unwrap(); + let operation = py.get_type_bound::(); + let binding = operation.call1(("ro".to_string(), 1, false)).unwrap(); + let new_op = binding.downcast::().unwrap(); let input_definition = Operation::from(DefinitionUsize::new(String::from("ro"), 1, false)); let copy_param = convert_operation_to_pyobject(input_definition).unwrap(); let comparison_copy = - bool::extract(new_op.call_method1("__eq__", (copy_param,)).unwrap()).unwrap(); + bool::extract_bound(&new_op.call_method1("__eq__", (copy_param,)).unwrap()).unwrap(); assert!(comparison_copy); let def_wrapper = new_op.extract::().unwrap(); - let new_op_diff = operation - .call1(("ro".to_string(), 1, true)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation.call1(("ro".to_string(), 1, true)).unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let def_wrapper_diff = new_op_diff.extract::().unwrap(); let helper_ne: bool = def_wrapper_diff != def_wrapper; assert!(helper_ne); @@ -135,25 +117,19 @@ fn test_pyo3_new_definition_usize() { fn test_pyo3_new_definition_bit() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let operation = py.get_type::(); - let new_op = operation - .call1(("ro".to_string(), 1, false)) - .unwrap() - .downcast::>() - .unwrap(); + let operation = py.get_type_bound::(); + let binding = operation.call1(("ro".to_string(), 1, false)).unwrap(); + let new_op = binding.downcast::().unwrap(); let input_definition = Operation::from(DefinitionBit::new(String::from("ro"), 1, false)); let copy_param = convert_operation_to_pyobject(input_definition).unwrap(); let comparison_copy = - bool::extract(new_op.call_method1("__eq__", (copy_param,)).unwrap()).unwrap(); + bool::extract_bound(&new_op.call_method1("__eq__", (copy_param,)).unwrap()).unwrap(); assert!(comparison_copy); let def_wrapper = new_op.extract::().unwrap(); - let new_op_diff = operation - .call1(("ro".to_string(), 1, true)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation.call1(("ro".to_string(), 1, true)).unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let def_wrapper_diff = new_op_diff.extract::().unwrap(); let helper_ne: bool = def_wrapper_diff != def_wrapper; assert!(helper_ne); @@ -172,25 +148,19 @@ fn test_pyo3_new_definition_bit() { fn test_pyo3_new_input_symbolic() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let operation = py.get_type::(); - let new_op = operation - .call1(("ro".to_string(), 1.0)) - .unwrap() - .downcast::>() - .unwrap(); + let operation = py.get_type_bound::(); + let binding = operation.call1(("ro".to_string(), 1.0)).unwrap(); + let new_op = binding.downcast::().unwrap(); let input_definition = Operation::from(InputSymbolic::new(String::from("ro"), 1.0)); let copy_param = convert_operation_to_pyobject(input_definition).unwrap(); let comparison_copy = - bool::extract(new_op.call_method1("__eq__", (copy_param,)).unwrap()).unwrap(); + bool::extract_bound(&new_op.call_method1("__eq__", (copy_param,)).unwrap()).unwrap(); assert!(comparison_copy); let def_wrapper = new_op.extract::().unwrap(); - let new_op_diff = operation - .call1(("ro".to_string(), 2.0)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation.call1(("ro".to_string(), 2.0)).unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let def_wrapper_diff = new_op_diff.extract::().unwrap(); let helper_ne: bool = def_wrapper_diff != def_wrapper; assert!(helper_ne); @@ -209,25 +179,19 @@ fn test_pyo3_new_input_symbolic() { fn test_pyo3_new_input_bit() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let operation = py.get_type::(); - let new_op = operation - .call1(("ro".to_string(), 1, false)) - .unwrap() - .downcast::>() - .unwrap(); + let operation = py.get_type_bound::(); + let binding = operation.call1(("ro".to_string(), 1, false)).unwrap(); + let new_op = binding.downcast::().unwrap(); let input_definition = Operation::from(InputBit::new(String::from("ro"), 1, false)); let copy_param = convert_operation_to_pyobject(input_definition).unwrap(); let comparison_copy = - bool::extract(new_op.call_method1("__eq__", (copy_param,)).unwrap()).unwrap(); + bool::extract_bound(&new_op.call_method1("__eq__", (copy_param,)).unwrap()).unwrap(); assert!(comparison_copy); let def_wrapper = new_op.extract::().unwrap(); - let new_op_diff = operation - .call1(("ro".to_string(), 2, false)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation.call1(("ro".to_string(), 2, false)).unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let def_wrapper_diff = new_op_diff.extract::().unwrap(); let helper_ne: bool = def_wrapper_diff != def_wrapper; assert!(helper_ne); @@ -253,7 +217,7 @@ fn test_pyo3_name(input_definition: Operation) { Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_definition).unwrap(); let name_op: String = - String::extract(operation.call_method0(py, "name").unwrap().as_ref(py)).unwrap(); + String::extract_bound(&operation.call_method0(py, "name").unwrap().bind(py)).unwrap(); let name_param: String = String::from("ro"); assert_eq!(name_op, name_param); }) @@ -269,7 +233,7 @@ fn test_pyo3_length(input_definition: Operation) { Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_definition).unwrap(); let length_op: &usize = - &usize::extract(operation.call_method0(py, "length").unwrap().as_ref(py)).unwrap(); + &usize::extract_bound(&operation.call_method0(py, "length").unwrap().bind(py)).unwrap(); let length_param: &usize = &1_usize; assert_eq!(length_op, length_param); }) @@ -285,7 +249,8 @@ fn test_pyo3_is_output(input_definition: Operation) { Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_definition).unwrap(); assert!( - !bool::extract(operation.call_method0(py, "is_output").unwrap().as_ref(py)).unwrap() + !bool::extract_bound(&operation.call_method0(py, "is_output").unwrap().bind(py)) + .unwrap() ); }) } @@ -301,7 +266,7 @@ fn test_pyo3_input_symbolic_input() { ))) .unwrap(); let input_op: &f64 = - &f64::extract(operation.call_method0(py, "input").unwrap().as_ref(py)).unwrap(); + &f64::extract_bound(&operation.call_method0(py, "input").unwrap().bind(py)).unwrap(); let input_param: &f64 = &1.0; assert_eq!(input_op, input_param); }) @@ -319,7 +284,7 @@ fn test_pyo3_input_bit_index() { ))) .unwrap(); let input_op: &usize = - &usize::extract(operation.call_method0(py, "index").unwrap().as_ref(py)).unwrap(); + &usize::extract_bound(&operation.call_method0(py, "index").unwrap().bind(py)).unwrap(); let input_param: &usize = &1; assert_eq!(input_op, input_param); }) @@ -337,7 +302,7 @@ fn test_pyo3_input_bit_value() { ))) .unwrap(); let input_op: &bool = - &bool::extract(operation.call_method0(py, "value").unwrap().as_ref(py)).unwrap(); + &bool::extract_bound(&operation.call_method0(py, "value").unwrap().bind(py)).unwrap(); let input_param: &bool = &true; assert_eq!(input_op, input_param); }) @@ -354,11 +319,11 @@ fn test_pyo3_involved_qubits(input_definition: Operation) { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_definition).unwrap(); - let involved_op: HashSet = HashSet::extract( - operation + let involved_op: HashSet = HashSet::extract_bound( + &operation .call_method0(py, "involved_qubits") .unwrap() - .as_ref(py), + .bind(py), ) .unwrap(); let involved_param: HashSet<_> = HashSet::new(); @@ -375,9 +340,9 @@ fn test_pyo3_format_repr(input_definition: Operation, format_repr: &str) { Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_definition).unwrap(); let to_format = operation.call_method1(py, "__format__", ("",)).unwrap(); - let format_op: &str = <&str>::extract(to_format.as_ref(py)).unwrap(); + let format_op: String = String::extract_bound(&to_format.bind(py)).unwrap(); let to_repr = operation.call_method0(py, "__repr__").unwrap(); - let repr_op: &str = <&str>::extract(to_repr.as_ref(py)).unwrap(); + let repr_op: String = String::extract_bound(&to_repr.bind(py)).unwrap(); let mut format_repr_param: String = String::from(format_repr); format_repr_param.push_str(" { name: \"ro\", length: 1, is_output: false }"); let comparison = format_repr_param.as_str(); @@ -397,9 +362,9 @@ fn test_pyo3_input_symbolic_format_repr() { ))) .unwrap(); let to_format = operation.call_method1(py, "__format__", ("",)).unwrap(); - let format_op: &str = <&str>::extract(to_format.as_ref(py)).unwrap(); + let format_op: String = String::extract_bound(&to_format.bind(py)).unwrap(); let to_repr = operation.call_method0(py, "__repr__").unwrap(); - let repr_op: &str = <&str>::extract(to_repr.as_ref(py)).unwrap(); + let repr_op: String = String::extract_bound(&to_repr.bind(py)).unwrap(); let format_repr_param: String = String::from("InputSymbolic { name: \"ro\", input: 1.0 }"); let comparison = format_repr_param.as_str(); assert_eq!(format_op, comparison); @@ -422,17 +387,17 @@ fn test_pyo3_copy_deepcopy(input_definition: Operation) { let deepcopy_op = operation.call_method1(py, "__deepcopy__", ("",)).unwrap(); let copy_deepcopy_param = operation; - let comparison_copy = bool::extract( - copy_op - .as_ref(py) + let comparison_copy = bool::extract_bound( + ©_op + .bind(py) .call_method1("__eq__", (copy_deepcopy_param.clone(),)) .unwrap(), ) .unwrap(); assert!(comparison_copy); - let comparison_deepcopy = bool::extract( - deepcopy_op - .as_ref(py) + let comparison_deepcopy = bool::extract_bound( + &deepcopy_op + .bind(py) .call_method1("__eq__", (copy_deepcopy_param,)) .unwrap(), ) @@ -453,7 +418,7 @@ fn test_pyo3_tags(input_definition: Operation, tag_name: &str) { Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_definition).unwrap(); let to_tag = operation.call_method0(py, "tags").unwrap(); - let tags_op: &Vec<&str> = &Vec::extract(to_tag.as_ref(py)).unwrap(); + let tags_op: &Vec = &Vec::extract_bound(&to_tag.bind(py)).unwrap(); let tags_param: &[&str] = &["Operation", "Definition", tag_name]; assert_eq!(tags_op, tags_param); }) @@ -471,7 +436,8 @@ fn test_pyo3_hqslang(input_definition: Operation, hqslang_param: String) { Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_definition).unwrap(); let hqslang_op: String = - String::extract(operation.call_method0(py, "hqslang").unwrap().as_ref(py)).unwrap(); + String::extract_bound(&operation.call_method0(py, "hqslang").unwrap().bind(py)) + .unwrap(); assert_eq!(hqslang_op, hqslang_param); }) } @@ -487,11 +453,11 @@ fn test_pyo3_is_parametrized(input_definition: Operation) { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_definition).unwrap(); - assert!(!bool::extract( - operation + assert!(!bool::extract_bound( + &operation .call_method0(py, "is_parametrized") .unwrap() - .as_ref(py) + .bind(py) ) .unwrap()); }) @@ -508,16 +474,16 @@ fn test_pyo3_substitute_parameters(input_definition: Operation) { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_definition).unwrap(); - let mut substitution_dict: HashMap<&str, f64> = HashMap::new(); - substitution_dict.insert("ro", 1.0); + let mut substitution_dict: HashMap = HashMap::new(); + substitution_dict.insert("ro".to_owned(), 1.0); let substitute_op = operation .call_method1(py, "substitute_parameters", (substitution_dict,)) .unwrap(); let substitute_param = operation; - let comparison_copy = bool::extract( - substitute_op - .as_ref(py) + let comparison_copy = bool::extract_bound( + &substitute_op + .bind(py) .call_method1("__eq__", (substitute_param,)) .unwrap(), ) @@ -540,8 +506,7 @@ fn test_pyo3_substitute_parameters_error(input_operation: Operation) { let mut substitution_dict: HashMap<&str, &str> = HashMap::new(); substitution_dict.insert("ro", "test"); let result = operation.call_method1(py, "substitute_parameters", (substitution_dict,)); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); }) } @@ -564,9 +529,9 @@ fn test_pyo3_remap_qubits(input_definition: Operation) { .unwrap(); let remap_param = operation; - let comparison_copy = bool::extract( - remap_op - .as_ref(py) + let comparison_copy = bool::extract_bound( + &remap_op + .bind(py) .call_method1("__eq__", (remap_param,)) .unwrap(), ) @@ -600,18 +565,18 @@ fn test_pyo3_richcmp(definition_1: Operation, definition_2: Operation) { let operation_one = convert_operation_to_pyobject(definition_1).unwrap(); let operation_two = convert_operation_to_pyobject(definition_2).unwrap(); - let comparison = bool::extract( - operation_one - .as_ref(py) + let comparison = bool::extract_bound( + &operation_one + .bind(py) .call_method1("__eq__", (operation_two.clone(),)) .unwrap(), ) .unwrap(); assert!(!comparison); - let comparison = bool::extract( - operation_one - .as_ref(py) + let comparison = bool::extract_bound( + &operation_one + .bind(py) .call_method1("__ne__", (operation_two.clone(),)) .unwrap(), ) @@ -663,17 +628,18 @@ fn test_pyo3_json_schema(operation: Operation) { _ => "1.0.0".to_string(), }; let pyobject = convert_operation_to_pyobject(operation).unwrap(); - let operation = pyobject.as_ref(py); + let operation = pyobject.bind(py); let schema: String = - String::extract(operation.call_method0("json_schema").unwrap()).unwrap(); + String::extract_bound(&operation.call_method0("json_schema").unwrap()).unwrap(); assert_eq!(schema, rust_schema); let current_version_string = - String::extract(operation.call_method0("current_version").unwrap()).unwrap(); + String::extract_bound(&operation.call_method0("current_version").unwrap()).unwrap(); let minimum_supported_version_string = - String::extract(operation.call_method0("min_supported_version").unwrap()).unwrap(); + String::extract_bound(&operation.call_method0("min_supported_version").unwrap()) + .unwrap(); assert_eq!(current_version_string, ROQOQO_VERSION); assert_eq!(minimum_supported_version_string, minimum_version); diff --git a/qoqo/tests/integration/operations/measurement_operations.rs b/qoqo/tests/integration/operations/measurement_operations.rs index c60e772b..4fbf187e 100644 --- a/qoqo/tests/integration/operations/measurement_operations.rs +++ b/qoqo/tests/integration/operations/measurement_operations.rs @@ -59,13 +59,14 @@ fn circuit_remapped() -> Circuit { circuit } -fn new_circuit(py: Python) -> &PyCell { - let circuit_type = py.get_type::(); +fn new_circuit(py: Python) -> Bound { + let circuit_type = py.get_type_bound::(); circuit_type .call0() .unwrap() - .downcast::>() + .downcast::() .unwrap() + .to_owned() } /// Test readout() input/function @@ -80,7 +81,8 @@ fn test_pyo3_readout(input_measurement: Operation) { Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_measurement).unwrap(); let readout_op: &String = - &String::extract(operation.call_method0(py, "readout").unwrap().as_ref(py)).unwrap(); + &String::extract_bound(&operation.call_method0(py, "readout").unwrap().bind(py)) + .unwrap(); let readout_param: String = String::from("ro"); assert_eq!(readout_op, &readout_param); }) @@ -93,13 +95,9 @@ fn test_pyo3_qubit_mapping(input_measurement: Operation, operation_name: &str) { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_measurement).unwrap(); - let readout_op: &HashMap = &HashMap::extract( - operation - .call_method0(py, operation_name) - .unwrap() - .as_ref(py), - ) - .unwrap(); + let readout_op: &HashMap = + &HashMap::extract_bound(&operation.call_method0(py, operation_name).unwrap().bind(py)) + .unwrap(); assert_eq!(readout_op, &create_qubit_mapping()); }) } @@ -114,14 +112,14 @@ fn test_pyo3_circuit(input_measurement: Operation) { Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_measurement).unwrap(); let to_circuit = operation.call_method0(py, "circuit").unwrap(); - let circuit_op = to_circuit.as_ref(py); + let circuit_op = to_circuit.bind(py); let circuit = new_circuit(py); let paulix = convert_operation_to_pyobject(Operation::from(PauliX::new(0))).unwrap(); circuit.call_method1("add", (paulix,)).unwrap(); let comparison_circuit = - bool::extract(circuit_op.call_method1("__eq__", (circuit,)).unwrap()).unwrap(); + bool::extract_bound(&circuit_op.call_method1("__eq__", (circuit,)).unwrap()).unwrap(); assert!(comparison_circuit); }) } @@ -139,15 +137,15 @@ fn test_pyo3_input_measurequbit_input() { .unwrap(); let qubit_op: &usize = - &usize::extract(operation.call_method0(py, "qubit").unwrap().as_ref(py)).unwrap(); + &usize::extract_bound(&operation.call_method0(py, "qubit").unwrap().bind(py)).unwrap(); let qubit_param: &usize = &0; assert_eq!(qubit_op, qubit_param); - let ro_index_op: &usize = &usize::extract( - operation + let ro_index_op: &usize = &usize::extract_bound( + &operation .call_method0(py, "readout_index") .unwrap() - .as_ref(py), + .bind(py), ) .unwrap(); let ro_index_param: &usize = &1; @@ -165,11 +163,11 @@ fn test_pyo3_input_pragmarepeatedmeasurements_input() { )) .unwrap(); - let nbr_meas_op: &usize = &usize::extract( - operation + let nbr_meas_op: &usize = &usize::extract_bound( + &operation .call_method0(py, "number_measurements") .unwrap() - .as_ref(py), + .bind(py), ) .unwrap(); let nbr_meas_param: &usize = &2; @@ -187,9 +185,9 @@ fn test_pyo3_involved_qubits_all(input_definition: Operation) { Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_definition).unwrap(); let to_involved = operation.call_method0(py, "involved_qubits").unwrap(); - let involved_op: HashSet<&str> = HashSet::extract(to_involved.as_ref(py)).unwrap(); - let mut involved_param: HashSet<&str> = HashSet::new(); - involved_param.insert("All"); + let involved_op: HashSet = HashSet::extract_bound(&to_involved.bind(py)).unwrap(); + let mut involved_param: HashSet = HashSet::new(); + involved_param.insert("All".to_owned()); assert_eq!(involved_op, involved_param); }) } @@ -202,7 +200,7 @@ fn test_pyo3_involved_qubits_0(input_definition: Operation) { Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_definition).unwrap(); let to_involved = operation.call_method0(py, "involved_qubits").unwrap(); - let involved_op: HashSet = HashSet::extract(to_involved.as_ref(py)).unwrap(); + let involved_op: HashSet = HashSet::extract_bound(&to_involved.bind(py)).unwrap(); let mut involved_param: HashSet = HashSet::new(); involved_param.insert(0); assert_eq!(involved_op, involved_param); @@ -221,9 +219,9 @@ fn test_pyo3_format_repr(input_measurement: Operation, format_repr: &str) { Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_measurement).unwrap(); let to_format = operation.call_method1(py, "__format__", ("",)).unwrap(); - let format_op: &str = <&str>::extract(to_format.as_ref(py)).unwrap(); + let format_op: String = String::extract_bound(&to_format.bind(py)).unwrap(); let to_repr = operation.call_method0(py, "__repr__").unwrap(); - let repr_op: &str = <&str>::extract(to_repr.as_ref(py)).unwrap(); + let repr_op: String = String::extract_bound(&to_repr.bind(py)).unwrap(); assert_eq!(format_op, format_repr); assert_eq!(repr_op, format_repr); }) @@ -244,17 +242,17 @@ fn test_pyo3_copy_deepcopy(input_measurement: Operation) { let deepcopy_op = operation.call_method1(py, "__deepcopy__", ("",)).unwrap(); let copy_deepcopy_param = operation; - let comparison_copy = bool::extract( - copy_op - .as_ref(py) + let comparison_copy = bool::extract_bound( + ©_op + .bind(py) .call_method1("__eq__", (copy_deepcopy_param.clone(),)) .unwrap(), ) .unwrap(); assert!(comparison_copy); - let comparison_deepcopy = bool::extract( - deepcopy_op - .as_ref(py) + let comparison_deepcopy = bool::extract_bound( + &deepcopy_op + .bind(py) .call_method1("__eq__", (copy_deepcopy_param,)) .unwrap(), ) @@ -274,7 +272,7 @@ fn test_pyo3_tags(input_measurement: Operation, tag_name: &str) { Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_measurement).unwrap(); let to_tag = operation.call_method0(py, "tags").unwrap(); - let tags_op: &Vec<&str> = &Vec::extract(to_tag.as_ref(py)).unwrap(); + let tags_op: &Vec = &Vec::extract_bound(&to_tag.bind(py)).unwrap(); let tags_param: &[&str] = &["Operation", "Measurement", "PragmaOperation", tag_name]; assert_eq!(tags_op, tags_param); }) @@ -292,7 +290,7 @@ fn test_pyo3_tags_measure_qubits() { ))) .unwrap(); let to_tag = operation.call_method0(py, "tags").unwrap(); - let tags_op: &Vec<&str> = &Vec::extract(to_tag.as_ref(py)).unwrap(); + let tags_op: &Vec = &Vec::extract_bound(&to_tag.bind(py)).unwrap(); let tags_param: &[&str] = &["Operation", "Measurement", "MeasureQubit"]; assert_eq!(tags_op, tags_param); }) @@ -310,7 +308,8 @@ fn test_pyo3_hqslang(input_measurement: Operation, hqslang_param: String) { Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_measurement).unwrap(); let hqslang_op: String = - String::extract(operation.call_method0(py, "hqslang").unwrap().as_ref(py)).unwrap(); + String::extract_bound(&operation.call_method0(py, "hqslang").unwrap().bind(py)) + .unwrap(); assert_eq!(hqslang_op, hqslang_param); }) } @@ -326,11 +325,11 @@ fn test_pyo3_is_parametrized(input_measurement: Operation) { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_measurement).unwrap(); - assert!(!bool::extract( - operation + assert!(!bool::extract_bound( + &operation .call_method0(py, "is_parametrized") .unwrap() - .as_ref(py) + .bind(py) ) .unwrap()); }) @@ -347,16 +346,16 @@ fn test_pyo3_substitute_parameters(input_measurement: Operation) { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_measurement).unwrap(); - let mut substitution_dict: HashMap<&str, f64> = HashMap::new(); - substitution_dict.insert("ro", 1.0); + let mut substitution_dict: HashMap = HashMap::new(); + substitution_dict.insert("ro".to_owned(), 1.0); let substitute_op = operation .call_method1(py, "substitute_parameters", (substitution_dict,)) .unwrap(); let substitute_param = operation; - let comparison_copy = bool::extract( - substitute_op - .as_ref(py) + let comparison_copy = bool::extract_bound( + &substitute_op + .bind(py) .call_method1("__eq__", (substitute_param,)) .unwrap(), ) @@ -385,8 +384,7 @@ fn test_pyo3_substitute_params_error(input_operation: Operation) { let mut substitution_dict: HashMap<&str, &str> = HashMap::new(); substitution_dict.insert("ro", "test"); let result = operation.call_method1(py, "substitute_parameters", (substitution_dict,)); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); }) } @@ -419,11 +417,11 @@ fn test_pyo3_remap_qubits(first_op: Operation, second_op: Operation) { .unwrap(); let comparison_op = convert_operation_to_pyobject(second_op).unwrap(); - let comparison = bool::extract( - remapped_op + let comparison = bool::extract_bound( + &remapped_op .call_method1(py, "__eq__", (comparison_op,)) .unwrap() - .as_ref(py), + .bind(py), ) .unwrap(); assert!(comparison); @@ -446,8 +444,7 @@ fn test_pyo3_remapqubits_error(input_operation: Operation) { let mut qubit_mapping: HashMap = HashMap::new(); qubit_mapping.insert(0, 2); let result = operation.call_method1(py, "remap_qubits", (qubit_mapping,)); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); }) } @@ -476,18 +473,18 @@ fn test_pyo3_richcmp(definition_1: Operation, definition_2: Operation) { let operation_one = convert_operation_to_pyobject(definition_1).unwrap(); let operation_two = convert_operation_to_pyobject(definition_2).unwrap(); - let comparison = bool::extract( - operation_one - .as_ref(py) + let comparison = bool::extract_bound( + &operation_one + .bind(py) .call_method1("__eq__", (operation_two.clone(),)) .unwrap(), ) .unwrap(); assert!(!comparison); - let comparison = bool::extract( - operation_one - .as_ref(py) + let comparison = bool::extract_bound( + &operation_one + .bind(py) .call_method1("__ne__", (operation_two.clone(),)) .unwrap(), ) @@ -507,25 +504,19 @@ fn test_pyo3_richcmp(definition_1: Operation, definition_2: Operation) { fn test_pyo3_new_set_number_of_measurements() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let operation = py.get_type::(); - let new_op = operation - .call1((0, "ro".to_string(), 1)) - .unwrap() - .downcast::>() - .unwrap(); + let operation = py.get_type_bound::(); + let binding = operation.call1((0, "ro".to_string(), 1)).unwrap(); + let new_op = binding.downcast::().unwrap(); let input_definition = Operation::from(MeasureQubit::new(0, String::from("ro"), 1)); let copy_param = convert_operation_to_pyobject(input_definition).unwrap(); let comparison_copy = - bool::extract(new_op.call_method1("__eq__", (copy_param,)).unwrap()).unwrap(); + bool::extract_bound(&new_op.call_method1("__eq__", (copy_param,)).unwrap()).unwrap(); assert!(comparison_copy); let meas_wrapper = new_op.extract::().unwrap(); - let new_op_diff = operation - .call1((1, "ro".to_string(), 1)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation.call1((1, "ro".to_string(), 1)).unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let meas_wrapper_diff = new_op_diff.extract::().unwrap(); let helper_ne: bool = meas_wrapper_diff != meas_wrapper; assert!(helper_ne); @@ -544,25 +535,23 @@ fn test_pyo3_new_set_number_of_measurements() { fn test_pyo3_new_get_statevector() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let operation = py.get_type::(); - let new_op = operation + let operation = py.get_type_bound::(); + let binding = operation .call1(("ro".to_string(), Option::::None)) - .unwrap() - .downcast::>() .unwrap(); + let new_op = binding.downcast::().unwrap(); let input_definition = Operation::from(PragmaGetStateVector::new(String::from("ro"), None)); let copy_param = convert_operation_to_pyobject(input_definition).unwrap(); let comparison_copy = - bool::extract(new_op.call_method1("__eq__", (copy_param,)).unwrap()).unwrap(); + bool::extract_bound(&new_op.call_method1("__eq__", (copy_param,)).unwrap()).unwrap(); assert!(comparison_copy); let meas_wrapper = new_op.extract::().unwrap(); - let new_op_diff = operation + let binding = operation .call1(("ro2".to_string(), new_circuit(py))) - .unwrap() - .downcast::>() .unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let meas_wrapper_diff = new_op_diff .extract::() .unwrap(); @@ -583,26 +572,24 @@ fn test_pyo3_new_get_statevector() { fn test_pyo3_new_get_density_matrix() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let operation = py.get_type::(); - let new_op = operation + let operation = py.get_type_bound::(); + let binding = operation .call1(("ro".to_string(), Option::::None)) - .unwrap() - .downcast::>() .unwrap(); + let new_op = binding.downcast::().unwrap(); let input_definition = Operation::from(PragmaGetDensityMatrix::new(String::from("ro"), None)); let copy_param = convert_operation_to_pyobject(input_definition).unwrap(); let comparison_copy = - bool::extract(new_op.call_method1("__eq__", (copy_param,)).unwrap()).unwrap(); + bool::extract_bound(&new_op.call_method1("__eq__", (copy_param,)).unwrap()).unwrap(); assert!(comparison_copy); let meas_wrapper = new_op.extract::().unwrap(); - let new_op_diff = operation + let binding = operation .call1(("ro2".to_string(), new_circuit(py))) - .unwrap() - .downcast::>() .unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let meas_wrapper_diff = new_op_diff .extract::() .unwrap(); @@ -623,11 +610,12 @@ fn test_pyo3_new_get_density_matrix() { fn test_pyo3_new_get_occupation_proba() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let operation = py.get_type::(); - let new_op = operation + let operation = py.get_type_bound::(); + let binding = operation .call1(("ro".to_string(), Option::::None)) - .unwrap() - .downcast::>() + .unwrap(); + let new_op = binding + .downcast::() .unwrap(); let input_definition = Operation::from(PragmaGetOccupationProbability::new( @@ -636,16 +624,17 @@ fn test_pyo3_new_get_occupation_proba() { )); let copy_param = convert_operation_to_pyobject(input_definition).unwrap(); let comparison_copy = - bool::extract(new_op.call_method1("__eq__", (copy_param,)).unwrap()).unwrap(); + bool::extract_bound(&new_op.call_method1("__eq__", (copy_param,)).unwrap()).unwrap(); assert!(comparison_copy); let meas_wrapper = new_op .extract::() .unwrap(); - let new_op_diff = operation + let binding = operation .call1(("ro2".to_string(), new_circuit(py))) - .unwrap() - .downcast::>() + .unwrap(); + let new_op_diff = binding + .downcast::() .unwrap(); let meas_wrapper_diff = new_op_diff .extract::() @@ -667,12 +656,11 @@ fn test_pyo3_new_get_occupation_proba() { fn test_pyo3_new_get_pauli_product() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let operation = py.get_type::(); - let new_op = operation + let operation = py.get_type_bound::(); + let binding = operation .call1((create_qubit_mapping(), "ro".to_string(), new_circuit(py))) - .unwrap() - .downcast::>() .unwrap(); + let new_op = binding.downcast::().unwrap(); let input_definition = Operation::from(PragmaGetPauliProduct::new( create_qubit_mapping(), @@ -681,15 +669,14 @@ fn test_pyo3_new_get_pauli_product() { )); let copy_param = convert_operation_to_pyobject(input_definition).unwrap(); let comparison_copy = - bool::extract(new_op.call_method1("__eq__", (copy_param,)).unwrap()).unwrap(); + bool::extract_bound(&new_op.call_method1("__eq__", (copy_param,)).unwrap()).unwrap(); assert!(comparison_copy); let meas_wrapper = new_op.extract::().unwrap(); - let new_op_diff = operation + let binding = operation .call1((create_qubit_mapping(), "ro2".to_string(), new_circuit(py))) - .unwrap() - .downcast::>() .unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let meas_wrapper_diff = new_op_diff .extract::() .unwrap(); @@ -710,11 +697,12 @@ fn test_pyo3_new_get_pauli_product() { fn test_pyo3_new_repeated_measurement() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let operation = py.get_type::(); - let new_op = operation + let operation = py.get_type_bound::(); + let binding = operation .call1(("ro".to_string(), 1, Some(create_qubit_mapping()))) - .unwrap() - .downcast::>() + .unwrap(); + let new_op = binding + .downcast::() .unwrap(); let input_definition = Operation::from(PragmaRepeatedMeasurement::new( @@ -724,16 +712,17 @@ fn test_pyo3_new_repeated_measurement() { )); let copy_param = convert_operation_to_pyobject(input_definition).unwrap(); let comparison_copy = - bool::extract(new_op.call_method1("__eq__", (copy_param,)).unwrap()).unwrap(); + bool::extract_bound(&new_op.call_method1("__eq__", (copy_param,)).unwrap()).unwrap(); assert!(comparison_copy); let meas_wrapper = new_op .extract::() .unwrap(); - let new_op_diff = operation + let binding = operation .call1(("ro".to_string(), 2, Some(create_qubit_mapping()))) - .unwrap() - .downcast::>() + .unwrap(); + let new_op_diff = binding + .downcast::() .unwrap(); let meas_wrapper_diff = new_op_diff .extract::() @@ -789,17 +778,18 @@ fn test_pyo3_json_schema(operation: Operation) { pyo3::prepare_freethreaded_python(); pyo3::Python::with_gil(|py| { let pyobject = convert_operation_to_pyobject(operation).unwrap(); - let operation = pyobject.as_ref(py); + let operation = pyobject.bind(py); let schema: String = - String::extract(operation.call_method0("json_schema").unwrap()).unwrap(); + String::extract_bound(&operation.call_method0("json_schema").unwrap()).unwrap(); assert_eq!(schema, rust_schema); let current_version_string = - String::extract(operation.call_method0("current_version").unwrap()).unwrap(); + String::extract_bound(&operation.call_method0("current_version").unwrap()).unwrap(); let minimum_supported_version_string = - String::extract(operation.call_method0("min_supported_version").unwrap()).unwrap(); + String::extract_bound(&operation.call_method0("min_supported_version").unwrap()) + .unwrap(); assert_eq!(current_version_string, ROQOQO_VERSION); assert_eq!(minimum_supported_version_string, "1.0.0"); diff --git a/qoqo/tests/integration/operations/mod.rs b/qoqo/tests/integration/operations/mod.rs index b1791493..21374b1e 100644 --- a/qoqo/tests/integration/operations/mod.rs +++ b/qoqo/tests/integration/operations/mod.rs @@ -41,18 +41,20 @@ use qoqo_calculator_pyo3::CalculatorFloatWrapper; pub fn convert_cf_to_pyobject( py: Python, parameter: CalculatorFloat, -) -> &PyCell { - let parameter_type = py.get_type::(); +) -> Bound { + let parameter_type = py.get_type_bound::(); match parameter { CalculatorFloat::Float(x) => parameter_type .call1((x,)) .unwrap() - .downcast::>() - .unwrap(), + .downcast::() + .unwrap() + .to_owned(), CalculatorFloat::Str(x) => parameter_type .call1((x,)) .unwrap() - .downcast::>() - .unwrap(), + .downcast::() + .unwrap() + .to_owned(), } } diff --git a/qoqo/tests/integration/operations/multi_qubit_gate_operations.rs b/qoqo/tests/integration/operations/multi_qubit_gate_operations.rs index 84de5aaf..7518e5f3 100644 --- a/qoqo/tests/integration/operations/multi_qubit_gate_operations.rs +++ b/qoqo/tests/integration/operations/multi_qubit_gate_operations.rs @@ -30,25 +30,7 @@ use std::collections::HashMap; use std::convert::TryInto; use test_case::test_case; -// helper function to convert CalculatorFloat into a python object -fn convert_cf_to_pyobject( - py: Python, - parameter: CalculatorFloat, -) -> &PyCell { - let parameter_type = py.get_type::(); - match parameter { - CalculatorFloat::Float(x) => parameter_type - .call1((x,)) - .unwrap() - .downcast::>() - .unwrap(), - CalculatorFloat::Str(x) => parameter_type - .call1((x,)) - .unwrap() - .downcast::>() - .unwrap(), - } -} +use super::convert_cf_to_pyobject; #[test_case(Operation::from(MultiQubitMS::new(vec![0, 1], CalculatorFloat::ZERO)), (vec![0, 1], 0.0,), "__eq__"; "MultiQubitMS_eq")] #[test_case(Operation::from(MultiQubitMS::new(vec![2, 3], CalculatorFloat::ZERO)), (vec![0, 1], 0.0,), "__ne__"; "MultiQubitMS_ne")] @@ -57,15 +39,12 @@ fn test_new_multi_qubit_ms(input_operation: Operation, arguments: (Vec, f64 pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { // Basic initialisation, no errors - let operation_type = py.get_type::(); - let operation_py = operation_type - .call1(arguments) - .unwrap() - .downcast::>() - .unwrap(); - let comparison = bool::extract( - operation - .as_ref(py) + let operation_type = py.get_type_bound::(); + let binding = operation_type.call1(arguments).unwrap(); + let operation_py = binding.downcast::().unwrap(); + let comparison = bool::extract_bound( + &operation + .bind(py) .call_method1(method, (operation_py,)) .unwrap(), ) @@ -74,16 +53,12 @@ fn test_new_multi_qubit_ms(input_operation: Operation, arguments: (Vec, f64 // Error initialisation let result = operation_type.call1(([0, 1], vec!["fails"])); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); // Testing PartialEq, Clone and Debug let def_wrapper = operation_py.extract::().unwrap(); - let new_op_diff = operation_type - .call1((vec![1, 2], 0.0)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation_type.call1((vec![1, 2], 0.0)).unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let def_wrapper_diff = new_op_diff.extract::().unwrap(); let helper_ne: bool = def_wrapper_diff != def_wrapper; assert!(helper_ne); @@ -104,15 +79,12 @@ fn test_new_multi_qubit_zz(input_operation: Operation, arguments: (Vec, f64 pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { // Basic initialisation, no errors - let operation_type = py.get_type::(); - let operation_py = operation_type - .call1(arguments) - .unwrap() - .downcast::>() - .unwrap(); - let comparison = bool::extract( - operation - .as_ref(py) + let operation_type = py.get_type_bound::(); + let binding = operation_type.call1(arguments).unwrap(); + let operation_py = binding.downcast::().unwrap(); + let comparison = bool::extract_bound( + &operation + .bind(py) .call_method1(method, (operation_py,)) .unwrap(), ) @@ -121,16 +93,12 @@ fn test_new_multi_qubit_zz(input_operation: Operation, arguments: (Vec, f64 // Error initialisation let result = operation_type.call1(([0, 1], vec!["fails"])); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); // Testing PartialEq, Clone and Debug let def_wrapper = operation_py.extract::().unwrap(); - let new_op_diff = operation_type - .call1((vec![1, 2], 0.0)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation_type.call1((vec![1, 2], 0.0)).unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let def_wrapper_diff = new_op_diff.extract::().unwrap(); let helper_ne: bool = def_wrapper_diff != def_wrapper; assert!(helper_ne); @@ -151,11 +119,11 @@ fn test_pyo3_is_parametrized(input_operation: Operation) { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_operation).unwrap(); - assert!(bool::extract( - operation + assert!(bool::extract_bound( + &operation .call_method0(py, "is_parametrized") .unwrap() - .as_ref(py) + .bind(py) ) .unwrap()); }) @@ -168,11 +136,11 @@ fn test_pyo3_is_not_parametrized(input_operation: Operation) { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_operation).unwrap(); - assert!(!bool::extract( - operation + assert!(!bool::extract_bound( + &operation .call_method0(py, "is_parametrized") .unwrap() - .as_ref(py) + .bind(py) ) .unwrap()); }) @@ -187,12 +155,12 @@ fn test_pyo3_theta(theta: CalculatorFloat, input_operation: Operation) { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_operation).unwrap(); - let theta_op: CalculatorFloatWrapper = CalculatorFloatWrapper::extract( - operation.call_method0(py, "theta").unwrap().as_ref(py), + let theta_op: CalculatorFloatWrapper = CalculatorFloatWrapper::extract_bound( + &operation.call_method0(py, "theta").unwrap().bind(py), ) .unwrap(); let theta_param: CalculatorFloatWrapper = - CalculatorFloatWrapper::extract(convert_cf_to_pyobject(py, theta)).unwrap(); + CalculatorFloatWrapper::extract_bound(&convert_cf_to_pyobject(py, theta)).unwrap(); assert_eq!(theta_op.internal, theta_param.internal); }) } @@ -209,7 +177,7 @@ fn test_pyo3_qubits(qubit: Vec, input_operation: Operation) { let qubit_op: Vec = operation .call_method0(py, "qubits") .unwrap() - .as_ref(py) + .bind(py) .extract() .unwrap(); assert_eq!(qubit_op, qubit); @@ -224,7 +192,8 @@ fn test_pyo3_hqslang(name: &'static str, input_operation: Operation) { Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_operation).unwrap(); let name_op: String = - String::extract(operation.call_method0(py, "hqslang").unwrap().as_ref(py)).unwrap(); + String::extract_bound(&operation.call_method0(py, "hqslang").unwrap().bind(py)) + .unwrap(); assert_eq!(name_op, name.to_string()); }) } @@ -255,7 +224,8 @@ fn test_pyo3_tags(input_operation: Operation, tags: Vec<&str>) { Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_operation).unwrap(); let tags_op: Vec = - Vec::::extract(operation.call_method0(py, "tags").unwrap().as_ref(py)).unwrap(); + Vec::::extract_bound(&operation.call_method0(py, "tags").unwrap().bind(py)) + .unwrap(); assert_eq!(tags_op.len(), tags.len()); for i in 0..tags.len() { assert_eq!(tags_op[i], tags[i]); @@ -274,7 +244,7 @@ fn test_pyo3_remapqubits(input_operation: Operation) { let qubits: Vec = operation .call_method0(py, "qubits") .unwrap() - .as_ref(py) + .bind(py) .extract() .unwrap(); assert_eq!(qubits, vec![0, 1, 2]); @@ -290,7 +260,7 @@ fn test_pyo3_remapqubits(input_operation: Operation) { let qubits_new: Vec = result .call_method0(py, "qubits") .unwrap() - .as_ref(py) + .bind(py) .extract() .unwrap(); assert_eq!(qubits_new, vec![1, 2, 0]); @@ -311,8 +281,7 @@ fn test_pyo3_remapqubits_error(input_operation: Operation) { let mut qubit_mapping: HashMap = HashMap::new(); qubit_mapping.insert(2, 0); let result = operation.call_method1(py, "remap_qubits", (qubit_mapping,)); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); }) } @@ -324,10 +293,13 @@ fn test_pyo3_unitarymatrix(input_operation: Operation) { Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_operation.clone()).unwrap(); let py_result = operation.call_method0(py, "unitary_matrix").unwrap(); - let result_matrix = py_result - .downcast::>(py) + let result_matrix: Array2 = py_result + .downcast_bound::>(py) .unwrap() - .to_owned_array(); + .as_gil_ref() + .readonly() + .as_array() + .to_owned(); // compare to reference matrix obtained in Rust directly (without passing to Python) let gate: MultiQubitGateOperation = input_operation.try_into().unwrap(); @@ -346,8 +318,7 @@ fn test_pyo3_unitarymatrix_error(input_operation: Operation) { Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_operation.clone()).unwrap(); let py_result = operation.call_method0(py, "unitary_matrix"); - let result_ref = py_result.as_ref(); - assert!(result_ref.is_err()); + assert!(py_result.is_err()); }) } @@ -412,17 +383,17 @@ fn test_pyo3_copy_deepcopy(input_operation: Operation) { let deepcopy_op = operation.call_method1(py, "__deepcopy__", ("",)).unwrap(); let copy_deepcopy_param = operation; - let comparison_copy = bool::extract( - copy_op - .as_ref(py) + let comparison_copy = bool::extract_bound( + ©_op + .bind(py) .call_method1("__eq__", (copy_deepcopy_param.clone(),)) .unwrap(), ) .unwrap(); assert!(comparison_copy); - let comparison_deepcopy = bool::extract( - deepcopy_op - .as_ref(py) + let comparison_deepcopy = bool::extract_bound( + &deepcopy_op + .bind(py) .call_method1("__eq__", (copy_deepcopy_param,)) .unwrap(), ) @@ -445,10 +416,10 @@ fn test_pyo3_format_repr(format_repr: &str, input_operation: Operation) { Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_operation).unwrap(); let to_format = operation.call_method1(py, "__format__", ("",)).unwrap(); - let format_op: &str = <&str>::extract(to_format.as_ref(py)).unwrap(); + let format_op: String = String::extract_bound(&to_format.bind(py)).unwrap(); assert_eq!(format_op, format_repr); let to_repr = operation.call_method0(py, "__repr__").unwrap(); - let repr_op: &str = <&str>::extract(to_repr.as_ref(py)).unwrap(); + let repr_op: String = String::extract_bound(&to_repr.bind(py)).unwrap(); assert_eq!(repr_op, format_repr); }) } @@ -460,8 +431,8 @@ fn test_pyo3_substitute_params_rotate(input_operation: Operation) { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_operation.clone()).unwrap(); - let mut substitution_dict_py: HashMap<&str, f64> = HashMap::new(); - substitution_dict_py.insert("theta", 1.0); + let mut substitution_dict_py: HashMap = HashMap::new(); + substitution_dict_py.insert("theta".to_owned(), 1.0); let substitute_op = operation .call_method1(py, "substitute_parameters", (substitution_dict_py,)) .unwrap(); @@ -473,9 +444,9 @@ fn test_pyo3_substitute_params_rotate(input_operation: Operation) { .unwrap(); let test_operation = convert_operation_to_pyobject(substitute_param).unwrap(); - let comparison = bool::extract( - substitute_op - .as_ref(py) + let comparison = bool::extract_bound( + &substitute_op + .bind(py) .call_method1("__eq__", (test_operation,)) .unwrap(), ) @@ -491,10 +462,9 @@ fn test_pyo3_substitute_params_error(input_operation: Operation) { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_operation).unwrap(); - let substitution_dict: HashMap<&str, f64> = HashMap::new(); + let substitution_dict: HashMap = HashMap::new(); let result = operation.call_method1(py, "substitute_parameters", (substitution_dict,)); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); }) } @@ -513,11 +483,11 @@ fn test_pyo3_rotate_powercf(first_op: Operation, second_op: Operation) { let comparison_op = convert_operation_to_pyobject(second_op).unwrap(); let remapped_op = operation.call_method1(py, "powercf", (power,)).unwrap(); - let comparison = bool::extract( - remapped_op + let comparison = bool::extract_bound( + &remapped_op .call_method1(py, "__eq__", (comparison_op,)) .unwrap() - .as_ref(py), + .bind(py), ) .unwrap(); assert!(comparison); @@ -537,18 +507,18 @@ fn test_pyo3_richcmp(definition_1: Operation, definition_2: Operation) { let operation_one = convert_operation_to_pyobject(definition_1).unwrap(); let operation_two = convert_operation_to_pyobject(definition_2).unwrap(); - let comparison = bool::extract( - operation_one - .as_ref(py) + let comparison = bool::extract_bound( + &operation_one + .bind(py) .call_method1("__eq__", (operation_two.clone(),)) .unwrap(), ) .unwrap(); assert!(!comparison); - let comparison = bool::extract( - operation_one - .as_ref(py) + let comparison = bool::extract_bound( + &operation_one + .bind(py) .call_method1("__ne__", (operation_two.clone(),)) .unwrap(), ) @@ -579,17 +549,18 @@ fn test_pyo3_json_schema(operation: Operation) { pyo3::prepare_freethreaded_python(); pyo3::Python::with_gil(|py| { let pyobject = convert_operation_to_pyobject(operation).unwrap(); - let operation = pyobject.as_ref(py); + let operation = pyobject.bind(py); let schema: String = - String::extract(operation.call_method0("json_schema").unwrap()).unwrap(); + String::extract_bound(&operation.call_method0("json_schema").unwrap()).unwrap(); assert_eq!(schema, rust_schema); let current_version_string = - String::extract(operation.call_method0("current_version").unwrap()).unwrap(); + String::extract_bound(&operation.call_method0("current_version").unwrap()).unwrap(); let minimum_supported_version_string = - String::extract(operation.call_method0("min_supported_version").unwrap()).unwrap(); + String::extract_bound(&operation.call_method0("min_supported_version").unwrap()) + .unwrap(); assert_eq!(current_version_string, ROQOQO_VERSION); assert_eq!(minimum_supported_version_string, "1.0.0"); diff --git a/qoqo/tests/integration/operations/operation_conversions.rs b/qoqo/tests/integration/operations/operation_conversions.rs index bdbba4f0..5bf50600 100644 --- a/qoqo/tests/integration/operations/operation_conversions.rs +++ b/qoqo/tests/integration/operations/operation_conversions.rs @@ -141,7 +141,7 @@ fn test_conversion(input: Operation) { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input.clone()).unwrap(); - let output = convert_pyany_to_operation(operation.as_ref(py)).unwrap(); + let output = convert_pyany_to_operation(operation.bind(py)).unwrap(); assert_eq!(input, output) }) } @@ -182,7 +182,7 @@ fn test_conversion_feature(input: Operation) { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input.clone()).unwrap(); - let output = convert_pyany_to_operation(operation.as_ref(py)).unwrap(); + let output = convert_pyany_to_operation(operation.bind(py)).unwrap(); assert_eq!(input, output) }) } diff --git a/qoqo/tests/integration/operations/pragma_operations.rs b/qoqo/tests/integration/operations/pragma_operations.rs index 87d35102..cf3b4e50 100644 --- a/qoqo/tests/integration/operations/pragma_operations.rs +++ b/qoqo/tests/integration/operations/pragma_operations.rs @@ -27,25 +27,7 @@ use roqoqo::ROQOQO_VERSION; use std::collections::{HashMap, HashSet}; use test_case::test_case; -// helper function to convert CalculatorFloat into a python object -fn convert_cf_to_pyobject( - py: Python, - parameter: CalculatorFloat, -) -> &PyCell { - let parameter_type = py.get_type::(); - match parameter { - CalculatorFloat::Float(x) => parameter_type - .call1((x,)) - .unwrap() - .downcast::>() - .unwrap(), - CalculatorFloat::Str(x) => parameter_type - .call1((x,)) - .unwrap() - .downcast::>() - .unwrap(), - } -} +use super::convert_cf_to_pyobject; fn reordering() -> HashMap { let mut reordering: HashMap = HashMap::new(); @@ -107,13 +89,14 @@ fn circuit_remapped() -> Circuit { circuit } -fn new_circuit(py: Python) -> &PyCell { - let circuit_type = py.get_type::(); +fn new_circuit(py: Python) -> Bound { + let circuit_type = py.get_type_bound::(); circuit_type .call0() .unwrap() - .downcast::>() + .downcast::() .unwrap() + .to_owned() } /// Test inputs of PragmaSetNumberOfMeasurements @@ -124,18 +107,19 @@ fn test_pyo3_inputs_setnumbermeasurements() { Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_pragma).unwrap(); - let nbr_meas_op: &usize = &usize::extract( - operation + let nbr_meas_op: &usize = &usize::extract_bound( + &operation .call_method0(py, "number_measurements") .unwrap() - .as_ref(py), + .bind(py), ) .unwrap(); let nbr_meas_param: &usize = &1_usize; assert_eq!(nbr_meas_op, nbr_meas_param); let readout_op: &String = - &String::extract(operation.call_method0(py, "readout").unwrap().as_ref(py)).unwrap(); + &String::extract_bound(&operation.call_method0(py, "readout").unwrap().bind(py)) + .unwrap(); let readout_param: &String = &String::from("ro"); assert_eq!(readout_op, readout_param); }) @@ -152,11 +136,8 @@ fn test_pyo3_inputs_loop() { Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_pragma).unwrap(); - let nbr_meas_op: &CalculatorFloatWrapper = &CalculatorFloatWrapper::extract( - operation - .call_method0(py, "repetitions") - .unwrap() - .as_ref(py), + let nbr_meas_op: &CalculatorFloatWrapper = &CalculatorFloatWrapper::extract_bound( + &operation.call_method0(py, "repetitions").unwrap().bind(py), ) .unwrap(); let nbr_meas_param: &CalculatorFloatWrapper = &CalculatorFloatWrapper { @@ -164,9 +145,10 @@ fn test_pyo3_inputs_loop() { }; assert_eq!(nbr_meas_op.internal, nbr_meas_param.internal); - let readout_op: &CircuitWrapper = - &CircuitWrapper::extract(operation.call_method0(py, "circuit").unwrap().as_ref(py)) - .unwrap(); + let readout_op: &CircuitWrapper = &CircuitWrapper::extract_bound( + &operation.call_method0(py, "circuit").unwrap().bind(py), + ) + .unwrap(); let readout_param: &CircuitWrapper = &CircuitWrapper { internal: Circuit::new(), }; @@ -184,8 +166,8 @@ fn test_pyo3_inputs_setstatevector() { let to_op: Py = operation.call_method0(py, "statevector").unwrap(); - let to_statevector_op: PyReadonlyArray1 = to_op.as_ref(py).extract().unwrap(); - let statevector_op: Array1 = to_statevector_op.to_owned_array(); + let to_statevector_op: PyReadonlyArray1 = to_op.bind(py).extract().unwrap(); + let statevector_op: Array1 = to_statevector_op.as_array().to_owned(); assert_eq!(statevector_op, statevector()); }) } @@ -199,10 +181,14 @@ fn test_pyo3_inputs_setdensitymatrix() { let operation = convert_operation_to_pyobject(input_pragma).unwrap(); let to_operators_py = operation.call_method0(py, "density_matrix").unwrap(); let to_operators_op = to_operators_py - .as_ref(py) + .bind(py) .downcast::>() .unwrap(); - let densmat_array = to_operators_op.readonly().as_array().to_owned(); + let densmat_array = to_operators_op + .as_gil_ref() + .readonly() + .as_array() + .to_owned(); assert_eq!(densmat_array, densitymatrix()); }) @@ -216,11 +202,11 @@ fn test_pyo3_inputs_repeatgate() { Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_pragma).unwrap(); - let repeat_op: &usize = &usize::extract( - operation + let repeat_op: &usize = &usize::extract_bound( + &operation .call_method0(py, "repetition_coefficient") .unwrap() - .as_ref(py), + .bind(py), ) .unwrap(); assert_eq!(repeat_op, &3_usize); @@ -240,22 +226,19 @@ fn test_pyo3_inputs_overrotation() { Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_pragma).unwrap(); - let string_op: &String = &String::extract( - operation - .call_method0(py, "gate_hqslang") - .unwrap() - .as_ref(py), - ) - .unwrap(); + let string_op: &String = + &String::extract_bound(&operation.call_method0(py, "gate_hqslang").unwrap().bind(py)) + .unwrap(); assert_eq!(string_op, &"RotateX".to_string()); let qubits_op: &Vec = - &Vec::extract(operation.call_method0(py, "qubits").unwrap().as_ref(py)).unwrap(); + &Vec::extract_bound(&operation.call_method0(py, "qubits").unwrap().bind(py)).unwrap(); assert_eq!(qubits_op, &vec![0]); let amp_op: &f64 = - &f64::extract(operation.call_method0(py, "amplitude").unwrap().as_ref(py)).unwrap(); + &f64::extract_bound(&operation.call_method0(py, "amplitude").unwrap().bind(py)) + .unwrap(); assert_eq!(amp_op, &0.03); let var_op: &f64 = - &f64::extract(operation.call_method0(py, "variance").unwrap().as_ref(py)).unwrap(); + &f64::extract_bound(&operation.call_method0(py, "variance").unwrap().bind(py)).unwrap(); assert_eq!(var_op, &0.001); }) } @@ -268,11 +251,11 @@ fn test_pyo3_inputs_boostnoise() { Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_pragma).unwrap(); - let boost_op: &f64 = &f64::extract( - operation + let boost_op: &f64 = &f64::extract_bound( + &operation .call_method0(py, "noise_coefficient") .unwrap() - .as_ref(py), + .bind(py), ) .unwrap(); assert_eq!( @@ -294,15 +277,15 @@ fn test_pyo3_inputs_stop() { let operation = convert_operation_to_pyobject(input_pragma).unwrap(); let qubits_op: &Vec = - &Vec::extract(operation.call_method0(py, "qubits").unwrap().as_ref(py)).unwrap(); + &Vec::extract_bound(&operation.call_method0(py, "qubits").unwrap().bind(py)).unwrap(); let qubits_param: Vec = vec![0, 1]; assert_eq!(qubits_op, &qubits_param); - let boost_op: &f64 = &f64::extract( - operation + let boost_op: &f64 = &f64::extract_bound( + &operation .call_method0(py, "execution_time") .unwrap() - .as_ref(py), + .bind(py), ) .unwrap(); assert_eq!( @@ -321,7 +304,7 @@ fn test_pyo3_inputs_globalphase() { let operation = convert_operation_to_pyobject(input_pragma).unwrap(); let boost_op: &f64 = - &f64::extract(operation.call_method0(py, "phase").unwrap().as_ref(py)).unwrap(); + &f64::extract_bound(&operation.call_method0(py, "phase").unwrap().bind(py)).unwrap(); assert_eq!(CalculatorFloat::from(boost_op), CalculatorFloat::from(0.05)); }) } @@ -338,12 +321,13 @@ fn test_pyo3_inputs_sleep() { let operation = convert_operation_to_pyobject(input_pragma).unwrap(); let qubits_op: &Vec = - &Vec::extract(operation.call_method0(py, "qubits").unwrap().as_ref(py)).unwrap(); + &Vec::extract_bound(&operation.call_method0(py, "qubits").unwrap().bind(py)).unwrap(); let qubits_param: Vec = vec![0, 1]; assert_eq!(qubits_op, &qubits_param); let boost_op: &f64 = - &f64::extract(operation.call_method0(py, "sleep_time").unwrap().as_ref(py)).unwrap(); + &f64::extract_bound(&operation.call_method0(py, "sleep_time").unwrap().bind(py)) + .unwrap(); assert_eq!( CalculatorFloat::from(boost_op), CalculatorFloat::from(0.0000001), @@ -360,7 +344,7 @@ fn test_pyo3_inputs_activereset() { let operation = convert_operation_to_pyobject(input_pragma).unwrap(); let qubit_op: &usize = - &usize::extract(operation.call_method0(py, "qubit").unwrap().as_ref(py)).unwrap(); + &usize::extract_bound(&operation.call_method0(py, "qubit").unwrap().bind(py)).unwrap(); let qubit_param: &usize = &0_usize; assert_eq!(qubit_op, qubit_param); }) @@ -376,15 +360,15 @@ fn test_pyo3_inputs_startdecompblock() { let operation = convert_operation_to_pyobject(input_pragma).unwrap(); let qubits_op: &Vec = - &Vec::extract(operation.call_method0(py, "qubits").unwrap().as_ref(py)).unwrap(); + &Vec::extract_bound(&operation.call_method0(py, "qubits").unwrap().bind(py)).unwrap(); let qubits_param: Vec = vec![0, 1]; assert_eq!(qubits_op, &qubits_param); - let boost_op: HashMap = HashMap::extract( - operation + let boost_op: HashMap = HashMap::extract_bound( + &operation .call_method0(py, "reordering_dictionary") .unwrap() - .as_ref(py), + .bind(py), ) .unwrap(); assert_eq!(boost_op, reordering()); @@ -400,7 +384,7 @@ fn test_pyo3_inputs_stopdecompblock() { let operation = convert_operation_to_pyobject(input_pragma).unwrap(); let qubits_op: &Vec = - &Vec::extract(operation.call_method0(py, "qubits").unwrap().as_ref(py)).unwrap(); + &Vec::extract_bound(&operation.call_method0(py, "qubits").unwrap().bind(py)).unwrap(); let qubits_param: Vec = vec![0, 1]; assert_eq!(qubits_op, &qubits_param); }) @@ -416,19 +400,20 @@ fn test_pyo3_inputs_noise(input_pragma: Operation) { let operation = convert_operation_to_pyobject(input_pragma).unwrap(); let qubit_op: &usize = - &usize::extract(operation.call_method0(py, "qubit").unwrap().as_ref(py)).unwrap(); + &usize::extract_bound(&operation.call_method0(py, "qubit").unwrap().bind(py)).unwrap(); let qubit_param: &usize = &0_usize; assert_eq!(qubit_op, qubit_param); let gate_time_op: &f64 = - &f64::extract(operation.call_method0(py, "gate_time").unwrap().as_ref(py)).unwrap(); + &f64::extract_bound(&operation.call_method0(py, "gate_time").unwrap().bind(py)) + .unwrap(); assert_eq!( CalculatorFloat::from(gate_time_op), CalculatorFloat::from(0.005), ); let rate_op: &f64 = - &f64::extract(operation.call_method0(py, "rate").unwrap().as_ref(py)).unwrap(); + &f64::extract_bound(&operation.call_method0(py, "rate").unwrap().bind(py)).unwrap(); assert_eq!(CalculatorFloat::from(rate_op), CalculatorFloat::from(0.02)); }) } @@ -447,22 +432,23 @@ fn test_pyo3_inputs_randomnoise() { let operation = convert_operation_to_pyobject(input_pragma).unwrap(); let qubit_op: &usize = - &usize::extract(operation.call_method0(py, "qubit").unwrap().as_ref(py)).unwrap(); + &usize::extract_bound(&operation.call_method0(py, "qubit").unwrap().bind(py)).unwrap(); let qubit_param: &usize = &0_usize; assert_eq!(qubit_op, qubit_param); let gate_time_op: &f64 = - &f64::extract(operation.call_method0(py, "gate_time").unwrap().as_ref(py)).unwrap(); + &f64::extract_bound(&operation.call_method0(py, "gate_time").unwrap().bind(py)) + .unwrap(); assert_eq!( CalculatorFloat::from(gate_time_op), CalculatorFloat::from(0.005), ); - let depol_rate_op: &f64 = &f64::extract( - operation + let depol_rate_op: &f64 = &f64::extract_bound( + &operation .call_method0(py, "depolarising_rate") .unwrap() - .as_ref(py), + .bind(py), ) .unwrap(); assert_eq!( @@ -470,11 +456,11 @@ fn test_pyo3_inputs_randomnoise() { CalculatorFloat::from(0.02) ); - let dephas_rate_op: &f64 = &f64::extract( - operation + let dephas_rate_op: &f64 = &f64::extract_bound( + &operation .call_method0(py, "dephasing_rate") .unwrap() - .as_ref(py), + .bind(py), ) .unwrap(); assert_eq!( @@ -497,12 +483,13 @@ fn test_pyo3_inputs_generalnoise() { let operation = convert_operation_to_pyobject(input_pragma).unwrap(); let qubit_op: &usize = - &usize::extract(operation.call_method0(py, "qubit").unwrap().as_ref(py)).unwrap(); + &usize::extract_bound(&operation.call_method0(py, "qubit").unwrap().bind(py)).unwrap(); let qubit_param: &usize = &0_usize; assert_eq!(qubit_op, qubit_param); let gate_time_op: &f64 = - &f64::extract(operation.call_method0(py, "gate_time").unwrap().as_ref(py)).unwrap(); + &f64::extract_bound(&operation.call_method0(py, "gate_time").unwrap().bind(py)) + .unwrap(); assert_eq!( CalculatorFloat::from(gate_time_op), CalculatorFloat::from(0.005), @@ -510,10 +497,14 @@ fn test_pyo3_inputs_generalnoise() { let to_operators_py = operation.call_method0(py, "rates").unwrap(); let to_operators_op = to_operators_py - .as_ref(py) + .bind(py) .downcast::>() .unwrap(); - let operators_op = to_operators_op.readonly().as_array().to_owned(); + let operators_op = to_operators_op + .as_gil_ref() + .readonly() + .as_array() + .to_owned(); assert_eq!(operators_op, operators()); }) } @@ -530,32 +521,32 @@ fn test_pyo3_inputs_conditional() { Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_pragma).unwrap(); - let condition_register_op: &String = &String::extract( - operation + let condition_register_op: &String = &String::extract_bound( + &operation .call_method0(py, "condition_register") .unwrap() - .as_ref(py), + .bind(py), ) .unwrap(); let condition_register_param: &String = &String::from("ro"); assert_eq!(condition_register_op, condition_register_param); - let condition_index_op: &usize = &usize::extract( - operation + let condition_index_op: &usize = &usize::extract_bound( + &operation .call_method0(py, "condition_index") .unwrap() - .as_ref(py), + .bind(py), ) .unwrap(); assert_eq!(condition_index_op, &1_usize); let to_circuit = operation.call_method0(py, "circuit").unwrap(); - let circuit_op = to_circuit.as_ref(py); + let circuit_op = to_circuit.bind(py); let circuit = new_circuit(py); let paulix = convert_operation_to_pyobject(Operation::from(PauliX::new(0))).unwrap(); circuit.call_method1("add", (paulix,)).unwrap(); let comparison_circuit = - bool::extract(circuit_op.call_method1("__eq__", (circuit,)).unwrap()).unwrap(); + bool::extract_bound(&circuit_op.call_method1("__eq__", (circuit,)).unwrap()).unwrap(); assert!(comparison_circuit); }) } @@ -568,22 +559,22 @@ fn test_pyo3_inputs_controlled_circuit() { Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_pragma).unwrap(); - let condition_index_op: &usize = &usize::extract( - operation + let condition_index_op: &usize = &usize::extract_bound( + &operation .call_method0(py, "controlling_qubit") .unwrap() - .as_ref(py), + .bind(py), ) .unwrap(); assert_eq!(condition_index_op, &1_usize); let to_circuit = operation.call_method0(py, "circuit").unwrap(); - let circuit_op = to_circuit.as_ref(py); + let circuit_op = to_circuit.bind(py); let circuit = new_circuit(py); let paulix = convert_operation_to_pyobject(Operation::from(PauliX::new(0))).unwrap(); circuit.call_method1("add", (paulix,)).unwrap(); let comparison_circuit = - bool::extract(circuit_op.call_method1("__eq__", (circuit,)).unwrap()).unwrap(); + bool::extract_bound(&circuit_op.call_method1("__eq__", (circuit,)).unwrap()).unwrap(); assert!(comparison_circuit); }) } @@ -599,9 +590,9 @@ fn test_pyo3_inputs_annotated_op() { let operation = convert_operation_to_pyobject(input_pragma).unwrap(); let op = operation.call_method0(py, "operation").unwrap(); - let op_ref = op.as_ref(py); - let comparison_op = bool::extract( - op_ref + let op_ref = op.bind(py); + let comparison_op = bool::extract_bound( + &op_ref .call_method1( "__eq__", (convert_operation_to_pyobject(input_op.clone()).unwrap(),), @@ -612,7 +603,8 @@ fn test_pyo3_inputs_annotated_op() { assert!(comparison_op); let annotation: String = - String::extract(operation.call_method0(py, "annotation").unwrap().as_ref(py)).unwrap(); + String::extract_bound(&operation.call_method0(py, "annotation").unwrap().bind(py)) + .unwrap(); assert_eq!(annotation, "test".to_string()); }) } @@ -628,7 +620,7 @@ fn test_pyo3_involved_qubits_none(input_definition: Operation) { Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_definition).unwrap(); let to_involved = operation.call_method0(py, "involved_qubits").unwrap(); - let involved_op: HashSet = HashSet::extract(to_involved.as_ref(py)).unwrap(); + let involved_op: HashSet = HashSet::extract_bound(&to_involved.bind(py)).unwrap(); let involved_param: HashSet = HashSet::new(); assert_eq!(involved_op, involved_param); }) @@ -644,9 +636,9 @@ fn test_pyo3_involved_qubits_all(input_definition: Operation) { Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_definition).unwrap(); let to_involved = operation.call_method0(py, "involved_qubits").unwrap(); - let involved_op: HashSet<&str> = HashSet::extract(to_involved.as_ref(py)).unwrap(); - let mut involved_param: HashSet<&str> = HashSet::new(); - involved_param.insert("All"); + let involved_op: HashSet = HashSet::extract_bound(&to_involved.bind(py)).unwrap(); + let mut involved_param: HashSet = HashSet::new(); + involved_param.insert("All".to_owned()); assert_eq!(involved_op, involved_param); }) } @@ -670,7 +662,7 @@ fn test_pyo3_involved_qubits_qubit(input_definition: Operation) { Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_definition).unwrap(); let to_involved = operation.call_method0(py, "involved_qubits").unwrap(); - let involved_op: HashSet = HashSet::extract(to_involved.as_ref(py)).unwrap(); + let involved_op: HashSet = HashSet::extract_bound(&to_involved.bind(py)).unwrap(); let mut involved_param: HashSet = HashSet::new(); involved_param.insert(0); assert_eq!(involved_op, involved_param); @@ -683,7 +675,7 @@ fn test_pyo3_involved_qubits_qubit_overrotation(input_definition: Operation) { Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_definition).unwrap(); let to_involved = operation.call_method0(py, "involved_qubits").unwrap(); - let involved_op: HashSet = HashSet::extract(to_involved.as_ref(py)).unwrap(); + let involved_op: HashSet = HashSet::extract_bound(&to_involved.bind(py)).unwrap(); let mut involved_param: HashSet = HashSet::new(); involved_param.insert(0); assert_eq!(involved_op, involved_param); @@ -736,9 +728,9 @@ fn test_pyo3_format_repr(input_measurement: Operation, format_repr: &str) { Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_measurement).unwrap(); let to_format = operation.call_method1(py, "__format__", ("",)).unwrap(); - let format_op: &str = <&str>::extract(to_format.as_ref(py)).unwrap(); + let format_op: String = String::extract_bound(&to_format.bind(py)).unwrap(); let to_repr = operation.call_method0(py, "__repr__").unwrap(); - let repr_op: &str = <&str>::extract(to_repr.as_ref(py)).unwrap(); + let repr_op: String = String::extract_bound(&to_repr.bind(py)).unwrap(); assert_eq!(format_op, format_repr); assert_eq!(repr_op, format_repr); }) @@ -751,9 +743,9 @@ fn test_pyo3_format_repr_overrotation(input_measurement: Operation, format_repr: Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_measurement).unwrap(); let to_format = operation.call_method1(py, "__format__", ("",)).unwrap(); - let format_op: &str = <&str>::extract(to_format.as_ref(py)).unwrap(); + let format_op: String = String::extract_bound(&to_format.bind(py)).unwrap(); let to_repr = operation.call_method0(py, "__repr__").unwrap(); - let repr_op: &str = <&str>::extract(to_repr.as_ref(py)).unwrap(); + let repr_op: String = String::extract_bound(&to_repr.bind(py)).unwrap(); assert_eq!(format_op, format_repr); assert_eq!(repr_op, format_repr); }) @@ -788,17 +780,17 @@ fn test_pyo3_copy_deepcopy(input_measurement: Operation) { let deepcopy_op = operation.call_method1(py, "__deepcopy__", ("",)).unwrap(); let copy_deepcopy_param = operation; - let comparison_copy = bool::extract( - copy_op - .as_ref(py) + let comparison_copy = bool::extract_bound( + ©_op + .bind(py) .call_method1("__eq__", (copy_deepcopy_param.clone(),)) .unwrap(), ) .unwrap(); assert!(comparison_copy); - let comparison_deepcopy = bool::extract( - deepcopy_op - .as_ref(py) + let comparison_deepcopy = bool::extract_bound( + &deepcopy_op + .bind(py) .call_method1("__eq__", (copy_deepcopy_param,)) .unwrap(), ) @@ -822,14 +814,14 @@ fn test_pyo3_copy_deepcopy_overrotation() { let deepcopy_op = operation.call_method1(py, "__deepcopy__", ("",)).unwrap(); let extracted_copy: PragmaOverrotationWrapper = - PragmaOverrotationWrapper::extract(copy_op.as_ref(py)).unwrap(); + PragmaOverrotationWrapper::extract_bound(©_op.bind(py)).unwrap(); assert_eq!( extracted_copy.internal, PragmaOverrotation::new("RotateX".to_string(), vec![0], 0.03, 0.001) ); - let comparison_copy = bool::extract( - copy_op - .as_ref(py) + let comparison_copy = bool::extract_bound( + ©_op + .bind(py) .call_method1("__eq__", (operation.clone(),)) .unwrap(), ) @@ -837,14 +829,14 @@ fn test_pyo3_copy_deepcopy_overrotation() { assert!(comparison_copy); let extracted_copy: PragmaOverrotationWrapper = - PragmaOverrotationWrapper::extract(copy_op.as_ref(py)).unwrap(); + PragmaOverrotationWrapper::extract_bound(©_op.bind(py)).unwrap(); assert_eq!( extracted_copy.internal, PragmaOverrotation::new("RotateX".to_string(), vec![0], 0.03, 0.001) ); - let comparison_deepcopy = bool::extract( - deepcopy_op - .as_ref(py) + let comparison_deepcopy = bool::extract_bound( + &deepcopy_op + .bind(py) .call_method1("__eq__", (operation,)) .unwrap(), ) @@ -867,7 +859,7 @@ fn test_pyo3_tags_simple(input_measurement: Operation, tag_name: &str) { Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_measurement).unwrap(); let to_tag = operation.call_method0(py, "tags").unwrap(); - let tags_op: &Vec<&str> = &Vec::extract(to_tag.as_ref(py)).unwrap(); + let tags_op: &Vec = &Vec::extract_bound(&to_tag.bind(py)).unwrap(); let tags_param: &[&str] = &["Operation", "PragmaOperation", tag_name]; assert_eq!(tags_op, tags_param); }) @@ -883,7 +875,7 @@ fn test_pyo3_tags_multi(input_measurement: Operation, tag_name: &str) { Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_measurement).unwrap(); let to_tag = operation.call_method0(py, "tags").unwrap(); - let tags_op: &Vec<&str> = &Vec::extract(to_tag.as_ref(py)).unwrap(); + let tags_op: &Vec = &Vec::extract_bound(&to_tag.bind(py)).unwrap(); let tags_param: &[&str] = &[ "Operation", "MultiQubitOperation", @@ -900,7 +892,7 @@ fn test_pyo3_tags_multi_overrotation(input_measurement: Operation, tag_name: &st Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_measurement).unwrap(); let to_tag = operation.call_method0(py, "tags").unwrap(); - let tags_op: &Vec<&str> = &Vec::extract(to_tag.as_ref(py)).unwrap(); + let tags_op: &Vec = &Vec::extract_bound(&to_tag.bind(py)).unwrap(); let tags_param: &[&str] = &[ "Operation", "MultiQubitOperation", @@ -918,7 +910,7 @@ fn test_pyo3_tags_single(input_measurement: Operation, tag_name: &str) { Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_measurement).unwrap(); let to_tag = operation.call_method0(py, "tags").unwrap(); - let tags_op: &Vec<&str> = &Vec::extract(to_tag.as_ref(py)).unwrap(); + let tags_op: &Vec = &Vec::extract_bound(&to_tag.bind(py)).unwrap(); let tags_param: &[&str] = &[ "Operation", "SingleQubitOperation", @@ -937,7 +929,7 @@ fn test_pyo3_tags_conditional(input_measurement: Operation, tag_name: &str) { Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_measurement).unwrap(); let to_tag = operation.call_method0(py, "tags").unwrap(); - let tags_op: &Vec<&str> = &Vec::extract(to_tag.as_ref(py)).unwrap(); + let tags_op: &Vec = &Vec::extract_bound(&to_tag.bind(py)).unwrap(); let tags_param: &[&str] = &["Operation", "PragmaOperation", tag_name]; assert_eq!(tags_op, tags_param); }) @@ -950,7 +942,7 @@ fn test_pyo3_tags_general_noise(input_measurement: Operation, tag_name: &str) { Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_measurement).unwrap(); let to_tag = operation.call_method0(py, "tags").unwrap(); - let tags_op: &Vec<&str> = &Vec::extract(to_tag.as_ref(py)).unwrap(); + let tags_op: &Vec = &Vec::extract_bound(&to_tag.bind(py)).unwrap(); let tags_param: &[&str] = &[ "Operation", "SingleQubitOperation", @@ -972,7 +964,7 @@ fn test_pyo3_tags_noise(input_measurement: Operation, tag_name: &str) { Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_measurement).unwrap(); let to_tag = operation.call_method0(py, "tags").unwrap(); - let tags_op: &Vec<&str> = &Vec::extract(to_tag.as_ref(py)).unwrap(); + let tags_op: &Vec = &Vec::extract_bound(&to_tag.bind(py)).unwrap(); let tags_param: &[&str] = &[ "Operation", "SingleQubitOperation", @@ -1011,7 +1003,8 @@ fn test_pyo3_hqslang(input_measurement: Operation, hqslang_param: &str) { Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_measurement).unwrap(); let hqslang_op: String = - String::extract(operation.call_method0(py, "hqslang").unwrap().as_ref(py)).unwrap(); + String::extract_bound(&operation.call_method0(py, "hqslang").unwrap().bind(py)) + .unwrap(); assert_eq!(hqslang_op, hqslang_param.to_string()); }) } @@ -1022,7 +1015,8 @@ fn test_pyo3_hqslang_overrotation(input_measurement: Operation, hqslang_param: & Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_measurement).unwrap(); let hqslang_op: String = - String::extract(operation.call_method0(py, "hqslang").unwrap().as_ref(py)).unwrap(); + String::extract_bound(&operation.call_method0(py, "hqslang").unwrap().bind(py)) + .unwrap(); assert_eq!(hqslang_op, hqslang_param.to_string()); }) } @@ -1052,11 +1046,11 @@ fn test_pyo3_is_parametrized_false(input_pragma: Operation) { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_pragma).unwrap(); - assert!(!bool::extract( - operation + assert!(!bool::extract_bound( + &operation .call_method0(py, "is_parametrized") .unwrap() - .as_ref(py) + .bind(py) ) .unwrap()); }) @@ -1068,11 +1062,11 @@ fn test_pyo3_is_parametrized_true(input_pragma: Operation) { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_pragma).unwrap(); - assert!(bool::extract( - operation + assert!(bool::extract_bound( + &operation .call_method0(py, "is_parametrized") .unwrap() - .as_ref(py) + .bind(py) ) .unwrap()); }) @@ -1083,11 +1077,11 @@ fn test_pyo3_is_parametrized_overrotation(input_measurement: Operation) { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_measurement).unwrap(); - assert!(!bool::extract( - operation + assert!(!bool::extract_bound( + &operation .call_method0(py, "is_parametrized") .unwrap() - .as_ref(py) + .bind(py) ) .unwrap()); }) @@ -1158,16 +1152,16 @@ fn test_pyo3_substitute_parameters(first_op: Operation, second_op: Operation) { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let operation = convert_operation_to_pyobject(first_op).unwrap(); - let mut substitution_dict: HashMap<&str, f64> = HashMap::new(); - substitution_dict.insert("test", 1.0); + let mut substitution_dict: HashMap = HashMap::new(); + substitution_dict.insert("test".to_owned(), 1.0); let substitute_op = operation .call_method1(py, "substitute_parameters", (substitution_dict,)) .unwrap(); let substitute_param = convert_operation_to_pyobject(second_op).unwrap(); - let comparison = bool::extract( - substitute_op - .as_ref(py) + let comparison = bool::extract_bound( + &substitute_op + .bind(py) .call_method1("__eq__", (substitute_param,)) .unwrap(), ) @@ -1188,22 +1182,22 @@ fn test_pyo3_substitute_parameters_overrotation() { ))) .unwrap(); - let mut substitution_dict: HashMap<&str, f64> = HashMap::new(); - substitution_dict.insert("test", 1.0); + let mut substitution_dict: HashMap = HashMap::new(); + substitution_dict.insert("test".to_owned(), 1.0); let substitute_op = operation .call_method1(py, "substitute_parameters", (substitution_dict,)) .unwrap(); let extracted: PragmaOverrotationWrapper = - PragmaOverrotationWrapper::extract(substitute_op.as_ref(py)).unwrap(); + PragmaOverrotationWrapper::extract_bound(&substitute_op.bind(py)).unwrap(); assert_eq!( extracted.internal, PragmaOverrotation::new("RotateX".to_string(), vec![0], 0.03, 0.001) ); - let comparison = bool::extract( - substitute_op - .as_ref(py) + let comparison = bool::extract_bound( + &substitute_op + .bind(py) .call_method1("__eq__", (operation,)) .unwrap(), ) @@ -1242,10 +1236,9 @@ fn test_pyo3_substitute_params_error(input_operation: Operation) { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_operation).unwrap(); - let substitution_dict: HashMap<&str, f64> = HashMap::new(); + let substitution_dict: HashMap = HashMap::new(); let result = operation.call_method1(py, "substitute_parameters", (substitution_dict,)); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); }) } @@ -1267,8 +1260,7 @@ fn test_pyo3_substituteparameters_error(input_operation: Operation) { let mut substitution_dict: HashMap<&str, &str> = HashMap::new(); substitution_dict.insert("ro", "test"); let result = operation.call_method1(py, "substitute_parameters", (substitution_dict,)); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); }) } @@ -1343,11 +1335,11 @@ fn test_pyo3_remap_qubits(first_op: Operation, second_op: Operation) { .unwrap(); let comparison_op = convert_operation_to_pyobject(second_op).unwrap(); - let comparison = bool::extract( - remapped_op + let comparison = bool::extract_bound( + &remapped_op .call_method1(py, "__eq__", (comparison_op,)) .unwrap() - .as_ref(py), + .bind(py), ) .unwrap(); assert!(comparison); @@ -1370,7 +1362,7 @@ fn test_pyo3_remap_qubits_overrotation() { .call_method1(py, "remap_qubits", (qubit_remapping(),)) .unwrap(); let extracted: PragmaOverrotationWrapper = - PragmaOverrotationWrapper::extract(remapped_op.as_ref(py)).unwrap(); + PragmaOverrotationWrapper::extract_bound(&remapped_op.bind(py)).unwrap(); assert_eq!( extracted.internal, PragmaOverrotation::new("RotateX".to_string(), vec![2], 0.03, 0.001) @@ -1380,9 +1372,9 @@ fn test_pyo3_remap_qubits_overrotation() { PragmaOverrotation::new("RotateX".to_string(), vec![2], 0.03, 0.001), )) .unwrap(); - let comparison = bool::extract( - remapped_op - .as_ref(py) + let comparison = bool::extract_bound( + &remapped_op + .bind(py) .call_method1("__eq__", (operation_two,)) .unwrap(), ) @@ -1392,8 +1384,7 @@ fn test_pyo3_remap_qubits_overrotation() { let mut qubit_mapping: HashMap = HashMap::new(); qubit_mapping.insert(2, 0); let result = operation.call_method1(py, "remap_qubits", (qubit_mapping,)); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); }) } @@ -1418,10 +1409,12 @@ fn test_pyo3_noise_superoperator_damping() { let to_superop_op = operation.call_method0(py, "superoperator").unwrap(); let superop_op = to_superop_op - .downcast::>(py) + .downcast_bound::>(py) .unwrap() - .to_owned_array(); - + .as_gil_ref() + .readonly() + .as_array() + .to_owned(); assert_eq!(superop_op, superop_param); }) } @@ -1452,9 +1445,12 @@ fn test_pyo3_noise_superoperator_depolarising() { let to_superop_op = operation.call_method0(py, "superoperator").unwrap(); let superop_op = to_superop_op - .downcast::>(py) + .downcast_bound::>(py) .unwrap() - .to_owned_array(); + .as_gil_ref() + .readonly() + .as_array() + .to_owned(); assert_eq!(superop_op, superop_param); }) @@ -1484,9 +1480,12 @@ fn test_pyo3_noise_superoperator_dephasing() { let to_superop_op = operation.call_method0(py, "superoperator").unwrap(); let superop_op = to_superop_op - .downcast::>(py) + .downcast_bound::>(py) .unwrap() - .to_owned_array(); + .as_gil_ref() + .readonly() + .as_array() + .to_owned(); assert_eq!(superop_op, superop_param); }) @@ -1517,10 +1516,12 @@ fn test_pyo3_noise_superoperator_randomnoise() { let to_superop_op = operation.call_method0(py, "superoperator").unwrap(); let superop_op = to_superop_op - .downcast::>(py) + .downcast_bound::>(py) .unwrap() - .to_owned_array(); - + .as_gil_ref() + .readonly() + .as_array() + .to_owned(); assert_eq!(superop_op, superop_param); }) } @@ -1535,13 +1536,9 @@ fn test_pyo3_noise_proba(noise_pragma: Operation, proba: f64) { Python::with_gil(|py| { let operation = convert_operation_to_pyobject(noise_pragma).unwrap(); - let gate_time_op: &f64 = &f64::extract( - operation - .call_method0(py, "probability") - .unwrap() - .as_ref(py), - ) - .unwrap(); + let gate_time_op: &f64 = + &f64::extract_bound(&operation.call_method0(py, "probability").unwrap().bind(py)) + .unwrap(); assert_eq!( CalculatorFloat::from(gate_time_op), CalculatorFloat::from(proba), @@ -1571,11 +1568,11 @@ fn test_pyo3_noise_powercf(first_op: Operation, second_op: Operation) { let comparison_op = convert_operation_to_pyobject(second_op).unwrap(); let remapped_op = operation.call_method1(py, "powercf", (power,)).unwrap(); - let comparison = bool::extract( - remapped_op + let comparison = bool::extract_bound( + &remapped_op .call_method1(py, "__eq__", (comparison_op,)) .unwrap() - .as_ref(py), + .bind(py), ) .unwrap(); assert!(comparison); @@ -1649,18 +1646,18 @@ fn test_pyo3_richcmp(definition_1: Operation, definition_2: Operation) { let operation_one = convert_operation_to_pyobject(definition_1).unwrap(); let operation_two = convert_operation_to_pyobject(definition_2).unwrap(); - let comparison = bool::extract( - operation_one - .as_ref(py) + let comparison = bool::extract_bound( + &operation_one + .bind(py) .call_method1("__eq__", (operation_two.clone(),)) .unwrap(), ) .unwrap(); assert!(!comparison); - let comparison = bool::extract( - operation_one - .as_ref(py) + let comparison = bool::extract_bound( + &operation_one + .bind(py) .call_method1("__ne__", (operation_two.clone(),)) .unwrap(), ) @@ -1689,15 +1686,15 @@ fn test_pyo3_richcmp_overrotation() { .unwrap(); let extracted_one: PragmaOverrotationWrapper = - PragmaOverrotationWrapper::extract(operation_one.as_ref(py)).unwrap(); + PragmaOverrotationWrapper::extract_bound(&operation_one.bind(py)).unwrap(); assert_eq!( extracted_one.internal, PragmaOverrotation::new("RotateX".to_string(), vec![0], 0.03, 0.001) ); - let comparison = bool::extract( - operation_one - .as_ref(py) + let comparison = bool::extract_bound( + &operation_one + .bind(py) .call_method1("__ne__", (operation_two.clone(),)) .unwrap(), ) @@ -1717,27 +1714,25 @@ fn test_pyo3_richcmp_overrotation() { fn test_pyo3_new_set_number_of_measurements() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let operation = py.get_type::(); - let new_op = operation - .call1((1, "ro".to_string())) - .unwrap() - .downcast::>() + let operation = py.get_type_bound::(); + let binding = operation.call1((1, "ro".to_string())).unwrap(); + let new_op = binding + .downcast::() .unwrap(); let input_definition = Operation::from(PragmaSetNumberOfMeasurements::new(1, String::from("ro"))); let copy_param = convert_operation_to_pyobject(input_definition).unwrap(); let comparison_copy = - bool::extract(new_op.call_method1("__eq__", (copy_param,)).unwrap()).unwrap(); + bool::extract_bound(&new_op.call_method1("__eq__", (copy_param,)).unwrap()).unwrap(); assert!(comparison_copy); let pragma_wrapper = new_op .extract::() .unwrap(); - let new_op_diff = operation - .call1((2, "ro".to_string())) - .unwrap() - .downcast::>() + let binding = operation.call1((2, "ro".to_string())).unwrap(); + let new_op_diff = binding + .downcast::() .unwrap(); let pragma_wrapper_diff = new_op_diff .extract::() @@ -1759,20 +1754,17 @@ fn test_pyo3_new_set_number_of_measurements() { fn test_pyo3_new_set_statevector() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let operation = py.get_type::(); + let operation = py.get_type_bound::(); let to_get_statevec_0 = Operation::from(PragmaSetStateVector::new(statevector())); let convert_to_get_statevec_0 = convert_operation_to_pyobject(to_get_statevec_0).unwrap(); let statevector_op_0 = convert_to_get_statevec_0 .call_method0(py, "statevector") .unwrap(); - let new_op = operation - .call1((statevector_op_0,)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation.call1((statevector_op_0,)).unwrap(); + let new_op = binding.downcast::().unwrap(); - let comparison_copy = bool::extract( - new_op + let comparison_copy = bool::extract_bound( + &new_op .call_method1("__eq__", (convert_to_get_statevec_0,)) .unwrap(), ) @@ -1786,11 +1778,8 @@ fn test_pyo3_new_set_statevector() { .unwrap(); let pragma_wrapper = new_op.extract::().unwrap(); - let new_op_diff = operation - .call1((statevector_op_1,)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation.call1((statevector_op_1,)).unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let pragma_wrapper_diff = new_op_diff .extract::() .unwrap(); @@ -1811,20 +1800,17 @@ fn test_pyo3_new_set_statevector() { fn test_pyo3_new_set_densitymatrix() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let operation = py.get_type::(); + let operation = py.get_type_bound::(); let to_get_densmat_0 = Operation::from(PragmaSetDensityMatrix::new(densitymatrix())); let convert_to_get_densmat_0 = convert_operation_to_pyobject(to_get_densmat_0).unwrap(); let densmat_op_0 = convert_to_get_densmat_0 .call_method0(py, "density_matrix") .unwrap(); - let new_op = operation - .call1((densmat_op_0,)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation.call1((densmat_op_0,)).unwrap(); + let new_op = binding.downcast::().unwrap(); - let comparison_copy = bool::extract( - new_op + let comparison_copy = bool::extract_bound( + &new_op .call_method1("__eq__", (convert_to_get_densmat_0,)) .unwrap(), ) @@ -1838,11 +1824,8 @@ fn test_pyo3_new_set_densitymatrix() { .unwrap(); let pragma_wrapper = new_op.extract::().unwrap(); - let new_op_diff = operation - .call1((densmat_op_1,)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation.call1((densmat_op_1,)).unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let pragma_wrapper_diff = new_op_diff .extract::() .unwrap(); @@ -1863,25 +1846,19 @@ fn test_pyo3_new_set_densitymatrix() { fn test_pyo3_new_repeated_gate() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let operation = py.get_type::(); - let new_op = operation - .call1((2,)) - .unwrap() - .downcast::>() - .unwrap(); + let operation = py.get_type_bound::(); + let binding = operation.call1((2,)).unwrap(); + let new_op = binding.downcast::().unwrap(); let input_definition = Operation::from(PragmaRepeatGate::new(2)); let copy_param = convert_operation_to_pyobject(input_definition).unwrap(); let comparison_copy = - bool::extract(new_op.call_method1("__eq__", (copy_param,)).unwrap()).unwrap(); + bool::extract_bound(&new_op.call_method1("__eq__", (copy_param,)).unwrap()).unwrap(); assert!(comparison_copy); let pragma_wrapper = new_op.extract::().unwrap(); - let new_op_diff = operation - .call1((3,)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation.call1((3,)).unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let pragma_wrapper_diff = new_op_diff.extract::().unwrap(); let helper_ne: bool = pragma_wrapper_diff != pragma_wrapper; assert!(helper_ne); @@ -1901,12 +1878,9 @@ fn test_pyo3_new_overrotation() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { // Basic initialisation, no errors - let operation = py.get_type::(); - let new_op = operation - .call1(("RotateX", vec![0], 0.03, 0.001)) - .unwrap() - .downcast::>() - .unwrap(); + let operation = py.get_type_bound::(); + let binding = operation.call1(("RotateX", vec![0], 0.03, 0.001)).unwrap(); + let new_op = binding.downcast::().unwrap(); let input_definition = Operation::from(PragmaOverrotation::new( "RotateX".to_string(), vec![0], @@ -1915,27 +1889,19 @@ fn test_pyo3_new_overrotation() { )); let copy_param = convert_operation_to_pyobject(input_definition).unwrap(); let extracted: PragmaOverrotationWrapper = - PragmaOverrotationWrapper::extract(new_op.as_ref()).unwrap(); + PragmaOverrotationWrapper::extract_bound(new_op).unwrap(); assert_eq!( extracted.internal, PragmaOverrotation::new("RotateX".to_string(), vec![0], 0.03, 0.001) ); - let comparison = bool::extract( - new_op - .as_ref() - .call_method1("__eq__", (copy_param,)) - .unwrap(), - ) - .unwrap(); + let comparison = + bool::extract_bound(&new_op.call_method1("__eq__", (copy_param,)).unwrap()).unwrap(); assert!(comparison); // Testing PartialEq, Clone and Debug let pragma_wrapper = new_op.extract::().unwrap(); - let new_op_diff = operation - .call1(("RotateX", vec![1], 0.03, 0.001)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation.call1(("RotateX", vec![1], 0.03, 0.001)).unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let pragma_wrapper_diff = new_op_diff.extract::().unwrap(); let helper_ne: bool = pragma_wrapper_diff != pragma_wrapper; assert!(helper_ne); @@ -1955,30 +1921,23 @@ fn test_pyo3_new_boost_noise() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { // Basic initialisation, no errors - let operation = py.get_type::(); - let new_op = operation - .call1((0.003,)) - .unwrap() - .downcast::>() - .unwrap(); + let operation = py.get_type_bound::(); + let binding = operation.call1((0.003,)).unwrap(); + let new_op = binding.downcast::().unwrap(); let input_definition = Operation::from(PragmaBoostNoise::new(CalculatorFloat::from(0.003))); let copy_param = convert_operation_to_pyobject(input_definition).unwrap(); let comparison_copy = - bool::extract(new_op.call_method1("__eq__", (copy_param,)).unwrap()).unwrap(); + bool::extract_bound(&new_op.call_method1("__eq__", (copy_param,)).unwrap()).unwrap(); assert!(comparison_copy); // Error initialisation let result = operation.call1((vec!["fails"],)); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); // Testing PartialEq, Clone and Debug let pragma_wrapper = new_op.extract::().unwrap(); - let new_op_diff = operation - .call1((0.001,)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation.call1((0.001,)).unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let pragma_wrapper_diff = new_op_diff.extract::().unwrap(); let helper_ne: bool = pragma_wrapper_diff != pragma_wrapper; assert!(helper_ne); @@ -1998,11 +1957,10 @@ fn test_pyo3_new_stop() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { // Basic initialisation, no errors - let operation = py.get_type::(); - let new_op = operation - .call1((vec![0], 0.0000001)) - .unwrap() - .downcast::>() + let operation = py.get_type_bound::(); + let binding = operation.call1((vec![0], 0.0000001)).unwrap(); + let new_op = binding + .downcast::() .unwrap(); let input_definition = Operation::from(PragmaStopParallelBlock::new( vec![0], @@ -2010,20 +1968,18 @@ fn test_pyo3_new_stop() { )); let copy_param = convert_operation_to_pyobject(input_definition).unwrap(); let comparison_copy = - bool::extract(new_op.call_method1("__eq__", (copy_param,)).unwrap()).unwrap(); + bool::extract_bound(&new_op.call_method1("__eq__", (copy_param,)).unwrap()).unwrap(); assert!(comparison_copy); // Error initialisation let result = operation.call1((vec![0], vec!["fails"])); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); // Testing PartialEq, Clone and Debug let pragma_wrapper = new_op.extract::().unwrap(); - let new_op_diff = operation - .call1((vec![1], 0.0000001)) - .unwrap() - .downcast::>() + let binding = operation.call1((vec![1], 0.0000001)).unwrap(); + let new_op_diff = binding + .downcast::() .unwrap(); let pragma_wrapper_diff = new_op_diff .extract::() @@ -2051,31 +2007,24 @@ fn test_pyo3_new_global_phase() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { // Basic initialisation, no errors - let operation = py.get_type::(); - let new_op = operation - .call1((0.003,)) - .unwrap() - .downcast::>() - .unwrap(); + let operation = py.get_type_bound::(); + let binding = operation.call1((0.003,)).unwrap(); + let new_op = binding.downcast::().unwrap(); let input_definition = Operation::from(PragmaGlobalPhase::new(CalculatorFloat::from(0.003))); let copy_param = convert_operation_to_pyobject(input_definition).unwrap(); let comparison_copy = - bool::extract(new_op.call_method1("__eq__", (copy_param,)).unwrap()).unwrap(); + bool::extract_bound(&new_op.call_method1("__eq__", (copy_param,)).unwrap()).unwrap(); assert!(comparison_copy); // Error initialisation let result = operation.call1((vec!["fails"],)); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); // Testing PartialEq, Clone and Debug let pragma_wrapper = new_op.extract::().unwrap(); - let new_op_diff = operation - .call1((0.001,)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation.call1((0.001,)).unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let pragma_wrapper_diff = new_op_diff.extract::().unwrap(); let helper_ne: bool = pragma_wrapper_diff != pragma_wrapper; assert!(helper_ne); @@ -2095,32 +2044,25 @@ fn test_pyo3_new_sleep() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { // Basic initialisation, no errors - let operation = py.get_type::(); - let new_op = operation - .call1((vec![0], 0.0000001)) - .unwrap() - .downcast::>() - .unwrap(); + let operation = py.get_type_bound::(); + let binding = operation.call1((vec![0], 0.0000001)).unwrap(); + let new_op = binding.downcast::().unwrap(); let input_definition = Operation::from(PragmaSleep::new(vec![0], CalculatorFloat::from(0.0000001))); let copy_param = convert_operation_to_pyobject(input_definition).unwrap(); let comparison_copy = - bool::extract(new_op.call_method1("__eq__", (copy_param,)).unwrap()).unwrap(); + bool::extract_bound(&new_op.call_method1("__eq__", (copy_param,)).unwrap()).unwrap(); assert!(comparison_copy); // Error initialisation let result = operation.call1((vec![0], vec!["fails"])); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); // Testing PartialEq, Clone and Debug let pragma_wrapper = new_op.extract::().unwrap(); - let new_op_diff = operation - .call1((vec![1], 0.0000001)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation.call1((vec![1], 0.0000001)).unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let pragma_wrapper_diff = new_op_diff.extract::().unwrap(); let helper_ne: bool = pragma_wrapper_diff != pragma_wrapper; assert!(helper_ne); @@ -2144,25 +2086,19 @@ fn test_pyo3_new_sleep() { fn test_pyo3_new_active_reset() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let operation = py.get_type::(); - let new_op = operation - .call1((0,)) - .unwrap() - .downcast::>() - .unwrap(); + let operation = py.get_type_bound::(); + let binding = operation.call1((0,)).unwrap(); + let new_op = binding.downcast::().unwrap(); let input_definition = Operation::from(PragmaActiveReset::new(0)); let copy_param = convert_operation_to_pyobject(input_definition).unwrap(); let comparison_copy = - bool::extract(new_op.call_method1("__eq__", (copy_param,)).unwrap()).unwrap(); + bool::extract_bound(&new_op.call_method1("__eq__", (copy_param,)).unwrap()).unwrap(); assert!(comparison_copy); let pragma_wrapper = new_op.extract::().unwrap(); - let new_op_diff = operation - .call1((1,)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation.call1((1,)).unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let pragma_wrapper_diff = new_op_diff.extract::().unwrap(); let helper_ne: bool = pragma_wrapper_diff != pragma_wrapper; assert!(helper_ne); @@ -2181,27 +2117,25 @@ fn test_pyo3_new_active_reset() { fn test_pyo3_new_start_decomposition_block() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let operation = py.get_type::(); - let new_op = operation - .call1((vec![0], reordering())) - .unwrap() - .downcast::>() + let operation = py.get_type_bound::(); + let binding = operation.call1((vec![0], reordering())).unwrap(); + let new_op = binding + .downcast::() .unwrap(); let input_definition = Operation::from(PragmaStartDecompositionBlock::new(vec![0], reordering())); let copy_param = convert_operation_to_pyobject(input_definition).unwrap(); let comparison_copy = - bool::extract(new_op.call_method1("__eq__", (copy_param,)).unwrap()).unwrap(); + bool::extract_bound(&new_op.call_method1("__eq__", (copy_param,)).unwrap()).unwrap(); assert!(comparison_copy); let pragma_wrapper = new_op .extract::() .unwrap(); - let new_op_diff = operation - .call1((vec![1], reordering())) - .unwrap() - .downcast::>() + let binding = operation.call1((vec![1], reordering())).unwrap(); + let new_op_diff = binding + .downcast::() .unwrap(); let pragma_wrapper_diff = new_op_diff .extract::() @@ -2223,26 +2157,24 @@ fn test_pyo3_new_start_decomposition_block() { fn test_pyo3_new_stop_decomposition_block() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let operation = py.get_type::(); - let new_op = operation - .call1((vec![0],)) - .unwrap() - .downcast::>() + let operation = py.get_type_bound::(); + let binding = operation.call1((vec![0],)).unwrap(); + let new_op = binding + .downcast::() .unwrap(); let input_definition = Operation::from(PragmaStopDecompositionBlock::new(vec![0])); let copy_param = convert_operation_to_pyobject(input_definition).unwrap(); let comparison_copy = - bool::extract(new_op.call_method1("__eq__", (copy_param,)).unwrap()).unwrap(); + bool::extract_bound(&new_op.call_method1("__eq__", (copy_param,)).unwrap()).unwrap(); assert!(comparison_copy); let pragma_wrapper = new_op .extract::() .unwrap(); - let new_op_diff = operation - .call1((vec![1],)) - .unwrap() - .downcast::>() + let binding = operation.call1((vec![1],)).unwrap(); + let new_op_diff = binding + .downcast::() .unwrap(); let pragma_wrapper_diff = new_op_diff .extract::() @@ -2265,12 +2197,9 @@ fn test_pyo3_new_damping() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { // Basic initialisation, no errors - let operation = py.get_type::(); - let new_op = operation - .call1((0, 0.005, 0.02)) - .unwrap() - .downcast::>() - .unwrap(); + let operation = py.get_type_bound::(); + let binding = operation.call1((0, 0.005, 0.02)).unwrap(); + let new_op = binding.downcast::().unwrap(); let input_definition = Operation::from(PragmaDamping::new( 0, CalculatorFloat::from(0.005), @@ -2278,24 +2207,19 @@ fn test_pyo3_new_damping() { )); let copy_param = convert_operation_to_pyobject(input_definition).unwrap(); let comparison_copy = - bool::extract(new_op.call_method1("__eq__", (copy_param,)).unwrap()).unwrap(); + bool::extract_bound(&new_op.call_method1("__eq__", (copy_param,)).unwrap()).unwrap(); assert!(comparison_copy); // Error initialisation let result = operation.call1((0, vec!["fails"], 0.0)); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); let result = operation.call1((0, 0.0, vec!["fails"])); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); // Testing PartialEq, Clone and Debug let pragma_wrapper = new_op.extract::().unwrap(); - let new_op_diff = operation - .call1((1, 0.005, 0.02)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation.call1((1, 0.005, 0.02)).unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let pragma_wrapper_diff = new_op_diff.extract::().unwrap(); let helper_ne: bool = pragma_wrapper_diff != pragma_wrapper; assert!(helper_ne); @@ -2315,12 +2239,9 @@ fn test_pyo3_new_depolarising() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { // Basic initialisation, no errors - let operation = py.get_type::(); - let new_op = operation - .call1((0, 0.005, 0.02)) - .unwrap() - .downcast::>() - .unwrap(); + let operation = py.get_type_bound::(); + let binding = operation.call1((0, 0.005, 0.02)).unwrap(); + let new_op = binding.downcast::().unwrap(); let input_definition = Operation::from(PragmaDepolarising::new( 0, CalculatorFloat::from(0.005), @@ -2328,24 +2249,19 @@ fn test_pyo3_new_depolarising() { )); let copy_param = convert_operation_to_pyobject(input_definition).unwrap(); let comparison_copy = - bool::extract(new_op.call_method1("__eq__", (copy_param,)).unwrap()).unwrap(); + bool::extract_bound(&new_op.call_method1("__eq__", (copy_param,)).unwrap()).unwrap(); assert!(comparison_copy); // Error initialisation let result = operation.call1((0, vec!["fails"], 0.0)); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); let result = operation.call1((0, 0.0, vec!["fails"])); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); // Testing PartialEq, Clone and Debug let pragma_wrapper = new_op.extract::().unwrap(); - let new_op_diff = operation - .call1((1, 0.005, 0.02)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation.call1((1, 0.005, 0.02)).unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let pragma_wrapper_diff = new_op_diff.extract::().unwrap(); let helper_ne: bool = pragma_wrapper_diff != pragma_wrapper; assert!(helper_ne); @@ -2365,12 +2281,9 @@ fn test_pyo3_new_dephasing() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { // Basic initialisation, no errors - let operation = py.get_type::(); - let new_op = operation - .call1((0, 0.005, 0.02)) - .unwrap() - .downcast::>() - .unwrap(); + let operation = py.get_type_bound::(); + let binding = operation.call1((0, 0.005, 0.02)).unwrap(); + let new_op = binding.downcast::().unwrap(); let input_definition = Operation::from(PragmaDephasing::new( 0, CalculatorFloat::from(0.005), @@ -2378,24 +2291,19 @@ fn test_pyo3_new_dephasing() { )); let copy_param = convert_operation_to_pyobject(input_definition).unwrap(); let comparison_copy = - bool::extract(new_op.call_method1("__eq__", (copy_param,)).unwrap()).unwrap(); + bool::extract_bound(&new_op.call_method1("__eq__", (copy_param,)).unwrap()).unwrap(); assert!(comparison_copy); // Error initialisation let result = operation.call1((0, vec!["fails"], 0.0)); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); let result = operation.call1((0, 0.0, vec!["fails"])); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); // Testing PartialEq, Clone and Debug let pragma_wrapper = new_op.extract::().unwrap(); - let new_op_diff = operation - .call1((1, 0.005, 0.02)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation.call1((1, 0.005, 0.02)).unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let pragma_wrapper_diff = new_op_diff.extract::().unwrap(); let helper_ne: bool = pragma_wrapper_diff != pragma_wrapper; assert!(helper_ne); @@ -2415,12 +2323,9 @@ fn test_pyo3_new_randomnoise() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { // Basic initialisation, no errors - let operation = py.get_type::(); - let new_op = operation - .call1((0, 0.005, 0.02, 0.01)) - .unwrap() - .downcast::>() - .unwrap(); + let operation = py.get_type_bound::(); + let binding = operation.call1((0, 0.005, 0.02, 0.01)).unwrap(); + let new_op = binding.downcast::().unwrap(); let input_definition = Operation::from(PragmaRandomNoise::new( 0, CalculatorFloat::from(0.005), @@ -2429,27 +2334,21 @@ fn test_pyo3_new_randomnoise() { )); let copy_param = convert_operation_to_pyobject(input_definition).unwrap(); let comparison_copy = - bool::extract(new_op.call_method1("__eq__", (copy_param,)).unwrap()).unwrap(); + bool::extract_bound(&new_op.call_method1("__eq__", (copy_param,)).unwrap()).unwrap(); assert!(comparison_copy); // Error initialisation let result = operation.call1((0, vec!["fails"], 0.0, 0.0)); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); let result = operation.call1((0, 0.0, vec!["fails"], 0.0)); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); let result = operation.call1((0, 0.0, 0.0, vec!["fails"])); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); // Testing PartialEq, Clone and Debug let pragma_wrapper = new_op.extract::().unwrap(); - let new_op_diff = operation - .call1((1, 0.005, 0.02, 0.01)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation.call1((1, 0.005, 0.02, 0.01)).unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let pragma_wrapper_diff = new_op_diff.extract::().unwrap(); let helper_ne: bool = pragma_wrapper_diff != pragma_wrapper; assert!(helper_ne); @@ -2469,7 +2368,7 @@ fn test_pyo3_new_general_noise() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { // Basic initialisation, no errors - let operation = py.get_type::(); + let operation = py.get_type_bound::(); let to_get_operators = Operation::from(PragmaGeneralNoise::new( 0, CalculatorFloat::from(0.005), @@ -2478,14 +2377,11 @@ fn test_pyo3_new_general_noise() { let convert_to_get_operators = convert_operation_to_pyobject(to_get_operators).unwrap(); let operators_op = convert_to_get_operators.call_method0(py, "rates").unwrap(); - let new_op = operation - .call1((0, 0.005, operators_op.clone())) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation.call1((0, 0.005, operators_op.clone())).unwrap(); + let new_op = binding.downcast::().unwrap(); - let comparison_copy = bool::extract( - new_op + let comparison_copy = bool::extract_bound( + &new_op .call_method1("__eq__", (convert_to_get_operators,)) .unwrap(), ) @@ -2494,20 +2390,15 @@ fn test_pyo3_new_general_noise() { // Error initialisation let result = operation.call1((0, vec!["fails"], 0.0, operators_op.clone())); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); let result = operation.call1((0, 0.0, vec!["fails"], operators_op.clone())); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); // Testing PartialEq, Clone and Debug let pragma_wrapper = new_op.extract::().unwrap(); - let new_op_diff = operation - .call1((1, 0.005, operators_op)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation.call1((1, 0.005, operators_op)).unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let pragma_wrapper_diff = new_op_diff.extract::().unwrap(); let helper_ne: bool = pragma_wrapper_diff != pragma_wrapper; assert!(helper_ne); @@ -2526,26 +2417,24 @@ fn test_pyo3_new_general_noise() { fn test_pyo3_new_conditional() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let operation = py.get_type::(); - let new_op = operation + let operation = py.get_type_bound::(); + let binding = operation .call1(("ro".to_string(), 0, new_circuit(py))) - .unwrap() - .downcast::>() .unwrap(); + let new_op = binding.downcast::().unwrap(); let input_definition = Operation::from(PragmaConditional::new("ro".to_string(), 0, Circuit::new())); let copy_param = convert_operation_to_pyobject(input_definition).unwrap(); let comparison_copy = - bool::extract(new_op.call_method1("__eq__", (copy_param,)).unwrap()).unwrap(); + bool::extract_bound(&new_op.call_method1("__eq__", (copy_param,)).unwrap()).unwrap(); assert!(comparison_copy); let pragma_wrapper = new_op.extract::().unwrap(); - let new_op_diff = operation + let binding = operation .call1(("ro".to_string(), 2, new_circuit(py))) - .unwrap() - .downcast::>() .unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let pragma_wrapper_diff = new_op_diff.extract::().unwrap(); let helper_ne: bool = pragma_wrapper_diff != pragma_wrapper; assert!(helper_ne); @@ -2564,24 +2453,22 @@ fn test_pyo3_new_conditional() { fn test_pyo3_new_controlled_circuit() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let operation = py.get_type::(); - let new_op = operation - .call1((0, new_circuit(py))) - .unwrap() - .downcast::>() + let operation = py.get_type_bound::(); + let binding = operation.call1((0, new_circuit(py))).unwrap(); + let new_op = binding + .downcast::() .unwrap(); let input_definition = Operation::from(PragmaControlledCircuit::new(0, Circuit::new())); let copy_param = convert_operation_to_pyobject(input_definition).unwrap(); let comparison_copy = - bool::extract(new_op.call_method1("__eq__", (copy_param,)).unwrap()).unwrap(); + bool::extract_bound(&new_op.call_method1("__eq__", (copy_param,)).unwrap()).unwrap(); assert!(comparison_copy); let pragma_wrapper = new_op.extract::().unwrap(); - let new_op_diff = operation - .call1((2, new_circuit(py))) - .unwrap() - .downcast::>() + let binding = operation.call1((2, new_circuit(py))).unwrap(); + let new_op_diff = binding + .downcast::() .unwrap(); let pragma_wrapper_diff = new_op_diff .extract::() @@ -2603,25 +2490,23 @@ fn test_pyo3_new_controlled_circuit() { fn test_pyo3_new_loop() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let operation = py.get_type::(); - let new_op = operation + let operation = py.get_type_bound::(); + let binding = operation .call1(("number_t".to_string(), new_circuit(py))) - .unwrap() - .downcast::>() .unwrap(); + let new_op = binding.downcast::().unwrap(); let input_definition = Operation::from(PragmaLoop::new("number_t".into(), Circuit::new())); let copy_param = convert_operation_to_pyobject(input_definition).unwrap(); let comparison_copy = - bool::extract(new_op.call_method1("__eq__", (copy_param,)).unwrap()).unwrap(); + bool::extract_bound(&new_op.call_method1("__eq__", (copy_param,)).unwrap()).unwrap(); assert!(comparison_copy); let pragma_wrapper = new_op.extract::().unwrap(); - let new_op_diff = operation + let binding = operation .call1(("ro".to_string(), new_circuit(py))) - .unwrap() - .downcast::>() .unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let pragma_wrapper_diff = new_op_diff.extract::().unwrap(); let helper_ne: bool = pragma_wrapper_diff != pragma_wrapper; assert!(helper_ne); @@ -2642,15 +2527,14 @@ fn test_pyo3_new_annotated_op() { let internal_op_1 = Operation::from(PauliX::new(1)); pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let operation = py.get_type::(); - let new_op = operation + let operation = py.get_type_bound::(); + let binding = operation .call1(( convert_operation_to_pyobject(internal_op_0).unwrap(), "test", )) - .unwrap() - .downcast::>() .unwrap(); + let new_op = binding.downcast::().unwrap(); let input_definition = Operation::from(PragmaAnnotatedOp::new( Operation::from(PauliX::new(0)), @@ -2658,18 +2542,17 @@ fn test_pyo3_new_annotated_op() { )); let copy_param = convert_operation_to_pyobject(input_definition).unwrap(); let comparison_copy = - bool::extract(new_op.call_method1("__eq__", (copy_param,)).unwrap()).unwrap(); + bool::extract_bound(&new_op.call_method1("__eq__", (copy_param,)).unwrap()).unwrap(); assert!(comparison_copy); let pragma_wrapper = new_op.extract::().unwrap(); - let new_op_diff = operation + let binding = operation .call1(( convert_operation_to_pyobject(internal_op_1).unwrap(), "test", )) - .unwrap() - .downcast::>() .unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let pragma_wrapper_diff = new_op_diff.extract::().unwrap(); let helper_ne: bool = pragma_wrapper_diff != pragma_wrapper; assert!(helper_ne); @@ -2705,8 +2588,7 @@ fn test_pyo3_remapqubits_error(input_operation: Operation) { let mut qubit_mapping: HashMap = HashMap::new(); qubit_mapping.insert(2, 0); let result = operation.call_method1(py, "remap_qubits", (qubit_mapping,)); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); }) } @@ -2808,17 +2690,18 @@ fn test_pyo3_json_schema(operation: PragmaOperation) { }; let converted_op = Operation::from(operation); let pyobject = convert_operation_to_pyobject(converted_op).unwrap(); - let operation = pyobject.as_ref(py); + let operation = pyobject.bind(py); let schema: String = - String::extract(operation.call_method0("json_schema").unwrap()).unwrap(); + String::extract_bound(&operation.call_method0("json_schema").unwrap()).unwrap(); assert_eq!(schema, rust_schema); let current_version_string = - String::extract(operation.call_method0("current_version").unwrap()).unwrap(); + String::extract_bound(&operation.call_method0("current_version").unwrap()).unwrap(); let minimum_supported_version_string = - String::extract(operation.call_method0("min_supported_version").unwrap()).unwrap(); + String::extract_bound(&operation.call_method0("min_supported_version").unwrap()) + .unwrap(); assert_eq!(current_version_string, ROQOQO_VERSION); assert_eq!(minimum_supported_version_string, minimum_version); diff --git a/qoqo/tests/integration/operations/single_qubit_gate_operations.rs b/qoqo/tests/integration/operations/single_qubit_gate_operations.rs index c269cdf0..8e2f353d 100644 --- a/qoqo/tests/integration/operations/single_qubit_gate_operations.rs +++ b/qoqo/tests/integration/operations/single_qubit_gate_operations.rs @@ -36,25 +36,7 @@ use std::convert::TryInto; use std::f64::consts::PI; use test_case::test_case; -// helper function to convert CalculatorFloat into a python object -fn convert_cf_to_pyobject( - py: Python, - parameter: CalculatorFloat, -) -> &PyCell { - let parameter_type = py.get_type::(); - match parameter { - CalculatorFloat::Float(x) => parameter_type - .call1((x,)) - .unwrap() - .downcast::>() - .unwrap(), - CalculatorFloat::Str(x) => parameter_type - .call1((x,)) - .unwrap() - .downcast::>() - .unwrap(), - } -} +use super::convert_cf_to_pyobject; /// Test new() function for PauliX #[test_case(Operation::from(PauliX::new(1)), (1,), "__eq__"; "PauliX_eq")] @@ -63,16 +45,13 @@ fn test_new_paulix(input_operation: Operation, arguments: (u32,), method: &str) let operation = convert_operation_to_pyobject(input_operation).unwrap(); pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let operation_type = py.get_type::(); - let operation_py = operation_type - .call1(arguments) - .unwrap() - .downcast::>() - .unwrap(); + let operation_type = py.get_type_bound::(); + let binding = operation_type.call1(arguments).unwrap(); + let operation_py = binding.downcast::().unwrap(); - let comparison = bool::extract( - operation - .as_ref(py) + let comparison = bool::extract_bound( + &operation + .bind(py) .call_method1(method, (operation_py,)) .unwrap(), ) @@ -80,11 +59,8 @@ fn test_new_paulix(input_operation: Operation, arguments: (u32,), method: &str) assert!(comparison); let def_wrapper = operation_py.extract::().unwrap(); - let new_op_diff = operation_type - .call1((2,)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation_type.call1((2,)).unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let def_wrapper_diff = new_op_diff.extract::().unwrap(); let helper_ne: bool = def_wrapper_diff != def_wrapper; assert!(helper_ne); @@ -105,16 +81,13 @@ fn test_new_pauliy(input_operation: Operation, arguments: (u32,), method: &str) let operation = convert_operation_to_pyobject(input_operation).unwrap(); pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let operation_type = py.get_type::(); - let operation_py = operation_type - .call1(arguments) - .unwrap() - .downcast::>() - .unwrap(); + let operation_type = py.get_type_bound::(); + let binding = operation_type.call1(arguments).unwrap(); + let operation_py = binding.downcast::().unwrap(); - let comparison = bool::extract( - operation - .as_ref(py) + let comparison = bool::extract_bound( + &operation + .bind(py) .call_method1(method, (operation_py,)) .unwrap(), ) @@ -122,11 +95,8 @@ fn test_new_pauliy(input_operation: Operation, arguments: (u32,), method: &str) assert!(comparison); let def_wrapper = operation_py.extract::().unwrap(); - let new_op_diff = operation_type - .call1((2,)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation_type.call1((2,)).unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let def_wrapper_diff = new_op_diff.extract::().unwrap(); let helper_ne: bool = def_wrapper_diff != def_wrapper; assert!(helper_ne); @@ -147,16 +117,13 @@ fn test_new_pauliz(input_operation: Operation, arguments: (u32,), method: &str) let operation = convert_operation_to_pyobject(input_operation).unwrap(); pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let operation_type = py.get_type::(); - let operation_py = operation_type - .call1(arguments) - .unwrap() - .downcast::>() - .unwrap(); + let operation_type = py.get_type_bound::(); + let binding = operation_type.call1(arguments).unwrap(); + let operation_py = binding.downcast::().unwrap(); - let comparison = bool::extract( - operation - .as_ref(py) + let comparison = bool::extract_bound( + &operation + .bind(py) .call_method1(method, (operation_py,)) .unwrap(), ) @@ -164,11 +131,8 @@ fn test_new_pauliz(input_operation: Operation, arguments: (u32,), method: &str) assert!(comparison); let def_wrapper = operation_py.extract::().unwrap(); - let new_op_diff = operation_type - .call1((2,)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation_type.call1((2,)).unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let def_wrapper_diff = new_op_diff.extract::().unwrap(); let helper_ne: bool = def_wrapper_diff != def_wrapper; assert!(helper_ne); @@ -189,16 +153,13 @@ fn test_new_sqrtpaulix(input_operation: Operation, arguments: (u32,), method: &s let operation = convert_operation_to_pyobject(input_operation).unwrap(); pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let operation_type = py.get_type::(); - let operation_py = operation_type - .call1(arguments) - .unwrap() - .downcast::>() - .unwrap(); + let operation_type = py.get_type_bound::(); + let binding = operation_type.call1(arguments).unwrap(); + let operation_py = binding.downcast::().unwrap(); - let comparison = bool::extract( - operation - .as_ref(py) + let comparison = bool::extract_bound( + &operation + .bind(py) .call_method1(method, (operation_py,)) .unwrap(), ) @@ -206,11 +167,8 @@ fn test_new_sqrtpaulix(input_operation: Operation, arguments: (u32,), method: &s assert!(comparison); let def_wrapper = operation_py.extract::().unwrap(); - let new_op_diff = operation_type - .call1((2,)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation_type.call1((2,)).unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let def_wrapper_diff = new_op_diff.extract::().unwrap(); let helper_ne: bool = def_wrapper_diff != def_wrapper; assert!(helper_ne); @@ -231,16 +189,13 @@ fn test_new_invsqrtpaulix(input_operation: Operation, arguments: (u32,), method: let operation = convert_operation_to_pyobject(input_operation).unwrap(); pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let operation_type = py.get_type::(); - let operation_py = operation_type - .call1(arguments) - .unwrap() - .downcast::>() - .unwrap(); + let operation_type = py.get_type_bound::(); + let binding = operation_type.call1(arguments).unwrap(); + let operation_py = binding.downcast::().unwrap(); - let comparison = bool::extract( - operation - .as_ref(py) + let comparison = bool::extract_bound( + &operation + .bind(py) .call_method1(method, (operation_py,)) .unwrap(), ) @@ -248,11 +203,8 @@ fn test_new_invsqrtpaulix(input_operation: Operation, arguments: (u32,), method: assert!(comparison); let def_wrapper = operation_py.extract::().unwrap(); - let new_op_diff = operation_type - .call1((2,)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation_type.call1((2,)).unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let def_wrapper_diff = new_op_diff.extract::().unwrap(); let helper_ne: bool = def_wrapper_diff != def_wrapper; assert!(helper_ne); @@ -272,16 +224,13 @@ fn test_new_sgate(input_operation: Operation, arguments: (u32,), method: &str) { let operation = convert_operation_to_pyobject(input_operation).unwrap(); pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let operation_type = py.get_type::(); - let operation_py = operation_type - .call1(arguments) - .unwrap() - .downcast::>() - .unwrap(); + let operation_type = py.get_type_bound::(); + let binding = operation_type.call1(arguments).unwrap(); + let operation_py = binding.downcast::().unwrap(); - let comparison = bool::extract( - operation - .as_ref(py) + let comparison = bool::extract_bound( + &operation + .bind(py) .call_method1(method, (operation_py,)) .unwrap(), ) @@ -289,11 +238,8 @@ fn test_new_sgate(input_operation: Operation, arguments: (u32,), method: &str) { assert!(comparison); let def_wrapper = operation_py.extract::().unwrap(); - let new_op_diff = operation_type - .call1((2,)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation_type.call1((2,)).unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let def_wrapper_diff = new_op_diff.extract::().unwrap(); let helper_ne: bool = def_wrapper_diff != def_wrapper; assert!(helper_ne); @@ -313,16 +259,13 @@ fn test_new_tgate(input_operation: Operation, arguments: (u32,), method: &str) { let operation = convert_operation_to_pyobject(input_operation).unwrap(); pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let operation_type = py.get_type::(); - let operation_py = operation_type - .call1(arguments) - .unwrap() - .downcast::>() - .unwrap(); + let operation_type = py.get_type_bound::(); + let binding = operation_type.call1(arguments).unwrap(); + let operation_py = binding.downcast::().unwrap(); - let comparison = bool::extract( - operation - .as_ref(py) + let comparison = bool::extract_bound( + &operation + .bind(py) .call_method1(method, (operation_py,)) .unwrap(), ) @@ -330,11 +273,8 @@ fn test_new_tgate(input_operation: Operation, arguments: (u32,), method: &str) { assert!(comparison); let def_wrapper = operation_py.extract::().unwrap(); - let new_op_diff = operation_type - .call1((2,)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation_type.call1((2,)).unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let def_wrapper_diff = new_op_diff.extract::().unwrap(); let helper_ne: bool = def_wrapper_diff != def_wrapper; assert!(helper_ne); @@ -354,16 +294,13 @@ fn test_new_hadamard(input_operation: Operation, arguments: (u32,), method: &str let operation = convert_operation_to_pyobject(input_operation).unwrap(); pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let operation_type = py.get_type::(); - let operation_py = operation_type - .call1(arguments) - .unwrap() - .downcast::>() - .unwrap(); + let operation_type = py.get_type_bound::(); + let binding = operation_type.call1(arguments).unwrap(); + let operation_py = binding.downcast::().unwrap(); - let comparison = bool::extract( - operation - .as_ref(py) + let comparison = bool::extract_bound( + &operation + .bind(py) .call_method1(method, (operation_py,)) .unwrap(), ) @@ -371,11 +308,8 @@ fn test_new_hadamard(input_operation: Operation, arguments: (u32,), method: &str assert!(comparison); let def_wrapper = operation_py.extract::().unwrap(); - let new_op_diff = operation_type - .call1((2,)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation_type.call1((2,)).unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let def_wrapper_diff = new_op_diff.extract::().unwrap(); let helper_ne: bool = def_wrapper_diff != def_wrapper; assert!(helper_ne); @@ -396,15 +330,12 @@ fn test_new_rotatex(input_operation: Operation, arguments: (u32, f64), method: & pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { // Basic initialisation, no errors - let operation_type = py.get_type::(); - let operation_py = operation_type - .call1(arguments) - .unwrap() - .downcast::>() - .unwrap(); - let comparison = bool::extract( - operation - .as_ref(py) + let operation_type = py.get_type_bound::(); + let binding = operation_type.call1(arguments).unwrap(); + let operation_py = binding.downcast::().unwrap(); + let comparison = bool::extract_bound( + &operation + .bind(py) .call_method1(method, (operation_py,)) .unwrap(), ) @@ -413,16 +344,12 @@ fn test_new_rotatex(input_operation: Operation, arguments: (u32, f64), method: & // Error initialisation let result = operation_type.call1((0, vec!["fails"])); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); // Testing PartialEq, Clone and Debug let def_wrapper = operation_py.extract::().unwrap(); - let new_op_diff = operation_type - .call1((2, 0.0)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation_type.call1((2, 0.0)).unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let def_wrapper_diff = new_op_diff.extract::().unwrap(); let helper_ne: bool = def_wrapper_diff != def_wrapper; assert!(helper_ne); @@ -443,15 +370,12 @@ fn test_new_rotatey(input_operation: Operation, arguments: (u32, f64), method: & pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { // Basic initialisation, no errors - let operation_type = py.get_type::(); - let operation_py = operation_type - .call1(arguments) - .unwrap() - .downcast::>() - .unwrap(); - let comparison = bool::extract( - operation - .as_ref(py) + let operation_type = py.get_type_bound::(); + let binding = operation_type.call1(arguments).unwrap(); + let operation_py = binding.downcast::().unwrap(); + let comparison = bool::extract_bound( + &operation + .bind(py) .call_method1(method, (operation_py,)) .unwrap(), ) @@ -460,16 +384,12 @@ fn test_new_rotatey(input_operation: Operation, arguments: (u32, f64), method: & // Error initialisation let result = operation_type.call1((0, vec!["fails"])); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); // Testing PartialEq, Clone and Debug let def_wrapper = operation_py.extract::().unwrap(); - let new_op_diff = operation_type - .call1((2, 0.0)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation_type.call1((2, 0.0)).unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let def_wrapper_diff = new_op_diff.extract::().unwrap(); let helper_ne: bool = def_wrapper_diff != def_wrapper; assert!(helper_ne); @@ -490,16 +410,13 @@ fn test_new_rotatez(input_operation: Operation, arguments: (u32, f64), method: & pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { // Basic initialisation, no errors - let operation_type = py.get_type::(); - let operation_py = operation_type - .call1(arguments) - .unwrap() - .downcast::>() - .unwrap(); + let operation_type = py.get_type_bound::(); + let binding = operation_type.call1(arguments).unwrap(); + let operation_py = binding.downcast::().unwrap(); - let comparison = bool::extract( - operation - .as_ref(py) + let comparison = bool::extract_bound( + &operation + .bind(py) .call_method1(method, (operation_py,)) .unwrap(), ) @@ -508,16 +425,12 @@ fn test_new_rotatez(input_operation: Operation, arguments: (u32, f64), method: & // Error initialisation let result = operation_type.call1((0, vec!["fails"])); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); // Testing PartialEq, Clone and Debug let def_wrapper = operation_py.extract::().unwrap(); - let new_op_diff = operation_type - .call1((2, 0.0)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation_type.call1((2, 0.0)).unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let def_wrapper_diff = new_op_diff.extract::().unwrap(); let helper_ne: bool = def_wrapper_diff != def_wrapper; assert!(helper_ne); @@ -538,16 +451,13 @@ fn test_new_phaseshiftstate0(input_operation: Operation, arguments: (u32, f64), pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { // Basic initialisation, no errors - let operation_type = py.get_type::(); - let operation_py = operation_type - .call1(arguments) - .unwrap() - .downcast::>() - .unwrap(); + let operation_type = py.get_type_bound::(); + let binding = operation_type.call1(arguments).unwrap(); + let operation_py = binding.downcast::().unwrap(); - let comparison = bool::extract( - operation - .as_ref(py) + let comparison = bool::extract_bound( + &operation + .bind(py) .call_method1(method, (operation_py,)) .unwrap(), ) @@ -556,16 +466,12 @@ fn test_new_phaseshiftstate0(input_operation: Operation, arguments: (u32, f64), // Error initialisation let result = operation_type.call1((0, vec!["fails"])); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); // Testing PartialEq, Clone and Debug let def_wrapper = operation_py.extract::().unwrap(); - let new_op_diff = operation_type - .call1((2, 0.0)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation_type.call1((2, 0.0)).unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let def_wrapper_diff = new_op_diff.extract::().unwrap(); let helper_ne: bool = def_wrapper_diff != def_wrapper; assert!(helper_ne); @@ -586,16 +492,13 @@ fn test_new_phaseshiftstate1(input_operation: Operation, arguments: (u32, f64), pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { // Basic initialisation, no errors - let operation_type = py.get_type::(); - let operation_py = operation_type - .call1(arguments) - .unwrap() - .downcast::>() - .unwrap(); + let operation_type = py.get_type_bound::(); + let binding = operation_type.call1(arguments).unwrap(); + let operation_py = binding.downcast::().unwrap(); - let comparison = bool::extract( - operation - .as_ref(py) + let comparison = bool::extract_bound( + &operation + .bind(py) .call_method1(method, (operation_py,)) .unwrap(), ) @@ -604,16 +507,12 @@ fn test_new_phaseshiftstate1(input_operation: Operation, arguments: (u32, f64), // Error initialisation let result = operation_type.call1((0, vec!["fails"])); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); // Testing PartialEq, Clone and Debug let def_wrapper = operation_py.extract::().unwrap(); - let new_op_diff = operation_type - .call1((2, 0.0)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation_type.call1((2, 0.0)).unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let def_wrapper_diff = new_op_diff.extract::().unwrap(); let helper_ne: bool = def_wrapper_diff != def_wrapper; assert!(helper_ne); @@ -634,16 +533,13 @@ fn test_new_gpi(input_operation: Operation, arguments: (u32, f64), method: &str) pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { // Basic initialisation, no errors - let operation_type = py.get_type::(); - let operation_py = operation_type - .call1(arguments) - .unwrap() - .downcast::>() - .unwrap(); + let operation_type = py.get_type_bound::(); + let binding = operation_type.call1(arguments).unwrap(); + let operation_py = binding.downcast::().unwrap(); - let comparison = bool::extract( - operation - .as_ref(py) + let comparison = bool::extract_bound( + &operation + .bind(py) .call_method1(method, (operation_py,)) .unwrap(), ) @@ -652,16 +548,12 @@ fn test_new_gpi(input_operation: Operation, arguments: (u32, f64), method: &str) // Error initialisation let result = operation_type.call1((0, vec!["fails"])); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); // Testing PartialEq, Clone and Debug let def_wrapper = operation_py.extract::().unwrap(); - let new_op_diff = operation_type - .call1((2, 0.0)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation_type.call1((2, 0.0)).unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let def_wrapper_diff = new_op_diff.extract::().unwrap(); let helper_ne: bool = def_wrapper_diff != def_wrapper; assert!(helper_ne); @@ -682,16 +574,13 @@ fn test_new_gpi2(input_operation: Operation, arguments: (u32, f64), method: &str pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { // Basic initialisation, no errors - let operation_type = py.get_type::(); - let operation_py = operation_type - .call1(arguments) - .unwrap() - .downcast::>() - .unwrap(); + let operation_type = py.get_type_bound::(); + let binding = operation_type.call1(arguments).unwrap(); + let operation_py = binding.downcast::().unwrap(); - let comparison = bool::extract( - operation - .as_ref(py) + let comparison = bool::extract_bound( + &operation + .bind(py) .call_method1(method, (operation_py,)) .unwrap(), ) @@ -700,16 +589,12 @@ fn test_new_gpi2(input_operation: Operation, arguments: (u32, f64), method: &str // Error initialisation let result = operation_type.call1((0, vec!["fails"])); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); // Testing PartialEq, Clone and Debug let def_wrapper = operation_py.extract::().unwrap(); - let new_op_diff = operation_type - .call1((2, 0.0)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation_type.call1((2, 0.0)).unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let def_wrapper_diff = new_op_diff.extract::().unwrap(); let helper_ne: bool = def_wrapper_diff != def_wrapper; assert!(helper_ne); @@ -744,15 +629,14 @@ fn test_new_rotate(input_operation: Operation, arguments: (u32, f64, f64, f64), pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { // Basic initialisation, no errors - let operation_type = py.get_type::(); - let operation_py = operation_type - .call1(arguments) - .unwrap() - .downcast::>() + let operation_type = py.get_type_bound::(); + let binding = operation_type.call1(arguments).unwrap(); + let operation_py = binding + .downcast::() .unwrap(); - let comparison = bool::extract( - operation - .as_ref(py) + let comparison = bool::extract_bound( + &operation + .bind(py) .call_method1(method, (operation_py,)) .unwrap(), ) @@ -761,23 +645,19 @@ fn test_new_rotate(input_operation: Operation, arguments: (u32, f64, f64, f64), // Error initialisation let result = operation_type.call1((0, vec!["fails"], 0.0, 0.0)); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); let result = operation_type.call1((0, 0.0, vec!["fails"], 0.0)); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); let result = operation_type.call1((0, 0.0, 0.0, vec!["fails"])); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); // Testing PartialEq, Clone and Debug let def_wrapper = operation_py .extract::() .unwrap(); - let new_op_diff = operation_type - .call1((2, 0.0, 0.0, 0.0)) - .unwrap() - .downcast::>() + let binding = operation_type.call1((2, 0.0, 0.0, 0.0)).unwrap(); + let new_op_diff = binding + .downcast::() .unwrap(); let def_wrapper_diff = new_op_diff .extract::() @@ -813,15 +693,12 @@ fn test_new_rotatexy(input_operation: Operation, arguments: (u32, f64, f64), met pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { // Basic initialisation, no errors - let operation_type = py.get_type::(); - let operation_py = operation_type - .call1(arguments) - .unwrap() - .downcast::>() - .unwrap(); - let comparison = bool::extract( - operation - .as_ref(py) + let operation_type = py.get_type_bound::(); + let binding = operation_type.call1(arguments).unwrap(); + let operation_py = binding.downcast::().unwrap(); + let comparison = bool::extract_bound( + &operation + .bind(py) .call_method1(method, (operation_py,)) .unwrap(), ) @@ -830,19 +707,14 @@ fn test_new_rotatexy(input_operation: Operation, arguments: (u32, f64, f64), met // Error initialisation let result = operation_type.call1((0, vec!["fails"], 0.0)); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); let result = operation_type.call1((0, vec!["fails"], 0.0)); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); // Testing PartialEq, Clone and Debug let def_wrapper = operation_py.extract::().unwrap(); - let new_op_diff = operation_type - .call1((2, 0.0, 0.0)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation_type.call1((2, 0.0, 0.0)).unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let def_wrapper_diff = new_op_diff.extract::().unwrap(); let helper_ne: bool = def_wrapper_diff != def_wrapper; assert!(helper_ne); @@ -885,16 +757,15 @@ fn test_new_singlequbitgate( pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { // Basic initialisation, no errors - let operation_type = py.get_type::(); - let operation_py = operation_type - .call1(arguments) - .unwrap() - .downcast::>() - .unwrap(); - let comparison = bool::extract( - operation - .as_ref(py) - .call_method1(method, (operation_py,)) + let operation_type = py.get_type_bound::(); + let operation_py = operation_type.call1(arguments).unwrap(); + let comparison = bool::extract_bound( + &operation + .bind(py) + .call_method1( + method, + (operation_py.downcast::().unwrap(),), + ) .unwrap(), ) .unwrap(); @@ -902,32 +773,24 @@ fn test_new_singlequbitgate( // Error initialisation let result = operation_type.call1((0, vec!["fails"], 0.0, 0.0, 0.0, 0.0)); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); let result = operation_type.call1((0, 0.0, vec!["fails"], 0.0, 0.0, 0.0)); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); let result = operation_type.call1((0, 0.0, 0.0, vec!["fails"], 0.0, 0.0)); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); let result = operation_type.call1((0, 0.0, 0.0, 0.0, vec!["fails"], 0.0)); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); let result = operation_type.call1((0, 0.0, 0.0, 0.0, 0.0, vec!["fails"])); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); // Testing PartialEq, Clone and Debug let def_wrapper = operation_py.extract::().unwrap(); - let new_op_diff = operation_type - .call1((2, 0.0, 0.0, 0.0, 0.0, 0.0)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation_type.call1((2, 0.0, 0.0, 0.0, 0.0, 0.0)).unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let def_wrapper_diff = new_op_diff.extract::().unwrap(); let helper_ne: bool = def_wrapper_diff != def_wrapper; assert!(helper_ne); @@ -948,16 +811,13 @@ fn test_new_identity(input_operation: Operation, arguments: (u32,), method: &str let operation = convert_operation_to_pyobject(input_operation).unwrap(); pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let operation_type = py.get_type::(); - let operation_py = operation_type - .call1(arguments) - .unwrap() - .downcast::>() - .unwrap(); + let operation_type = py.get_type_bound::(); + let binding = operation_type.call1(arguments).unwrap(); + let operation_py = binding.downcast::().unwrap(); - let comparison = bool::extract( - operation - .as_ref(py) + let comparison = bool::extract_bound( + &operation + .bind(py) .call_method1(method, (operation_py,)) .unwrap(), ) @@ -965,11 +825,8 @@ fn test_new_identity(input_operation: Operation, arguments: (u32,), method: &str assert!(comparison); let def_wrapper = operation_py.extract::().unwrap(); - let new_op_diff = operation_type - .call1((2,)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation_type.call1((2,)).unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let def_wrapper_diff = new_op_diff.extract::().unwrap(); let helper_ne: bool = def_wrapper_diff != def_wrapper; assert!(helper_ne); @@ -1023,11 +880,11 @@ fn test_pyo3_is_parametrized(input_operation: Operation) { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_operation).unwrap(); - assert!(bool::extract( - operation + assert!(bool::extract_bound( + &operation .call_method0(py, "is_parametrized") .unwrap() - .as_ref(py) + .bind(py) ) .unwrap()); }) @@ -1082,11 +939,11 @@ fn test_pyo3_is_not_parametrized(input_operation: Operation) { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_operation).unwrap(); - assert!(!bool::extract( - operation + assert!(!bool::extract_bound( + &operation .call_method0(py, "is_parametrized") .unwrap() - .as_ref(py) + .bind(py) ) .unwrap()); }) @@ -1114,12 +971,12 @@ fn test_pyo3_theta(theta: CalculatorFloat, input_operation: Operation) { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_operation).unwrap(); - let theta_op: CalculatorFloatWrapper = CalculatorFloatWrapper::extract( - operation.call_method0(py, "theta").unwrap().as_ref(py), + let theta_op: CalculatorFloatWrapper = CalculatorFloatWrapper::extract_bound( + &operation.call_method0(py, "theta").unwrap().bind(py), ) .unwrap(); let theta_param: CalculatorFloatWrapper = - CalculatorFloatWrapper::extract(convert_cf_to_pyobject(py, theta)).unwrap(); + CalculatorFloatWrapper::extract_bound(&convert_cf_to_pyobject(py, theta)).unwrap(); assert_eq!(theta_op.internal, theta_param.internal); }) } @@ -1163,7 +1020,7 @@ fn test_pyo3_qubit(qubit: usize, input_operation: Operation) { Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_operation).unwrap(); let qubit_op: usize = - usize::extract(operation.call_method0(py, "qubit").unwrap().as_ref(py)).unwrap(); + usize::extract_bound(&operation.call_method0(py, "qubit").unwrap().bind(py)).unwrap(); assert_eq!(qubit_op, qubit); }) } @@ -1217,7 +1074,8 @@ fn test_pyo3_hqslang(name: &'static str, input_operation: Operation) { Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_operation).unwrap(); let name_op: String = - String::extract(operation.call_method0(py, "hqslang").unwrap().as_ref(py)).unwrap(); + String::extract_bound(&operation.call_method0(py, "hqslang").unwrap().bind(py)) + .unwrap(); assert_eq!(name_op, name.to_string()); }) } @@ -1412,7 +1270,8 @@ fn test_pyo3_tags(input_operation: Operation, tags: Vec<&str>) { Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_operation).unwrap(); let tags_op: Vec = - Vec::::extract(operation.call_method0(py, "tags").unwrap().as_ref(py)).unwrap(); + Vec::::extract_bound(&operation.call_method0(py, "tags").unwrap().bind(py)) + .unwrap(); assert_eq!(tags_op.len(), tags.len()); for i in 0..tags.len() { assert_eq!(tags_op[i], tags[i]); @@ -1471,7 +1330,7 @@ fn test_pyo3_remapqubits(input_operation: Operation) { let operation = convert_operation_to_pyobject(input_operation).unwrap(); // test initial qubit let qubit: usize = - usize::extract(operation.call_method0(py, "qubit").unwrap().as_ref(py)).unwrap(); + usize::extract_bound(&operation.call_method0(py, "qubit").unwrap().bind(py)).unwrap(); assert_eq!(qubit.clone(), 0); // remap qubits let mut qubit_mapping: HashMap = HashMap::new(); @@ -1482,7 +1341,7 @@ fn test_pyo3_remapqubits(input_operation: Operation) { .unwrap(); // test re-mapped qubit let qubit_new: usize = - usize::extract(result.call_method0(py, "qubit").unwrap().as_ref(py)).unwrap(); + usize::extract_bound(&result.call_method0(py, "qubit").unwrap().bind(py)).unwrap(); assert_eq!(qubit_new.clone(), 1); // test that initial and rempapped qubits are different assert_ne!(qubit, qubit_new); @@ -1543,8 +1402,7 @@ fn test_pyo3_remapqubits_error(input_operation: Operation) { let mut qubit_mapping: HashMap = HashMap::new(); qubit_mapping.insert(2, 0); let result = operation.call_method1(py, "remap_qubits", (qubit_mapping,)); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); }) } @@ -1599,9 +1457,12 @@ fn test_pyo3_unitarymatrix(input_operation: Operation) { let operation = convert_operation_to_pyobject(input_operation.clone()).unwrap(); let py_result = operation.call_method0(py, "unitary_matrix").unwrap(); let result_matrix = py_result - .downcast::>(py) + .downcast_bound::>(py) .unwrap() - .to_owned_array(); + .as_gil_ref() + .readonly() + .as_array() + .to_owned(); // compare to reference matrix obtained in Rust directly (without passing to Python) let gate: SingleQubitGateOperation = input_operation.try_into().unwrap(); @@ -1642,8 +1503,7 @@ fn test_pyo3_unitarymatrix_error(input_operation: Operation) { Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_operation.clone()).unwrap(); let py_result = operation.call_method0(py, "unitary_matrix"); - let result_ref = py_result.as_ref(); - assert!(result_ref.is_err()); + assert!(py_result.is_err()); }) } @@ -1675,8 +1535,7 @@ fn test_pyo3_unitarymatrix_singlequbitgate(input_operation: Operation) { Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_operation.clone()).unwrap(); let py_result = operation.call_method0(py, "unitary_matrix"); - let result_ref = py_result.as_ref(); - assert!(result_ref.is_err()); + assert!(py_result.is_err()); }) } @@ -1733,17 +1592,17 @@ fn test_pyo3_copy_deepcopy(input_operation: Operation) { let deepcopy_op = operation.call_method1(py, "__deepcopy__", ("",)).unwrap(); let copy_deepcopy_param = operation; - let comparison_copy = bool::extract( - copy_op - .as_ref(py) + let comparison_copy = bool::extract_bound( + ©_op + .bind(py) .call_method1("__eq__", (copy_deepcopy_param.clone(),)) .unwrap(), ) .unwrap(); assert!(comparison_copy); - let comparison_deepcopy = bool::extract( - deepcopy_op - .as_ref(py) + let comparison_deepcopy = bool::extract_bound( + &deepcopy_op + .bind(py) .call_method1("__eq__", (copy_deepcopy_param,)) .unwrap(), ) @@ -1805,11 +1664,11 @@ fn test_pyo3_alpha_r(input_operation: Operation) { let gate: SingleQubitGateOperation = input_operation.try_into().unwrap(); let alpha_r = gate.alpha_r(); let alpha_r_param: CalculatorFloatWrapper = - CalculatorFloatWrapper::extract(convert_cf_to_pyobject(py, alpha_r)).unwrap(); + CalculatorFloatWrapper::extract_bound(&convert_cf_to_pyobject(py, alpha_r)).unwrap(); let method_op = operation.call_method0(py, "alpha_r").unwrap(); - let comparison_alpha_r = bool::extract( - method_op - .as_ref(py) + let comparison_alpha_r = bool::extract_bound( + &method_op + .bind(py) .call_method1("__eq__", (alpha_r_param,)) .unwrap(), ) @@ -1871,11 +1730,11 @@ fn test_pyo3_alpha_i(input_operation: Operation) { let gate: SingleQubitGateOperation = input_operation.try_into().unwrap(); let alpha_i = gate.alpha_i(); let alpha_i_param: CalculatorFloatWrapper = - CalculatorFloatWrapper::extract(convert_cf_to_pyobject(py, alpha_i)).unwrap(); + CalculatorFloatWrapper::extract_bound(&convert_cf_to_pyobject(py, alpha_i)).unwrap(); let method_op = operation.call_method0(py, "alpha_i").unwrap(); - let comparison_alpha_i = bool::extract( - method_op - .as_ref(py) + let comparison_alpha_i = bool::extract_bound( + &method_op + .bind(py) .call_method1("__eq__", (alpha_i_param,)) .unwrap(), ) @@ -1937,11 +1796,11 @@ fn test_pyo3_beta_r(input_operation: Operation) { let gate: SingleQubitGateOperation = input_operation.try_into().unwrap(); let beta_r = gate.beta_r(); let beta_r_param: CalculatorFloatWrapper = - CalculatorFloatWrapper::extract(convert_cf_to_pyobject(py, beta_r)).unwrap(); + CalculatorFloatWrapper::extract_bound(&convert_cf_to_pyobject(py, beta_r)).unwrap(); let method_op = operation.call_method0(py, "beta_r").unwrap(); - let comparison_beta_r = bool::extract( - method_op - .as_ref(py) + let comparison_beta_r = bool::extract_bound( + &method_op + .bind(py) .call_method1("__eq__", (beta_r_param,)) .unwrap(), ) @@ -2003,11 +1862,11 @@ fn test_pyo3_beta_i(input_operation: Operation) { let gate: SingleQubitGateOperation = input_operation.try_into().unwrap(); let beta_i = gate.beta_i(); let beta_i_param: CalculatorFloatWrapper = - CalculatorFloatWrapper::extract(convert_cf_to_pyobject(py, beta_i)).unwrap(); + CalculatorFloatWrapper::extract_bound(&convert_cf_to_pyobject(py, beta_i)).unwrap(); let method_op = operation.call_method0(py, "beta_i").unwrap(); - let comparison_beta_i = bool::extract( - method_op - .as_ref(py) + let comparison_beta_i = bool::extract_bound( + &method_op + .bind(py) .call_method1("__eq__", (beta_i_param,)) .unwrap(), ) @@ -2069,11 +1928,12 @@ fn test_pyo3_global_phase(input_operation: Operation) { let gate: SingleQubitGateOperation = input_operation.try_into().unwrap(); let global_phase = gate.global_phase(); let global_phase_param: CalculatorFloatWrapper = - CalculatorFloatWrapper::extract(convert_cf_to_pyobject(py, global_phase)).unwrap(); + CalculatorFloatWrapper::extract_bound(&convert_cf_to_pyobject(py, global_phase)) + .unwrap(); let method_op = operation.call_method0(py, "global_phase").unwrap(); - let comparison_global_phase = bool::extract( - method_op - .as_ref(py) + let comparison_global_phase = bool::extract_bound( + &method_op + .bind(py) .call_method1("__eq__", (global_phase_param,)) .unwrap(), ) @@ -2175,10 +2035,10 @@ fn test_pyo3_format_repr(format_repr: &str, input_operation: Operation) { Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_operation).unwrap(); let to_format = operation.call_method1(py, "__format__", ("",)).unwrap(); - let format_op: &str = <&str>::extract(to_format.as_ref(py)).unwrap(); + let format_op: String = String::extract_bound(&to_format.bind(py)).unwrap(); assert_eq!(format_op, format_repr); let to_repr = operation.call_method0(py, "__repr__").unwrap(); - let repr_op: &str = <&str>::extract(to_repr.as_ref(py)).unwrap(); + let repr_op: String = String::extract_bound(&to_repr.bind(py)).unwrap(); assert_eq!(repr_op, format_repr); }) } @@ -2208,9 +2068,9 @@ fn test_pyo3_substitute_parameters(input_operation: Operation) { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_operation.clone()).unwrap(); - let mut substitution_dict_py: HashMap<&str, f64> = HashMap::new(); - substitution_dict_py.insert("param", 1.0); - substitution_dict_py.insert("param2", 0.0); + let mut substitution_dict_py: HashMap = HashMap::new(); + substitution_dict_py.insert("param".to_owned(), 1.0); + substitution_dict_py.insert("param2".to_owned(), 0.0); let substitute_op = operation .call_method1(py, "substitute_parameters", (substitution_dict_py,)) .unwrap(); @@ -2223,9 +2083,9 @@ fn test_pyo3_substitute_parameters(input_operation: Operation) { .unwrap(); let test_operation = convert_operation_to_pyobject(substitute_param).unwrap(); - let comparison = bool::extract( - substitute_op - .as_ref(py) + let comparison = bool::extract_bound( + &substitute_op + .bind(py) .call_method1("__eq__", (test_operation,)) .unwrap(), ) @@ -2246,8 +2106,8 @@ fn test_pyo3_substitute_params_rotate(input_operation: Operation) { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_operation.clone()).unwrap(); - let mut substitution_dict_py: HashMap<&str, f64> = HashMap::new(); - substitution_dict_py.insert("theta", 1.0); + let mut substitution_dict_py: HashMap = HashMap::new(); + substitution_dict_py.insert("theta".to_owned(), 1.0); let substitute_op = operation .call_method1(py, "substitute_parameters", (substitution_dict_py,)) .unwrap(); @@ -2259,9 +2119,9 @@ fn test_pyo3_substitute_params_rotate(input_operation: Operation) { .unwrap(); let test_operation = convert_operation_to_pyobject(substitute_param).unwrap(); - let comparison = bool::extract( - substitute_op - .as_ref(py) + let comparison = bool::extract_bound( + &substitute_op + .bind(py) .call_method1("__eq__", (test_operation,)) .unwrap(), ) @@ -2302,10 +2162,9 @@ fn test_pyo3_substitute_params_error(input_operation: Operation) { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_operation).unwrap(); - let substitution_dict: HashMap<&str, f64> = HashMap::new(); + let substitution_dict: HashMap = HashMap::new(); let result = operation.call_method1(py, "substitute_parameters", (substitution_dict,)); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); }) } @@ -2330,15 +2189,15 @@ fn test_ineffective_substitute_parameters(input_operation: Operation) { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_operation.clone()).unwrap(); - let mut substitution_dict_py: HashMap<&str, f64> = HashMap::new(); - substitution_dict_py.insert("theta", 0.0); + let mut substitution_dict_py: HashMap = HashMap::new(); + substitution_dict_py.insert("theta".to_owned(), 0.0); let substitute_op = operation .call_method1(py, "substitute_parameters", (substitution_dict_py,)) .unwrap(); - let comparison = bool::extract( - substitute_op - .as_ref(py) + let comparison = bool::extract_bound( + &substitute_op + .bind(py) .call_method1("__eq__", (operation,)) .unwrap(), ) @@ -2394,11 +2253,11 @@ fn test_pyo3_rotate_powercf(first_op: Operation, second_op: Operation) { let comparison_op = convert_operation_to_pyobject(second_op).unwrap(); let remapped_op = operation.call_method1(py, "powercf", (power,)).unwrap(); - let comparison = bool::extract( - remapped_op + let comparison = bool::extract_bound( + &remapped_op .call_method1(py, "__eq__", (comparison_op,)) .unwrap() - .as_ref(py), + .bind(py), ) .unwrap(); assert!(comparison); @@ -2638,18 +2497,18 @@ fn test_pyo3_richcmp(definition_1: Operation, definition_2: Operation) { let operation_one = convert_operation_to_pyobject(definition_1).unwrap(); let operation_two = convert_operation_to_pyobject(definition_2).unwrap(); - let comparison = bool::extract( - operation_one - .as_ref(py) + let comparison = bool::extract_bound( + &operation_one + .bind(py) .call_method1("__eq__", (operation_two.clone(),)) .unwrap(), ) .unwrap(); assert!(!comparison); - let comparison = bool::extract( - operation_one - .as_ref(py) + let comparison = bool::extract_bound( + &operation_one + .bind(py) .call_method1("__ne__", (operation_two.clone(),)) .unwrap(), ) @@ -2781,17 +2640,18 @@ fn test_pyo3_json_schema(operation: SingleQubitGateOperation) { }; let converted_op = Operation::from(operation); let pyobject = convert_operation_to_pyobject(converted_op).unwrap(); - let operation = pyobject.as_ref(py); + let operation = pyobject.bind(py); let schema: String = - String::extract(operation.call_method0("json_schema").unwrap()).unwrap(); + String::extract_bound(&operation.call_method0("json_schema").unwrap()).unwrap(); assert_eq!(schema, rust_schema); let current_version_string = - String::extract(operation.call_method0("current_version").unwrap()).unwrap(); + String::extract_bound(&operation.call_method0("current_version").unwrap()).unwrap(); let minimum_supported_version_string = - String::extract(operation.call_method0("min_supported_version").unwrap()).unwrap(); + String::extract_bound(&operation.call_method0("min_supported_version").unwrap()) + .unwrap(); assert_eq!(current_version_string, ROQOQO_VERSION); assert_eq!(minimum_supported_version_string, minimum_version); diff --git a/qoqo/tests/integration/operations/spin_boson_operations.rs b/qoqo/tests/integration/operations/spin_boson_operations.rs index 3ea55039..deb22bf0 100644 --- a/qoqo/tests/integration/operations/spin_boson_operations.rs +++ b/qoqo/tests/integration/operations/spin_boson_operations.rs @@ -18,7 +18,6 @@ use qoqo::operations::{ QuantumRabiWrapper, SingleExcitationLoadWrapper, SingleExcitationStoreWrapper, }; use qoqo_calculator::{Calculator, CalculatorFloat}; -use qoqo_calculator_pyo3::CalculatorFloatWrapper; use roqoqo::operations::Operation; use roqoqo::operations::*; #[cfg(feature = "json_schema")] @@ -26,25 +25,7 @@ use roqoqo::ROQOQO_VERSION; use std::collections::{HashMap, HashSet}; use test_case::test_case; -// helper function to convert CalculatorFloat into a python object -fn convert_cf_to_pyobject( - py: Python, - parameter: CalculatorFloat, -) -> &PyCell { - let parameter_type = py.get_type::(); - match parameter { - CalculatorFloat::Float(x) => parameter_type - .call1((x,)) - .unwrap() - .downcast::>() - .unwrap(), - CalculatorFloat::Str(x) => parameter_type - .call1((x,)) - .unwrap() - .downcast::>() - .unwrap(), - } -} +use super::convert_cf_to_pyobject; /// Test new() function for QuantumRabi #[test_case(Operation::from(QuantumRabi::new(1, 0, 1.0.into())), (1, 0, 1.0,), "__eq__"; "QuantumRabi_eq")] @@ -53,16 +34,13 @@ fn test_new_quantum_rabi(input_operation: Operation, arguments: (u32, u32, f64), let operation = convert_operation_to_pyobject(input_operation).unwrap(); pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let operation_type = py.get_type::(); - let operation_py = operation_type - .call1(arguments) - .unwrap() - .downcast::>() - .unwrap(); + let operation_type = py.get_type_bound::(); + let binding = operation_type.call1(arguments).unwrap(); + let operation_py = binding.downcast::().unwrap(); - let comparison = bool::extract( - operation - .as_ref(py) + let comparison = bool::extract_bound( + &operation + .bind(py) .call_method1(method, (operation_py,)) .unwrap(), ) @@ -70,11 +48,8 @@ fn test_new_quantum_rabi(input_operation: Operation, arguments: (u32, u32, f64), assert!(comparison); let def_wrapper = operation_py.extract::().unwrap(); - let new_op_diff = operation_type - .call1((2, 3, 1.0)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation_type.call1((2, 3, 1.0)).unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let def_wrapper_diff = new_op_diff.extract::().unwrap(); let helper_ne: bool = def_wrapper_diff != def_wrapper; assert!(helper_ne); @@ -86,11 +61,11 @@ fn test_new_quantum_rabi(input_operation: Operation, arguments: (u32, u32, f64), "QuantumRabiWrapper { internal: QuantumRabi { qubit: 2, mode: 3, theta: Float(1.0) } }" ); - let comparison_copy = bool::extract( - operation + let comparison_copy = bool::extract_bound( + &operation .call_method0(py, "theta") .unwrap() - .as_ref(py) + .bind(py) .call_method1( "__eq__", (convert_cf_to_pyobject(py, CalculatorFloat::Float(1.0)),), @@ -113,16 +88,13 @@ fn test_new_longitudinal_coupling( let operation = convert_operation_to_pyobject(input_operation).unwrap(); pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let operation_type = py.get_type::(); - let operation_py = operation_type - .call1(arguments) - .unwrap() - .downcast::>() - .unwrap(); + let operation_type = py.get_type_bound::(); + let binding = operation_type.call1(arguments).unwrap(); + let operation_py = binding.downcast::().unwrap(); - let comparison = bool::extract( - operation - .as_ref(py) + let comparison = bool::extract_bound( + &operation + .bind(py) .call_method1(method, (operation_py,)) .unwrap(), ) @@ -132,11 +104,8 @@ fn test_new_longitudinal_coupling( let def_wrapper = operation_py .extract::() .unwrap(); - let new_op_diff = operation_type - .call1((2, 3, 1.0)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation_type.call1((2, 3, 1.0)).unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let def_wrapper_diff = new_op_diff .extract::() .unwrap(); @@ -150,11 +119,11 @@ fn test_new_longitudinal_coupling( "LongitudinalCouplingWrapper { internal: LongitudinalCoupling { qubit: 2, mode: 3, theta: Float(1.0) } }" ); - let comparison_copy = bool::extract( - operation + let comparison_copy = bool::extract_bound( + &operation .call_method0(py, "theta") .unwrap() - .as_ref(py) + .bind(py) .call_method1( "__eq__", (convert_cf_to_pyobject(py, CalculatorFloat::Float(1.0)),), @@ -173,16 +142,13 @@ fn test_new_jaynes_cummings(input_operation: Operation, arguments: (u32, u32, f6 let operation = convert_operation_to_pyobject(input_operation).unwrap(); pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let operation_type = py.get_type::(); - let operation_py = operation_type - .call1(arguments) - .unwrap() - .downcast::>() - .unwrap(); + let operation_type = py.get_type_bound::(); + let binding = operation_type.call1(arguments).unwrap(); + let operation_py = binding.downcast::().unwrap(); - let comparison = bool::extract( - operation - .as_ref(py) + let comparison = bool::extract_bound( + &operation + .bind(py) .call_method1(method, (operation_py,)) .unwrap(), ) @@ -190,11 +156,8 @@ fn test_new_jaynes_cummings(input_operation: Operation, arguments: (u32, u32, f6 assert!(comparison); let def_wrapper = operation_py.extract::().unwrap(); - let new_op_diff = operation_type - .call1((2, 3, 1.0)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation_type.call1((2, 3, 1.0)).unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let def_wrapper_diff = new_op_diff.extract::().unwrap(); let helper_ne: bool = def_wrapper_diff != def_wrapper; assert!(helper_ne); @@ -206,11 +169,11 @@ fn test_new_jaynes_cummings(input_operation: Operation, arguments: (u32, u32, f6 "JaynesCummingsWrapper { internal: JaynesCummings { qubit: 2, mode: 3, theta: Float(1.0) } }" ); - let comparison_copy = bool::extract( - operation + let comparison_copy = bool::extract_bound( + &operation .call_method0(py, "theta") .unwrap() - .as_ref(py) + .bind(py) .call_method1( "__eq__", (convert_cf_to_pyobject(py, CalculatorFloat::Float(1.0)),), @@ -233,16 +196,13 @@ fn test_new_single_excitation_load( let operation = convert_operation_to_pyobject(input_operation).unwrap(); pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let operation_type = py.get_type::(); - let operation_py = operation_type - .call1(arguments) - .unwrap() - .downcast::>() - .unwrap(); + let operation_type = py.get_type_bound::(); + let binding = operation_type.call1(arguments).unwrap(); + let operation_py = binding.downcast::().unwrap(); - let comparison = bool::extract( - operation - .as_ref(py) + let comparison = bool::extract_bound( + &operation + .bind(py) .call_method1(method, (operation_py,)) .unwrap(), ) @@ -252,11 +212,8 @@ fn test_new_single_excitation_load( let def_wrapper = operation_py .extract::() .unwrap(); - let new_op_diff = operation_type - .call1((2, 3)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation_type.call1((2, 3)).unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let def_wrapper_diff = new_op_diff .extract::() .unwrap(); @@ -283,16 +240,13 @@ fn test_new_single_excitation_store( let operation = convert_operation_to_pyobject(input_operation).unwrap(); pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let operation_type = py.get_type::(); - let operation_py = operation_type - .call1(arguments) - .unwrap() - .downcast::>() - .unwrap(); + let operation_type = py.get_type_bound::(); + let binding = operation_type.call1(arguments).unwrap(); + let operation_py = binding.downcast::().unwrap(); - let comparison = bool::extract( - operation - .as_ref(py) + let comparison = bool::extract_bound( + &operation + .bind(py) .call_method1(method, (operation_py,)) .unwrap(), ) @@ -302,11 +256,8 @@ fn test_new_single_excitation_store( let def_wrapper = operation_py .extract::() .unwrap(); - let new_op_diff = operation_type - .call1((2, 3)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation_type.call1((2, 3)).unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let def_wrapper_diff = new_op_diff .extract::() .unwrap(); @@ -329,16 +280,13 @@ fn test_new_cz_qubit_resonator(input_operation: Operation, arguments: (u32, u32) let operation = convert_operation_to_pyobject(input_operation).unwrap(); pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let operation_type = py.get_type::(); - let operation_py = operation_type - .call1(arguments) - .unwrap() - .downcast::>() - .unwrap(); + let operation_type = py.get_type_bound::(); + let binding = operation_type.call1(arguments).unwrap(); + let operation_py = binding.downcast::().unwrap(); - let comparison = bool::extract( - operation - .as_ref(py) + let comparison = bool::extract_bound( + &operation + .bind(py) .call_method1(method, (operation_py,)) .unwrap(), ) @@ -346,11 +294,8 @@ fn test_new_cz_qubit_resonator(input_operation: Operation, arguments: (u32, u32) assert!(comparison); let def_wrapper = operation_py.extract::().unwrap(); - let new_op_diff = operation_type - .call1((2, 3)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation_type.call1((2, 3)).unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let def_wrapper_diff = new_op_diff.extract::().unwrap(); let helper_ne: bool = def_wrapper_diff != def_wrapper; assert!(helper_ne); @@ -372,11 +317,11 @@ fn test_pyo3_is_parametrized(input_operation: Operation) { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_operation).unwrap(); - assert!(bool::extract( - operation + assert!(bool::extract_bound( + &operation .call_method0(py, "is_parametrized") .unwrap() - .as_ref(py) + .bind(py) ) .unwrap()); }) @@ -393,11 +338,11 @@ fn test_pyo3_is_not_parametrized(input_operation: Operation) { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_operation).unwrap(); - assert!(!bool::extract( - operation + assert!(!bool::extract_bound( + &operation .call_method0(py, "is_parametrized") .unwrap() - .as_ref(py) + .bind(py) ) .unwrap()); }) @@ -415,7 +360,7 @@ fn test_pyo3_mode(mode: usize, input_operation: Operation) { Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_operation).unwrap(); let mode_op: usize = - usize::extract(operation.call_method0(py, "mode").unwrap().as_ref(py)).unwrap(); + usize::extract_bound(&operation.call_method0(py, "mode").unwrap().bind(py)).unwrap(); assert_eq!(mode_op, mode); }) } @@ -431,7 +376,7 @@ fn test_pyo3_qubit(qubit: usize, input_operation: Operation) { Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_operation).unwrap(); let qubit_op: usize = - usize::extract(operation.call_method0(py, "qubit").unwrap().as_ref(py)).unwrap(); + usize::extract_bound(&operation.call_method0(py, "qubit").unwrap().bind(py)).unwrap(); assert_eq!(qubit_op, qubit); }) } @@ -448,7 +393,8 @@ fn test_pyo3_hqslang(name: &'static str, input_operation: Operation) { Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_operation).unwrap(); let name_op: String = - String::extract(operation.call_method0(py, "hqslang").unwrap().as_ref(py)).unwrap(); + String::extract_bound(&operation.call_method0(py, "hqslang").unwrap().bind(py)) + .unwrap(); assert_eq!(name_op, name.to_string()); }) } @@ -525,7 +471,8 @@ fn test_pyo3_tags(input_operation: Operation, tags: Vec<&str>) { Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_operation).unwrap(); let tags_op: Vec = - Vec::::extract(operation.call_method0(py, "tags").unwrap().as_ref(py)).unwrap(); + Vec::::extract_bound(&operation.call_method0(py, "tags").unwrap().bind(py)) + .unwrap(); assert_eq!(tags_op.len(), tags.len()); for i in 0..tags.len() { assert_eq!(tags_op[i], tags[i]); @@ -545,11 +492,11 @@ fn test_pyo3_involved_modes(input_operation: Operation, modes: HashSet) { Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_operation).unwrap(); // test initial mode - let involved_modes: HashSet = HashSet::::extract( - operation + let involved_modes: HashSet = HashSet::::extract_bound( + &operation .call_method0(py, "involved_modes") .unwrap() - .as_ref(py), + .bind(py), ) .unwrap(); assert_eq!(involved_modes, modes); @@ -569,7 +516,7 @@ fn test_pyo3_remapqubits(input_operation: Operation) { let operation = convert_operation_to_pyobject(input_operation).unwrap(); // test initial qubit let qubit: usize = - usize::extract(operation.call_method0(py, "qubit").unwrap().as_ref(py)).unwrap(); + usize::extract_bound(&operation.call_method0(py, "qubit").unwrap().bind(py)).unwrap(); assert_eq!(qubit.clone(), 1); // remap qubits let mut qubit_mapping: HashMap = HashMap::new(); @@ -580,7 +527,7 @@ fn test_pyo3_remapqubits(input_operation: Operation) { .unwrap(); // test re-mapped qubit let qubit_new: usize = - usize::extract(result.call_method0(py, "qubit").unwrap().as_ref(py)).unwrap(); + usize::extract_bound(&result.call_method0(py, "qubit").unwrap().bind(py)).unwrap(); assert_eq!(qubit_new.clone(), 0); // test that initial and rempapped qubits are different assert_ne!(qubit, qubit_new); @@ -600,7 +547,7 @@ fn test_pyo3_remapmodes_single(input_operation: Operation) { let operation = convert_operation_to_pyobject(input_operation).unwrap(); // test initial mode let mode: usize = - usize::extract(operation.call_method0(py, "mode").unwrap().as_ref(py)).unwrap(); + usize::extract_bound(&operation.call_method0(py, "mode").unwrap().bind(py)).unwrap(); assert_eq!(mode.clone(), 0); // remap modes let mut mode_mapping: HashMap = HashMap::new(); @@ -611,7 +558,7 @@ fn test_pyo3_remapmodes_single(input_operation: Operation) { .unwrap(); // test re-mapped mode let mode_new: usize = - usize::extract(result.call_method0(py, "mode").unwrap().as_ref(py)).unwrap(); + usize::extract_bound(&result.call_method0(py, "mode").unwrap().bind(py)).unwrap(); assert_eq!(mode_new.clone(), 1); // test that initial and rempapped modes are different assert_ne!(mode, mode_new); @@ -634,8 +581,7 @@ fn test_pyo3_remapmodes_error(input_operation: Operation) { let mut mode_mapping: HashMap = HashMap::new(); mode_mapping.insert(2, 0); let result = operation.call_method1(py, "remap_modes", (mode_mapping,)); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); }) } @@ -655,8 +601,7 @@ fn test_pyo3_remapqubits_error(input_operation: Operation) { let mut qubit_mapping: HashMap = HashMap::new(); qubit_mapping.insert(2, 0); let result = operation.call_method1(py, "remap_qubits", (qubit_mapping,)); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); }) } @@ -675,17 +620,17 @@ fn test_pyo3_copy_deepcopy(input_operation: Operation) { let deepcopy_op = operation.call_method1(py, "__deepcopy__", ("",)).unwrap(); let copy_deepcopy_param = operation; - let comparison_copy = bool::extract( - copy_op - .as_ref(py) + let comparison_copy = bool::extract_bound( + ©_op + .bind(py) .call_method1("__eq__", (copy_deepcopy_param.clone(),)) .unwrap(), ) .unwrap(); assert!(comparison_copy); - let comparison_deepcopy = bool::extract( - deepcopy_op - .as_ref(py) + let comparison_deepcopy = bool::extract_bound( + &deepcopy_op + .bind(py) .call_method1("__eq__", (copy_deepcopy_param,)) .unwrap(), ) @@ -724,10 +669,10 @@ fn test_pyo3_format_repr(format_repr: &str, input_operation: Operation) { Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_operation).unwrap(); let to_format = operation.call_method1(py, "__format__", ("",)).unwrap(); - let format_op: &str = <&str>::extract(to_format.as_ref(py)).unwrap(); + let format_op: String = String::extract_bound(&to_format.bind(py)).unwrap(); assert_eq!(format_op, format_repr); let to_repr = operation.call_method0(py, "__repr__").unwrap(); - let repr_op: &str = <&str>::extract(to_repr.as_ref(py)).unwrap(); + let repr_op: String = String::extract_bound(&to_repr.bind(py)).unwrap(); assert_eq!(repr_op, format_repr); }) } @@ -740,8 +685,8 @@ fn test_pyo3_substitute_params_single(input_operation: Operation) { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_operation.clone()).unwrap(); - let mut substitution_dict_py: HashMap<&str, f64> = HashMap::new(); - substitution_dict_py.insert("theta", 1.0); + let mut substitution_dict_py: HashMap = HashMap::new(); + substitution_dict_py.insert("theta".to_owned(), 1.0); let substitute_op = operation .call_method1(py, "substitute_parameters", (substitution_dict_py,)) .unwrap(); @@ -753,9 +698,9 @@ fn test_pyo3_substitute_params_single(input_operation: Operation) { .unwrap(); let test_operation = convert_operation_to_pyobject(substitute_param).unwrap(); - let comparison = bool::extract( - substitute_op - .as_ref(py) + let comparison = bool::extract_bound( + &substitute_op + .bind(py) .call_method1("__eq__", (test_operation,)) .unwrap(), ) @@ -772,10 +717,9 @@ fn test_pyo3_substitute_params_error(input_operation: Operation) { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_operation).unwrap(); - let substitution_dict: HashMap<&str, f64> = HashMap::new(); + let substitution_dict: HashMap = HashMap::new(); let result = operation.call_method1(py, "substitute_parameters", (substitution_dict,)); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); }) } @@ -790,15 +734,15 @@ fn test_ineffective_substitute_parameters(input_operation: Operation) { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_operation.clone()).unwrap(); - let mut substitution_dict_py: HashMap<&str, f64> = HashMap::new(); - substitution_dict_py.insert("theta", 0.0); + let mut substitution_dict_py: HashMap = HashMap::new(); + substitution_dict_py.insert("theta".to_owned(), 0.0); let substitute_op = operation .call_method1(py, "substitute_parameters", (substitution_dict_py,)) .unwrap(); - let comparison = bool::extract( - substitute_op - .as_ref(py) + let comparison = bool::extract_bound( + &substitute_op + .bind(py) .call_method1("__eq__", (operation,)) .unwrap(), ) @@ -838,18 +782,18 @@ fn test_pyo3_richcmp(definition_1: Operation, definition_2: Operation) { let operation_one = convert_operation_to_pyobject(definition_1).unwrap(); let operation_two = convert_operation_to_pyobject(definition_2).unwrap(); - let comparison = bool::extract( - operation_one - .as_ref(py) + let comparison = bool::extract_bound( + &operation_one + .bind(py) .call_method1("__eq__", (operation_two.clone(),)) .unwrap(), ) .unwrap(); assert!(!comparison); - let comparison = bool::extract( - operation_one - .as_ref(py) + let comparison = bool::extract_bound( + &operation_one + .bind(py) .call_method1("__ne__", (operation_two.clone(),)) .unwrap(), ) @@ -898,17 +842,18 @@ fn test_pyo3_json_schema(operation: Operation) { pyo3::Python::with_gil(|py| { let minimum_version: String = "1.11.0".to_string(); let pyobject = convert_operation_to_pyobject(operation).unwrap(); - let operation = pyobject.as_ref(py); + let operation = pyobject.bind(py); let schema: String = - String::extract(operation.call_method0("json_schema").unwrap()).unwrap(); + String::extract_bound(&operation.call_method0("json_schema").unwrap()).unwrap(); assert_eq!(schema, rust_schema); let current_version_string = - String::extract(operation.call_method0("current_version").unwrap()).unwrap(); + String::extract_bound(&operation.call_method0("current_version").unwrap()).unwrap(); let minimum_supported_version_string = - String::extract(operation.call_method0("min_supported_version").unwrap()).unwrap(); + String::extract_bound(&operation.call_method0("min_supported_version").unwrap()) + .unwrap(); assert_eq!(current_version_string, ROQOQO_VERSION); assert_eq!(minimum_supported_version_string, minimum_version); diff --git a/qoqo/tests/integration/operations/three_qubit_gate_operations.rs b/qoqo/tests/integration/operations/three_qubit_gate_operations.rs index 9e3d954c..b29de3f9 100644 --- a/qoqo/tests/integration/operations/three_qubit_gate_operations.rs +++ b/qoqo/tests/integration/operations/three_qubit_gate_operations.rs @@ -41,11 +41,11 @@ fn test_pyo3_is_not_parametrized(input_operation: Operation) { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_operation).unwrap(); - assert!(!bool::extract( - operation + assert!(!bool::extract_bound( + &operation .call_method0(py, "is_parametrized") .unwrap() - .as_ref(py) + .bind(py) ) .unwrap()); }) @@ -81,7 +81,8 @@ fn test_pyo3_tags(tags: Vec<&str>, input_operation: Operation) { Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_operation).unwrap(); let tags_op: Vec = - Vec::::extract(operation.call_method0(py, "tags").unwrap().as_ref(py)).unwrap(); + Vec::::extract_bound(&operation.call_method0(py, "tags").unwrap().bind(py)) + .unwrap(); assert_eq!(tags_op.len(), tags.len()); for i in 0..tags.len() { assert_eq!(tags_op[i], tags[i]); @@ -97,7 +98,8 @@ fn test_pyo3_hqslang(name: &'static str, input_operation: Operation) { Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_operation).unwrap(); let name_op: String = - String::extract(operation.call_method0(py, "hqslang").unwrap().as_ref(py)).unwrap(); + String::extract_bound(&operation.call_method0(py, "hqslang").unwrap().bind(py)) + .unwrap(); assert_eq!(name_op, name.to_string()); }) } @@ -112,13 +114,15 @@ fn test_pyo3_remapqubits(input_operation: Operation) { // test initial qubits let control_0: usize = - usize::extract(operation.call_method0(py, "control_0").unwrap().as_ref(py)).unwrap(); + usize::extract_bound(&operation.call_method0(py, "control_0").unwrap().bind(py)) + .unwrap(); assert_eq!(control_0.clone(), 0); let control_1: usize = - usize::extract(operation.call_method0(py, "control_1").unwrap().as_ref(py)).unwrap(); + usize::extract_bound(&operation.call_method0(py, "control_1").unwrap().bind(py)) + .unwrap(); assert_eq!(control_1.clone(), 1); let target: usize = - usize::extract(operation.call_method0(py, "target").unwrap().as_ref(py)).unwrap(); + usize::extract_bound(&operation.call_method0(py, "target").unwrap().bind(py)).unwrap(); assert_eq!(target.clone(), 2); // remap qubits @@ -133,13 +137,13 @@ fn test_pyo3_remapqubits(input_operation: Operation) { // test re-mapped qubit let control_0_new: usize = - usize::extract(result.call_method0(py, "control_0").unwrap().as_ref(py)).unwrap(); + usize::extract_bound(&result.call_method0(py, "control_0").unwrap().bind(py)).unwrap(); assert_eq!(control_0_new.clone(), 2); let control_1_new: usize = - usize::extract(result.call_method0(py, "control_1").unwrap().as_ref(py)).unwrap(); + usize::extract_bound(&result.call_method0(py, "control_1").unwrap().bind(py)).unwrap(); assert_eq!(control_1_new.clone(), 3); let target_new: usize = - usize::extract(result.call_method0(py, "target").unwrap().as_ref(py)).unwrap(); + usize::extract_bound(&result.call_method0(py, "target").unwrap().bind(py)).unwrap(); assert_eq!(target_new.clone(), 0); // test that initial and rempapped qubits are different @@ -161,8 +165,7 @@ fn test_pyo3_remapqubits_error(input_operation: Operation) { let mut qubit_mapping: HashMap = HashMap::new(); qubit_mapping.insert(2, 0); let result = operation.call_method1(py, "remap_qubits", (qubit_mapping,)); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); }) } @@ -172,8 +175,7 @@ fn test_pyo3_unitarymatrix_error(input_operation: Operation) { Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_operation.clone()).unwrap(); let py_result = operation.call_method0(py, "unitary_matrix"); - let result_ref = py_result.as_ref(); - assert!(result_ref.is_err()); + assert!(py_result.is_err()); }) } @@ -186,9 +188,12 @@ fn test_pyo3_unitarymatrix(input_operation: Operation) { let operation = convert_operation_to_pyobject(input_operation.clone()).unwrap(); let py_result = operation.call_method0(py, "unitary_matrix").unwrap(); let result_matrix = py_result - .downcast::>(py) + .downcast_bound::>(py) .unwrap() - .to_owned_array(); + .as_gil_ref() + .readonly() + .as_array() + .to_owned(); // compare to reference matrix obtained in Rust directly (without passing to Python) let gate: GateOperation = input_operation.try_into().unwrap(); @@ -213,9 +218,9 @@ fn test_pyo3_format_repr(format_repr: &str, input_operation: Operation) { Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_operation).unwrap(); let to_format = operation.call_method1(py, "__format__", ("",)).unwrap(); - let format_op: &str = <&str>::extract(to_format.as_ref(py)).unwrap(); + let format_op: String = String::extract_bound(&to_format.bind(py)).unwrap(); let to_repr = operation.call_method0(py, "__repr__").unwrap(); - let repr_op: &str = <&str>::extract(to_repr.as_ref(py)).unwrap(); + let repr_op: String = String::extract_bound(&to_repr.bind(py)).unwrap(); assert_eq!(format_op, format_repr); assert_eq!(repr_op, format_repr); }) @@ -232,17 +237,17 @@ fn test_pyo3_copy_deepcopy(input_operation: Operation) { let deepcopy_op = operation.call_method1(py, "__deepcopy__", ("",)).unwrap(); let copy_deepcopy_param = operation; - let comparison_copy = bool::extract( - copy_op - .as_ref(py) + let comparison_copy = bool::extract_bound( + ©_op + .bind(py) .call_method1("__eq__", (copy_deepcopy_param.clone(),)) .unwrap(), ) .unwrap(); assert!(comparison_copy); - let comparison_deepcopy = bool::extract( - deepcopy_op - .as_ref(py) + let comparison_deepcopy = bool::extract_bound( + &deepcopy_op + .bind(py) .call_method1("__eq__", (copy_deepcopy_param,)) .unwrap(), ) @@ -261,16 +266,16 @@ fn test_pyo3_substitute_parameters(first_op: Operation, second_op: Operation) { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let operation = convert_operation_to_pyobject(first_op).unwrap(); - let mut substitution_dict: HashMap<&str, f64> = HashMap::new(); - substitution_dict.insert("test", 1.0); + let mut substitution_dict: HashMap = HashMap::new(); + substitution_dict.insert("test".to_owned(), 1.0); let substitute_op = operation .call_method1(py, "substitute_parameters", (substitution_dict,)) .unwrap(); let substitute_param = convert_operation_to_pyobject(second_op).unwrap(); - let comparison = bool::extract( - substitute_op - .as_ref(py) + let comparison = bool::extract_bound( + &substitute_op + .bind(py) .call_method1("__eq__", (substitute_param,)) .unwrap(), ) @@ -284,10 +289,9 @@ fn test_pyo3_substitute_params_error(input_operation: Operation) { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_operation).unwrap(); - let substitution_dict: HashMap<&str, f64> = HashMap::new(); + let substitution_dict: HashMap = HashMap::new(); let result = operation.call_method1(py, "substitute_parameters", (substitution_dict,)); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); }) } @@ -302,11 +306,11 @@ fn test_pyo3_powercf(first_op: Operation, second_op: Operation) { let comparison_op = convert_operation_to_pyobject(second_op).unwrap(); let remapped_op = operation.call_method1(py, "powercf", (power,)).unwrap(); - let comparison = bool::extract( - remapped_op + let comparison = bool::extract_bound( + &remapped_op .call_method1(py, "__eq__", (comparison_op,)) .unwrap() - .as_ref(py), + .bind(py), ) .unwrap(); assert!(comparison); @@ -324,15 +328,14 @@ fn test_new_controlledcontrolledpauliz( pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { // Basic initialisation, no errors - let operation_type = py.get_type::(); - let operation_py = operation_type - .call1(arguments) - .unwrap() - .downcast::>() + let operation_type = py.get_type_bound::(); + let binding = operation_type.call1(arguments).unwrap(); + let operation_py = binding + .downcast::() .unwrap(); - let comparison = bool::extract( - operation - .as_ref(py) + let comparison = bool::extract_bound( + &operation + .bind(py) .call_method1(method, (operation_py,)) .unwrap(), ) @@ -341,21 +344,18 @@ fn test_new_controlledcontrolledpauliz( // Error initialisation let result = operation_type.call1((0, 1, vec!["fails"])); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); let result = operation_type.call1((0, vec!["fails"], 2)); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); // Testing PartialEq, Clone and Debug let def_wrapper = operation_py .extract::() .unwrap(); - let new_op_diff = operation_type - .call1((1, 2, 3)) - .unwrap() - .downcast::>() + let binding = operation_type.call1((1, 2, 3)).unwrap(); + let new_op_diff = binding + .downcast::() .unwrap(); let def_wrapper_diff = new_op_diff .extract::() @@ -383,15 +383,14 @@ fn test_new_controlledcontrolledphaseshift( pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { // Basic initialisation, no errors - let operation_type = py.get_type::(); - let operation_py = operation_type - .call1(arguments) - .unwrap() - .downcast::>() + let operation_type = py.get_type_bound::(); + let binding = operation_type.call1(arguments).unwrap(); + let operation_py = binding + .downcast::() .unwrap(); - let comparison = bool::extract( - operation - .as_ref(py) + let comparison = bool::extract_bound( + &operation + .bind(py) .call_method1(method, (operation_py,)) .unwrap(), ) @@ -400,21 +399,18 @@ fn test_new_controlledcontrolledphaseshift( // Error initialisation let result = operation_type.call1((0, 1, 2, vec!["fails"])); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); let result = operation_type.call1((0, vec!["fails"], 2)); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); // Testing PartialEq, Clone and Debug let def_wrapper = operation_py .extract::() .unwrap(); - let new_op_diff = operation_type - .call1((1, 2, 3, 0.0)) - .unwrap() - .downcast::>() + let binding = operation_type.call1((1, 2, 3, 0.0)).unwrap(); + let new_op_diff = binding + .downcast::() .unwrap(); let def_wrapper_diff = new_op_diff .extract::() @@ -438,15 +434,12 @@ fn test_new_toffoli(input_operation: Operation, arguments: (u32, u32, u32), meth pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { // Basic initialisation, no errors - let operation_type = py.get_type::(); - let operation_py = operation_type - .call1(arguments) - .unwrap() - .downcast::>() - .unwrap(); - let comparison = bool::extract( - operation - .as_ref(py) + let operation_type = py.get_type_bound::(); + let binding = operation_type.call1(arguments).unwrap(); + let operation_py = binding.downcast::().unwrap(); + let comparison = bool::extract_bound( + &operation + .bind(py) .call_method1(method, (operation_py,)) .unwrap(), ) @@ -455,20 +448,15 @@ fn test_new_toffoli(input_operation: Operation, arguments: (u32, u32, u32), meth // Error initialisation let result = operation_type.call1((0, 1, vec!["fails"])); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); let result = operation_type.call1((0, vec!["fails"], 2)); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); // Testing PartialEq, Clone and Debug let def_wrapper = operation_py.extract::().unwrap(); - let new_op_diff = operation_type - .call1((1, 2, 3)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation_type.call1((1, 2, 3)).unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let def_wrapper_diff = new_op_diff.extract::().unwrap(); let helper_ne: bool = def_wrapper_diff != def_wrapper; assert!(helper_ne); @@ -581,17 +569,18 @@ fn test_pyo3_json_schema(operation: ThreeQubitGateOperation) { pyo3::Python::with_gil(|py| { let converted_op = Operation::from(operation); let pyobject = convert_operation_to_pyobject(converted_op).unwrap(); - let operation = pyobject.as_ref(py); + let operation = pyobject.bind(py); let schema: String = - String::extract(operation.call_method0("json_schema").unwrap()).unwrap(); + String::extract_bound(&operation.call_method0("json_schema").unwrap()).unwrap(); assert_eq!(schema, rust_schema); let current_version_string = - String::extract(operation.call_method0("current_version").unwrap()).unwrap(); + String::extract_bound(&operation.call_method0("current_version").unwrap()).unwrap(); let minimum_supported_version_string = - String::extract(operation.call_method0("min_supported_version").unwrap()).unwrap(); + String::extract_bound(&operation.call_method0("min_supported_version").unwrap()) + .unwrap(); assert_eq!(current_version_string, ROQOQO_VERSION); assert_eq!(minimum_supported_version_string, "1.3.0"); diff --git a/qoqo/tests/integration/operations/two_qubit_gate_operations.rs b/qoqo/tests/integration/operations/two_qubit_gate_operations.rs index 0652ebe6..be119384 100644 --- a/qoqo/tests/integration/operations/two_qubit_gate_operations.rs +++ b/qoqo/tests/integration/operations/two_qubit_gate_operations.rs @@ -67,11 +67,11 @@ fn test_pyo3_is_not_parametrized(input_operation: Operation) { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_operation).unwrap(); - assert!(!bool::extract( - operation + assert!(!bool::extract_bound( + &operation .call_method0(py, "is_parametrized") .unwrap() - .as_ref(py) + .bind(py) ) .unwrap()); }) @@ -290,7 +290,8 @@ fn test_pyo3_tags(tags: Vec<&str>, input_operation: Operation) { Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_operation).unwrap(); let tags_op: Vec = - Vec::::extract(operation.call_method0(py, "tags").unwrap().as_ref(py)).unwrap(); + Vec::::extract_bound(&operation.call_method0(py, "tags").unwrap().bind(py)) + .unwrap(); assert_eq!(tags_op.len(), tags.len()); for i in 0..tags.len() { assert_eq!(tags_op[i], tags[i]); @@ -332,7 +333,8 @@ fn test_pyo3_hqslang(name: &'static str, input_operation: Operation) { Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_operation).unwrap(); let name_op: String = - String::extract(operation.call_method0(py, "hqslang").unwrap().as_ref(py)).unwrap(); + String::extract_bound(&operation.call_method0(py, "hqslang").unwrap().bind(py)) + .unwrap(); assert_eq!(name_op, name.to_string()); }) } @@ -370,10 +372,10 @@ fn test_pyo3_remapqubits(input_operation: Operation) { // test initial qubits let control: usize = - usize::extract(operation.call_method0(py, "control").unwrap().as_ref(py)).unwrap(); + usize::extract_bound(&operation.call_method0(py, "control").unwrap().bind(py)).unwrap(); assert_eq!(control.clone(), 0); let target: usize = - usize::extract(operation.call_method0(py, "target").unwrap().as_ref(py)).unwrap(); + usize::extract_bound(&operation.call_method0(py, "target").unwrap().bind(py)).unwrap(); assert_eq!(target.clone(), 1); // remap qubits @@ -388,10 +390,10 @@ fn test_pyo3_remapqubits(input_operation: Operation) { // test re-mapped qubit let control_new: usize = - usize::extract(result.call_method0(py, "control").unwrap().as_ref(py)).unwrap(); + usize::extract_bound(&result.call_method0(py, "control").unwrap().bind(py)).unwrap(); assert_eq!(control_new.clone(), 2); let target_new: usize = - usize::extract(result.call_method0(py, "target").unwrap().as_ref(py)).unwrap(); + usize::extract_bound(&result.call_method0(py, "target").unwrap().bind(py)).unwrap(); assert_eq!(target_new.clone(), 3); // test that initial and rempapped qubits are different @@ -435,8 +437,7 @@ fn test_pyo3_remapqubits_error(input_operation: Operation) { let mut qubit_mapping: HashMap = HashMap::new(); qubit_mapping.insert(2, 0); let result = operation.call_method1(py, "remap_qubits", (qubit_mapping,)); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); }) } @@ -461,8 +462,7 @@ fn test_pyo3_unitarymatrix_error(input_operation: Operation) { Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_operation.clone()).unwrap(); let py_result = operation.call_method0(py, "unitary_matrix"); - let result_ref = py_result.as_ref(); - assert!(result_ref.is_err()); + assert!(py_result.is_err()); }) } @@ -498,9 +498,12 @@ fn test_pyo3_unitarymatrix(input_operation: Operation) { let operation = convert_operation_to_pyobject(input_operation.clone()).unwrap(); let py_result = operation.call_method0(py, "unitary_matrix").unwrap(); let result_matrix = py_result - .downcast::>(py) + .downcast_bound::>(py) .unwrap() - .to_owned_array(); + .as_gil_ref() + .readonly() + .as_array() + .to_owned(); // compare to reference matrix obtained in Rust directly (without passing to Python) let gate: GateOperation = input_operation.try_into().unwrap(); @@ -593,9 +596,9 @@ fn test_pyo3_format_repr(format_repr: &str, input_operation: Operation) { Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_operation).unwrap(); let to_format = operation.call_method1(py, "__format__", ("",)).unwrap(); - let format_op: &str = <&str>::extract(to_format.as_ref(py)).unwrap(); + let format_op: String = String::extract_bound(&to_format.bind(py)).unwrap(); let to_repr = operation.call_method0(py, "__repr__").unwrap(); - let repr_op: &str = <&str>::extract(to_repr.as_ref(py)).unwrap(); + let repr_op: String = String::extract_bound(&to_repr.bind(py)).unwrap(); assert_eq!(format_op, format_repr); assert_eq!(repr_op, format_repr); }) @@ -635,17 +638,17 @@ fn test_pyo3_copy_deepcopy(input_operation: Operation) { let deepcopy_op = operation.call_method1(py, "__deepcopy__", ("",)).unwrap(); let copy_deepcopy_param = operation; - let comparison_copy = bool::extract( - copy_op - .as_ref(py) + let comparison_copy = bool::extract_bound( + ©_op + .bind(py) .call_method1("__eq__", (copy_deepcopy_param.clone(),)) .unwrap(), ) .unwrap(); assert!(comparison_copy); - let comparison_deepcopy = bool::extract( - deepcopy_op - .as_ref(py) + let comparison_deepcopy = bool::extract_bound( + &deepcopy_op + .bind(py) .call_method1("__eq__", (copy_deepcopy_param,)) .unwrap(), ) @@ -734,16 +737,16 @@ fn test_pyo3_substitute_parameters(first_op: Operation, second_op: Operation) { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let operation = convert_operation_to_pyobject(first_op).unwrap(); - let mut substitution_dict: HashMap<&str, f64> = HashMap::new(); - substitution_dict.insert("test", 1.0); + let mut substitution_dict: HashMap = HashMap::new(); + substitution_dict.insert("test".to_owned(), 1.0); let substitute_op = operation .call_method1(py, "substitute_parameters", (substitution_dict,)) .unwrap(); let substitute_param = convert_operation_to_pyobject(second_op).unwrap(); - let comparison = bool::extract( - substitute_op - .as_ref(py) + let comparison = bool::extract_bound( + &substitute_op + .bind(py) .call_method1("__eq__", (substitute_param,)) .unwrap(), ) @@ -784,10 +787,9 @@ fn test_pyo3_substitute_params_error(input_operation: Operation) { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let operation = convert_operation_to_pyobject(input_operation).unwrap(); - let substitution_dict: HashMap<&str, f64> = HashMap::new(); + let substitution_dict: HashMap = HashMap::new(); let result = operation.call_method1(py, "substitute_parameters", (substitution_dict,)); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); }) } @@ -822,11 +824,11 @@ fn test_pyo3_powercf(first_op: Operation, second_op: Operation) { let comparison_op = convert_operation_to_pyobject(second_op).unwrap(); let remapped_op = operation.call_method1(py, "powercf", (power,)).unwrap(); - let comparison = bool::extract( - remapped_op + let comparison = bool::extract_bound( + &remapped_op .call_method1(py, "__eq__", (comparison_op,)) .unwrap() - .as_ref(py), + .bind(py), ) .unwrap(); assert!(comparison); @@ -840,16 +842,13 @@ fn test_new_cnot(input_operation: Operation, arguments: (u32, u32), method: &str let operation = convert_operation_to_pyobject(input_operation).unwrap(); pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let operation_type = py.get_type::(); - let operation_py = operation_type - .call1(arguments) - .unwrap() - .downcast::>() - .unwrap(); + let operation_type = py.get_type_bound::(); + let binding = operation_type.call1(arguments).unwrap(); + let operation_py = binding.downcast::().unwrap(); - let comparison = bool::extract( - operation - .as_ref(py) + let comparison = bool::extract_bound( + &operation + .bind(py) .call_method1(method, (operation_py,)) .unwrap(), ) @@ -857,11 +856,8 @@ fn test_new_cnot(input_operation: Operation, arguments: (u32, u32), method: &str assert!(comparison); let def_wrapper = operation_py.extract::().unwrap(); - let new_op_diff = operation_type - .call1((1, 2)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation_type.call1((1, 2)).unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let def_wrapper_diff = new_op_diff.extract::().unwrap(); let helper_ne: bool = def_wrapper_diff != def_wrapper; assert!(helper_ne); @@ -882,16 +878,13 @@ fn test_new_swap(input_operation: Operation, arguments: (u32, u32), method: &str let operation = convert_operation_to_pyobject(input_operation).unwrap(); pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let operation_type = py.get_type::(); - let operation_py = operation_type - .call1(arguments) - .unwrap() - .downcast::>() - .unwrap(); + let operation_type = py.get_type_bound::(); + let binding = operation_type.call1(arguments).unwrap(); + let operation_py = binding.downcast::().unwrap(); - let comparison = bool::extract( - operation - .as_ref(py) + let comparison = bool::extract_bound( + &operation + .bind(py) .call_method1(method, (operation_py,)) .unwrap(), ) @@ -899,11 +892,8 @@ fn test_new_swap(input_operation: Operation, arguments: (u32, u32), method: &str assert!(comparison); let def_wrapper = operation_py.extract::().unwrap(); - let new_op_diff = operation_type - .call1((1, 2)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation_type.call1((1, 2)).unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let def_wrapper_diff = new_op_diff.extract::().unwrap(); let helper_ne: bool = def_wrapper_diff != def_wrapper; assert!(helper_ne); @@ -924,16 +914,13 @@ fn test_new_iswap(input_operation: Operation, arguments: (u32, u32), method: &st let operation = convert_operation_to_pyobject(input_operation).unwrap(); pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let operation_type = py.get_type::(); - let operation_py = operation_type - .call1(arguments) - .unwrap() - .downcast::>() - .unwrap(); + let operation_type = py.get_type_bound::(); + let binding = operation_type.call1(arguments).unwrap(); + let operation_py = binding.downcast::().unwrap(); - let comparison = bool::extract( - operation - .as_ref(py) + let comparison = bool::extract_bound( + &operation + .bind(py) .call_method1(method, (operation_py,)) .unwrap(), ) @@ -941,11 +928,8 @@ fn test_new_iswap(input_operation: Operation, arguments: (u32, u32), method: &st assert!(comparison); let def_wrapper = operation_py.extract::().unwrap(); - let new_op_diff = operation_type - .call1((1, 2)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation_type.call1((1, 2)).unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let def_wrapper_diff = new_op_diff.extract::().unwrap(); let helper_ne: bool = def_wrapper_diff != def_wrapper; assert!(helper_ne); @@ -966,16 +950,13 @@ fn test_new_fswap(input_operation: Operation, arguments: (u32, u32), method: &st let operation = convert_operation_to_pyobject(input_operation).unwrap(); pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let operation_type = py.get_type::(); - let operation_py = operation_type - .call1(arguments) - .unwrap() - .downcast::>() - .unwrap(); + let operation_type = py.get_type_bound::(); + let binding = operation_type.call1(arguments).unwrap(); + let operation_py = binding.downcast::().unwrap(); - let comparison = bool::extract( - operation - .as_ref(py) + let comparison = bool::extract_bound( + &operation + .bind(py) .call_method1(method, (operation_py,)) .unwrap(), ) @@ -983,11 +964,8 @@ fn test_new_fswap(input_operation: Operation, arguments: (u32, u32), method: &st assert!(comparison); let def_wrapper = operation_py.extract::().unwrap(); - let new_op_diff = operation_type - .call1((1, 2)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation_type.call1((1, 2)).unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let def_wrapper_diff = new_op_diff.extract::().unwrap(); let helper_ne: bool = def_wrapper_diff != def_wrapper; assert!(helper_ne); @@ -1008,16 +986,13 @@ fn test_new_sqrtiswap(input_operation: Operation, arguments: (u32, u32), method: let operation = convert_operation_to_pyobject(input_operation).unwrap(); pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let operation_type = py.get_type::(); - let operation_py = operation_type - .call1(arguments) - .unwrap() - .downcast::>() - .unwrap(); + let operation_type = py.get_type_bound::(); + let binding = operation_type.call1(arguments).unwrap(); + let operation_py = binding.downcast::().unwrap(); - let comparison = bool::extract( - operation - .as_ref(py) + let comparison = bool::extract_bound( + &operation + .bind(py) .call_method1(method, (operation_py,)) .unwrap(), ) @@ -1025,11 +1000,8 @@ fn test_new_sqrtiswap(input_operation: Operation, arguments: (u32, u32), method: assert!(comparison); let def_wrapper = operation_py.extract::().unwrap(); - let new_op_diff = operation_type - .call1((1, 2)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation_type.call1((1, 2)).unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let def_wrapper_diff = new_op_diff.extract::().unwrap(); let helper_ne: bool = def_wrapper_diff != def_wrapper; assert!(helper_ne); @@ -1050,16 +1022,13 @@ fn test_new_invsqrtiswap(input_operation: Operation, arguments: (u32, u32), meth let operation = convert_operation_to_pyobject(input_operation).unwrap(); pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let operation_type = py.get_type::(); - let operation_py = operation_type - .call1(arguments) - .unwrap() - .downcast::>() - .unwrap(); + let operation_type = py.get_type_bound::(); + let binding = operation_type.call1(arguments).unwrap(); + let operation_py = binding.downcast::().unwrap(); - let comparison = bool::extract( - operation - .as_ref(py) + let comparison = bool::extract_bound( + &operation + .bind(py) .call_method1(method, (operation_py,)) .unwrap(), ) @@ -1067,11 +1036,8 @@ fn test_new_invsqrtiswap(input_operation: Operation, arguments: (u32, u32), meth assert!(comparison); let def_wrapper = operation_py.extract::().unwrap(); - let new_op_diff = operation_type - .call1((1, 2)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation_type.call1((1, 2)).unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let def_wrapper_diff = new_op_diff.extract::().unwrap(); let helper_ne: bool = def_wrapper_diff != def_wrapper; assert!(helper_ne); @@ -1092,16 +1058,13 @@ fn test_new_controlledpauliy(input_operation: Operation, arguments: (u32, u32), let operation = convert_operation_to_pyobject(input_operation).unwrap(); pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let operation_type = py.get_type::(); - let operation_py = operation_type - .call1(arguments) - .unwrap() - .downcast::>() - .unwrap(); + let operation_type = py.get_type_bound::(); + let binding = operation_type.call1(arguments).unwrap(); + let operation_py = binding.downcast::().unwrap(); - let comparison = bool::extract( - operation - .as_ref(py) + let comparison = bool::extract_bound( + &operation + .bind(py) .call_method1(method, (operation_py,)) .unwrap(), ) @@ -1109,11 +1072,8 @@ fn test_new_controlledpauliy(input_operation: Operation, arguments: (u32, u32), assert!(comparison); let def_wrapper = operation_py.extract::().unwrap(); - let new_op_diff = operation_type - .call1((1, 2)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation_type.call1((1, 2)).unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let def_wrapper_diff = new_op_diff.extract::().unwrap(); let helper_ne: bool = def_wrapper_diff != def_wrapper; assert!(helper_ne); @@ -1134,16 +1094,13 @@ fn test_new_controlledpauliz(input_operation: Operation, arguments: (u32, u32), let operation = convert_operation_to_pyobject(input_operation).unwrap(); pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let operation_type = py.get_type::(); - let operation_py = operation_type - .call1(arguments) - .unwrap() - .downcast::>() - .unwrap(); + let operation_type = py.get_type_bound::(); + let binding = operation_type.call1(arguments).unwrap(); + let operation_py = binding.downcast::().unwrap(); - let comparison = bool::extract( - operation - .as_ref(py) + let comparison = bool::extract_bound( + &operation + .bind(py) .call_method1(method, (operation_py,)) .unwrap(), ) @@ -1151,11 +1108,8 @@ fn test_new_controlledpauliz(input_operation: Operation, arguments: (u32, u32), assert!(comparison); let def_wrapper = operation_py.extract::().unwrap(); - let new_op_diff = operation_type - .call1((1, 2)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation_type.call1((1, 2)).unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let def_wrapper_diff = new_op_diff.extract::().unwrap(); let helper_ne: bool = def_wrapper_diff != def_wrapper; assert!(helper_ne); @@ -1176,16 +1130,13 @@ fn test_new_molmersorensenxx(input_operation: Operation, arguments: (u32, u32), let operation = convert_operation_to_pyobject(input_operation).unwrap(); pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let operation_type = py.get_type::(); - let operation_py = operation_type - .call1(arguments) - .unwrap() - .downcast::>() - .unwrap(); + let operation_type = py.get_type_bound::(); + let binding = operation_type.call1(arguments).unwrap(); + let operation_py = binding.downcast::().unwrap(); - let comparison = bool::extract( - operation - .as_ref(py) + let comparison = bool::extract_bound( + &operation + .bind(py) .call_method1(method, (operation_py,)) .unwrap(), ) @@ -1193,11 +1144,8 @@ fn test_new_molmersorensenxx(input_operation: Operation, arguments: (u32, u32), assert!(comparison); let def_wrapper = operation_py.extract::().unwrap(); - let new_op_diff = operation_type - .call1((1, 2)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation_type.call1((1, 2)).unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let def_wrapper_diff = new_op_diff.extract::().unwrap(); let helper_ne: bool = def_wrapper_diff != def_wrapper; assert!(helper_ne); @@ -1219,15 +1167,12 @@ fn test_new_xy(input_operation: Operation, arguments: (u32, u32, f64), method: & pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { // Basic initialisation, no errors - let operation_type = py.get_type::(); - let operation_py = operation_type - .call1(arguments) - .unwrap() - .downcast::>() - .unwrap(); - let comparison = bool::extract( - operation - .as_ref(py) + let operation_type = py.get_type_bound::(); + let binding = operation_type.call1(arguments).unwrap(); + let operation_py = binding.downcast::().unwrap(); + let comparison = bool::extract_bound( + &operation + .bind(py) .call_method1(method, (operation_py,)) .unwrap(), ) @@ -1236,16 +1181,12 @@ fn test_new_xy(input_operation: Operation, arguments: (u32, u32, f64), method: & // Error initialisation let result = operation_type.call1((0, 1, vec!["fails"])); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); // Testing PartialEq, Clone and Debug let def_wrapper = operation_py.extract::().unwrap(); - let new_op_diff = operation_type - .call1((1, 2, 0.0)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation_type.call1((1, 2, 0.0)).unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let def_wrapper_diff = new_op_diff.extract::().unwrap(); let helper_ne: bool = def_wrapper_diff != def_wrapper; assert!(helper_ne); @@ -1271,15 +1212,12 @@ fn test_new_controlledphaseshift( pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { // Basic initialisation, no errors - let operation_type = py.get_type::(); - let operation_py = operation_type - .call1(arguments) - .unwrap() - .downcast::>() - .unwrap(); - let comparison = bool::extract( - operation - .as_ref(py) + let operation_type = py.get_type_bound::(); + let binding = operation_type.call1(arguments).unwrap(); + let operation_py = binding.downcast::().unwrap(); + let comparison = bool::extract_bound( + &operation + .bind(py) .call_method1(method, (operation_py,)) .unwrap(), ) @@ -1288,18 +1226,14 @@ fn test_new_controlledphaseshift( // Error initialisation let result = operation_type.call1((0, 1, vec!["fails"])); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); // Testing PartialEq, Clone and Debug let def_wrapper = operation_py .extract::() .unwrap(); - let new_op_diff = operation_type - .call1((1, 2, 0.0)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation_type.call1((1, 2, 0.0)).unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let def_wrapper_diff = new_op_diff .extract::() .unwrap(); @@ -1323,15 +1257,12 @@ fn test_new_variablemsxx(input_operation: Operation, arguments: (u32, u32, f64), pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { // Basic initialisation, no errors - let operation_type = py.get_type::(); - let operation_py = operation_type - .call1(arguments) - .unwrap() - .downcast::>() - .unwrap(); - let comparison = bool::extract( - operation - .as_ref(py) + let operation_type = py.get_type_bound::(); + let binding = operation_type.call1(arguments).unwrap(); + let operation_py = binding.downcast::().unwrap(); + let comparison = bool::extract_bound( + &operation + .bind(py) .call_method1(method, (operation_py,)) .unwrap(), ) @@ -1340,16 +1271,12 @@ fn test_new_variablemsxx(input_operation: Operation, arguments: (u32, u32, f64), // Error initialisation let result = operation_type.call1((0, 1, vec!["fails"])); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); // Testing PartialEq, Clone and Debug let def_wrapper = operation_py.extract::().unwrap(); - let new_op_diff = operation_type - .call1((1, 2, 0.0)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation_type.call1((1, 2, 0.0)).unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let def_wrapper_diff = new_op_diff.extract::().unwrap(); let helper_ne: bool = def_wrapper_diff != def_wrapper; assert!(helper_ne); @@ -1371,15 +1298,12 @@ fn test_new_pminteraction(input_operation: Operation, arguments: (u32, u32, f64) pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { // Basic initialisation, no errors - let operation_type = py.get_type::(); - let operation_py = operation_type - .call1(arguments) - .unwrap() - .downcast::>() - .unwrap(); - let comparison = bool::extract( - operation - .as_ref(py) + let operation_type = py.get_type_bound::(); + let binding = operation_type.call1(arguments).unwrap(); + let operation_py = binding.downcast::().unwrap(); + let comparison = bool::extract_bound( + &operation + .bind(py) .call_method1(method, (operation_py,)) .unwrap(), ) @@ -1388,16 +1312,12 @@ fn test_new_pminteraction(input_operation: Operation, arguments: (u32, u32, f64) // Error initialisation let result = operation_type.call1((0, 1, vec!["fails"])); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); // Testing PartialEq, Clone and Debug let def_wrapper = operation_py.extract::().unwrap(); - let new_op_diff = operation_type - .call1((1, 2, 0.0)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation_type.call1((1, 2, 0.0)).unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let def_wrapper_diff = new_op_diff.extract::().unwrap(); let helper_ne: bool = def_wrapper_diff != def_wrapper; assert!(helper_ne); @@ -1423,15 +1343,12 @@ fn test_new_givensrotation( pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { // Basic initialisation, no errors - let operation_type = py.get_type::(); - let operation_py = operation_type - .call1(arguments) - .unwrap() - .downcast::>() - .unwrap(); - let comparison = bool::extract( - operation - .as_ref(py) + let operation_type = py.get_type_bound::(); + let binding = operation_type.call1(arguments).unwrap(); + let operation_py = binding.downcast::().unwrap(); + let comparison = bool::extract_bound( + &operation + .bind(py) .call_method1(method, (operation_py,)) .unwrap(), ) @@ -1440,20 +1357,15 @@ fn test_new_givensrotation( // Error initialisation let result = operation_type.call1((0, 1, vec!["fails"], 0.0)); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); let result = operation_type.call1((0, 1, 0.0, vec!["fails"])); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); // Testing PartialEq, Clone and Debug let def_wrapper = operation_py.extract::().unwrap(); - let new_op_diff = operation_type - .call1((1, 2, 0.0, 0.0)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation_type.call1((1, 2, 0.0, 0.0)).unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let def_wrapper_diff = new_op_diff.extract::().unwrap(); let helper_ne: bool = def_wrapper_diff != def_wrapper; assert!(helper_ne); @@ -1479,15 +1391,14 @@ fn test_new_givensrotationlittleendian( pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { // Basic initialisation, no errors - let operation_type = py.get_type::(); - let operation_py = operation_type - .call1(arguments) - .unwrap() - .downcast::>() + let operation_type = py.get_type_bound::(); + let binding = operation_type.call1(arguments).unwrap(); + let operation_py = binding + .downcast::() .unwrap(); - let comparison = bool::extract( - operation - .as_ref(py) + let comparison = bool::extract_bound( + &operation + .bind(py) .call_method1(method, (operation_py,)) .unwrap(), ) @@ -1496,21 +1407,18 @@ fn test_new_givensrotationlittleendian( // Error initialisation let result = operation_type.call1((0, 1, vec!["fails"], 0.0)); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); let result = operation_type.call1((0, 1, 0.0, vec!["fails"])); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); // Testing PartialEq, Clone and Debug let def_wrapper = operation_py .extract::() .unwrap(); - let new_op_diff = operation_type - .call1((1, 2, 0.0, 0.0)) - .unwrap() - .downcast::>() + let binding = operation_type.call1((1, 2, 0.0, 0.0)).unwrap(); + let new_op_diff = binding + .downcast::() .unwrap(); let def_wrapper_diff = new_op_diff .extract::() @@ -1535,15 +1443,12 @@ fn test_new_bogoliubov(input_operation: Operation, arguments: (u32, u32, f64, f6 pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { // Basic initialisation, no errors - let operation_type = py.get_type::(); - let operation_py = operation_type - .call1(arguments) - .unwrap() - .downcast::>() - .unwrap(); - let comparison = bool::extract( - operation - .as_ref(py) + let operation_type = py.get_type_bound::(); + let binding = operation_type.call1(arguments).unwrap(); + let operation_py = binding.downcast::().unwrap(); + let comparison = bool::extract_bound( + &operation + .bind(py) .call_method1(method, (operation_py,)) .unwrap(), ) @@ -1552,20 +1457,15 @@ fn test_new_bogoliubov(input_operation: Operation, arguments: (u32, u32, f64, f6 // Error initialisation let result = operation_type.call1((0, 1, vec!["fails"], 0.0)); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); let result = operation_type.call1((0, 1, 0.0, vec!["fails"])); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); // Testing PartialEq, Clone and Debug let def_wrapper = operation_py.extract::().unwrap(); - let new_op_diff = operation_type - .call1((1, 2, 0.0, 0.0)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation_type.call1((1, 2, 0.0, 0.0)).unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let def_wrapper_diff = new_op_diff.extract::().unwrap(); let helper_ne: bool = def_wrapper_diff != def_wrapper; assert!(helper_ne); @@ -1591,15 +1491,12 @@ fn test_new_complexpminteraction( pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { // Basic initialisation, no errors - let operation_type = py.get_type::(); - let operation_py = operation_type - .call1(arguments) - .unwrap() - .downcast::>() - .unwrap(); - let comparison = bool::extract( - operation - .as_ref(py) + let operation_type = py.get_type_bound::(); + let binding = operation_type.call1(arguments).unwrap(); + let operation_py = binding.downcast::().unwrap(); + let comparison = bool::extract_bound( + &operation + .bind(py) .call_method1(method, (operation_py,)) .unwrap(), ) @@ -1608,22 +1505,17 @@ fn test_new_complexpminteraction( // Error initialisation let result = operation_type.call1((0, 1, vec!["fails"], 0.0)); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); let result = operation_type.call1((0, 1, 0.0, vec!["fails"])); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); // Testing PartialEq, Clone and Debug let def_wrapper = operation_py .extract::() .unwrap(); - let new_op_diff = operation_type - .call1((1, 2, 0.0, 0.0)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation_type.call1((1, 2, 0.0, 0.0)).unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let def_wrapper_diff = new_op_diff .extract::() .unwrap(); @@ -1647,15 +1539,12 @@ fn test_new_qsim(input_operation: Operation, arguments: (u32, u32, f64, f64, f64 pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { // Basic initialisation, no errors - let operation_type = py.get_type::(); - let operation_py = operation_type - .call1(arguments) - .unwrap() - .downcast::>() - .unwrap(); - let comparison = bool::extract( - operation - .as_ref(py) + let operation_type = py.get_type_bound::(); + let binding = operation_type.call1(arguments).unwrap(); + let operation_py = binding.downcast::().unwrap(); + let comparison = bool::extract_bound( + &operation + .bind(py) .call_method1(method, (operation_py,)) .unwrap(), ) @@ -1664,24 +1553,18 @@ fn test_new_qsim(input_operation: Operation, arguments: (u32, u32, f64, f64, f64 // Error initialisation let result = operation_type.call1((0, 1, vec!["fails"], 0.0, 0.0)); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); let result = operation_type.call1((0, 1, 0.0, vec!["fails"], 0.0)); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); let result = operation_type.call1((0, 1, 0.0, 0.0, vec!["fails"])); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); // Testing PartialEq, Clone and Debug let def_wrapper = operation_py.extract::().unwrap(); - let new_op_diff = operation_type - .call1((1, 2, 0.0, 0.0, 0.0)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation_type.call1((1, 2, 0.0, 0.0, 0.0)).unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let def_wrapper_diff = new_op_diff.extract::().unwrap(); let helper_ne: bool = def_wrapper_diff != def_wrapper; assert!(helper_ne); @@ -1703,15 +1586,12 @@ fn test_new_fsim(input_operation: Operation, arguments: (u32, u32, f64, f64, f64 pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { // Basic initialisation, no errors - let operation_type = py.get_type::(); - let operation_py = operation_type - .call1(arguments) - .unwrap() - .downcast::>() - .unwrap(); - let comparison = bool::extract( - operation - .as_ref(py) + let operation_type = py.get_type_bound::(); + let binding = operation_type.call1(arguments).unwrap(); + let operation_py = binding.downcast::().unwrap(); + let comparison = bool::extract_bound( + &operation + .bind(py) .call_method1(method, (operation_py,)) .unwrap(), ) @@ -1720,24 +1600,18 @@ fn test_new_fsim(input_operation: Operation, arguments: (u32, u32, f64, f64, f64 // Error initialisation let result = operation_type.call1((0, 1, vec!["fails"], 0.0, 0.0)); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); let result = operation_type.call1((0, 1, 0.0, vec!["fails"], 0.0)); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); let result = operation_type.call1((0, 1, 0.0, 0.0, vec!["fails"])); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); // Testing PartialEq, Clone and Debug let def_wrapper = operation_py.extract::().unwrap(); - let new_op_diff = operation_type - .call1((1, 2, 0.0, 0.0, 0.0)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation_type.call1((1, 2, 0.0, 0.0, 0.0)).unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let def_wrapper_diff = new_op_diff.extract::().unwrap(); let helper_ne: bool = def_wrapper_diff != def_wrapper; assert!(helper_ne); @@ -1763,16 +1637,13 @@ fn test_new_spininteraction( pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { // Basic initialisation, no errors - let operation_type = py.get_type::(); - let operation_py = operation_type - .call1(arguments) - .unwrap() - .downcast::>() - .unwrap(); + let operation_type = py.get_type_bound::(); + let binding = operation_type.call1(arguments).unwrap(); + let operation_py = binding.downcast::().unwrap(); - let comparison = bool::extract( - operation - .as_ref(py) + let comparison = bool::extract_bound( + &operation + .bind(py) .call_method1(method, (operation_py,)) .unwrap(), ) @@ -1781,24 +1652,18 @@ fn test_new_spininteraction( // Error initialisation let result = operation_type.call1((0, 1, vec!["fails"], 0.0, 0.0)); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); let result = operation_type.call1((0, 1, 0.0, vec!["fails"], 0.0)); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); let result = operation_type.call1((0, 1, 0.0, 0.0, vec!["fails"])); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); // Testing PartialEq, Clone and Debug let def_wrapper = operation_py.extract::().unwrap(); - let new_op_diff = operation_type - .call1((1, 2, 0.0, 0.0, 0.0)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation_type.call1((1, 2, 0.0, 0.0, 0.0)).unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let def_wrapper_diff = new_op_diff.extract::().unwrap(); let helper_ne: bool = def_wrapper_diff != def_wrapper; assert!(helper_ne); @@ -1824,15 +1689,14 @@ fn test_new_phaseshiftedcontrolledz( pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { // Basic initialisation, no errors - let operation_type = py.get_type::(); - let operation_py = operation_type - .call1(arguments) - .unwrap() - .downcast::>() + let operation_type = py.get_type_bound::(); + let binding = operation_type.call1(arguments).unwrap(); + let operation_py = binding + .downcast::() .unwrap(); - let comparison = bool::extract( - operation - .as_ref(py) + let comparison = bool::extract_bound( + &operation + .bind(py) .call_method1(method, (operation_py,)) .unwrap(), ) @@ -1841,17 +1705,15 @@ fn test_new_phaseshiftedcontrolledz( // Error initialisation let result = operation_type.call1((0, 1, vec!["fails"])); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); // Testing PartialEq, Clone and Debug let def_wrapper = operation_py .extract::() .unwrap(); - let new_op_diff = operation_type - .call1((1, 2, 0.0)) - .unwrap() - .downcast::>() + let binding = operation_type.call1((1, 2, 0.0)).unwrap(); + let new_op_diff = binding + .downcast::() .unwrap(); let def_wrapper_diff = new_op_diff .extract::() @@ -1880,15 +1742,14 @@ fn test_new_phaseshiftedcontrolledphase( pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { // Basic initialization, no errors - let operation_type = py.get_type::(); - let operation_py = operation_type - .call1(arguments) - .unwrap() - .downcast::>() + let operation_type = py.get_type_bound::(); + let binding = operation_type.call1(arguments).unwrap(); + let operation_py = binding + .downcast::() .unwrap(); - let comparison = bool::extract( - operation - .as_ref(py) + let comparison = bool::extract_bound( + &operation + .bind(py) .call_method1(method, (operation_py,)) .unwrap(), ) @@ -1897,17 +1758,15 @@ fn test_new_phaseshiftedcontrolledphase( // Error initialisation let result = operation_type.call1((0, 1, vec!["fails"], vec!["fails"])); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); // Testing PartialEq, Clone and Debug let def_wrapper = operation_py .extract::() .unwrap(); - let new_op_diff = operation_type - .call1((1, 2, 0.0, 0.0)) - .unwrap() - .downcast::>() + let binding = operation_type.call1((1, 2, 0.0, 0.0)).unwrap(); + let new_op_diff = binding + .downcast::() .unwrap(); let def_wrapper_diff = new_op_diff .extract::() @@ -1936,15 +1795,12 @@ fn test_new_controlledrotatex( pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { // Basic initialization, no errors - let operation_type = py.get_type::(); - let operation_py = operation_type - .call1(arguments) - .unwrap() - .downcast::>() - .unwrap(); - let comparison = bool::extract( - operation - .as_ref(py) + let operation_type = py.get_type_bound::(); + let binding = operation_type.call1(arguments).unwrap(); + let operation_py = binding.downcast::().unwrap(); + let comparison = bool::extract_bound( + &operation + .bind(py) .call_method1(method, (operation_py,)) .unwrap(), ) @@ -1953,16 +1809,12 @@ fn test_new_controlledrotatex( // Error initialisation let result = operation_type.call1((0, 1, vec!["fails"])); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); // Testing PartialEq, Clone and Debug let def_wrapper = operation_py.extract::().unwrap(); - let new_op_diff = operation_type - .call1((1, 2, 0.0)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation_type.call1((1, 2, 0.0)).unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let def_wrapper_diff = new_op_diff.extract::().unwrap(); let helper_ne: bool = def_wrapper_diff != def_wrapper; assert!(helper_ne); @@ -1988,15 +1840,12 @@ fn test_new_controlledrotatexy( pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { // Basic initialization, no errors - let operation_type = py.get_type::(); - let operation_py = operation_type - .call1(arguments) - .unwrap() - .downcast::>() - .unwrap(); - let comparison = bool::extract( - operation - .as_ref(py) + let operation_type = py.get_type_bound::(); + let binding = operation_type.call1(arguments).unwrap(); + let operation_py = binding.downcast::().unwrap(); + let comparison = bool::extract_bound( + &operation + .bind(py) .call_method1(method, (operation_py,)) .unwrap(), ) @@ -2005,16 +1854,12 @@ fn test_new_controlledrotatexy( // Error initialisation let result = operation_type.call1((0, 1, vec!["fails"], vec!["fails"])); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); // Testing PartialEq, Clone and Debug let def_wrapper = operation_py.extract::().unwrap(); - let new_op_diff = operation_type - .call1((1, 2, 0.0, 0.0)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation_type.call1((1, 2, 0.0, 0.0)).unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let def_wrapper_diff = new_op_diff.extract::().unwrap(); let helper_ne: bool = def_wrapper_diff != def_wrapper; assert!(helper_ne); @@ -2036,15 +1881,12 @@ fn test_new_echocrossresonance(input_operation: Operation, arguments: (u32, u32) pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { // Basic initialization, no errors - let operation_type = py.get_type::(); - let operation_py = operation_type - .call1(arguments) - .unwrap() - .downcast::>() - .unwrap(); - let comparison = bool::extract( - operation - .as_ref(py) + let operation_type = py.get_type_bound::(); + let binding = operation_type.call1(arguments).unwrap(); + let operation_py = binding.downcast::().unwrap(); + let comparison = bool::extract_bound( + &operation + .bind(py) .call_method1(method, (operation_py,)) .unwrap(), ) @@ -2053,16 +1895,12 @@ fn test_new_echocrossresonance(input_operation: Operation, arguments: (u32, u32) // Error initialisation let result = operation_type.call1((0, 1, 0.0)); - let result_ref = result.as_ref(); - assert!(result_ref.is_err()); + assert!(result.is_err()); // Testing PartialEq, Clone and Debug let def_wrapper = operation_py.extract::().unwrap(); - let new_op_diff = operation_type - .call1((1, 2)) - .unwrap() - .downcast::>() - .unwrap(); + let binding = operation_type.call1((1, 2)).unwrap(); + let new_op_diff = binding.downcast::().unwrap(); let def_wrapper_diff = new_op_diff.extract::().unwrap(); let helper_ne: bool = def_wrapper_diff != def_wrapper; assert!(helper_ne); @@ -2158,18 +1996,18 @@ fn test_pyo3_richcmp(definition_1: Operation, definition_2: Operation) { let operation_one = convert_operation_to_pyobject(definition_1).unwrap(); let operation_two = convert_operation_to_pyobject(definition_2).unwrap(); - let comparison = bool::extract( - operation_one - .as_ref(py) + let comparison = bool::extract_bound( + &operation_one + .bind(py) .call_method1("__eq__", (operation_two.clone(),)) .unwrap(), ) .unwrap(); assert!(!comparison); - let comparison = bool::extract( - operation_one - .as_ref(py) + let comparison = bool::extract_bound( + &operation_one + .bind(py) .call_method1("__ne__", (operation_two.clone(),)) .unwrap(), ) @@ -2303,17 +2141,18 @@ fn test_pyo3_json_schema(operation: TwoQubitGateOperation) { }; let converted_op = Operation::from(operation); let pyobject = convert_operation_to_pyobject(converted_op).unwrap(); - let operation = pyobject.as_ref(py); + let operation = pyobject.bind(py); let schema: String = - String::extract(operation.call_method0("json_schema").unwrap()).unwrap(); + String::extract_bound(&operation.call_method0("json_schema").unwrap()).unwrap(); assert_eq!(schema, rust_schema); let current_version_string = - String::extract(operation.call_method0("current_version").unwrap()).unwrap(); + String::extract_bound(&operation.call_method0("current_version").unwrap()).unwrap(); let minimum_supported_version_string = - String::extract(operation.call_method0("min_supported_version").unwrap()).unwrap(); + String::extract_bound(&operation.call_method0("min_supported_version").unwrap()) + .unwrap(); assert_eq!(current_version_string, ROQOQO_VERSION); assert_eq!(minimum_supported_version_string, minimum_version); diff --git a/qoqo/tests/integration/quantum_program.rs b/qoqo/tests/integration/quantum_program.rs index 7ee5c978..f5a000da 100644 --- a/qoqo/tests/integration/quantum_program.rs +++ b/qoqo/tests/integration/quantum_program.rs @@ -43,12 +43,11 @@ impl TestBackend { } } -fn create_measurement(py: Python) -> &PyCell { - let input_type = py.get_type::(); - let input = input_type - .call0() - .unwrap() - .downcast::>() +fn create_measurement(py: Python) -> Bound { + let input_type = py.get_type_bound::(); + let binding = input_type.call0().unwrap(); + let input = binding + .downcast::() .unwrap(); let _ = input.call_method1("add_pauliz_product", ("ro",)).unwrap(); @@ -56,12 +55,13 @@ fn create_measurement(py: Python) -> &PyCell { let mut circ1 = CircuitWrapper::new(); circ1.internal += roqoqo::operations::RotateX::new(0, 0.0.into()); circs.push(circ1); - let br_type = py.get_type::(); + let br_type = py.get_type_bound::(); br_type .call1((Some(CircuitWrapper::new()), circs.clone(), input)) .unwrap() - .downcast::>() + .downcast::() .unwrap() + .to_owned() } /// Test basic traits of QuantumProgramWrapper @@ -70,26 +70,25 @@ fn test_basic_traits() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let input = create_measurement(py); - let program_type = py.get_type::(); - let program = program_type - .call1((input, vec!["test".to_string()])) - .unwrap() - .downcast::>() + let program_type = py.get_type_bound::(); + let binding = program_type + .call1((&input, vec!["test".to_string()])) .unwrap(); + let program = binding.downcast::().unwrap(); let program_wrapper = program.extract::().unwrap(); let helper_ne: bool = - QuantumProgramWrapper::new(input, vec!["error".into()]).unwrap() != program_wrapper; + QuantumProgramWrapper::new(&input, vec!["error".into()]).unwrap() != program_wrapper; assert!(helper_ne); let helper_eq: bool = - QuantumProgramWrapper::new(input, vec!["test".into()]).unwrap() == program_wrapper; + QuantumProgramWrapper::new(&input, vec!["test".into()]).unwrap() == program_wrapper; assert!(helper_eq); let helper_eq: bool = program_wrapper == program_wrapper; assert!(helper_eq); assert_eq!( - format!("{:?}", QuantumProgramWrapper::new(input, vec!["test".into()]).unwrap()), + format!("{:?}", QuantumProgramWrapper::new(&input, vec!["test".into()]).unwrap()), "QuantumProgramWrapper { internal: CheatedPauliZProduct { measurement: CheatedPauliZProduct { constant_circuit: Some(Circuit { definitions: [], operations: [], _roqoqo_version: RoqoqoVersion }), circuits: [Circuit { definitions: [], operations: [], _roqoqo_version: RoqoqoVersion }, Circuit { definitions: [], operations: [RotateX(RotateX { qubit: 0, theta: Float(0.0) })], _roqoqo_version: RoqoqoVersion }], input: CheatedPauliZProductInput { measured_exp_vals: {}, pauli_product_keys: {\"ro\": 0} } }, input_parameter_names: [\"test\"] } }" ); }) @@ -100,12 +99,9 @@ fn test_basic_traits() { fn test_new_run_br() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let input_type = py.get_type::(); - let input_instance = input_type - .call1((3, false)) - .unwrap() - .downcast::>() - .unwrap(); + let input_type = py.get_type_bound::(); + let binding = input_type.call1((3, false)).unwrap(); + let input_instance = binding.downcast::().unwrap(); let _ = input_instance .call_method1("add_pauliz_product", ("ro", vec![0])) .unwrap(); @@ -114,19 +110,17 @@ fn test_new_run_br() { let mut circ1 = CircuitWrapper::new(); circ1.internal += RotateX::new(0, 0.0.into()); circs.push(circ1.clone()); - let br_type = py.get_type::(); - let input = br_type + let br_type = py.get_type_bound::(); + let binding = br_type .call1((Some(CircuitWrapper::new()), circs.clone(), input_instance)) - .unwrap() - .downcast::>() .unwrap(); + let input = binding.downcast::().unwrap(); - let program_type = py.get_type::(); - let program = program_type + let program_type = py.get_type_bound::(); + let binding = program_type .call1((input, vec!["test".to_string()])) - .unwrap() - .downcast::>() .unwrap(); + let program = binding.downcast::().unwrap(); let program_wrapper = program.extract::().unwrap(); let mut bri = PauliZProductInput::new(3, false); @@ -147,8 +141,8 @@ fn test_new_run_br() { } ); - let measurement = PauliZProductWrapper::extract( - program + let measurement = PauliZProductWrapper::extract_bound( + &program .call_method1("run", (TestBackend, Some(vec![0.0]))) .unwrap(), ) @@ -162,11 +156,10 @@ fn test_new_run_br() { fn test_new_run_cheated_br() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let input_type = py.get_type::(); - let input_instance = input_type - .call0() - .unwrap() - .downcast::>() + let input_type = py.get_type_bound::(); + let binding = input_type.call0().unwrap(); + let input_instance = binding + .downcast::() .unwrap(); let _ = input_instance .call_method1("add_pauliz_product", ("ro",)) @@ -176,19 +169,17 @@ fn test_new_run_cheated_br() { let mut circ1 = CircuitWrapper::new(); circ1.internal += RotateX::new(0, 0.0.into()); circs.push(circ1.clone()); - let br_type = py.get_type::(); - let input = br_type + let br_type = py.get_type_bound::(); + let binding = br_type .call1((Some(CircuitWrapper::new()), circs.clone(), input_instance)) - .unwrap() - .downcast::>() .unwrap(); + let input = binding.downcast::().unwrap(); - let program_type = py.get_type::(); - let program = program_type + let program_type = py.get_type_bound::(); + let binding = program_type .call1((input, vec!["test".to_string()])) - .unwrap() - .downcast::>() .unwrap(); + let program = binding.downcast::().unwrap(); let program_wrapper = program.extract::().unwrap(); let mut cbri = CheatedPauliZProductInput::new(); @@ -209,8 +200,8 @@ fn test_new_run_cheated_br() { } ); - let measurement = CheatedPauliZProductWrapper::extract( - program + let measurement = CheatedPauliZProductWrapper::extract_bound( + &program .call_method1("run", (TestBackend, Some(vec![0.0]))) .unwrap(), ) @@ -226,30 +217,25 @@ fn test_new_run_cheated_br() { fn test_new_run_cheated() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let input_type = py.get_type::(); - let input_instance = input_type - .call1((2,)) - .unwrap() - .downcast::>() - .unwrap(); + let input_type = py.get_type_bound::(); + let binding = input_type.call1((2,)).unwrap(); + let input_instance = binding.downcast::().unwrap(); let mut circs: Vec = vec![CircuitWrapper::new()]; let mut circ1 = CircuitWrapper::new(); circ1.internal += RotateX::new(0, 0.0.into()); circs.push(circ1.clone()); - let br_type = py.get_type::(); - let input = br_type + let br_type = py.get_type_bound::(); + let binding = br_type .call1((Some(CircuitWrapper::new()), circs.clone(), input_instance)) - .unwrap() - .downcast::>() .unwrap(); + let input = binding.downcast::().unwrap(); - let program_type = py.get_type::(); - let program = program_type + let program_type = py.get_type_bound::(); + let binding = program_type .call1((input, vec!["test".to_string()])) - .unwrap() - .downcast::>() .unwrap(); + let program = binding.downcast::().unwrap(); let program_wrapper = program.extract::().unwrap(); let ci = CheatedInput::new(2); @@ -269,8 +255,8 @@ fn test_new_run_cheated() { } ); - let measurement = CheatedWrapper::extract( - program + let measurement = CheatedWrapper::extract_bound( + &program .call_method1("run", (TestBackend, Some(vec![0.0]))) .unwrap(), ) @@ -288,19 +274,17 @@ fn test_new_run_classical_register() { let mut circ1 = CircuitWrapper::new(); circ1.internal += RotateX::new(0, 0.0.into()); circs.push(circ1.clone()); - let br_type = py.get_type::(); - let input = br_type + let br_type = py.get_type_bound::(); + let binding = br_type .call1((Some(CircuitWrapper::new()), circs.clone())) - .unwrap() - .downcast::>() .unwrap(); + let input = binding.downcast::().unwrap(); - let program_type = py.get_type::(); - let program = program_type + let program_type = py.get_type_bound::(); + let binding = program_type .call1((input, vec!["test".to_string()])) - .unwrap() - .downcast::>() .unwrap(); + let program = binding.downcast::().unwrap(); let program_wrapper = program.extract::().unwrap(); let cr = ClassicalRegister { @@ -318,8 +302,8 @@ fn test_new_run_classical_register() { } ); - let measurement = ClassicalRegisterWrapper::extract( - program + let measurement = ClassicalRegisterWrapper::extract_bound( + &program .call_method1("run_registers", (TestBackend, Some(vec![0.0]))) .unwrap(), ) @@ -336,7 +320,7 @@ fn test_new_error_1() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let circs: Vec = Vec::new(); - let program_type = py.get_type::(); + let program_type = py.get_type_bound::(); let program = program_type.call1((circs, vec!["test".to_string()])); assert!(program.is_err()); }) @@ -348,26 +332,25 @@ fn test_copy_deepcopy() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let input = create_measurement(py); - let program_type = py.get_type::(); - let program = program_type - .call1((input, vec!["test".to_string()])) - .unwrap() - .downcast::>() + let program_type = py.get_type_bound::(); + let binding = program_type + .call1((&input, vec!["test".to_string()])) .unwrap(); + let program = binding.downcast::().unwrap(); let copy_circ = program.call_method0("__copy__").unwrap(); let deepcopy_circ = program.call_method1("__deepcopy__", ("",)).unwrap(); let copy_deepcopy_param = program; - let comparison_copy = bool::extract( - copy_circ + let comparison_copy = bool::extract_bound( + ©_circ .call_method1("__eq__", (copy_deepcopy_param,)) .unwrap(), ) .unwrap(); assert!(comparison_copy); - let comparison_deepcopy = bool::extract( - deepcopy_circ + let comparison_deepcopy = bool::extract_bound( + &deepcopy_circ .call_method1("__eq__", (copy_deepcopy_param,)) .unwrap(), ) @@ -382,12 +365,11 @@ fn test_qoqo_versions() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let input = create_measurement(py); - let program_type = py.get_type::(); - let program = program_type - .call1((input, vec!["test".to_string()])) - .unwrap() - .downcast::>() + let program_type = py.get_type_bound::(); + let binding = program_type + .call1((&input, vec!["test".to_string()])) .unwrap(); + let program = binding.downcast::().unwrap(); let mut rsplit = ROQOQO_VERSION.split('.').take(2); let mut qsplit = QOQO_VERSION.split('.').take(2); @@ -402,8 +384,8 @@ fn test_qoqo_versions() { qsplit.next().expect("QOQO_VERSION badly formatted") ); - let comparison_copy: Vec<&str> = - Vec::extract(program.call_method0("_qoqo_versions").unwrap()).unwrap(); + let comparison_copy: Vec = + Vec::extract_bound(&program.call_method0("_qoqo_versions").unwrap()).unwrap(); assert_eq!(comparison_copy, vec![rver.as_str(), qver.as_str()]); }) } @@ -414,23 +396,25 @@ fn test_to_from_bincode() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let input = create_measurement(py); - let program_type = py.get_type::(); - let program = program_type - .call1((input, vec!["test".to_string()])) - .unwrap() - .downcast::>() + let program_type = py.get_type_bound::(); + let binding = program_type + .call1((&input, vec!["test".to_string()])) .unwrap(); + let program = binding.downcast::().unwrap(); // testing 'to_bincode' and 'from_bincode' functions let serialised = program.call_method0("to_bincode").unwrap(); - let new = program_type - .call1((input, vec!["new".to_string()])) - .unwrap() - .downcast::>() - .unwrap(); - let deserialised = new.call_method1("from_bincode", (serialised,)).unwrap(); - let comparison = - bool::extract(deserialised.call_method1("__eq__", (program,)).unwrap()).unwrap(); + let binding = program_type + .call1((&input, vec!["new".to_string()])) + .unwrap(); + let new = binding.downcast::().unwrap(); + let deserialised = new.call_method1("from_bincode", (&serialised,)).unwrap(); + let comparison = bool::extract_bound( + &deserialised + .call_method1("__eq__", (program.clone(),)) + .unwrap(), + ) + .unwrap(); assert!(comparison); let deserialised_error = @@ -449,11 +433,12 @@ fn test_to_from_bincode() { // testing that 'from_bincode' can be called directly on a QuantumProgram (python staticmethod) let deserialised_py = program_type - .call_method1("from_bincode", (serialised,)) + .call_method1("from_bincode", (&serialised,)) .unwrap(); let comparison = - bool::extract(deserialised_py.call_method1("__eq__", (program,)).unwrap()).unwrap(); + bool::extract_bound(&deserialised_py.call_method1("__eq__", (program,)).unwrap()) + .unwrap(); assert!(comparison); }) } @@ -463,26 +448,23 @@ fn test_value_error_bincode() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let input = create_measurement(py); - let program_type = py.get_type::(); - let program = program_type - .call1((input, vec!["test".to_string()])) - .unwrap() - .downcast::>() + let program_type = py.get_type_bound::(); + let binding = program_type + .call1((&input, vec!["test".to_string()])) .unwrap(); + let program = binding.downcast::().unwrap(); let program_clone = program; let serialised = program.call_method0("to_bincode").unwrap(); - let deserialised = program_clone - .call_method1("from_bincode", (serialised,)) - .unwrap() - .downcast::>() + let binding = program_clone + .call_method1("from_bincode", (&serialised,)) .unwrap(); + let deserialised = binding.downcast::().unwrap(); - let new = program_type - .call1((input, vec!["new".to_string()])) - .unwrap() - .downcast::>() + let binding = program_type + .call1((&input, vec!["new".to_string()])) .unwrap(); + let new = binding.downcast::().unwrap(); let deserialised_error = new.call_method1("from_bincode", (deserialised,)); assert!(deserialised_error.is_err()); }) @@ -494,23 +476,21 @@ fn test_to_from_json() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let input = create_measurement(py); - let program_type = py.get_type::(); - let program = program_type - .call1((input, vec!["test".to_string()])) - .unwrap() - .downcast::>() + let program_type = py.get_type_bound::(); + let binding = program_type + .call1((&input, vec!["test".to_string()])) .unwrap(); + let program = binding.downcast::().unwrap(); // testing 'from_json' and 'to_json' functions let serialised = program.call_method0("to_json").unwrap(); - let new = program_type - .call1((input, vec!["new".to_string()])) - .unwrap() - .downcast::>() + let binding = program_type + .call1((&input, vec!["new".to_string()])) .unwrap(); - let deserialised = new.call_method1("from_json", (serialised,)).unwrap(); + let new = binding.downcast::().unwrap(); + let deserialised = new.call_method1("from_json", (&serialised,)).unwrap(); let comparison = - bool::extract(deserialised.call_method1("__eq__", (program,)).unwrap()).unwrap(); + bool::extract_bound(&deserialised.call_method1("__eq__", (program,)).unwrap()).unwrap(); assert!(comparison); let deserialised_error = @@ -529,11 +509,12 @@ fn test_to_from_json() { // testing that 'from_json' can be called directly on a QuantumProgram (python staticmethod) let deserialised_py = program_type - .call_method1("from_json", (serialised,)) + .call_method1("from_json", (&serialised,)) .unwrap(); let comparison = - bool::extract(deserialised_py.call_method1("__eq__", (program,)).unwrap()).unwrap(); + bool::extract_bound(&deserialised_py.call_method1("__eq__", (program,)).unwrap()) + .unwrap(); assert!(comparison); }) } @@ -545,14 +526,14 @@ fn test_json_schema() { pyo3::prepare_freethreaded_python(); pyo3::Python::with_gil(|py| { let input = create_measurement(py); - let program_type = py.get_type::(); - let program = program_type + let program_type = py.get_type_bound::(); + let binding = program_type .call1((input, vec!["test".to_string()])) - .unwrap() - .downcast::>() .unwrap(); + let program = binding.downcast::().unwrap(); - let schema: String = String::extract(program.call_method0("json_schema").unwrap()).unwrap(); + let schema: String = + String::extract_bound(&program.call_method0("json_schema").unwrap()).unwrap(); let rust_schema = serde_json::to_string_pretty(&schemars::schema_for!(QuantumProgram)).unwrap(); assert_eq!(schema, rust_schema); @@ -565,25 +546,27 @@ fn test_richcmp() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { let input = create_measurement(py); - let program_type = py.get_type::(); - let program_one = program_type - .call1((input, vec!["one".to_string()])) - .unwrap() - .downcast::>() + let program_type = py.get_type_bound::(); + let binding = program_type + .call1((&input, vec!["one".to_string()])) .unwrap(); - let program_two = program_type - .call1((input, vec!["two".to_string()])) - .unwrap() - .downcast::>() + let program_one = binding.downcast::().unwrap(); + let binding = program_type + .call1((&input, vec!["two".to_string()])) .unwrap(); + let program_two = binding.downcast::().unwrap(); let operation1 = convert_operation_to_pyobject(Operation::from(PauliX::new(0))).unwrap(); - let comparison = - bool::extract(program_one.call_method1("__eq__", (program_two,)).unwrap()).unwrap(); + let comparison = bool::extract_bound( + &program_one + .call_method1("__eq__", (program_two.clone(),)) + .unwrap(), + ) + .unwrap(); assert!(!comparison); - let comparison = bool::extract( - program_one + let comparison = bool::extract_bound( + &program_one .call_method1("__eq__", (operation1.clone(),)) .unwrap(), ) @@ -591,17 +574,18 @@ fn test_richcmp() { assert!(!comparison); let comparison = - bool::extract(program_one.call_method1("__ne__", (program_two,)).unwrap()).unwrap(); + bool::extract_bound(&program_one.call_method1("__ne__", (program_two,)).unwrap()) + .unwrap(); assert!(comparison); - let comparison = bool::extract( - program_one + let comparison = bool::extract_bound( + &program_one .call_method1("__ne__", (operation1.clone(),)) .unwrap(), ) .unwrap(); assert!(comparison); - let comparison = program_one.call_method1("__ge__", (operation1,)); + let comparison = program_one.call_method1("__ge__", (&operation1,)); assert!(comparison.is_err()); }) } @@ -613,16 +597,15 @@ fn test_convert_into_program() { let added_op = Operation::from(PauliX::new(0)); let operation = convert_operation_to_pyobject(added_op).unwrap(); let input = create_measurement(py); - let program_type = py.get_type::(); - let program = program_type - .call1((input, vec!["one".to_string()])) - .unwrap() - .downcast::>() + let program_type = py.get_type_bound::(); + let binding = program_type + .call1((&input, vec!["one".to_string()])) .unwrap(); + let program = binding.downcast::().unwrap(); let comparison = program.call_method1("convert_into_quantum_program", (operation.clone(),)); assert!(comparison.is_err()); assert_eq!( - convert_into_quantum_program(operation.as_ref(py)), + convert_into_quantum_program(operation.bind(py)), Err(QoqoError::CannotExtractObject) ); // assert_eq!(convert_into_quantum_program(circ), Err(QoqoError::VersionMismatch)); @@ -635,11 +618,10 @@ fn test_return_measurement_cheatedpaulizproduct() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { // Create measurement - let input_type = py.get_type::(); - let input = input_type - .call0() - .unwrap() - .downcast::>() + let input_type = py.get_type_bound::(); + let binding = input_type.call0().unwrap(); + let input = binding + .downcast::() .unwrap(); let _ = input.call_method1("add_pauliz_product", ("ro",)).unwrap(); @@ -647,25 +629,20 @@ fn test_return_measurement_cheatedpaulizproduct() { let mut circ1 = CircuitWrapper::new(); circ1.internal += roqoqo::operations::RotateX::new(0, 0.0.into()); circs.push(circ1); - let br_type = py.get_type::(); - let measurement_input = br_type + let br_type = py.get_type_bound::(); + let binding = br_type .call1((Some(CircuitWrapper::new()), circs.clone(), input)) - .unwrap() - .downcast::>() .unwrap(); + let measurement_input = binding.downcast::().unwrap(); - let program_type = py.get_type::(); - let program = program_type + let program_type = py.get_type_bound::(); + let binding = program_type .call1((measurement_input, vec!["test".to_string()])) - .unwrap() - .downcast::>() .unwrap(); + let program = binding.downcast::().unwrap(); - let measurement_returned = program - .call_method0("measurement") - .unwrap() - .downcast::>() - .unwrap(); + let binding = program.call_method0("measurement").unwrap(); + let measurement_returned = &binding.downcast::().unwrap(); assert_eq!( format!("{:?}", measurement_returned), @@ -680,12 +657,9 @@ fn test_return_measurement_paulizproduct() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { // Create measurement - let input_type = py.get_type::(); - let input = input_type - .call1((3, false)) - .unwrap() - .downcast::>() - .unwrap(); + let input_type = py.get_type_bound::(); + let binding = input_type.call1((3, false)).unwrap(); + let input = binding.downcast::().unwrap(); let tmp_vec: Vec = Vec::new(); let _ = input .call_method1("add_pauliz_product", ("ro", tmp_vec)) @@ -693,25 +667,20 @@ fn test_return_measurement_paulizproduct() { let circs: Vec = vec![CircuitWrapper::new()]; - let br_type = py.get_type::(); - let measurement_input = br_type + let br_type = py.get_type_bound::(); + let binding = br_type .call1((Some(CircuitWrapper::new()), circs, input)) - .unwrap() - .downcast::>() .unwrap(); + let measurement_input = binding.downcast::().unwrap(); - let program_type = py.get_type::(); - let program = program_type + let program_type = py.get_type_bound::(); + let binding = program_type .call1((measurement_input, vec!["test".to_string()])) - .unwrap() - .downcast::>() .unwrap(); + let program = binding.downcast::().unwrap(); - let measurement_returned = program - .call_method0("measurement") - .unwrap() - .downcast::>() - .unwrap(); + let binding = program.call_method0("measurement").unwrap(); + let measurement_returned = binding.downcast::().unwrap(); assert_eq!( format!("{:?}", measurement_returned), @@ -726,12 +695,9 @@ fn test_return_measurement_cheated() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { // Create measurement - let input_type = py.get_type::(); - let input = input_type - .call1((3,)) - .unwrap() - .downcast::>() - .unwrap(); + let input_type = py.get_type_bound::(); + let binding = input_type.call1((3,)).unwrap(); + let input = binding.downcast::().unwrap(); let test_matrix = vec![ (0, 0, Complex64::new(1.0, 0.0)), (0, 1, Complex64::new(0.0, 0.0)), @@ -746,25 +712,20 @@ fn test_return_measurement_cheated() { let mut circ1 = CircuitWrapper::new(); circ1.internal += roqoqo::operations::RotateX::new(0, "theta".into()); circs.push(circ1); - let br_type = py.get_type::(); - let measurement_input = br_type + let br_type = py.get_type_bound::(); + let binding = br_type .call1((Some(CircuitWrapper::new()), circs.clone(), input)) - .unwrap() - .downcast::>() .unwrap(); + let measurement_input = binding.downcast::().unwrap(); - let program_type = py.get_type::(); - let program = program_type + let program_type = py.get_type_bound::(); + let binding = program_type .call1((measurement_input, vec!["test".to_string()])) - .unwrap() - .downcast::>() .unwrap(); + let program = binding.downcast::().unwrap(); - let measurement_returned = program - .call_method0("measurement") - .unwrap() - .downcast::>() - .unwrap(); + let binding = program.call_method0("measurement").unwrap(); + let measurement_returned = binding.downcast::().unwrap(); assert_eq!( format!("{:?}", measurement_returned), @@ -783,25 +744,20 @@ fn test_return_measurement_classicalreg() { let mut circ1 = CircuitWrapper::new(); circ1.internal += roqoqo::operations::RotateX::new(0, "theta".into()); circs.push(circ1); - let br_type = py.get_type::(); - let measurement_input = br_type + let br_type = py.get_type_bound::(); + let binding = br_type .call1((Some(CircuitWrapper::new()), circs.clone())) - .unwrap() - .downcast::>() .unwrap(); + let measurement_input = binding.downcast::().unwrap(); - let program_type = py.get_type::(); - let program = program_type + let program_type = py.get_type_bound::(); + let binding = program_type .call1((measurement_input, vec!["test".to_string()])) - .unwrap() - .downcast::>() .unwrap(); + let program = binding.downcast::().unwrap(); - let measurement_returned = program - .call_method0("measurement") - .unwrap() - .downcast::>() - .unwrap(); + let binding = program.call_method0("measurement").unwrap(); + let measurement_returned = binding.downcast::().unwrap(); assert_eq!( format!("{:?}", measurement_returned), @@ -816,11 +772,10 @@ fn test_input_parameter_names() { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { // Create measurement - let input_type = py.get_type::(); - let input = input_type - .call0() - .unwrap() - .downcast::>() + let input_type = py.get_type_bound::(); + let binding = input_type.call0().unwrap(); + let input = binding + .downcast::() .unwrap(); let _ = input.call_method1("add_pauliz_product", ("ro",)).unwrap(); @@ -828,19 +783,17 @@ fn test_input_parameter_names() { let mut circ1 = CircuitWrapper::new(); circ1.internal += roqoqo::operations::RotateX::new(0, "test".into()); circs.push(circ1); - let br_type = py.get_type::(); - let measurement_input = br_type + let br_type = py.get_type_bound::(); + let binding = br_type .call1((Some(CircuitWrapper::new()), circs.clone(), input)) - .unwrap() - .downcast::>() .unwrap(); + let measurement_input = binding.downcast::().unwrap(); - let program_type = py.get_type::(); - let program = program_type + let program_type = py.get_type_bound::(); + let binding = program_type .call1((measurement_input, vec!["test".to_string()])) - .unwrap() - .downcast::>() .unwrap(); + let program = binding.downcast::().unwrap(); let params_returned = program.call_method0("input_parameter_names").unwrap(); diff --git a/roqoqo-derive/Cargo.toml b/roqoqo-derive/Cargo.toml index e9236f48..b16239d4 100644 --- a/roqoqo-derive/Cargo.toml +++ b/roqoqo-derive/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "roqoqo-derive" -version = "1.11.0" +version = "1.12.0" authors = ["HQS Quantum Simulations "] license = "Apache-2.0" edition = "2021" diff --git a/roqoqo-test/Cargo.toml b/roqoqo-test/Cargo.toml index 7671747e..1539e8ac 100644 --- a/roqoqo-test/Cargo.toml +++ b/roqoqo-test/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "roqoqo-test" -version = "1.11.0" +version = "1.12.0" authors = ["HQS Quantum Simulations "] license = "Apache-2.0" edition = "2021" @@ -18,8 +18,8 @@ doctest = false crate-type = ["rlib"] [dependencies] -qoqo_calculator = { version="1.1" } -roqoqo = {version="1.11.0", path="../roqoqo", features=["serialize"]} +qoqo_calculator = { version = "1.2" } +roqoqo = { version = "1.12.0", path = "../roqoqo", features = ["serialize"] } rand = "0.8" nalgebra = "0.32" ndarray = { version = "0.15" } diff --git a/roqoqo/Cargo.toml b/roqoqo/Cargo.toml index 726bfee9..89b715e9 100644 --- a/roqoqo/Cargo.toml +++ b/roqoqo/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "roqoqo" -version = "1.11.0" +version = "1.12.0" authors = ["HQS Quantum Simulations "] license = "Apache-2.0" edition = "2021" @@ -22,24 +22,24 @@ path = "src/lib.rs" doctest = false [dependencies] -serde = { version = "1.0", features = ["derive"], optional=true} +serde = { version = "1.0", features = ["derive"], optional = true } ndarray = { version = "0.15" } -num-complex = { version = "0.4"} +num-complex = { version = "0.4" } thiserror = "1.0" -dyn-clone = {version="1.0", optional=true} -qoqo_calculator = { version="1.1"} -roqoqo-derive = {version="1.11.0", path="../roqoqo-derive"} -typetag = {version="0.2", optional=true} +dyn-clone = { version = "1.0", optional = true } +qoqo_calculator = { version = "1.2" } +roqoqo-derive = { version = "1.12.0", path = "../roqoqo-derive" } +typetag = { version = "0.2", optional = true } nalgebra = "0.32" -schemars = { version="0.8", optional=true } -jsonschema = { version="0.17", optional=true } -rand_distr = {version="0.4", optional=true} -rand = { version = "0.8.4"} -async-trait = {version = "0.1", optional = true} -futures ={version = "0.3", optional=true} -petgraph = {version = "0.6.2", optional=true} -bincode = {version="1.3", optional=true} -struqture = {version = "1.5"} +schemars = { version = "0.8", optional = true } +jsonschema = { version = "0.17", optional = true } +rand_distr = { version = "0.4", optional = true } +rand = { version = "0.8.4" } +async-trait = { version = "0.1", optional = true } +futures = { version = "0.3", optional = true } +petgraph = { version = "0.6.2", optional = true } +bincode = { version = "1.3", optional = true } +struqture = { version = "1.7" } [dev-dependencies] serde_test = "1.0" @@ -50,19 +50,30 @@ serde_json = "1.0" quote = "1.0" syn = { version = "2.0", features = ["full", "visit"] } proc-macro2 = "1.0" -rand = {version="0.8"} +rand = { version = "0.8" } [package.metadata.docs.rs] -rustdoc-args = ["--document-private-items" ] +rustdoc-args = ["--document-private-items"] [features] default = ["serialize", "circuitdag"] dynamic = ["typetag", "dyn-clone"] unstable_qoqo_devices = [] -serialize = ["serde", "ndarray/serde", "num-complex/serde", "bincode", "petgraph/serde-1"] -overrotate = [ "rand_distr", "roqoqo-derive/overrotate"] +serialize = [ + "serde", + "ndarray/serde", + "num-complex/serde", + "bincode", + "petgraph/serde-1", +] +overrotate = ["rand_distr", "roqoqo-derive/overrotate"] async = ["async-trait", "futures"] -json_schema=["schemars", "serialize", "qoqo_calculator/json_schema", "jsonschema"] +json_schema = [ + "schemars", + "serialize", + "qoqo_calculator/json_schema", + "jsonschema", +] circuitdag = ["petgraph"] unstable_chain_with_environment = [] unstable_analog_operations = [] diff --git a/roqoqo/build.rs b/roqoqo/build.rs index 32771374..581aa1d2 100644 --- a/roqoqo/build.rs +++ b/roqoqo/build.rs @@ -106,7 +106,7 @@ impl Visitor { /// Helps filtering Operation id's for minor version pub fn filter_for_version(&self, id: &Ident, minor_version: usize) -> bool { if minor_version == 0 { - self.roqoqo_version_register.get(id).is_none() + !self.roqoqo_version_register.contains_key(id) } else if let Some(saved_version) = self.roqoqo_version_register.get(id) { saved_version == &minor_version } else { diff --git a/roqoqo/src/circuitdag.rs b/roqoqo/src/circuitdag.rs index dfa6f80b..27da0020 100644 --- a/roqoqo/src/circuitdag.rs +++ b/roqoqo/src/circuitdag.rs @@ -546,7 +546,8 @@ impl CircuitDag { } } // Update last_operation_involving_classical with the temporary HashMap - self.last_operation_involving_classical = temp_map.clone(); + self.last_operation_involving_classical + .clone_from(&temp_map); } InvolvedClassical::None => (), } @@ -590,7 +591,8 @@ impl CircuitDag { } } // Update first_operation_involving_classical with the temporary HashMap - self.first_operation_involving_classical = temp_map.clone(); + self.first_operation_involving_classical + .clone_from(&temp_map); } InvolvedClassical::None => (), } @@ -884,7 +886,7 @@ impl<'a> Iterator for ParallelBlocks<'a> { } // Update parallel_block and return it - self.parallel_block = new_parallel_block.clone(); + self.parallel_block.clone_from(&new_parallel_block); if new_parallel_block.is_empty() { return None; } diff --git a/roqoqo/src/devices/generic_device.rs b/roqoqo/src/devices/generic_device.rs index 89d7b934..c82a33e3 100644 --- a/roqoqo/src/devices/generic_device.rs +++ b/roqoqo/src/devices/generic_device.rs @@ -484,7 +484,7 @@ impl Device for GenericDevice { } fn two_qubit_gate_time(&self, hqslang: &str, control: &usize, target: &usize) -> Option { - match self.two_qubit_gates.get(&hqslang.to_string()) { + match self.two_qubit_gates.get(hqslang) { Some(x) => x.get(&(*control, *target)).copied(), None => None, } @@ -497,7 +497,7 @@ impl Device for GenericDevice { control_1: &usize, target: &usize, ) -> Option { - match self.multi_qubit_gates.get(&hqslang.to_string()) { + match self.multi_qubit_gates.get(hqslang) { Some(x) => { let qubits: Vec = vec![*control_0, *control_1, *target]; x.get(&qubits).copied() @@ -509,7 +509,7 @@ impl Device for GenericDevice { fn multi_qubit_gate_time(&self, hqslang: &str, qubits: &[usize]) -> Option { // variable unused in AllToAllDevice, is kept here for consistency purposes. - match self.multi_qubit_gates.get(&hqslang.to_string()) { + match self.multi_qubit_gates.get(hqslang) { Some(x) => { let qubits: Vec = qubits.to_vec(); x.get(&qubits).copied() diff --git a/roqoqo/src/operations/measurement_operations.rs b/roqoqo/src/operations/measurement_operations.rs index c417d6f6..25c1f35d 100644 --- a/roqoqo/src/operations/measurement_operations.rs +++ b/roqoqo/src/operations/measurement_operations.rs @@ -396,7 +396,7 @@ impl Substitute for PragmaRepeatedMeasurement { mutable_mapping.insert(*new_key, *val); } for (key, val) in mapping.iter() { - if mutable_mapping.get(key).is_none() { + if !mutable_mapping.contains_key(key) { mutable_mapping.insert(*key, *val); } } diff --git a/roqoqo/src/operations/mod.rs b/roqoqo/src/operations/mod.rs index 47eb993d..7e621ce7 100644 --- a/roqoqo/src/operations/mod.rs +++ b/roqoqo/src/operations/mod.rs @@ -813,37 +813,37 @@ pub trait OperateMultiQubitGate: } /// Marker trait to show that some operation has been implemented in roqoqo 1.1.0 -pub(crate) trait ImplementedIn1point1: Operate {} +pub trait ImplementedIn1point1: Operate {} /// Marker trait to show that some operation has been implemented in roqoqo 1.2.0 -pub(crate) trait ImplementedIn1point2: Operate {} +pub trait ImplementedIn1point2: Operate {} /// Marker trait to show that some operation has been implemented in roqoqo 1.3.0 -pub(crate) trait ImplementedIn1point3: Operate {} +pub trait ImplementedIn1point3: Operate {} /// Marker trait to show that some operation has been implemented in roqoqo 1.4.0 -pub(crate) trait ImplementedIn1point4: Operate {} +pub trait ImplementedIn1point4: Operate {} /// Marker trait to show that some operation has been implemented in roqoqo 1.5.0 -pub(crate) trait ImplementedIn1point5: Operate {} +pub trait ImplementedIn1point5: Operate {} /// Marker trait to show that some operation has been implemented in roqoqo 1.6.0 -pub(crate) trait ImplementedIn1point6: Operate {} +pub trait ImplementedIn1point6: Operate {} /// Marker trait to show that some operation has been implemented in roqoqo 1.7.0 -pub(crate) trait ImplementedIn1point7: Operate {} +pub trait ImplementedIn1point7: Operate {} /// Marker trait to show that some operation has been implemented in roqoqo 1.8.0 -pub(crate) trait ImplementedIn1point8: Operate {} +pub trait ImplementedIn1point8: Operate {} /// Marker trait to show that some operation has been implemented in roqoqo 1.9.0 -pub(crate) trait ImplementedIn1point9: Operate {} +pub trait ImplementedIn1point9: Operate {} /// Marker trait to show that some operation has been implemented in roqoqo 1.10.0 -pub(crate) trait ImplementedIn1point10: Operate {} +pub trait ImplementedIn1point10: Operate {} /// Marker trait to show that some operation has been implemented in roqoqo 1.11.0 -pub(crate) trait ImplementedIn1point11: Operate {} +pub trait ImplementedIn1point11: Operate {} #[cfg(feature = "dynamic")] /// A wrapper for Operate trait objects. ///