Repository: Qiskit/qiskit

Issue:
Adding `__repr__` method for the `DAGNode` object
<!-- ⚠️ 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. -->

### Current Behaviour
There does not exist any representation method for the `qiskit.dagcircuit.dagnode.DAGNode` object as of yet

### What is the expected behavior?
Just like a `Qubit` object, a `DAGNode` should be more informative and allow a user to get a basic idea about the information it contains.

### Suggested changes
A `__repr__` method for the `DAGNode` which displays basic attribute information like `qargs`, `cargs` and `type` for the `DAGNode` object




Discussion:
Re-opening as I think this would be a useful improvement, especially if it could be incorporated into the `dag_drawer`. Feel free to let me know if there was another reason for closing this.
I thought this wasn't really necessary at the moment as there was no response. I'd be happy to add the `__repr__` method.

Resolving patch:
diff --git a/qiskit/dagcircuit/dagnode.py b/qiskit/dagcircuit/dagnode.py
--- a/qiskit/dagcircuit/dagnode.py
+++ b/qiskit/dagcircuit/dagnode.py
@@ -341,6 +341,10 @@ def name(self, new_name):
         """Sets the Instruction name corresponding to the op for this node"""
         self.op.name = new_name
 
+    def __repr__(self):
+        """Returns a representation of the DAGOpNode"""
+        return f"DAGOpNode(op={self.op}, qargs={self.qargs}, cargs={self.cargs})"
+
 
 class DAGInNode(DAGNode):
     """Object to represent an incoming wire node in the DAGCircuit."""
@@ -356,6 +360,10 @@ def __init__(self, wire):
         # only works as str([]) for DAGInNodes. Need to figure out why.
         self.sort_key = str([])
 
+    def __repr__(self):
+        """Returns a representation of the DAGInNode"""
+        return f"DAGInNode(wire={self.wire})"
+
 
 class DAGOutNode(DAGNode):
     """Object to represent an outgoing wire node in the DAGCircuit."""
@@ -370,3 +378,7 @@ def __init__(self, wire):
         # TODO sort_key which is used in dagcircuit.topological_nodes
         # only works as str([]) for DAGOutNodes. Need to figure out why.
         self.sort_key = str([])
+
+    def __repr__(self):
+        """Returns a representation of the DAGOutNode"""
+        return f"DAGOutNode(wire={self.wire})"


Test patch:
diff --git a/test/python/dagcircuit/test_dagcircuit.py b/test/python/dagcircuit/test_dagcircuit.py
--- a/test/python/dagcircuit/test_dagcircuit.py
+++ b/test/python/dagcircuit/test_dagcircuit.py
@@ -602,6 +602,24 @@ def test_get_op_nodes_all(self):
         for node in op_nodes:
             self.assertIsInstance(node.op, Instruction)
 
+    def test_node_representations(self):
+        """Test the __repr__ methods of the DAG Nodes"""
+        self.dag.apply_operation_back(CXGate(), [self.qubit0, self.qubit1], [])
+        # test OpNode
+        cx_node = self.dag.named_nodes("cx")[0]
+        self.assertEqual(
+            repr(cx_node),
+            f"DAGOpNode(op={cx_node.op}, qargs={cx_node.qargs}, cargs={cx_node.cargs})",
+        )
+        # test InNode
+        predecessor_cnot = self.dag.quantum_predecessors(cx_node)
+        predecessor = next(predecessor_cnot)
+        self.assertEqual(repr(predecessor), f"DAGInNode(wire={predecessor.wire})")
+        # test OutNode
+        successor_cnot = self.dag.quantum_successors(cx_node)
+        successor = next(successor_cnot)
+        self.assertEqual(repr(successor), f"DAGOutNode(wire={successor.wire})")
+
     def test_get_op_nodes_particular(self):
         """The method dag.gates_nodes(op=AGate) returns all the AGate nodes"""
         self.dag.apply_operation_back(HGate(), [self.qubit0], [])