Repository: Qiskit/qiskit

Issue:
Deprecate Qobj in unitary_simulator.py
> I also just realized that `qiskit.providers.basicaer.UnitarySimulatorPy.run()` (https://github.com/Qiskit/qiskit/blob/main/qiskit/providers/basicaer/unitary_simulator.py#L206) never deprecated a Qobj input and will still support it while the qasm simulator and statevector simulator will not. I still think we should move forward with your PR, but it's something we'll want to clean up in a subsequent PR.

_Originally posted by @mtreinish in https://github.com/Qiskit/qiskit/pull/10872#pullrequestreview-1685997898_
            


Discussion:
Hi, I'd like to work on this. the description isn't very clear, though, could you help me with what needs to be done? Should I just deprecate Qobj input or remove this functionality?
When a `QasmQobj` is supplied to `QasmSimulatorPy.run` or `StatevectorSimulatorPy.run`, the error raised is:
```python
QiskitError: 'bad input to assemble() function; must be either circuits or schedules'
```

And when a  `QasmQobj` is supplied to `QasmSimulatorPy.run`, it complains that there's no `n_qubits` property for `QasmQobj` rather than clearly stating that only circuits are supported. (as the `assemble` call is tucked under a conditional)

Since a `Qobj` input cannot be used anyway, I think it's better to **remove** `Qobj` support directly rather than deprecate it and remove it in a later release. What do you think @1ucian0 @mtreinish?

Based on the conversation [here](https://qiskit.slack.com/archives/C024ELK40TW/p1701877287222499) with @1ucian0 I'll start with a deprecation PR to `stable\0.46` and once that's done, I'll do a removal PR to `main`. 

Resolving patch:
diff --git a/qiskit/providers/basicaer/unitary_simulator.py b/qiskit/providers/basicaer/unitary_simulator.py
--- a/qiskit/providers/basicaer/unitary_simulator.py
+++ b/qiskit/providers/basicaer/unitary_simulator.py
@@ -17,11 +17,11 @@
 
 .. code-block:: python
 
-    UnitarySimulator().run(qobj)
+    UnitarySimulator().run(run_input)
 
-Where the input is a Qobj object and the output is a BasicAerJob object, which can
-later be queried for the Result object. The result will contain a 'unitary'
-data field, which is a 2**n x 2**n complex numpy array representing the
+Where the input is a either Qobj object (deprecated) or QuantumCircuit or a list of circuits and 
+the output is a BasicAerJob object, which can later be queried for the Result object. The result 
+will contain a 'unitary' data field, which is a 2**n x 2**n complex numpy array representing the
 circuit's unitary matrix.
 """
 import logging
@@ -39,6 +39,7 @@
 from qiskit.providers.options import Options
 from qiskit.providers.basicaer.basicaerjob import BasicAerJob
 from qiskit.result import Result
+from qiskit.utils.deprecation import deprecate_arg
 from .exceptions import BasicAerError
 from .basicaertools import single_gate_matrix
 from .basicaertools import SINGLE_QUBIT_GATES
@@ -203,11 +204,18 @@ def _get_unitary(self):
         unitary[abs(unitary) < self._chop_threshold] = 0.0
         return unitary
 
-    def run(self, qobj, **backend_options):
-        """Run qobj asynchronously.
+    @deprecate_arg(
+        "run_input",
+        deprecation_description="Using a QasmQobj for the first argument to UnitarySimulatorPy.run()",
+        since="0.46.0",
+        pending=False,
+        predicate=lambda run_input: not isinstance(run_input, (QuantumCircuit, list)),
+    )
+    def run(self, run_input, **backend_options):
+        """Run experiments in run_input asynchronously.
 
         Args:
-            qobj (Qobj): payload of the experiment
+            run_input (Qobj, QuantumCircuit, list): payload of the experiment
             backend_options (dict): backend options
 
         Returns:
@@ -222,7 +230,7 @@ def run(self, qobj, **backend_options):
             The "initial_unitary" option specifies a custom initial unitary
             matrix for the simulator to be used instead of the identity
             matrix. This size of this matrix must be correct for the number
-            of qubits inall experiments in the qobj.
+            of qubits in all experiments in the run_input.
 
             The "chop_threshold" option specifies a truncation value for
             setting small values to zero in the output unitary. The default
@@ -238,7 +246,7 @@ def run(self, qobj, **backend_options):
                     "chop_threshold": 1e-15
                 }
         """
-        if isinstance(qobj, (QuantumCircuit, list)):
+        if isinstance(run_input, (QuantumCircuit, list)):
             from qiskit.compiler import assemble
 
             out_options = {}
@@ -249,9 +257,10 @@ def run(self, qobj, **backend_options):
                     )
                 else:
                     out_options[key] = backend_options[key]
-            qobj = assemble(qobj, self, **out_options)
+            qobj = assemble(run_input, self, **out_options)
             qobj_options = qobj.config
         else:
+            qobj = run_input
             qobj_options = None
         self._set_options(qobj_config=qobj_options, backend_options=backend_options)
         job_id = str(uuid.uuid4())


Test patch: