qiskit 2.0.3__cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- qiskit/VERSION.txt +1 -0
- qiskit/__init__.py +141 -0
- qiskit/_accelerate.abi3.so +0 -0
- qiskit/_numpy_compat.py +73 -0
- qiskit/circuit/__init__.py +1343 -0
- qiskit/circuit/_add_control.py +312 -0
- qiskit/circuit/_classical_resource_map.py +150 -0
- qiskit/circuit/_standard_gates_commutations.py +3849 -0
- qiskit/circuit/_utils.py +167 -0
- qiskit/circuit/annotated_operation.py +279 -0
- qiskit/circuit/barrier.py +46 -0
- qiskit/circuit/classical/__init__.py +41 -0
- qiskit/circuit/classical/expr/__init__.py +266 -0
- qiskit/circuit/classical/expr/constructors.py +764 -0
- qiskit/circuit/classical/expr/expr.py +498 -0
- qiskit/circuit/classical/expr/visitors.py +375 -0
- qiskit/circuit/classical/types/__init__.py +113 -0
- qiskit/circuit/classical/types/ordering.py +229 -0
- qiskit/circuit/classical/types/types.py +153 -0
- qiskit/circuit/commutation_checker.py +133 -0
- qiskit/circuit/commutation_library.py +20 -0
- qiskit/circuit/controlflow/__init__.py +59 -0
- qiskit/circuit/controlflow/_builder_utils.py +211 -0
- qiskit/circuit/controlflow/box.py +163 -0
- qiskit/circuit/controlflow/break_loop.py +56 -0
- qiskit/circuit/controlflow/builder.py +791 -0
- qiskit/circuit/controlflow/continue_loop.py +56 -0
- qiskit/circuit/controlflow/control_flow.py +94 -0
- qiskit/circuit/controlflow/for_loop.py +218 -0
- qiskit/circuit/controlflow/if_else.py +498 -0
- qiskit/circuit/controlflow/switch_case.py +411 -0
- qiskit/circuit/controlflow/while_loop.py +166 -0
- qiskit/circuit/controlledgate.py +274 -0
- qiskit/circuit/delay.py +157 -0
- qiskit/circuit/duration.py +80 -0
- qiskit/circuit/equivalence.py +94 -0
- qiskit/circuit/equivalence_library.py +18 -0
- qiskit/circuit/exceptions.py +19 -0
- qiskit/circuit/gate.py +261 -0
- qiskit/circuit/instruction.py +564 -0
- qiskit/circuit/instructionset.py +132 -0
- qiskit/circuit/library/__init__.py +984 -0
- qiskit/circuit/library/arithmetic/__init__.py +40 -0
- qiskit/circuit/library/arithmetic/adders/__init__.py +18 -0
- qiskit/circuit/library/arithmetic/adders/adder.py +235 -0
- qiskit/circuit/library/arithmetic/adders/cdkm_ripple_carry_adder.py +123 -0
- qiskit/circuit/library/arithmetic/adders/draper_qft_adder.py +129 -0
- qiskit/circuit/library/arithmetic/adders/vbe_ripple_carry_adder.py +95 -0
- qiskit/circuit/library/arithmetic/exact_reciprocal.py +131 -0
- qiskit/circuit/library/arithmetic/functional_pauli_rotations.py +114 -0
- qiskit/circuit/library/arithmetic/integer_comparator.py +200 -0
- qiskit/circuit/library/arithmetic/linear_amplitude_function.py +363 -0
- qiskit/circuit/library/arithmetic/linear_pauli_rotations.py +243 -0
- qiskit/circuit/library/arithmetic/multipliers/__init__.py +17 -0
- qiskit/circuit/library/arithmetic/multipliers/hrs_cumulative_multiplier.py +145 -0
- qiskit/circuit/library/arithmetic/multipliers/multiplier.py +201 -0
- qiskit/circuit/library/arithmetic/multipliers/rg_qft_multiplier.py +108 -0
- qiskit/circuit/library/arithmetic/piecewise_chebyshev.py +502 -0
- qiskit/circuit/library/arithmetic/piecewise_linear_pauli_rotations.py +387 -0
- qiskit/circuit/library/arithmetic/piecewise_polynomial_pauli_rotations.py +493 -0
- qiskit/circuit/library/arithmetic/polynomial_pauli_rotations.py +389 -0
- qiskit/circuit/library/arithmetic/quadratic_form.py +364 -0
- qiskit/circuit/library/arithmetic/weighted_adder.py +409 -0
- qiskit/circuit/library/basis_change/__init__.py +15 -0
- qiskit/circuit/library/basis_change/qft.py +316 -0
- qiskit/circuit/library/bit_flip_oracle.py +130 -0
- qiskit/circuit/library/blueprintcircuit.py +316 -0
- qiskit/circuit/library/boolean_logic/__init__.py +18 -0
- qiskit/circuit/library/boolean_logic/inner_product.py +157 -0
- qiskit/circuit/library/boolean_logic/quantum_and.py +204 -0
- qiskit/circuit/library/boolean_logic/quantum_or.py +206 -0
- qiskit/circuit/library/boolean_logic/quantum_xor.py +167 -0
- qiskit/circuit/library/data_preparation/__init__.py +57 -0
- qiskit/circuit/library/data_preparation/_z_feature_map.py +115 -0
- qiskit/circuit/library/data_preparation/_zz_feature_map.py +150 -0
- qiskit/circuit/library/data_preparation/initializer.py +107 -0
- qiskit/circuit/library/data_preparation/pauli_feature_map.py +656 -0
- qiskit/circuit/library/data_preparation/state_preparation.py +336 -0
- qiskit/circuit/library/fourier_checking.py +160 -0
- qiskit/circuit/library/generalized_gates/__init__.py +30 -0
- qiskit/circuit/library/generalized_gates/diagonal.py +159 -0
- qiskit/circuit/library/generalized_gates/gms.py +175 -0
- qiskit/circuit/library/generalized_gates/gr.py +219 -0
- qiskit/circuit/library/generalized_gates/isometry.py +370 -0
- qiskit/circuit/library/generalized_gates/linear_function.py +318 -0
- qiskit/circuit/library/generalized_gates/mcg_up_to_diagonal.py +143 -0
- qiskit/circuit/library/generalized_gates/mcmt.py +316 -0
- qiskit/circuit/library/generalized_gates/pauli.py +84 -0
- qiskit/circuit/library/generalized_gates/permutation.py +198 -0
- qiskit/circuit/library/generalized_gates/rv.py +96 -0
- qiskit/circuit/library/generalized_gates/uc.py +303 -0
- qiskit/circuit/library/generalized_gates/uc_pauli_rot.py +164 -0
- qiskit/circuit/library/generalized_gates/ucrx.py +32 -0
- qiskit/circuit/library/generalized_gates/ucry.py +32 -0
- qiskit/circuit/library/generalized_gates/ucrz.py +32 -0
- qiskit/circuit/library/generalized_gates/unitary.py +217 -0
- qiskit/circuit/library/graph_state.py +172 -0
- qiskit/circuit/library/grover_operator.py +583 -0
- qiskit/circuit/library/hamiltonian_gate.py +142 -0
- qiskit/circuit/library/hidden_linear_function.py +163 -0
- qiskit/circuit/library/iqp.py +180 -0
- qiskit/circuit/library/n_local/__init__.py +45 -0
- qiskit/circuit/library/n_local/efficient_su2.py +282 -0
- qiskit/circuit/library/n_local/evolved_operator_ansatz.py +520 -0
- qiskit/circuit/library/n_local/excitation_preserving.py +303 -0
- qiskit/circuit/library/n_local/n_local.py +1477 -0
- qiskit/circuit/library/n_local/pauli_two_design.py +246 -0
- qiskit/circuit/library/n_local/qaoa_ansatz.py +367 -0
- qiskit/circuit/library/n_local/real_amplitudes.py +312 -0
- qiskit/circuit/library/n_local/two_local.py +289 -0
- qiskit/circuit/library/overlap.py +183 -0
- qiskit/circuit/library/pauli_evolution.py +201 -0
- qiskit/circuit/library/phase_estimation.py +177 -0
- qiskit/circuit/library/phase_oracle.py +239 -0
- qiskit/circuit/library/quantum_volume.py +180 -0
- qiskit/circuit/library/standard_gates/__init__.py +141 -0
- qiskit/circuit/library/standard_gates/dcx.py +77 -0
- qiskit/circuit/library/standard_gates/ecr.py +129 -0
- qiskit/circuit/library/standard_gates/equivalence_library.py +1800 -0
- qiskit/circuit/library/standard_gates/global_phase.py +84 -0
- qiskit/circuit/library/standard_gates/h.py +253 -0
- qiskit/circuit/library/standard_gates/i.py +76 -0
- qiskit/circuit/library/standard_gates/iswap.py +133 -0
- qiskit/circuit/library/standard_gates/p.py +422 -0
- qiskit/circuit/library/standard_gates/r.py +114 -0
- qiskit/circuit/library/standard_gates/rx.py +293 -0
- qiskit/circuit/library/standard_gates/rxx.py +180 -0
- qiskit/circuit/library/standard_gates/ry.py +286 -0
- qiskit/circuit/library/standard_gates/ryy.py +180 -0
- qiskit/circuit/library/standard_gates/rz.py +307 -0
- qiskit/circuit/library/standard_gates/rzx.py +226 -0
- qiskit/circuit/library/standard_gates/rzz.py +193 -0
- qiskit/circuit/library/standard_gates/s.py +419 -0
- qiskit/circuit/library/standard_gates/swap.py +281 -0
- qiskit/circuit/library/standard_gates/sx.py +310 -0
- qiskit/circuit/library/standard_gates/t.py +178 -0
- qiskit/circuit/library/standard_gates/u.py +395 -0
- qiskit/circuit/library/standard_gates/u1.py +490 -0
- qiskit/circuit/library/standard_gates/u2.py +145 -0
- qiskit/circuit/library/standard_gates/u3.py +428 -0
- qiskit/circuit/library/standard_gates/x.py +1481 -0
- qiskit/circuit/library/standard_gates/xx_minus_yy.py +202 -0
- qiskit/circuit/library/standard_gates/xx_plus_yy.py +236 -0
- qiskit/circuit/library/standard_gates/y.py +257 -0
- qiskit/circuit/library/standard_gates/z.py +338 -0
- qiskit/circuit/library/templates/__init__.py +92 -0
- qiskit/circuit/library/templates/clifford/__init__.py +33 -0
- qiskit/circuit/library/templates/clifford/clifford_2_1.py +34 -0
- qiskit/circuit/library/templates/clifford/clifford_2_2.py +35 -0
- qiskit/circuit/library/templates/clifford/clifford_2_3.py +34 -0
- qiskit/circuit/library/templates/clifford/clifford_2_4.py +34 -0
- qiskit/circuit/library/templates/clifford/clifford_3_1.py +35 -0
- qiskit/circuit/library/templates/clifford/clifford_4_1.py +38 -0
- qiskit/circuit/library/templates/clifford/clifford_4_2.py +37 -0
- qiskit/circuit/library/templates/clifford/clifford_4_3.py +38 -0
- qiskit/circuit/library/templates/clifford/clifford_4_4.py +37 -0
- qiskit/circuit/library/templates/clifford/clifford_5_1.py +40 -0
- qiskit/circuit/library/templates/clifford/clifford_6_1.py +40 -0
- qiskit/circuit/library/templates/clifford/clifford_6_2.py +40 -0
- qiskit/circuit/library/templates/clifford/clifford_6_3.py +40 -0
- qiskit/circuit/library/templates/clifford/clifford_6_4.py +38 -0
- qiskit/circuit/library/templates/clifford/clifford_6_5.py +40 -0
- qiskit/circuit/library/templates/clifford/clifford_8_1.py +42 -0
- qiskit/circuit/library/templates/clifford/clifford_8_2.py +42 -0
- qiskit/circuit/library/templates/clifford/clifford_8_3.py +41 -0
- qiskit/circuit/library/templates/nct/__init__.py +67 -0
- qiskit/circuit/library/templates/nct/template_nct_2a_1.py +34 -0
- qiskit/circuit/library/templates/nct/template_nct_2a_2.py +35 -0
- qiskit/circuit/library/templates/nct/template_nct_2a_3.py +37 -0
- qiskit/circuit/library/templates/nct/template_nct_4a_1.py +43 -0
- qiskit/circuit/library/templates/nct/template_nct_4a_2.py +41 -0
- qiskit/circuit/library/templates/nct/template_nct_4a_3.py +39 -0
- qiskit/circuit/library/templates/nct/template_nct_4b_1.py +41 -0
- qiskit/circuit/library/templates/nct/template_nct_4b_2.py +39 -0
- qiskit/circuit/library/templates/nct/template_nct_5a_1.py +40 -0
- qiskit/circuit/library/templates/nct/template_nct_5a_2.py +40 -0
- qiskit/circuit/library/templates/nct/template_nct_5a_3.py +40 -0
- qiskit/circuit/library/templates/nct/template_nct_5a_4.py +39 -0
- qiskit/circuit/library/templates/nct/template_nct_6a_1.py +40 -0
- qiskit/circuit/library/templates/nct/template_nct_6a_2.py +41 -0
- qiskit/circuit/library/templates/nct/template_nct_6a_3.py +41 -0
- qiskit/circuit/library/templates/nct/template_nct_6a_4.py +41 -0
- qiskit/circuit/library/templates/nct/template_nct_6b_1.py +41 -0
- qiskit/circuit/library/templates/nct/template_nct_6b_2.py +41 -0
- qiskit/circuit/library/templates/nct/template_nct_6c_1.py +41 -0
- qiskit/circuit/library/templates/nct/template_nct_7a_1.py +43 -0
- qiskit/circuit/library/templates/nct/template_nct_7b_1.py +43 -0
- qiskit/circuit/library/templates/nct/template_nct_7c_1.py +43 -0
- qiskit/circuit/library/templates/nct/template_nct_7d_1.py +43 -0
- qiskit/circuit/library/templates/nct/template_nct_7e_1.py +43 -0
- qiskit/circuit/library/templates/nct/template_nct_9a_1.py +45 -0
- qiskit/circuit/library/templates/nct/template_nct_9c_1.py +43 -0
- qiskit/circuit/library/templates/nct/template_nct_9c_10.py +44 -0
- qiskit/circuit/library/templates/nct/template_nct_9c_11.py +44 -0
- qiskit/circuit/library/templates/nct/template_nct_9c_12.py +44 -0
- qiskit/circuit/library/templates/nct/template_nct_9c_2.py +44 -0
- qiskit/circuit/library/templates/nct/template_nct_9c_3.py +44 -0
- qiskit/circuit/library/templates/nct/template_nct_9c_4.py +44 -0
- qiskit/circuit/library/templates/nct/template_nct_9c_5.py +44 -0
- qiskit/circuit/library/templates/nct/template_nct_9c_6.py +44 -0
- qiskit/circuit/library/templates/nct/template_nct_9c_7.py +44 -0
- qiskit/circuit/library/templates/nct/template_nct_9c_8.py +44 -0
- qiskit/circuit/library/templates/nct/template_nct_9c_9.py +44 -0
- qiskit/circuit/library/templates/nct/template_nct_9d_1.py +43 -0
- qiskit/circuit/library/templates/nct/template_nct_9d_10.py +44 -0
- qiskit/circuit/library/templates/nct/template_nct_9d_2.py +44 -0
- qiskit/circuit/library/templates/nct/template_nct_9d_3.py +44 -0
- qiskit/circuit/library/templates/nct/template_nct_9d_4.py +44 -0
- qiskit/circuit/library/templates/nct/template_nct_9d_5.py +44 -0
- qiskit/circuit/library/templates/nct/template_nct_9d_6.py +44 -0
- qiskit/circuit/library/templates/nct/template_nct_9d_7.py +44 -0
- qiskit/circuit/library/templates/nct/template_nct_9d_8.py +44 -0
- qiskit/circuit/library/templates/nct/template_nct_9d_9.py +44 -0
- qiskit/circuit/library/templates/rzx/__init__.py +25 -0
- qiskit/circuit/library/templates/rzx/rzx_cy.py +47 -0
- qiskit/circuit/library/templates/rzx/rzx_xz.py +54 -0
- qiskit/circuit/library/templates/rzx/rzx_yz.py +45 -0
- qiskit/circuit/library/templates/rzx/rzx_zz1.py +69 -0
- qiskit/circuit/library/templates/rzx/rzx_zz2.py +59 -0
- qiskit/circuit/library/templates/rzx/rzx_zz3.py +59 -0
- qiskit/circuit/measure.py +53 -0
- qiskit/circuit/operation.py +68 -0
- qiskit/circuit/parameter.py +179 -0
- qiskit/circuit/parameterexpression.py +703 -0
- qiskit/circuit/parametertable.py +119 -0
- qiskit/circuit/parametervector.py +140 -0
- qiskit/circuit/quantumcircuit.py +7540 -0
- qiskit/circuit/quantumcircuitdata.py +136 -0
- qiskit/circuit/random/__init__.py +15 -0
- qiskit/circuit/random/utils.py +366 -0
- qiskit/circuit/reset.py +37 -0
- qiskit/circuit/singleton.py +600 -0
- qiskit/circuit/store.py +89 -0
- qiskit/circuit/tools/__init__.py +16 -0
- qiskit/circuit/tools/pi_check.py +193 -0
- qiskit/circuit/twirling.py +145 -0
- qiskit/compiler/__init__.py +27 -0
- qiskit/compiler/transpiler.py +375 -0
- qiskit/converters/__init__.py +74 -0
- qiskit/converters/circuit_to_dag.py +80 -0
- qiskit/converters/circuit_to_dagdependency.py +49 -0
- qiskit/converters/circuit_to_dagdependency_v2.py +46 -0
- qiskit/converters/circuit_to_gate.py +107 -0
- qiskit/converters/circuit_to_instruction.py +142 -0
- qiskit/converters/dag_to_circuit.py +79 -0
- qiskit/converters/dag_to_dagdependency.py +54 -0
- qiskit/converters/dag_to_dagdependency_v2.py +43 -0
- qiskit/converters/dagdependency_to_circuit.py +40 -0
- qiskit/converters/dagdependency_to_dag.py +48 -0
- qiskit/dagcircuit/__init__.py +55 -0
- qiskit/dagcircuit/collect_blocks.py +407 -0
- qiskit/dagcircuit/dagcircuit.py +24 -0
- qiskit/dagcircuit/dagdependency.py +612 -0
- qiskit/dagcircuit/dagdependency_v2.py +566 -0
- qiskit/dagcircuit/dagdepnode.py +160 -0
- qiskit/dagcircuit/dagnode.py +188 -0
- qiskit/dagcircuit/exceptions.py +42 -0
- qiskit/exceptions.py +153 -0
- qiskit/passmanager/__init__.py +258 -0
- qiskit/passmanager/base_tasks.py +230 -0
- qiskit/passmanager/compilation_status.py +74 -0
- qiskit/passmanager/exceptions.py +19 -0
- qiskit/passmanager/flow_controllers.py +116 -0
- qiskit/passmanager/passmanager.py +353 -0
- qiskit/primitives/__init__.py +490 -0
- qiskit/primitives/backend_estimator_v2.py +530 -0
- qiskit/primitives/backend_sampler_v2.py +339 -0
- qiskit/primitives/base/__init__.py +20 -0
- qiskit/primitives/base/base_estimator.py +247 -0
- qiskit/primitives/base/base_primitive_job.py +78 -0
- qiskit/primitives/base/base_primitive_v1.py +45 -0
- qiskit/primitives/base/base_result_v1.py +65 -0
- qiskit/primitives/base/base_sampler.py +196 -0
- qiskit/primitives/base/estimator_result_v1.py +46 -0
- qiskit/primitives/base/sampler_result_v1.py +45 -0
- qiskit/primitives/base/validation_v1.py +250 -0
- qiskit/primitives/containers/__init__.py +26 -0
- qiskit/primitives/containers/bindings_array.py +391 -0
- qiskit/primitives/containers/bit_array.py +764 -0
- qiskit/primitives/containers/data_bin.py +175 -0
- qiskit/primitives/containers/estimator_pub.py +222 -0
- qiskit/primitives/containers/object_array.py +94 -0
- qiskit/primitives/containers/observables_array.py +296 -0
- qiskit/primitives/containers/primitive_result.py +53 -0
- qiskit/primitives/containers/pub_result.py +51 -0
- qiskit/primitives/containers/sampler_pub.py +193 -0
- qiskit/primitives/containers/sampler_pub_result.py +74 -0
- qiskit/primitives/containers/shape.py +129 -0
- qiskit/primitives/primitive_job.py +81 -0
- qiskit/primitives/statevector_estimator.py +175 -0
- qiskit/primitives/statevector_sampler.py +290 -0
- qiskit/primitives/utils.py +72 -0
- qiskit/providers/__init__.py +677 -0
- qiskit/providers/backend.py +364 -0
- qiskit/providers/basic_provider/__init__.py +47 -0
- qiskit/providers/basic_provider/basic_provider.py +121 -0
- qiskit/providers/basic_provider/basic_provider_job.py +65 -0
- qiskit/providers/basic_provider/basic_provider_tools.py +218 -0
- qiskit/providers/basic_provider/basic_simulator.py +693 -0
- qiskit/providers/basic_provider/exceptions.py +30 -0
- qiskit/providers/exceptions.py +33 -0
- qiskit/providers/fake_provider/__init__.py +69 -0
- qiskit/providers/fake_provider/generic_backend_v2.py +374 -0
- qiskit/providers/fake_provider/utils/__init__.py +15 -0
- qiskit/providers/job.py +147 -0
- qiskit/providers/jobstatus.py +30 -0
- qiskit/providers/options.py +273 -0
- qiskit/providers/providerutils.py +110 -0
- qiskit/qasm/libs/dummy/stdgates.inc +75 -0
- qiskit/qasm/libs/qelib1.inc +266 -0
- qiskit/qasm/libs/stdgates.inc +82 -0
- qiskit/qasm2/__init__.py +669 -0
- qiskit/qasm2/exceptions.py +27 -0
- qiskit/qasm2/export.py +364 -0
- qiskit/qasm2/parse.py +438 -0
- qiskit/qasm3/__init__.py +372 -0
- qiskit/qasm3/ast.py +782 -0
- qiskit/qasm3/exceptions.py +27 -0
- qiskit/qasm3/experimental.py +70 -0
- qiskit/qasm3/exporter.py +1340 -0
- qiskit/qasm3/printer.py +608 -0
- qiskit/qpy/__init__.py +1965 -0
- qiskit/qpy/binary_io/__init__.py +35 -0
- qiskit/qpy/binary_io/circuits.py +1455 -0
- qiskit/qpy/binary_io/parse_sympy_repr.py +121 -0
- qiskit/qpy/binary_io/schedules.py +308 -0
- qiskit/qpy/binary_io/value.py +1165 -0
- qiskit/qpy/common.py +353 -0
- qiskit/qpy/exceptions.py +53 -0
- qiskit/qpy/formats.py +442 -0
- qiskit/qpy/interface.py +344 -0
- qiskit/qpy/type_keys.py +409 -0
- qiskit/quantum_info/__init__.py +162 -0
- qiskit/quantum_info/analysis/__init__.py +17 -0
- qiskit/quantum_info/analysis/average.py +47 -0
- qiskit/quantum_info/analysis/distance.py +104 -0
- qiskit/quantum_info/analysis/make_observable.py +44 -0
- qiskit/quantum_info/analysis/z2_symmetries.py +484 -0
- qiskit/quantum_info/operators/__init__.py +28 -0
- qiskit/quantum_info/operators/base_operator.py +145 -0
- qiskit/quantum_info/operators/channel/__init__.py +29 -0
- qiskit/quantum_info/operators/channel/chi.py +191 -0
- qiskit/quantum_info/operators/channel/choi.py +218 -0
- qiskit/quantum_info/operators/channel/kraus.py +337 -0
- qiskit/quantum_info/operators/channel/ptm.py +204 -0
- qiskit/quantum_info/operators/channel/quantum_channel.py +348 -0
- qiskit/quantum_info/operators/channel/stinespring.py +296 -0
- qiskit/quantum_info/operators/channel/superop.py +373 -0
- qiskit/quantum_info/operators/channel/transformations.py +490 -0
- qiskit/quantum_info/operators/custom_iterator.py +48 -0
- qiskit/quantum_info/operators/dihedral/__init__.py +18 -0
- qiskit/quantum_info/operators/dihedral/dihedral.py +511 -0
- qiskit/quantum_info/operators/dihedral/dihedral_circuits.py +216 -0
- qiskit/quantum_info/operators/dihedral/polynomial.py +313 -0
- qiskit/quantum_info/operators/dihedral/random.py +64 -0
- qiskit/quantum_info/operators/linear_op.py +25 -0
- qiskit/quantum_info/operators/measures.py +418 -0
- qiskit/quantum_info/operators/mixins/__init__.py +52 -0
- qiskit/quantum_info/operators/mixins/adjoint.py +52 -0
- qiskit/quantum_info/operators/mixins/group.py +171 -0
- qiskit/quantum_info/operators/mixins/linear.py +84 -0
- qiskit/quantum_info/operators/mixins/multiply.py +62 -0
- qiskit/quantum_info/operators/mixins/tolerances.py +72 -0
- qiskit/quantum_info/operators/op_shape.py +525 -0
- qiskit/quantum_info/operators/operator.py +869 -0
- qiskit/quantum_info/operators/operator_utils.py +76 -0
- qiskit/quantum_info/operators/predicates.py +183 -0
- qiskit/quantum_info/operators/random.py +154 -0
- qiskit/quantum_info/operators/scalar_op.py +254 -0
- qiskit/quantum_info/operators/symplectic/__init__.py +23 -0
- qiskit/quantum_info/operators/symplectic/base_pauli.py +719 -0
- qiskit/quantum_info/operators/symplectic/clifford.py +1032 -0
- qiskit/quantum_info/operators/symplectic/clifford_circuits.py +558 -0
- qiskit/quantum_info/operators/symplectic/pauli.py +755 -0
- qiskit/quantum_info/operators/symplectic/pauli_list.py +1242 -0
- qiskit/quantum_info/operators/symplectic/pauli_utils.py +40 -0
- qiskit/quantum_info/operators/symplectic/random.py +117 -0
- qiskit/quantum_info/operators/symplectic/sparse_pauli_op.py +1239 -0
- qiskit/quantum_info/operators/utils/__init__.py +20 -0
- qiskit/quantum_info/operators/utils/anti_commutator.py +36 -0
- qiskit/quantum_info/operators/utils/commutator.py +36 -0
- qiskit/quantum_info/operators/utils/double_commutator.py +76 -0
- qiskit/quantum_info/quaternion.py +156 -0
- qiskit/quantum_info/random.py +26 -0
- qiskit/quantum_info/states/__init__.py +28 -0
- qiskit/quantum_info/states/densitymatrix.py +857 -0
- qiskit/quantum_info/states/measures.py +288 -0
- qiskit/quantum_info/states/quantum_state.py +503 -0
- qiskit/quantum_info/states/random.py +157 -0
- qiskit/quantum_info/states/stabilizerstate.py +805 -0
- qiskit/quantum_info/states/statevector.py +977 -0
- qiskit/quantum_info/states/utils.py +247 -0
- qiskit/result/__init__.py +61 -0
- qiskit/result/counts.py +189 -0
- qiskit/result/distributions/__init__.py +17 -0
- qiskit/result/distributions/probability.py +100 -0
- qiskit/result/distributions/quasi.py +154 -0
- qiskit/result/exceptions.py +40 -0
- qiskit/result/models.py +241 -0
- qiskit/result/postprocess.py +239 -0
- qiskit/result/result.py +385 -0
- qiskit/result/sampled_expval.py +74 -0
- qiskit/result/utils.py +294 -0
- qiskit/synthesis/__init__.py +240 -0
- qiskit/synthesis/arithmetic/__init__.py +18 -0
- qiskit/synthesis/arithmetic/adders/__init__.py +17 -0
- qiskit/synthesis/arithmetic/adders/cdkm_ripple_carry_adder.py +154 -0
- qiskit/synthesis/arithmetic/adders/draper_qft_adder.py +103 -0
- qiskit/synthesis/arithmetic/adders/vbe_ripple_carry_adder.py +161 -0
- qiskit/synthesis/arithmetic/comparators/__init__.py +16 -0
- qiskit/synthesis/arithmetic/comparators/compare_2s.py +112 -0
- qiskit/synthesis/arithmetic/comparators/compare_greedy.py +66 -0
- qiskit/synthesis/arithmetic/multipliers/__init__.py +16 -0
- qiskit/synthesis/arithmetic/multipliers/hrs_cumulative_multiplier.py +103 -0
- qiskit/synthesis/arithmetic/multipliers/rg_qft_multiplier.py +100 -0
- qiskit/synthesis/arithmetic/weighted_sum.py +155 -0
- qiskit/synthesis/boolean/__init__.py +13 -0
- qiskit/synthesis/boolean/boolean_expression.py +231 -0
- qiskit/synthesis/boolean/boolean_expression_synth.py +124 -0
- qiskit/synthesis/boolean/boolean_expression_visitor.py +96 -0
- qiskit/synthesis/clifford/__init__.py +19 -0
- qiskit/synthesis/clifford/clifford_decompose_ag.py +178 -0
- qiskit/synthesis/clifford/clifford_decompose_bm.py +46 -0
- qiskit/synthesis/clifford/clifford_decompose_full.py +64 -0
- qiskit/synthesis/clifford/clifford_decompose_greedy.py +58 -0
- qiskit/synthesis/clifford/clifford_decompose_layers.py +447 -0
- qiskit/synthesis/cnotdihedral/__init__.py +17 -0
- qiskit/synthesis/cnotdihedral/cnotdihedral_decompose_full.py +52 -0
- qiskit/synthesis/cnotdihedral/cnotdihedral_decompose_general.py +141 -0
- qiskit/synthesis/cnotdihedral/cnotdihedral_decompose_two_qubits.py +266 -0
- qiskit/synthesis/discrete_basis/__init__.py +16 -0
- qiskit/synthesis/discrete_basis/commutator_decompose.py +265 -0
- qiskit/synthesis/discrete_basis/gate_sequence.py +421 -0
- qiskit/synthesis/discrete_basis/generate_basis_approximations.py +165 -0
- qiskit/synthesis/discrete_basis/solovay_kitaev.py +240 -0
- qiskit/synthesis/evolution/__init__.py +21 -0
- qiskit/synthesis/evolution/evolution_synthesis.py +48 -0
- qiskit/synthesis/evolution/lie_trotter.py +120 -0
- qiskit/synthesis/evolution/matrix_synthesis.py +47 -0
- qiskit/synthesis/evolution/pauli_network.py +80 -0
- qiskit/synthesis/evolution/product_formula.py +313 -0
- qiskit/synthesis/evolution/qdrift.py +130 -0
- qiskit/synthesis/evolution/suzuki_trotter.py +224 -0
- qiskit/synthesis/linear/__init__.py +26 -0
- qiskit/synthesis/linear/cnot_synth.py +69 -0
- qiskit/synthesis/linear/linear_circuits_utils.py +128 -0
- qiskit/synthesis/linear/linear_depth_lnn.py +61 -0
- qiskit/synthesis/linear/linear_matrix_utils.py +27 -0
- qiskit/synthesis/linear_phase/__init__.py +17 -0
- qiskit/synthesis/linear_phase/cnot_phase_synth.py +206 -0
- qiskit/synthesis/linear_phase/cx_cz_depth_lnn.py +61 -0
- qiskit/synthesis/linear_phase/cz_depth_lnn.py +58 -0
- qiskit/synthesis/multi_controlled/__init__.py +25 -0
- qiskit/synthesis/multi_controlled/mcmt_vchain.py +52 -0
- qiskit/synthesis/multi_controlled/mcx_synthesis.py +359 -0
- qiskit/synthesis/multi_controlled/multi_control_rotation_gates.py +206 -0
- qiskit/synthesis/one_qubit/__init__.py +15 -0
- qiskit/synthesis/one_qubit/one_qubit_decompose.py +288 -0
- qiskit/synthesis/permutation/__init__.py +18 -0
- qiskit/synthesis/permutation/permutation_full.py +78 -0
- qiskit/synthesis/permutation/permutation_lnn.py +54 -0
- qiskit/synthesis/permutation/permutation_reverse_lnn.py +93 -0
- qiskit/synthesis/permutation/permutation_utils.py +16 -0
- qiskit/synthesis/qft/__init__.py +16 -0
- qiskit/synthesis/qft/qft_decompose_full.py +97 -0
- qiskit/synthesis/qft/qft_decompose_lnn.py +79 -0
- qiskit/synthesis/stabilizer/__init__.py +16 -0
- qiskit/synthesis/stabilizer/stabilizer_circuit.py +149 -0
- qiskit/synthesis/stabilizer/stabilizer_decompose.py +194 -0
- qiskit/synthesis/two_qubit/__init__.py +20 -0
- qiskit/synthesis/two_qubit/local_invariance.py +63 -0
- qiskit/synthesis/two_qubit/two_qubit_decompose.py +583 -0
- qiskit/synthesis/two_qubit/xx_decompose/__init__.py +19 -0
- qiskit/synthesis/two_qubit/xx_decompose/circuits.py +300 -0
- qiskit/synthesis/two_qubit/xx_decompose/decomposer.py +324 -0
- qiskit/synthesis/two_qubit/xx_decompose/embodiments.py +163 -0
- qiskit/synthesis/two_qubit/xx_decompose/paths.py +412 -0
- qiskit/synthesis/two_qubit/xx_decompose/polytopes.py +262 -0
- qiskit/synthesis/two_qubit/xx_decompose/utilities.py +40 -0
- qiskit/synthesis/two_qubit/xx_decompose/weyl.py +133 -0
- qiskit/synthesis/unitary/__init__.py +13 -0
- qiskit/synthesis/unitary/aqc/__init__.py +177 -0
- qiskit/synthesis/unitary/aqc/approximate.py +116 -0
- qiskit/synthesis/unitary/aqc/aqc.py +175 -0
- qiskit/synthesis/unitary/aqc/cnot_structures.py +300 -0
- qiskit/synthesis/unitary/aqc/cnot_unit_circuit.py +103 -0
- qiskit/synthesis/unitary/aqc/cnot_unit_objective.py +299 -0
- qiskit/synthesis/unitary/aqc/elementary_operations.py +108 -0
- qiskit/synthesis/unitary/aqc/fast_gradient/__init__.py +164 -0
- qiskit/synthesis/unitary/aqc/fast_gradient/fast_grad_utils.py +237 -0
- qiskit/synthesis/unitary/aqc/fast_gradient/fast_gradient.py +226 -0
- qiskit/synthesis/unitary/aqc/fast_gradient/layer.py +370 -0
- qiskit/synthesis/unitary/aqc/fast_gradient/pmatrix.py +312 -0
- qiskit/synthesis/unitary/qsd.py +288 -0
- qiskit/transpiler/__init__.py +1345 -0
- qiskit/transpiler/basepasses.py +190 -0
- qiskit/transpiler/coupling.py +500 -0
- qiskit/transpiler/exceptions.py +59 -0
- qiskit/transpiler/instruction_durations.py +281 -0
- qiskit/transpiler/layout.py +740 -0
- qiskit/transpiler/passes/__init__.py +276 -0
- qiskit/transpiler/passes/analysis/__init__.py +23 -0
- qiskit/transpiler/passes/analysis/count_ops.py +30 -0
- qiskit/transpiler/passes/analysis/count_ops_longest_path.py +26 -0
- qiskit/transpiler/passes/analysis/dag_longest_path.py +24 -0
- qiskit/transpiler/passes/analysis/depth.py +33 -0
- qiskit/transpiler/passes/analysis/num_qubits.py +26 -0
- qiskit/transpiler/passes/analysis/num_tensor_factors.py +26 -0
- qiskit/transpiler/passes/analysis/resource_estimation.py +41 -0
- qiskit/transpiler/passes/analysis/size.py +36 -0
- qiskit/transpiler/passes/analysis/width.py +27 -0
- qiskit/transpiler/passes/basis/__init__.py +19 -0
- qiskit/transpiler/passes/basis/basis_translator.py +138 -0
- qiskit/transpiler/passes/basis/decompose.py +137 -0
- qiskit/transpiler/passes/basis/translate_parameterized.py +175 -0
- qiskit/transpiler/passes/basis/unroll_3q_or_more.py +84 -0
- qiskit/transpiler/passes/basis/unroll_custom_definitions.py +110 -0
- qiskit/transpiler/passes/layout/__init__.py +26 -0
- qiskit/transpiler/passes/layout/_csp_custom_solver.py +65 -0
- qiskit/transpiler/passes/layout/apply_layout.py +128 -0
- qiskit/transpiler/passes/layout/csp_layout.py +132 -0
- qiskit/transpiler/passes/layout/dense_layout.py +177 -0
- qiskit/transpiler/passes/layout/disjoint_utils.py +219 -0
- qiskit/transpiler/passes/layout/enlarge_with_ancilla.py +49 -0
- qiskit/transpiler/passes/layout/full_ancilla_allocation.py +116 -0
- qiskit/transpiler/passes/layout/layout_2q_distance.py +77 -0
- qiskit/transpiler/passes/layout/sabre_layout.py +506 -0
- qiskit/transpiler/passes/layout/sabre_pre_layout.py +225 -0
- qiskit/transpiler/passes/layout/set_layout.py +69 -0
- qiskit/transpiler/passes/layout/trivial_layout.py +66 -0
- qiskit/transpiler/passes/layout/vf2_layout.py +256 -0
- qiskit/transpiler/passes/layout/vf2_post_layout.py +376 -0
- qiskit/transpiler/passes/layout/vf2_utils.py +235 -0
- qiskit/transpiler/passes/optimization/__init__.py +42 -0
- qiskit/transpiler/passes/optimization/_gate_extension.py +80 -0
- qiskit/transpiler/passes/optimization/collect_1q_runs.py +31 -0
- qiskit/transpiler/passes/optimization/collect_2q_blocks.py +35 -0
- qiskit/transpiler/passes/optimization/collect_and_collapse.py +117 -0
- qiskit/transpiler/passes/optimization/collect_cliffords.py +109 -0
- qiskit/transpiler/passes/optimization/collect_linear_functions.py +85 -0
- qiskit/transpiler/passes/optimization/collect_multiqubit_blocks.py +242 -0
- qiskit/transpiler/passes/optimization/commutation_analysis.py +44 -0
- qiskit/transpiler/passes/optimization/commutative_cancellation.py +82 -0
- qiskit/transpiler/passes/optimization/commutative_inverse_cancellation.py +140 -0
- qiskit/transpiler/passes/optimization/consolidate_blocks.py +176 -0
- qiskit/transpiler/passes/optimization/contract_idle_wires_in_control_flow.py +104 -0
- qiskit/transpiler/passes/optimization/elide_permutations.py +91 -0
- qiskit/transpiler/passes/optimization/hoare_opt.py +420 -0
- qiskit/transpiler/passes/optimization/inverse_cancellation.py +95 -0
- qiskit/transpiler/passes/optimization/light_cone.py +135 -0
- qiskit/transpiler/passes/optimization/optimize_1q_commutation.py +267 -0
- qiskit/transpiler/passes/optimization/optimize_1q_decomposition.py +250 -0
- qiskit/transpiler/passes/optimization/optimize_1q_gates.py +384 -0
- qiskit/transpiler/passes/optimization/optimize_annotated.py +449 -0
- qiskit/transpiler/passes/optimization/optimize_cliffords.py +89 -0
- qiskit/transpiler/passes/optimization/optimize_swap_before_measure.py +71 -0
- qiskit/transpiler/passes/optimization/remove_diagonal_gates_before_measure.py +41 -0
- qiskit/transpiler/passes/optimization/remove_final_reset.py +37 -0
- qiskit/transpiler/passes/optimization/remove_identity_equiv.py +70 -0
- qiskit/transpiler/passes/optimization/remove_reset_in_zero_state.py +37 -0
- qiskit/transpiler/passes/optimization/reset_after_measure_simplification.py +50 -0
- qiskit/transpiler/passes/optimization/split_2q_unitaries.py +63 -0
- qiskit/transpiler/passes/optimization/template_matching/__init__.py +19 -0
- qiskit/transpiler/passes/optimization/template_matching/backward_match.py +749 -0
- qiskit/transpiler/passes/optimization/template_matching/forward_match.py +452 -0
- qiskit/transpiler/passes/optimization/template_matching/maximal_matches.py +77 -0
- qiskit/transpiler/passes/optimization/template_matching/template_matching.py +370 -0
- qiskit/transpiler/passes/optimization/template_matching/template_substitution.py +639 -0
- qiskit/transpiler/passes/optimization/template_optimization.py +158 -0
- qiskit/transpiler/passes/routing/__init__.py +21 -0
- qiskit/transpiler/passes/routing/algorithms/__init__.py +33 -0
- qiskit/transpiler/passes/routing/algorithms/token_swapper.py +105 -0
- qiskit/transpiler/passes/routing/algorithms/types.py +46 -0
- qiskit/transpiler/passes/routing/algorithms/util.py +103 -0
- qiskit/transpiler/passes/routing/basic_swap.py +166 -0
- qiskit/transpiler/passes/routing/commuting_2q_gate_routing/__init__.py +25 -0
- qiskit/transpiler/passes/routing/commuting_2q_gate_routing/commuting_2q_block.py +60 -0
- qiskit/transpiler/passes/routing/commuting_2q_gate_routing/commuting_2q_gate_router.py +397 -0
- qiskit/transpiler/passes/routing/commuting_2q_gate_routing/pauli_2q_evolution_commutation.py +145 -0
- qiskit/transpiler/passes/routing/commuting_2q_gate_routing/swap_strategy.py +306 -0
- qiskit/transpiler/passes/routing/layout_transformation.py +119 -0
- qiskit/transpiler/passes/routing/lookahead_swap.py +390 -0
- qiskit/transpiler/passes/routing/sabre_swap.py +463 -0
- qiskit/transpiler/passes/routing/star_prerouting.py +408 -0
- qiskit/transpiler/passes/routing/utils.py +35 -0
- qiskit/transpiler/passes/scheduling/__init__.py +21 -0
- qiskit/transpiler/passes/scheduling/alignments/__init__.py +79 -0
- qiskit/transpiler/passes/scheduling/alignments/check_durations.py +70 -0
- qiskit/transpiler/passes/scheduling/alignments/reschedule.py +251 -0
- qiskit/transpiler/passes/scheduling/padding/__init__.py +16 -0
- qiskit/transpiler/passes/scheduling/padding/base_padding.py +284 -0
- qiskit/transpiler/passes/scheduling/padding/dynamical_decoupling.py +415 -0
- qiskit/transpiler/passes/scheduling/padding/pad_delay.py +90 -0
- qiskit/transpiler/passes/scheduling/scheduling/__init__.py +17 -0
- qiskit/transpiler/passes/scheduling/scheduling/alap.py +93 -0
- qiskit/transpiler/passes/scheduling/scheduling/asap.py +100 -0
- qiskit/transpiler/passes/scheduling/scheduling/base_scheduler.py +88 -0
- qiskit/transpiler/passes/scheduling/scheduling/set_io_latency.py +64 -0
- qiskit/transpiler/passes/scheduling/time_unit_conversion.py +237 -0
- qiskit/transpiler/passes/synthesis/__init__.py +20 -0
- qiskit/transpiler/passes/synthesis/aqc_plugin.py +153 -0
- qiskit/transpiler/passes/synthesis/default_unitary_synth_plugin.py +653 -0
- qiskit/transpiler/passes/synthesis/high_level_synthesis.py +429 -0
- qiskit/transpiler/passes/synthesis/hls_plugins.py +1963 -0
- qiskit/transpiler/passes/synthesis/linear_functions_synthesis.py +41 -0
- qiskit/transpiler/passes/synthesis/plugin.py +738 -0
- qiskit/transpiler/passes/synthesis/solovay_kitaev_synthesis.py +313 -0
- qiskit/transpiler/passes/synthesis/unitary_synthesis.py +425 -0
- qiskit/transpiler/passes/utils/__init__.py +32 -0
- qiskit/transpiler/passes/utils/barrier_before_final_measurements.py +41 -0
- qiskit/transpiler/passes/utils/check_gate_direction.py +60 -0
- qiskit/transpiler/passes/utils/check_map.py +78 -0
- qiskit/transpiler/passes/utils/contains_instruction.py +45 -0
- qiskit/transpiler/passes/utils/control_flow.py +61 -0
- qiskit/transpiler/passes/utils/dag_fixed_point.py +36 -0
- qiskit/transpiler/passes/utils/error.py +69 -0
- qiskit/transpiler/passes/utils/filter_op_nodes.py +66 -0
- qiskit/transpiler/passes/utils/fixed_point.py +48 -0
- qiskit/transpiler/passes/utils/gate_direction.py +93 -0
- qiskit/transpiler/passes/utils/gates_basis.py +51 -0
- qiskit/transpiler/passes/utils/merge_adjacent_barriers.py +163 -0
- qiskit/transpiler/passes/utils/minimum_point.py +118 -0
- qiskit/transpiler/passes/utils/remove_barriers.py +50 -0
- qiskit/transpiler/passes/utils/remove_final_measurements.py +121 -0
- qiskit/transpiler/passes/utils/unroll_forloops.py +81 -0
- qiskit/transpiler/passmanager.py +503 -0
- qiskit/transpiler/passmanager_config.py +151 -0
- qiskit/transpiler/preset_passmanagers/__init__.py +93 -0
- qiskit/transpiler/preset_passmanagers/builtin_plugins.py +993 -0
- qiskit/transpiler/preset_passmanagers/common.py +672 -0
- qiskit/transpiler/preset_passmanagers/generate_preset_pass_manager.py +437 -0
- qiskit/transpiler/preset_passmanagers/level0.py +104 -0
- qiskit/transpiler/preset_passmanagers/level1.py +108 -0
- qiskit/transpiler/preset_passmanagers/level2.py +109 -0
- qiskit/transpiler/preset_passmanagers/level3.py +110 -0
- qiskit/transpiler/preset_passmanagers/plugin.py +346 -0
- qiskit/transpiler/target.py +905 -0
- qiskit/transpiler/timing_constraints.py +59 -0
- qiskit/user_config.py +266 -0
- qiskit/utils/__init__.py +90 -0
- qiskit/utils/classtools.py +146 -0
- qiskit/utils/deprecation.py +382 -0
- qiskit/utils/lazy_tester.py +363 -0
- qiskit/utils/optionals.py +354 -0
- qiskit/utils/parallel.py +318 -0
- qiskit/utils/units.py +146 -0
- qiskit/version.py +84 -0
- qiskit/visualization/__init__.py +290 -0
- qiskit/visualization/array.py +207 -0
- qiskit/visualization/bloch.py +778 -0
- qiskit/visualization/circuit/__init__.py +15 -0
- qiskit/visualization/circuit/_utils.py +675 -0
- qiskit/visualization/circuit/circuit_visualization.py +735 -0
- qiskit/visualization/circuit/latex.py +661 -0
- qiskit/visualization/circuit/matplotlib.py +2019 -0
- qiskit/visualization/circuit/qcstyle.py +278 -0
- qiskit/visualization/circuit/styles/__init__.py +13 -0
- qiskit/visualization/circuit/styles/bw.json +202 -0
- qiskit/visualization/circuit/styles/clifford.json +202 -0
- qiskit/visualization/circuit/styles/iqp-dark.json +214 -0
- qiskit/visualization/circuit/styles/iqp.json +214 -0
- qiskit/visualization/circuit/styles/textbook.json +202 -0
- qiskit/visualization/circuit/text.py +1849 -0
- qiskit/visualization/circuit_visualization.py +19 -0
- qiskit/visualization/counts_visualization.py +487 -0
- qiskit/visualization/dag_visualization.py +318 -0
- qiskit/visualization/exceptions.py +21 -0
- qiskit/visualization/gate_map.py +1424 -0
- qiskit/visualization/library.py +40 -0
- qiskit/visualization/pass_manager_visualization.py +312 -0
- qiskit/visualization/state_visualization.py +1546 -0
- qiskit/visualization/timeline/__init__.py +21 -0
- qiskit/visualization/timeline/core.py +495 -0
- qiskit/visualization/timeline/drawings.py +260 -0
- qiskit/visualization/timeline/generators.py +506 -0
- qiskit/visualization/timeline/interface.py +444 -0
- qiskit/visualization/timeline/layouts.py +115 -0
- qiskit/visualization/timeline/plotters/__init__.py +16 -0
- qiskit/visualization/timeline/plotters/base_plotter.py +58 -0
- qiskit/visualization/timeline/plotters/matplotlib.py +195 -0
- qiskit/visualization/timeline/stylesheet.py +301 -0
- qiskit/visualization/timeline/types.py +148 -0
- qiskit/visualization/transition_visualization.py +369 -0
- qiskit/visualization/utils.py +49 -0
- qiskit-2.0.3.dist-info/METADATA +220 -0
- qiskit-2.0.3.dist-info/RECORD +690 -0
- qiskit-2.0.3.dist-info/WHEEL +6 -0
- qiskit-2.0.3.dist-info/entry_points.txt +82 -0
- qiskit-2.0.3.dist-info/licenses/LICENSE.txt +203 -0
- qiskit-2.0.3.dist-info/top_level.txt +1 -0
@@ -0,0 +1,59 @@
|
|
1
|
+
# This code is part of Qiskit.
|
2
|
+
#
|
3
|
+
# (C) Copyright IBM 2017, 2020.
|
4
|
+
#
|
5
|
+
# This code is licensed under the Apache License, Version 2.0. You may
|
6
|
+
# obtain a copy of this license in the LICENSE.txt file in the root directory
|
7
|
+
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
|
8
|
+
#
|
9
|
+
# Any modifications or derivative works of this code must retain this
|
10
|
+
# copyright notice, and modified files need to carry a notice indicating
|
11
|
+
# that they have been altered from the originals.
|
12
|
+
|
13
|
+
"""Timing Constraints class."""
|
14
|
+
|
15
|
+
from qiskit.transpiler.exceptions import TranspilerError
|
16
|
+
|
17
|
+
|
18
|
+
class TimingConstraints:
|
19
|
+
"""Hardware Instruction Timing Constraints."""
|
20
|
+
|
21
|
+
def __init__(
|
22
|
+
self,
|
23
|
+
granularity: int = 1,
|
24
|
+
min_length: int = 1,
|
25
|
+
pulse_alignment: int = 1,
|
26
|
+
acquire_alignment: int = 1,
|
27
|
+
):
|
28
|
+
"""Initialize a TimingConstraints object
|
29
|
+
|
30
|
+
Args:
|
31
|
+
granularity: An integer value representing minimum pulse gate
|
32
|
+
resolution in units of ``dt``. A user-defined pulse gate should have
|
33
|
+
duration of a multiple of this granularity value.
|
34
|
+
min_length: An integer value representing minimum pulse gate
|
35
|
+
length in units of ``dt``. A user-defined pulse gate should be longer
|
36
|
+
than this length.
|
37
|
+
pulse_alignment: An integer value representing a time resolution of gate
|
38
|
+
instruction starting time. Gate instruction should start at time which
|
39
|
+
is a multiple of the alignment value.
|
40
|
+
acquire_alignment: An integer value representing a time resolution of measure
|
41
|
+
instruction starting time. Measure instruction should start at time which
|
42
|
+
is a multiple of the alignment value.
|
43
|
+
|
44
|
+
Notes:
|
45
|
+
This information will be provided by the backend configuration.
|
46
|
+
|
47
|
+
Raises:
|
48
|
+
TranspilerError: When any invalid constraint value is passed.
|
49
|
+
"""
|
50
|
+
self.granularity = granularity
|
51
|
+
self.min_length = min_length
|
52
|
+
self.pulse_alignment = pulse_alignment
|
53
|
+
self.acquire_alignment = acquire_alignment
|
54
|
+
|
55
|
+
for key, value in self.__dict__.items():
|
56
|
+
if not isinstance(value, int) or value < 1:
|
57
|
+
raise TranspilerError(
|
58
|
+
f"Timing constraint {key} should be nonzero integer. Not {value}."
|
59
|
+
)
|
qiskit/user_config.py
ADDED
@@ -0,0 +1,266 @@
|
|
1
|
+
# This code is part of Qiskit.
|
2
|
+
#
|
3
|
+
# (C) Copyright IBM 2017, 2019.
|
4
|
+
#
|
5
|
+
# This code is licensed under the Apache License, Version 2.0. You may
|
6
|
+
# obtain a copy of this license in the LICENSE.txt file in the root directory
|
7
|
+
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
|
8
|
+
#
|
9
|
+
# Any modifications or derivative works of this code must retain this
|
10
|
+
# copyright notice, and modified files need to carry a notice indicating
|
11
|
+
# that they have been altered from the originals.
|
12
|
+
|
13
|
+
"""Utils for reading a user preference config files."""
|
14
|
+
|
15
|
+
import configparser
|
16
|
+
import os
|
17
|
+
from warnings import warn
|
18
|
+
|
19
|
+
from qiskit import exceptions
|
20
|
+
|
21
|
+
DEFAULT_FILENAME = os.path.join(os.path.expanduser("~"), ".qiskit", "settings.conf")
|
22
|
+
|
23
|
+
|
24
|
+
class UserConfig:
|
25
|
+
"""Class representing a user config file
|
26
|
+
|
27
|
+
The config file format should look like:
|
28
|
+
|
29
|
+
[default]
|
30
|
+
circuit_drawer = mpl
|
31
|
+
circuit_mpl_style = default
|
32
|
+
circuit_mpl_style_path = ~/.qiskit:<default location>
|
33
|
+
circuit_reverse_bits = True
|
34
|
+
circuit_idle_wires = False
|
35
|
+
transpile_optimization_level = 1
|
36
|
+
parallel = False
|
37
|
+
num_processes = 4
|
38
|
+
sabre_all_threads = true
|
39
|
+
|
40
|
+
"""
|
41
|
+
|
42
|
+
def __init__(self, filename=None):
|
43
|
+
"""Create a UserConfig
|
44
|
+
|
45
|
+
Args:
|
46
|
+
filename (str): The path to the user config file. If one isn't
|
47
|
+
specified, ~/.qiskit/settings.conf is used.
|
48
|
+
"""
|
49
|
+
if filename is None:
|
50
|
+
self.filename = DEFAULT_FILENAME
|
51
|
+
else:
|
52
|
+
self.filename = filename
|
53
|
+
self.settings = {}
|
54
|
+
self.config_parser = configparser.ConfigParser()
|
55
|
+
|
56
|
+
def read_config_file(self):
|
57
|
+
"""Read config file and parse the contents into the settings attr."""
|
58
|
+
if not os.path.isfile(self.filename):
|
59
|
+
return
|
60
|
+
self.config_parser.read(self.filename)
|
61
|
+
if "default" in self.config_parser.sections():
|
62
|
+
# Parse circuit_drawer
|
63
|
+
circuit_drawer = self.config_parser.get("default", "circuit_drawer", fallback=None)
|
64
|
+
if circuit_drawer:
|
65
|
+
if circuit_drawer not in ["text", "mpl", "latex", "latex_source", "auto"]:
|
66
|
+
raise exceptions.QiskitUserConfigError(
|
67
|
+
f"{circuit_drawer} is not a valid circuit drawer backend. Must be "
|
68
|
+
"either 'text', 'mpl', 'latex', 'latex_source', or "
|
69
|
+
"'auto'."
|
70
|
+
)
|
71
|
+
self.settings["circuit_drawer"] = circuit_drawer
|
72
|
+
|
73
|
+
# Parse state_drawer
|
74
|
+
state_drawer = self.config_parser.get("default", "state_drawer", fallback=None)
|
75
|
+
if state_drawer:
|
76
|
+
valid_state_drawers = [
|
77
|
+
"repr",
|
78
|
+
"text",
|
79
|
+
"latex",
|
80
|
+
"latex_source",
|
81
|
+
"qsphere",
|
82
|
+
"hinton",
|
83
|
+
"bloch",
|
84
|
+
]
|
85
|
+
if state_drawer not in valid_state_drawers:
|
86
|
+
valid_choices_string = "', '".join(c for c in valid_state_drawers)
|
87
|
+
raise exceptions.QiskitUserConfigError(
|
88
|
+
f"'{state_drawer}' is not a valid state drawer backend. "
|
89
|
+
f"Choose from: '{valid_choices_string}'"
|
90
|
+
)
|
91
|
+
self.settings["state_drawer"] = state_drawer
|
92
|
+
|
93
|
+
# Parse circuit_mpl_style
|
94
|
+
circuit_mpl_style = self.config_parser.get(
|
95
|
+
"default", "circuit_mpl_style", fallback=None
|
96
|
+
)
|
97
|
+
if circuit_mpl_style:
|
98
|
+
if not isinstance(circuit_mpl_style, str):
|
99
|
+
warn(
|
100
|
+
f"{circuit_mpl_style} is not a valid mpl circuit style. Must be "
|
101
|
+
"a text string. Will not load style.",
|
102
|
+
UserWarning,
|
103
|
+
2,
|
104
|
+
)
|
105
|
+
self.settings["circuit_mpl_style"] = circuit_mpl_style
|
106
|
+
|
107
|
+
# Parse circuit_mpl_style_path
|
108
|
+
circuit_mpl_style_path = self.config_parser.get(
|
109
|
+
"default", "circuit_mpl_style_path", fallback=None
|
110
|
+
)
|
111
|
+
if circuit_mpl_style_path:
|
112
|
+
cpath_list = circuit_mpl_style_path.split(":")
|
113
|
+
for path in cpath_list:
|
114
|
+
if not os.path.exists(os.path.expanduser(path)):
|
115
|
+
warn(
|
116
|
+
f"{path} is not a valid circuit mpl style path."
|
117
|
+
" Correct the path in ~/.qiskit/settings.conf.",
|
118
|
+
UserWarning,
|
119
|
+
2,
|
120
|
+
)
|
121
|
+
self.settings["circuit_mpl_style_path"] = cpath_list
|
122
|
+
|
123
|
+
# Parse circuit_reverse_bits
|
124
|
+
try:
|
125
|
+
circuit_reverse_bits = self.config_parser.getboolean(
|
126
|
+
"default", "circuit_reverse_bits", fallback=None
|
127
|
+
)
|
128
|
+
except ValueError as err:
|
129
|
+
raise exceptions.QiskitUserConfigError(
|
130
|
+
f"Value assigned to circuit_reverse_bits is not valid. {str(err)}"
|
131
|
+
)
|
132
|
+
if circuit_reverse_bits is not None:
|
133
|
+
self.settings["circuit_reverse_bits"] = circuit_reverse_bits
|
134
|
+
|
135
|
+
# Parse circuit_idle_wires
|
136
|
+
try:
|
137
|
+
circuit_idle_wires = self.config_parser.getboolean(
|
138
|
+
"default", "circuit_idle_wires", fallback=None
|
139
|
+
)
|
140
|
+
except ValueError as err:
|
141
|
+
raise exceptions.QiskitUserConfigError(
|
142
|
+
f"Value assigned to circuit_idle_wires is not valid. {str(err)}"
|
143
|
+
)
|
144
|
+
if circuit_idle_wires is not None:
|
145
|
+
self.settings["circuit_idle_wires"] = circuit_idle_wires
|
146
|
+
|
147
|
+
# Parse transpile_optimization_level
|
148
|
+
transpile_optimization_level = self.config_parser.getint(
|
149
|
+
"default", "transpile_optimization_level", fallback=-1
|
150
|
+
)
|
151
|
+
if transpile_optimization_level != -1:
|
152
|
+
if transpile_optimization_level < 0 or transpile_optimization_level > 3:
|
153
|
+
raise exceptions.QiskitUserConfigError(
|
154
|
+
"%s is not a valid optimization level. Must be 0, 1, 2, or 3."
|
155
|
+
)
|
156
|
+
self.settings["transpile_optimization_level"] = transpile_optimization_level
|
157
|
+
|
158
|
+
# Parse parallel
|
159
|
+
parallel_enabled = self.config_parser.getboolean("default", "parallel", fallback=None)
|
160
|
+
if parallel_enabled is not None:
|
161
|
+
self.settings["parallel_enabled"] = parallel_enabled
|
162
|
+
|
163
|
+
# Parse num_processes
|
164
|
+
num_processes = self.config_parser.getint("default", "num_processes", fallback=-1)
|
165
|
+
if num_processes != -1:
|
166
|
+
if num_processes <= 0:
|
167
|
+
raise exceptions.QiskitUserConfigError(
|
168
|
+
"%s is not a valid number of processes. Must be greater than 0"
|
169
|
+
)
|
170
|
+
self.settings["num_processes"] = num_processes
|
171
|
+
|
172
|
+
# Parse sabre_all_threads
|
173
|
+
sabre_all_threads = self.config_parser.getboolean(
|
174
|
+
"default", "sabre_all_threads", fallback=None
|
175
|
+
)
|
176
|
+
if sabre_all_threads is not None:
|
177
|
+
self.settings["sabre_all_threads"] = sabre_all_threads
|
178
|
+
|
179
|
+
|
180
|
+
def set_config(key, value, section=None, file_path=None):
|
181
|
+
"""Adds or modifies a user configuration
|
182
|
+
|
183
|
+
It will add configuration to the currently configured location
|
184
|
+
or the value of file argument.
|
185
|
+
|
186
|
+
Only valid user config can be set in 'default' section. Custom
|
187
|
+
user config can be added in any other sections.
|
188
|
+
|
189
|
+
Changes to the existing config file will not be reflected in
|
190
|
+
the current session since the config file is parsed at import time.
|
191
|
+
|
192
|
+
Args:
|
193
|
+
key (str): name of the config
|
194
|
+
value (obj): value of the config
|
195
|
+
section (str, optional): if not specified, adds it to the
|
196
|
+
`default` section of the config file.
|
197
|
+
file_path (str, optional): the file to which config is added.
|
198
|
+
If not specified, adds it to the default config file or
|
199
|
+
if set, the value of `QISKIT_SETTINGS` env variable.
|
200
|
+
|
201
|
+
Raises:
|
202
|
+
QiskitUserConfigError: if the config is invalid
|
203
|
+
"""
|
204
|
+
filename = file_path or os.getenv("QISKIT_SETTINGS", DEFAULT_FILENAME)
|
205
|
+
section = "default" if section is None else section
|
206
|
+
|
207
|
+
if not isinstance(key, str):
|
208
|
+
raise exceptions.QiskitUserConfigError("Key must be string type")
|
209
|
+
|
210
|
+
valid_config = {
|
211
|
+
"circuit_drawer",
|
212
|
+
"circuit_mpl_style",
|
213
|
+
"circuit_mpl_style_path",
|
214
|
+
"circuit_reverse_bits",
|
215
|
+
"circuit_idle_wires",
|
216
|
+
"transpile_optimization_level",
|
217
|
+
"parallel",
|
218
|
+
"num_processes",
|
219
|
+
"sabre_all_threads",
|
220
|
+
}
|
221
|
+
|
222
|
+
if section in [None, "default"]:
|
223
|
+
if key not in valid_config:
|
224
|
+
raise exceptions.QiskitUserConfigError(f"{key} is not a valid user config.")
|
225
|
+
|
226
|
+
config = configparser.ConfigParser()
|
227
|
+
config.read(filename)
|
228
|
+
|
229
|
+
if section not in config.sections():
|
230
|
+
config.add_section(section)
|
231
|
+
|
232
|
+
config.set(section, key, str(value))
|
233
|
+
|
234
|
+
try:
|
235
|
+
with open(filename, "w") as cfgfile:
|
236
|
+
config.write(cfgfile)
|
237
|
+
except OSError as ex:
|
238
|
+
raise exceptions.QiskitUserConfigError(
|
239
|
+
f"Unable to load the config file {filename}. Error: '{str(ex)}'"
|
240
|
+
)
|
241
|
+
|
242
|
+
# validates config
|
243
|
+
user_config = UserConfig(filename)
|
244
|
+
user_config.read_config_file()
|
245
|
+
|
246
|
+
|
247
|
+
def get_config():
|
248
|
+
"""Read the config file from the default location or env var.
|
249
|
+
|
250
|
+
It will read a config file at the location specified by the ``QISKIT_SETTINGS`` environment
|
251
|
+
variable if set, or ``$HOME/.qiskit/settings.conf`` if not.
|
252
|
+
|
253
|
+
If the environment variable ``QISKIT_IGNORE_USER_SETTINGS`` is set to the string ``TRUE``, this
|
254
|
+
will return an empty configuration, regardless of all other variables.
|
255
|
+
|
256
|
+
Returns:
|
257
|
+
dict: The settings dict from the parsed config file.
|
258
|
+
"""
|
259
|
+
if os.getenv("QISKIT_IGNORE_USER_SETTINGS", "false").lower() == "true":
|
260
|
+
return {}
|
261
|
+
filename = os.getenv("QISKIT_SETTINGS", DEFAULT_FILENAME)
|
262
|
+
if not os.path.isfile(filename):
|
263
|
+
return {}
|
264
|
+
user_config = UserConfig(filename)
|
265
|
+
user_config.read_config_file()
|
266
|
+
return user_config.settings
|
qiskit/utils/__init__.py
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
# This code is part of Qiskit.
|
2
|
+
#
|
3
|
+
# (C) Copyright IBM 2018, 2023.
|
4
|
+
#
|
5
|
+
# This code is licensed under the Apache License, Version 2.0. You may
|
6
|
+
# obtain a copy of this license in the LICENSE.txt file in the root directory
|
7
|
+
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
|
8
|
+
#
|
9
|
+
# Any modifications or derivative works of this code must retain this
|
10
|
+
# copyright notice, and modified files need to carry a notice indicating
|
11
|
+
# that they have been altered from the originals.
|
12
|
+
|
13
|
+
|
14
|
+
"""
|
15
|
+
===============================
|
16
|
+
Utilities (:mod:`qiskit.utils`)
|
17
|
+
===============================
|
18
|
+
|
19
|
+
.. currentmodule:: qiskit.utils
|
20
|
+
|
21
|
+
Deprecations
|
22
|
+
============
|
23
|
+
|
24
|
+
.. autofunction:: add_deprecation_to_docstring
|
25
|
+
.. autofunction:: deprecate_arg
|
26
|
+
.. autofunction:: deprecate_func
|
27
|
+
|
28
|
+
SI unit conversion
|
29
|
+
==================
|
30
|
+
|
31
|
+
.. autofunction:: apply_prefix
|
32
|
+
.. autofunction:: detach_prefix
|
33
|
+
|
34
|
+
Class tools
|
35
|
+
===========
|
36
|
+
|
37
|
+
.. autofunction:: wrap_method
|
38
|
+
|
39
|
+
Multiprocessing
|
40
|
+
===============
|
41
|
+
|
42
|
+
.. autofunction:: default_num_processes
|
43
|
+
.. autofunction:: is_main_process
|
44
|
+
.. autofunction:: local_hardware_info
|
45
|
+
.. autofunction:: should_run_in_parallel
|
46
|
+
|
47
|
+
A helper function for calling a custom function with Python
|
48
|
+
:class:`~concurrent.futures.ProcessPoolExecutor`. Tasks can be executed in parallel using this function.
|
49
|
+
|
50
|
+
.. autofunction:: parallel_map
|
51
|
+
|
52
|
+
Optional Dependency Checkers
|
53
|
+
============================
|
54
|
+
|
55
|
+
.. automodule:: qiskit.utils.optionals
|
56
|
+
"""
|
57
|
+
|
58
|
+
from .deprecation import (
|
59
|
+
add_deprecation_to_docstring,
|
60
|
+
deprecate_arg,
|
61
|
+
deprecate_func,
|
62
|
+
)
|
63
|
+
from .units import apply_prefix, detach_prefix
|
64
|
+
from .classtools import wrap_method
|
65
|
+
from .lazy_tester import LazyDependencyManager, LazyImportTester, LazySubprocessTester
|
66
|
+
|
67
|
+
from . import optionals
|
68
|
+
|
69
|
+
from .parallel import (
|
70
|
+
parallel_map,
|
71
|
+
should_run_in_parallel,
|
72
|
+
local_hardware_info,
|
73
|
+
is_main_process,
|
74
|
+
default_num_processes,
|
75
|
+
)
|
76
|
+
|
77
|
+
__all__ = [
|
78
|
+
"LazyDependencyManager",
|
79
|
+
"LazyImportTester",
|
80
|
+
"LazySubprocessTester",
|
81
|
+
"add_deprecation_to_docstring",
|
82
|
+
"apply_prefix",
|
83
|
+
"default_num_processes",
|
84
|
+
"deprecate_arg",
|
85
|
+
"deprecate_func",
|
86
|
+
"is_main_process",
|
87
|
+
"local_hardware_info",
|
88
|
+
"parallel_map",
|
89
|
+
"should_run_in_parallel",
|
90
|
+
]
|
@@ -0,0 +1,146 @@
|
|
1
|
+
# This code is part of Qiskit.
|
2
|
+
#
|
3
|
+
# (C) Copyright IBM 2022.
|
4
|
+
#
|
5
|
+
# This code is licensed under the Apache License, Version 2.0. You may
|
6
|
+
# obtain a copy of this license in the LICENSE.txt file in the root directory
|
7
|
+
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
|
8
|
+
#
|
9
|
+
# Any modifications or derivative works of this code must retain this
|
10
|
+
# copyright notice, and modified files need to carry a notice indicating
|
11
|
+
# that they have been altered from the originals.
|
12
|
+
|
13
|
+
"""Tools useful for creating decorators, and other high-level callables."""
|
14
|
+
|
15
|
+
import functools
|
16
|
+
import inspect
|
17
|
+
import types
|
18
|
+
from typing import Type, Callable
|
19
|
+
|
20
|
+
|
21
|
+
# On user-defined classes, `__new__` is magically inferred to be a staticmethod, `__init_subclass__`
|
22
|
+
# is magically inferred to be a class method and `__prepare__` must be defined as a classmethod, but
|
23
|
+
# the CPython types implemented in C (such as `object` and `type`) are `types.BuiltinMethodType`,
|
24
|
+
# which we can't distinguish properly, so we need a little magic.
|
25
|
+
_MAGIC_STATICMETHODS = {"__new__"}
|
26
|
+
_MAGIC_CLASSMETHODS = {"__init_subclass__", "__prepare__"}
|
27
|
+
|
28
|
+
|
29
|
+
class _lift_to_method: # pylint: disable=invalid-name
|
30
|
+
"""A decorator that ensures that an input callable object implements ``__get__``. It is
|
31
|
+
returned unchanged if so, otherwise it is turned into the default implementation for functions,
|
32
|
+
which makes them bindable to instances.
|
33
|
+
|
34
|
+
Python-space functions and lambdas already have this behavior, but builtins like ``print``
|
35
|
+
don't; using this class allows us to do::
|
36
|
+
|
37
|
+
wrap_method(MyClass, "maybe_mutates_arguments", before=print, after=print)
|
38
|
+
|
39
|
+
to simply print all the arguments on entry and exit of the function, which otherwise wouldn't be
|
40
|
+
valid, since ``print`` isn't a descriptor.
|
41
|
+
"""
|
42
|
+
|
43
|
+
__slots__ = ("_method",)
|
44
|
+
|
45
|
+
def __new__(cls, method):
|
46
|
+
if hasattr(method, "__get__"):
|
47
|
+
return method
|
48
|
+
return super().__new__(cls)
|
49
|
+
|
50
|
+
def __init__(self, method):
|
51
|
+
if method is self:
|
52
|
+
# Prevent double-initialization if we are passed an instance of this object to lift.
|
53
|
+
return
|
54
|
+
self._method = method
|
55
|
+
|
56
|
+
def __get__(self, obj, objtype):
|
57
|
+
# This is effectively the same implementation as `types.FunctionType.__get__`, but we can't
|
58
|
+
# bind that directly because it also includes a requirement that its `self` reference is of
|
59
|
+
# the correct type, and this isn't.
|
60
|
+
if obj is None:
|
61
|
+
return self._method
|
62
|
+
return types.MethodType(self._method, obj)
|
63
|
+
|
64
|
+
|
65
|
+
class _WrappedMethod:
|
66
|
+
"""Descriptor which calls its two arguments in succession, correctly handling instance- and
|
67
|
+
class-method calls.
|
68
|
+
|
69
|
+
It is intended that this class will replace the attribute that ``inner`` previously was on a
|
70
|
+
class or instance. When accessed as that attribute, this descriptor will behave it is the same
|
71
|
+
function call, but with the ``function`` called before or after.
|
72
|
+
"""
|
73
|
+
|
74
|
+
__slots__ = ("_method_decorator", "_method_has_get", "_method", "_before", "_after")
|
75
|
+
|
76
|
+
def __init__(self, method, before=None, after=None):
|
77
|
+
if isinstance(method, (classmethod, staticmethod)):
|
78
|
+
self._method_decorator = type(method)
|
79
|
+
elif isinstance(method, type(self)):
|
80
|
+
self._method_decorator = method._method_decorator
|
81
|
+
elif getattr(method, "__name__", None) in _MAGIC_STATICMETHODS:
|
82
|
+
self._method_decorator = staticmethod
|
83
|
+
elif getattr(method, "__name__", None) in _MAGIC_CLASSMETHODS:
|
84
|
+
self._method_decorator = classmethod
|
85
|
+
else:
|
86
|
+
self._method_decorator = _lift_to_method
|
87
|
+
before = (self._method_decorator(before),) if before is not None else ()
|
88
|
+
after = (self._method_decorator(after),) if after is not None else ()
|
89
|
+
if isinstance(method, type(self)):
|
90
|
+
self._method = method._method
|
91
|
+
self._before = before + method._before
|
92
|
+
self._after = method._after + after
|
93
|
+
else:
|
94
|
+
self._before = before
|
95
|
+
self._after = after
|
96
|
+
self._method = method
|
97
|
+
# If the inner method doesn't have `__get__` (like some builtin methods), it's faster to
|
98
|
+
# test a Boolean each time than the repeatedly raise and catch an exception, which is what
|
99
|
+
# `hasattr` does.
|
100
|
+
self._method_has_get = hasattr(self._method, "__get__")
|
101
|
+
|
102
|
+
def __get__(self, obj, objtype=None):
|
103
|
+
# `self._method` doesn't invoke the `_method` descriptor (if it is one) because that only
|
104
|
+
# happens for class variables. Here it's an instance variable, so we can pass through `obj`
|
105
|
+
# and `objtype` correctly like this.
|
106
|
+
method = self._method.__get__(obj, objtype) if self._method_has_get else self._method
|
107
|
+
|
108
|
+
@functools.wraps(method)
|
109
|
+
def out(*args, **kwargs):
|
110
|
+
for callback in self._before:
|
111
|
+
callback.__get__(obj, objtype)(*args, **kwargs)
|
112
|
+
retval = method(*args, **kwargs)
|
113
|
+
for callback in self._after:
|
114
|
+
callback.__get__(obj, objtype)(*args, **kwargs)
|
115
|
+
return retval
|
116
|
+
|
117
|
+
return out
|
118
|
+
|
119
|
+
|
120
|
+
def wrap_method(cls: Type, name: str, *, before: Callable = None, after: Callable = None):
|
121
|
+
"""Wrap the functionality the instance- or class method ``cls.name`` with additional behavior
|
122
|
+
``before`` and ``after``.
|
123
|
+
|
124
|
+
This mutates ``cls``, replacing the attribute ``name`` with the new functionality. This is
|
125
|
+
useful when creating class decorators. The method is allowed to be defined on any parent class
|
126
|
+
instead.
|
127
|
+
|
128
|
+
If either ``before`` or ``after`` are given, they should be callables with a compatible
|
129
|
+
signature to the method referred to. They will be called immediately before or after the method
|
130
|
+
as appropriate, and any return value will be ignored.
|
131
|
+
|
132
|
+
Args:
|
133
|
+
cls: the class to modify.
|
134
|
+
name: the name of the method on the class to wrap.
|
135
|
+
before: a callable that should be called before the method that is being wrapped.
|
136
|
+
after: a callable that should be called after the method that is being wrapped.
|
137
|
+
|
138
|
+
Raises:
|
139
|
+
ValueError: if the named method is not defined on the class or any parent class.
|
140
|
+
"""
|
141
|
+
# The best time to apply decorators to methods is before they are bound (e.g. by using function
|
142
|
+
# decorators during the class definition), but if we're making a class decorator, we can't do
|
143
|
+
# that. We need the actual definition of the method, so we have to dodge the normal output of
|
144
|
+
# `type.__getattribute__`, which evalutes descriptors if it finds them.
|
145
|
+
method = inspect.getattr_static(cls, name)
|
146
|
+
setattr(cls, name, _WrappedMethod(method, before, after))
|