diff --git a/docs/getting_started.rst b/docs/getting_started.rst
index 2b9f94d280fd..52e04ec7a990 100644
--- a/docs/getting_started.rst
+++ b/docs/getting_started.rst
@@ -198,7 +198,7 @@ Tier 1 platforms are currently:
* Linux x86_64 (distributions compatible with the
`manylinux 2014 `__
packaging specification).
- * macOS x86_64 (10.9 or newer)
+ * macOS x86_64 (10.12 or newer)
* Windows 64 bit
Tier 2
@@ -211,10 +211,6 @@ functioning Python environment.
Tier 2 platforms are currently:
- * Linux i686 (distributions compatible with the
- `manylinux 2014 `__ packaging
- specification) for Python < 3.10
- * Windows 32 bit for Python < 3.10
* Linux aarch64 (distributions compatible with the
`manylinux 2014 `__ packaging
specification)
@@ -240,8 +236,8 @@ Tier 3 platforms are currently:
* macOS arm64 (10.15 or newer)
* Linux i686 (distributions compatible with the
`manylinux 2014 `__ packaging
- specification) for Python >= 3.10
- * Windows 32 bit for Python >= 3.10
+ specification)
+ * Windows 32 bit
Ready to get going?...
======================
diff --git a/pyproject.toml b/pyproject.toml
index 25ff0a5dade7..172c0625d25b 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -10,7 +10,7 @@ target-version = ['py38', 'py39', 'py310', 'py311']
manylinux-x86_64-image = "manylinux2014"
manylinux-i686-image = "manylinux2014"
skip = "pp* cp36-* cp37-* *musllinux*"
-test-skip = "cp310-win32 cp310-manylinux_i686 cp311-win32 cp311-manylinux_i686"
+test-skip = "*win32 *linux_i686"
test-command = "python {project}/examples/python/stochastic_swap.py"
# We need to use pre-built versions of Numpy and Scipy in the tests; they have a
# tendency to crash if they're installed from source by `pip install`, and since
@@ -25,6 +25,7 @@ environment = 'PATH="$PATH:$HOME/.cargo/bin" CARGO_NET_GIT_FETCH_WITH_CLI="true"
repair-wheel-command = "auditwheel repair -w {dest_dir} {wheel} && pipx run abi3audit --strict --report {wheel}"
[tool.cibuildwheel.macos]
+environment = "MACOSX_DEPLOYMENT_TARGET=10.12"
repair-wheel-command = "delocate-wheel --require-archs {delocate_archs} -w {dest_dir} -v {wheel} && pipx run abi3audit --strict --report {wheel}"
[tool.cibuildwheel.windows]
diff --git a/qiskit/circuit/parameter.py b/qiskit/circuit/parameter.py
index e354a708eace..42ffad5ebf0a 100644
--- a/qiskit/circuit/parameter.py
+++ b/qiskit/circuit/parameter.py
@@ -17,8 +17,9 @@
from uuid import uuid4, UUID
+import symengine
+
from qiskit.circuit.exceptions import CircuitError
-from qiskit.utils import optionals as _optionals
from .parameterexpression import ParameterExpression
@@ -75,14 +76,7 @@ def __init__(
"""
self._name = name
self._uuid = uuid4() if uuid is None else uuid
- if not _optionals.HAS_SYMENGINE:
- from sympy import Symbol
-
- symbol = Symbol(name)
- else:
- import symengine
-
- symbol = symengine.Symbol(name)
+ symbol = symengine.Symbol(name)
self._symbol_expr = symbol
self._parameter_keys = frozenset((self._hash_key(),))
@@ -102,11 +96,7 @@ def assign(self, parameter, value):
return value
# This is the `super().bind` case, where we're required to return a `ParameterExpression`,
# so we need to lift the given value to a symbolic expression.
- if _optionals.HAS_SYMENGINE:
- from symengine import sympify
- else:
- from sympy import sympify
- return ParameterExpression({}, sympify(value))
+ return ParameterExpression({}, symengine.sympify(value))
def subs(self, parameter_map: dict, allow_unknown_parameters: bool = False):
"""Substitute self with the corresponding parameter in ``parameter_map``."""
diff --git a/qiskit/circuit/parameterexpression.py b/qiskit/circuit/parameterexpression.py
index 6b88cede34e1..790fc29b8135 100644
--- a/qiskit/circuit/parameterexpression.py
+++ b/qiskit/circuit/parameterexpression.py
@@ -20,9 +20,9 @@
import operator
import numpy
+import symengine
from qiskit.circuit.exceptions import CircuitError
-from qiskit.utils import optionals as _optionals
# This type is redefined at the bottom to insert the full reference to "ParameterExpression", so it
# can safely be used by runtime type-checkers like Sphinx. Mypy does not need this because it
@@ -69,14 +69,9 @@ def _names(self) -> dict:
def conjugate(self) -> "ParameterExpression":
"""Return the conjugate."""
- if _optionals.HAS_SYMENGINE:
- import symengine
-
- conjugated = ParameterExpression(
- self._parameter_symbols, symengine.conjugate(self._symbol_expr)
- )
- else:
- conjugated = ParameterExpression(self._parameter_symbols, self._symbol_expr.conjugate())
+ conjugated = ParameterExpression(
+ self._parameter_symbols, symengine.conjugate(self._symbol_expr)
+ )
return conjugated
def assign(self, parameter, value: ParameterValueType) -> "ParameterExpression":
@@ -185,15 +180,7 @@ def subs(
new_parameter_symbols = {
p: s for p, s in self._parameter_symbols.items() if p not in parameter_map
}
-
- if _optionals.HAS_SYMENGINE:
- import symengine
-
- symbol_type = symengine.Symbol
- else:
- from sympy import Symbol
-
- symbol_type = Symbol
+ symbol_type = symengine.Symbol
# If new_param is an expr, we'll need to construct a matching sympy expr
# but with our sympy symbols instead of theirs.
@@ -306,15 +293,7 @@ def gradient(self, param) -> Union["ParameterExpression", complex]:
# Compute the gradient of the parameter expression w.r.t. param
key = self._parameter_symbols[param]
- if _optionals.HAS_SYMENGINE:
- import symengine
-
- expr_grad = symengine.Derivative(self._symbol_expr, key)
- else:
- # TODO enable nth derivative
- from sympy import Derivative
-
- expr_grad = Derivative(self._symbol_expr, key).doit()
+ expr_grad = symengine.Derivative(self._symbol_expr, key)
# generate the new dictionary of symbols
# this needs to be done since in the derivative some symbols might disappear (e.g.
@@ -367,102 +346,39 @@ def _call(self, ufunc):
def sin(self):
"""Sine of a ParameterExpression"""
- if _optionals.HAS_SYMENGINE:
- import symengine
-
- return self._call(symengine.sin)
- else:
- from sympy import sin as _sin
-
- return self._call(_sin)
+ return self._call(symengine.sin)
def cos(self):
"""Cosine of a ParameterExpression"""
- if _optionals.HAS_SYMENGINE:
- import symengine
-
- return self._call(symengine.cos)
- else:
- from sympy import cos as _cos
-
- return self._call(_cos)
+ return self._call(symengine.cos)
def tan(self):
"""Tangent of a ParameterExpression"""
- if _optionals.HAS_SYMENGINE:
- import symengine
-
- return self._call(symengine.tan)
- else:
- from sympy import tan as _tan
-
- return self._call(_tan)
+ return self._call(symengine.tan)
def arcsin(self):
"""Arcsin of a ParameterExpression"""
- if _optionals.HAS_SYMENGINE:
- import symengine
-
- return self._call(symengine.asin)
- else:
- from sympy import asin as _asin
-
- return self._call(_asin)
+ return self._call(symengine.asin)
def arccos(self):
"""Arccos of a ParameterExpression"""
- if _optionals.HAS_SYMENGINE:
- import symengine
-
- return self._call(symengine.acos)
- else:
- from sympy import acos as _acos
-
- return self._call(_acos)
+ return self._call(symengine.acos)
def arctan(self):
"""Arctan of a ParameterExpression"""
- if _optionals.HAS_SYMENGINE:
- import symengine
-
- return self._call(symengine.atan)
- else:
- from sympy import atan as _atan
-
- return self._call(_atan)
+ return self._call(symengine.atan)
def exp(self):
"""Exponential of a ParameterExpression"""
- if _optionals.HAS_SYMENGINE:
- import symengine
-
- return self._call(symengine.exp)
- else:
- from sympy import exp as _exp
-
- return self._call(_exp)
+ return self._call(symengine.exp)
def log(self):
"""Logarithm of a ParameterExpression"""
- if _optionals.HAS_SYMENGINE:
- import symengine
-
- return self._call(symengine.log)
- else:
- from sympy import log as _log
-
- return self._call(_log)
+ return self._call(symengine.log)
def sign(self):
"""Sign of a ParameterExpression"""
- if _optionals.HAS_SYMENGINE:
- import symengine
-
- return self._call(symengine.sign)
- else:
- from sympy import sign as _sign
-
- return self._call(_sign)
+ return self._call(symengine.sign)
def __repr__(self):
return f"{self.__class__.__name__}({str(self)})"
@@ -494,24 +410,21 @@ def __float__(self):
"ParameterExpression with unbound parameters ({}) "
"cannot be cast to a float.".format(self.parameters)
) from None
- try:
- # In symengine, if an expression was complex at any time, its type is likely to have
- # stayed "complex" even when the imaginary part symbolically (i.e. exactly)
- # cancelled out. Sympy tends to more aggressively recognise these as symbolically
- # real. This second attempt at a cast is a way of unifying the behaviour to the
- # more expected form for our users.
- cval = complex(self)
- if cval.imag == 0.0:
- return cval.real
- except TypeError:
- pass
+ # In symengine, if an expression was complex at any time, its type is likely to have
+ # stayed "complex" even when the imaginary part symbolically (i.e. exactly)
+ # cancelled out. Sympy tends to more aggressively recognise these as symbolically
+ # real. This second attempt at a cast is a way of unifying the behaviour to the
+ # more expected form for our users.
+ cval = complex(self)
+ if cval.imag == 0.0:
+ return cval.real
raise TypeError("could not cast expression to float") from exc
def __int__(self):
try:
return int(self._symbol_expr)
- # TypeError is for sympy, RuntimeError for symengine
- except (TypeError, RuntimeError) as exc:
+ # TypeError is for backwards compatibility, RuntimeError is raised by symengine
+ except RuntimeError as exc:
if self.parameters:
raise TypeError(
"ParameterExpression with unbound parameters ({}) "
@@ -530,14 +443,7 @@ def __deepcopy__(self, memo=None):
def __abs__(self):
"""Absolute of a ParameterExpression"""
- if _optionals.HAS_SYMENGINE:
- import symengine
-
- return self._call(symengine.Abs)
- else:
- from sympy import Abs as _abs
-
- return self._call(_abs)
+ return self._call(symengine.Abs)
def abs(self):
"""Absolute of a ParameterExpression"""
@@ -555,12 +461,9 @@ def __eq__(self, other):
if isinstance(other, ParameterExpression):
if self.parameters != other.parameters:
return False
- if _optionals.HAS_SYMENGINE:
- from sympy import sympify
+ from sympy import sympify
- return sympify(self._symbol_expr).equals(sympify(other._symbol_expr))
- else:
- return self._symbol_expr.equals(other._symbol_expr)
+ return sympify(self._symbol_expr).equals(sympify(other._symbol_expr))
elif isinstance(other, numbers.Number):
return len(self.parameters) == 0 and complex(self._symbol_expr) == other
return False
@@ -570,7 +473,7 @@ def is_real(self):
# workaround for symengine behavior that const * (0 + 1 * I) is not real
# see https://github.com/symengine/symengine.py/issues/414
- if _optionals.HAS_SYMENGINE and self._symbol_expr.is_real is None:
+ if self._symbol_expr.is_real is None:
symbol_expr = self._symbol_expr.evalf()
else:
symbol_expr = self._symbol_expr
@@ -581,9 +484,8 @@ def is_real(self):
# but the parameter will evaluate as real. Check that if the
# expression's is_real attribute returns false that we have a
# non-zero imaginary
- if _optionals.HAS_SYMENGINE:
- if symbol_expr.imag == 0.0:
- return True
+ if symbol_expr.imag == 0.0:
+ return True
return False
return symbol_expr.is_real
diff --git a/qiskit/pulse/library/symbolic_pulses.py b/qiskit/pulse/library/symbolic_pulses.py
index 9bc18c9c7f13..a943bb1acf60 100644
--- a/qiskit/pulse/library/symbolic_pulses.py
+++ b/qiskit/pulse/library/symbolic_pulses.py
@@ -23,19 +23,14 @@
from copy import deepcopy
import numpy as np
+import symengine as sym
from qiskit.circuit.parameterexpression import ParameterExpression, ParameterValueType
from qiskit.pulse.exceptions import PulseError
from qiskit.pulse.library.pulse import Pulse
from qiskit.pulse.library.waveform import Waveform
-from qiskit.utils import optionals as _optional
from qiskit.utils.deprecation import deprecate_arg
-if _optional.HAS_SYMENGINE:
- import symengine as sym
-else:
- import sympy as sym
-
def _lifted_gaussian(
t: sym.Symbol,
@@ -183,34 +178,31 @@ def __set__(self, instance, value):
continue
params.append(p)
- if _optional.HAS_SYMENGINE:
- try:
- lamb = sym.lambdify(params, [value], real=False)
-
- def _wrapped_lamb(*args):
- if isinstance(args[0], np.ndarray):
- # When the args[0] is a vector ("t"), tile other arguments args[1:]
- # to prevent evaluation from looping over each element in t.
- t = args[0]
- args = np.hstack(
- (
- t.reshape(t.size, 1),
- np.tile(args[1:], t.size).reshape(t.size, len(args) - 1),
- )
+ try:
+ lamb = sym.lambdify(params, [value], real=False)
+
+ def _wrapped_lamb(*args):
+ if isinstance(args[0], np.ndarray):
+ # When the args[0] is a vector ("t"), tile other arguments args[1:]
+ # to prevent evaluation from looping over each element in t.
+ t = args[0]
+ args = np.hstack(
+ (
+ t.reshape(t.size, 1),
+ np.tile(args[1:], t.size).reshape(t.size, len(args) - 1),
)
- return lamb(args)
-
- func = _wrapped_lamb
- except RuntimeError:
- # Currently symengine doesn't support complex_double version for
- # several functions such as comparison operator and piecewise.
- # If expression contains these function, it fall back to sympy lambdify.
- # See https://github.com/symengine/symengine.py/issues/406 for details.
- import sympy
-
- func = sympy.lambdify(params, value)
- else:
- func = sym.lambdify(params, value)
+ )
+ return lamb(args)
+
+ func = _wrapped_lamb
+ except RuntimeError:
+ # Currently symengine doesn't support complex_double version for
+ # several functions such as comparison operator and piecewise.
+ # If expression contains these function, it fall back to sympy lambdify.
+ # See https://github.com/symengine/symengine.py/issues/406 for details.
+ import sympy
+
+ func = sympy.lambdify(params, value)
self.lambda_funcs[key] = func
diff --git a/qiskit/qpy/binary_io/schedules.py b/qiskit/qpy/binary_io/schedules.py
index 25ca9388bb4e..ce22702c89da 100644
--- a/qiskit/qpy/binary_io/schedules.py
+++ b/qiskit/qpy/binary_io/schedules.py
@@ -19,6 +19,10 @@
from io import BytesIO
import numpy as np
+import symengine as sym
+from symengine.lib.symengine_wrapper import ( # pylint: disable = no-name-in-module
+ load_basic,
+)
from qiskit.exceptions import QiskitError
from qiskit.pulse import library, channels, instructions
@@ -26,14 +30,8 @@
from qiskit.qpy import formats, common, type_keys
from qiskit.qpy.binary_io import value
from qiskit.qpy.exceptions import QpyError
-from qiskit.utils import optionals as _optional
from qiskit.pulse.configuration import Kernel, Discriminator
-if _optional.HAS_SYMENGINE:
- import symengine as sym
-else:
- import sympy as sym
-
def _read_channel(file_obj, version):
type_key = common.read_type_key(file_obj)
@@ -106,23 +104,15 @@ def _read_discriminator(file_obj, version):
def _loads_symbolic_expr(expr_bytes, use_symengine=False):
if expr_bytes == b"":
return None
+ expr_bytes = zlib.decompress(expr_bytes)
if use_symengine:
- _optional.HAS_SYMENGINE.require_now("load a symengine expression")
- from symengine.lib.symengine_wrapper import ( # pylint: disable = no-name-in-module
- load_basic,
- )
-
- expr = load_basic(zlib.decompress(expr_bytes))
+ return load_basic(expr_bytes)
else:
from sympy import parse_expr
- expr_txt = zlib.decompress(expr_bytes).decode(common.ENCODE)
+ expr_txt = expr_bytes.decode(common.ENCODE)
expr = parse_expr(expr_txt)
- if _optional.HAS_SYMENGINE:
- from symengine import sympify
-
- return sympify(expr)
- return expr
+ return sym.sympify(expr)
def _read_symbolic_pulse(file_obj, version):
@@ -404,7 +394,6 @@ def _dumps_symbolic_expr(expr, use_symengine):
if expr is None:
return b""
if use_symengine:
- _optional.HAS_SYMENGINE.require_now("dump a symengine expression")
expr_bytes = expr.__reduce__()[1][0]
else:
from sympy import srepr, sympify
diff --git a/qiskit/qpy/binary_io/value.py b/qiskit/qpy/binary_io/value.py
index 7bae82c6911f..686e72c9a4e6 100644
--- a/qiskit/qpy/binary_io/value.py
+++ b/qiskit/qpy/binary_io/value.py
@@ -19,6 +19,11 @@
import uuid
import numpy as np
+import symengine
+from symengine.lib.symengine_wrapper import ( # pylint: disable = no-name-in-module
+ load_basic,
+)
+
from qiskit.circuit import CASE_DEFAULT, Clbit, ClassicalRegister
from qiskit.circuit.classical import expr, types
@@ -26,7 +31,6 @@
from qiskit.circuit.parameterexpression import ParameterExpression
from qiskit.circuit.parametervector import ParameterVector, ParameterVectorElement
from qiskit.qpy import common, formats, exceptions, type_keys
-from qiskit.utils import optionals as _optional
def _write_parameter(file_obj, obj):
@@ -51,7 +55,6 @@ def _write_parameter_vec(file_obj, obj):
def _write_parameter_expression(file_obj, obj, use_symengine):
if use_symengine:
- _optional.HAS_SYMENGINE.require_now("write_parameter_expression")
expr_bytes = obj._symbol_expr.__reduce__()[1][0]
else:
from sympy import srepr, sympify
@@ -224,13 +227,7 @@ def _read_parameter_expression(file_obj):
)
from sympy.parsing.sympy_parser import parse_expr
- if _optional.HAS_SYMENGINE:
- from symengine import sympify
-
- expr_ = sympify(parse_expr(file_obj.read(data.expr_size).decode(common.ENCODE)))
- else:
- expr_ = parse_expr(file_obj.read(data.expr_size).decode(common.ENCODE))
-
+ expr_ = symengine.sympify(parse_expr(file_obj.read(data.expr_size).decode(common.ENCODE)))
symbol_map = {}
for _ in range(data.map_elements):
elem_data = formats.PARAM_EXPR_MAP_ELEM(
@@ -264,23 +261,14 @@ def _read_parameter_expression_v3(file_obj, vectors, use_symengine):
data = formats.PARAMETER_EXPR(
*struct.unpack(formats.PARAMETER_EXPR_PACK, file_obj.read(formats.PARAMETER_EXPR_SIZE))
)
- from sympy.parsing.sympy_parser import parse_expr
payload = file_obj.read(data.expr_size)
if use_symengine:
- _optional.HAS_SYMENGINE.require_now("read_parameter_expression_v3")
- from symengine.lib.symengine_wrapper import ( # pylint: disable = no-name-in-module
- load_basic,
- )
-
expr_ = load_basic(payload)
else:
- if _optional.HAS_SYMENGINE:
- from symengine import sympify
+ from sympy.parsing.sympy_parser import parse_expr
- expr_ = sympify(parse_expr(payload.decode(common.ENCODE)))
- else:
- expr_ = parse_expr(payload.decode(common.ENCODE))
+ expr_ = symengine.sympify(parse_expr(payload.decode(common.ENCODE)))
symbol_map = {}
for _ in range(data.map_elements):
diff --git a/qiskit/qpy/interface.py b/qiskit/qpy/interface.py
index f4a77ec14598..6de673afbc0f 100644
--- a/qiskit/qpy/interface.py
+++ b/qiskit/qpy/interface.py
@@ -75,7 +75,7 @@ def dump(
programs: Union[List[QPY_SUPPORTED_TYPES], QPY_SUPPORTED_TYPES],
file_obj: BinaryIO,
metadata_serializer: Optional[Type[JSONEncoder]] = None,
- use_symengine: bool = False,
+ use_symengine: bool = True,
):
"""Write QPY binary data to a file
diff --git a/releasenotes/notes/platform-support-f7f693aaf5dec044.yaml b/releasenotes/notes/platform-support-f7f693aaf5dec044.yaml
new file mode 100644
index 000000000000..f52aef82c80c
--- /dev/null
+++ b/releasenotes/notes/platform-support-f7f693aaf5dec044.yaml
@@ -0,0 +1,29 @@
+---
+upgrade:
+ - |
+ The ``symengine`` library is now a hard requirement for all platforms.
+ Previously, ``symengine`` was required only on platforms that had
+ pre-compiled packages available and ``sympy`` would be used as a fallback
+ if it wasn't installed. These split requirements were resulting in increased
+ complexity, as it was necessary to determine which libraries were installed
+ to debug an issue. Requiring ``symengine`` for all systems greatly decreases
+ the complexity and optimizes Qiskit for higher performance. However,
+ users on i686 Linux, 32 bit Windows, and s390x Linux (the platforms without
+ precompiled packages on PyPI) will need to build symengine from source.
+ - |
+ Support for 32 bit platforms, i686 Linux and 32 bit Windows, on
+ Python < 3.10 has been downgraded from Tier 2 to Tier 3, as documented in
+ the :ref:`platform_support` page. This is a consequence of making
+ ``symengine`` required for all users, as there is a lack of pre-compiled packages
+ available for these platforms, so users will need to build symengine from
+ source.
+ - |
+ For macOS users, the minimum version of macOS is now 10.12. Previously, the
+ precompiled binary wheel packages for macOS x86_64 were published with
+ support for >=10.9. However, because of changes in the
+ `support policy `__
+ for the Rust programming language the minimum version needed to raised
+ to macOS 10.12. If you're using Qiskit on macOS 10.9 you can probably
+ build Qiskit from source while the Qiskit MSRV (minimum supported Rust
+ version) is < 1.74, but the precompiled binaries published to PyPI will
+ only be compatible with macOS >= 10.12.
diff --git a/requirements.txt b/requirements.txt
index d41eee50ce95..7620b00ee3ec 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -8,7 +8,4 @@ dill>=0.3
python-dateutil>=2.8.0
stevedore>=3.0.0
typing-extensions; python_version<'3.11'
-# symengine pinning needed due lowered precision handling complex
-# multiplication in version 0.10 wich breaks parameter assignment test
-# (can be removed once issue is fix)
-symengine>=0.9, <0.10; platform_machine == 'x86_64' or platform_machine == 'aarch64' or platform_machine == 'ppc64le' or platform_machine == 'amd64' or platform_machine == 'arm64'
+symengine>=0.9, <0.10
diff --git a/test/python/circuit/test_circuit_load_from_qpy.py b/test/python/circuit/test_circuit_load_from_qpy.py
index 4f8523358dbd..5695a298f782 100644
--- a/test/python/circuit/test_circuit_load_from_qpy.py
+++ b/test/python/circuit/test_circuit_load_from_qpy.py
@@ -55,7 +55,6 @@
from qiskit.quantum_info.random import random_unitary
from qiskit.circuit.controlledgate import ControlledGate
from qiskit.utils import optionals
-from qiskit.exceptions import MissingOptionalLibraryError
@ddt.ddt
@@ -1747,22 +1746,3 @@ def test_symengine_full_path(self):
new_circ = load(qpy_file)[0]
self.assertEqual(self.qc, new_circ)
self.assertDeprecatedBitProperties(self.qc, new_circ)
-
- @unittest.skipIf(not optionals.HAS_SYMENGINE, "Install symengine to run this test.")
- def test_dump_no_symengine(self):
- """Test dump fails if symengine is not installed and use_symengine==True."""
- qpy_file = io.BytesIO()
- with optionals.HAS_SYMENGINE.disable_locally():
- with self.assertRaises(MissingOptionalLibraryError):
- dump(self.qc, qpy_file, use_symengine=True)
-
- @unittest.skipIf(not optionals.HAS_SYMENGINE, "Install symengine to run this test.")
- def test_load_no_symengine(self):
- """Test that load fails if symengine is not installed and the
- file was created with use_symengine==True."""
- qpy_file = io.BytesIO()
- dump(self.qc, qpy_file, use_symengine=True)
- qpy_file.seek(0)
- with optionals.HAS_SYMENGINE.disable_locally():
- with self.assertRaises(MissingOptionalLibraryError):
- _ = load(qpy_file)[0]
diff --git a/test/python/qpy/test_block_load_from_qpy.py b/test/python/qpy/test_block_load_from_qpy.py
index 8137ef21a6bb..321e018d5a64 100644
--- a/test/python/qpy/test_block_load_from_qpy.py
+++ b/test/python/qpy/test_block_load_from_qpy.py
@@ -37,7 +37,6 @@
)
from qiskit.pulse.instructions import Play, TimeBlockade
from qiskit.circuit import Parameter, QuantumCircuit, Gate
-from qiskit.exceptions import MissingOptionalLibraryError
from qiskit.test import QiskitTestCase
from qiskit.qpy import dump, load
from qiskit.utils import optionals as _optional
@@ -460,22 +459,3 @@ def test_symengine_full_path(self):
qpy_file.seek(0)
new_sched = load(qpy_file)[0]
self.assertEqual(self.test_sched, new_sched)
-
- @unittest.skipIf(not _optional.HAS_SYMENGINE, "Install symengine to run this test.")
- def test_dump_no_symengine(self):
- """Test dump fails if symengine is not installed and use_symengine==True."""
- qpy_file = io.BytesIO()
- with _optional.HAS_SYMENGINE.disable_locally():
- with self.assertRaises(MissingOptionalLibraryError):
- dump(self.test_sched, qpy_file, use_symengine=True)
-
- @unittest.skipIf(not _optional.HAS_SYMENGINE, "Install symengine to run this test.")
- def test_load_no_symengine(self):
- """Test that load fails if symengine is not installed and the
- file was created with use_symengine==True."""
- qpy_file = io.BytesIO()
- dump(self.test_sched, qpy_file, use_symengine=True)
- qpy_file.seek(0)
- with _optional.HAS_SYMENGINE.disable_locally():
- with self.assertRaises(MissingOptionalLibraryError):
- _ = load(qpy_file)[0]