Repository: Qiskit/qiskit

Issue:
Unify basis_gates parameter handling (using a list)
<!-- ⚠️ If you do not respect this template, your issue will be closed -->
<!-- ⚠️ Make sure to browse the opened and closed issues to confirm this idea does not exist. -->

### What is the expected enhancement?

(I have the feeling there is already an issue for this topic but can't seem to find it - apologies if it ends up being a duplicated issue).

After #1323, the `basis_gates` for a backend is defined in its configuration as a list:
```
'basis_gates': ['u1', 'u2', 'u3', 'cx', 'id', 'snapshot']
```

Traditionally, we have been passing a comma-separated string around for the internal functions (throughout the transpiler layers), which is a tad ackward and cumbersome (specially since the final "consumers" of the basis gates end up splitting the string into a list, such as the `DAGBackend`). 

Actually one of the changes in #1323 was actually to "stringify" back the basis gates [at the right point in the transpilation process](https://github.com/Qiskit/qiskit-terra/blob/master/qiskit/transpiler/_transpiler.py#L62), mostly for avoiding modifying the function signatures. It might be a good time to avoid that going back and forth entirely, making it always a list throughout the whole transpilation process.

### Proposed solution

Remove the default value for `basis_gates` in the functions involved in the transpilation process, updating the docstrings and ensuring that it is handled properly at the main entry point. A potential drawback is that we might need to change the format of the argument in the public `compile()` method, deprecating or similar (although might not be a concern if we mostly keep the change internal).




Discussion:

Resolving patch:
diff --git a/qiskit/tools/compiler.py b/qiskit/tools/compiler.py
--- a/qiskit/tools/compiler.py
+++ b/qiskit/tools/compiler.py
@@ -30,7 +30,8 @@ def compile(circuits, backend,
         circuits (QuantumCircuit or list[QuantumCircuit]): circuits to compile
         backend (BaseBackend): a backend to compile for
         config (dict): dictionary of parameters (e.g. noise) used by runner
-        basis_gates (str): comma-separated basis gate set to compile to
+        basis_gates (list[str]): list of basis gates names supported by the
+            target. Default: ['u1','u2','u3','cx','id']
         coupling_map (list): coupling map (perhaps custom) to target in mapping
         initial_layout (list): initial layout of qubits in mapping
         shots (int): number of repetitions of each circuit, for sampling
@@ -84,7 +85,8 @@ def execute(circuits, backend, config=None, basis_gates=None, coupling_map=None,
         circuits (QuantumCircuit or list[QuantumCircuit]): circuits to execute
         backend (BaseBackend): a backend to execute the circuits on
         config (dict): dictionary of parameters (e.g. noise) used by runner
-        basis_gates (str): comma-separated basis gate set to compile to
+        basis_gates (list[str]): list of basis gate names supported by the
+            target. Default: ['u1','u2','u3','cx','id']
         coupling_map (list): coupling map (perhaps custom) to target in mapping
         initial_layout (list): initial layout of qubits in mapping
         shots (int): number of repetitions of each circuit, for sampling
diff --git a/qiskit/transpiler/_transpiler.py b/qiskit/transpiler/_transpiler.py
--- a/qiskit/transpiler/_transpiler.py
+++ b/qiskit/transpiler/_transpiler.py
@@ -7,6 +7,7 @@
 
 """Tools for compiling a batch of quantum circuits."""
 import logging
+import warnings
 
 from qiskit.circuit import QuantumCircuit
 from qiskit.mapper import CouplingMap, swap_mapper
@@ -16,7 +17,6 @@
 from qiskit.extensions.standard import SwapGate
 from qiskit.mapper import Layout
 
-
 from .passes.cx_cancellation import CXCancellation
 from .passes.decompose import Decompose
 from .passes.optimize_1q_gates import Optimize1qGates
@@ -39,7 +39,8 @@ def transpile(circuits, backend=None, basis_gates=None, coupling_map=None,
     Args:
         circuits (QuantumCircuit or list[QuantumCircuit]): circuits to compile
         backend (BaseBackend): a backend to compile for
-        basis_gates (str): comma-separated basis gate set to compile to
+        basis_gates (list[str]): list of basis gate names supported by the
+            target. Default: ['u1','u2','u3','cx','id']
         coupling_map (list): coupling map (perhaps custom) to target in mapping
         initial_layout (list): initial layout of qubits in mapping
         seed_mapper (int): random seed for the swap_mapper
@@ -57,7 +58,7 @@ def transpile(circuits, backend=None, basis_gates=None, coupling_map=None,
         return_form_is_single = True
 
     # Check for valid parameters for the experiments.
-    basis_gates = basis_gates or ','.join(backend.configuration().basis_gates)
+    basis_gates = basis_gates or backend.configuration().basis_gates
     coupling_map = coupling_map or getattr(backend.configuration(),
                                            'coupling_map', None)
 
@@ -82,7 +83,8 @@ def _transpilation(circuit, basis_gates=None, coupling_map=None,
 
     Args:
         circuit (QuantumCircuit): A circuit to transpile.
-        basis_gates (str): comma-separated basis gate set to compile to
+        basis_gates (list[str]): list of basis gate names supported by the
+            target. Default: ['u1','u2','u3','cx','id']
         coupling_map (list): coupling map (perhaps custom) to target in mapping
         initial_layout (list): initial layout of qubits in mapping
         seed_mapper (int): random seed for the swap_mapper
@@ -133,14 +135,15 @@ def _transpilation(circuit, basis_gates=None, coupling_map=None,
 
 
 # pylint: disable=redefined-builtin
-def transpile_dag(dag, basis_gates='u1,u2,u3,cx,id', coupling_map=None,
+def transpile_dag(dag, basis_gates=None, coupling_map=None,
                   initial_layout=None, seed_mapper=None, pass_manager=None):
     """Transform a dag circuit into another dag circuit (transpile), through
     consecutive passes on the dag.
 
     Args:
         dag (DAGCircuit): dag circuit to transform via transpilation
-        basis_gates (str): a comma separated string for the target basis gates
+        basis_gates (list[str]): list of basis gate names supported by the
+            target. Default: ['u1','u2','u3','cx','id']
         coupling_map (list): A graph of coupling::
 
             [
@@ -180,7 +183,14 @@ def transpile_dag(dag, basis_gates='u1,u2,u3,cx,id', coupling_map=None,
     if num_qubits == 1 or coupling_map == "all-to-all":
         coupling_map = None
 
-    final_layout = None
+    if basis_gates is None:
+        basis_gates = ['u1', 'u2', 'u3', 'cx', 'id']
+    if isinstance(basis_gates, str):
+        warnings.warn("The parameter basis_gates is now a list of strings. "
+                      "For example, this basis ['u1','u2','u3','cx'] should be used "
+                      "instead of 'u1,u2,u3,cx'. The string format will be "
+                      "removed after 0.9", DeprecationWarning, 2)
+        basis_gates = basis_gates.split(',')
 
     if pass_manager:
         # run the passes specified by the pass manager
@@ -189,10 +199,9 @@ def transpile_dag(dag, basis_gates='u1,u2,u3,cx,id', coupling_map=None,
     else:
         # default set of passes
         # TODO: move each step here to a pass, and use a default passmanager below
-        basis = basis_gates.split(',') if basis_gates else []
         name = dag.name
 
-        dag = Unroller(basis).run(dag)
+        dag = Unroller(basis_gates).run(dag)
         dag = BarrierBeforeFinalMeasurements().run(dag)
 
         # if a coupling map is given compile to the map


Test patch:
diff --git a/test/python/transpiler/test_transpile.py b/test/python/transpiler/test_transpile.py
--- a/test/python/transpiler/test_transpile.py
+++ b/test/python/transpiler/test_transpile.py
@@ -60,7 +60,7 @@ def test_pass_manager_none(self):
         circuit.cx(qr[0], qr[1])
 
         coupling_map = [[1, 0]]
-        basis_gates = 'u1,u2,u3,cx,id'
+        basis_gates = ['u1', 'u2', 'u3', 'cx', 'id']
 
         backend = BasicAer.get_backend('qasm_simulator')
         circuit2 = transpile(circuit, backend, coupling_map=coupling_map, basis_gates=basis_gates,