We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
dag_drawer should check the existence of filename extension
### Information

- **Qiskit Terra version**: 0.10.0.dev0+831d942
- **Python version**: 3.7
- **Operating system**: Mac

### What is the current behavior?

If a filename without extension is passed to the function `dag_drawer`, this [line](https://github.com/Qiskit/qiskit-terra/blob/d090eca91dc1afdb68f563885c4ccf13b31de20e/qiskit/visualization/dag_visualization.py#L91) reports two errors:
```
nxpd.pydot.InvocationException: Program terminated with status: 1. stderr follows: Format: "XXXXX" not recognized. Use one of: ......
During handling of the above exception, another exception occurred:
qiskit.visualization.exceptions.VisualizationError: 'dag_drawer requires GraphViz installed in the system. Check https://www.graphviz.org/download/ for details on how to install GraphViz in your system.'
```

This is confusing because the second error thrown by Qiskit is not the cause of the problem.

### Steps to reproduce the problem

Try `dag_drawer(dag, filename='abc')`

### What is the expected behavior? 

Make the error catching better.

### Suggested solutions

We could either catch this error by reading and filtering the error message, or we could check the existence of the filename's extension, and provide a default one.


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `qiskit/exceptions.py`
Content:
```
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 """Exceptions for errors raised by Qiskit."""
14 
15 from typing import Optional
16 import warnings
17 
18 
19 class QiskitError(Exception):
20     """Base class for errors raised by Qiskit."""
21 
22     def __init__(self, *message):
23         """Set the error message."""
24         super().__init__(" ".join(message))
25         self.message = " ".join(message)
26 
27     def __str__(self):
28         """Return the message."""
29         return repr(self.message)
30 
31 
32 class QiskitIndexError(QiskitError, IndexError):
33     """Raised when a sequence subscript is out of range."""
34 
35     def __init__(self, *args):
36         """Set the error message."""
37         warnings.warn(
38             "QiskitIndexError class is being deprecated and it is going to be remove in the future",
39             DeprecationWarning,
40             stacklevel=2,
41         )
42         super().__init__(*args)
43 
44 
45 class QiskitUserConfigError(QiskitError):
46     """Raised when an error is encountered reading a user config file."""
47 
48     message = "User config invalid"
49 
50 
51 class MissingOptionalLibraryError(QiskitError, ImportError):
52     """Raised when an optional library is missing."""
53 
54     def __init__(
55         self, libname: str, name: str, pip_install: Optional[str] = None, msg: Optional[str] = None
56     ) -> None:
57         """Set the error message.
58         Args:
59             libname: Name of missing library
60             name: Name of class, function, module that uses this library
61             pip_install: pip install command, if any
62             msg: Descriptive message, if any
63         """
64         message = [f"The '{libname}' library is required to use '{name}'."]
65         if pip_install:
66             message.append(f"You can install it with '{pip_install}'.")
67         if msg:
68             message.append(f" {msg}.")
69 
70         super().__init__(" ".join(message))
71         self.message = " ".join(message)
72 
73     def __str__(self) -> str:
74         """Return the message."""
75         return repr(self.message)
76
```

Path: `qiskit/visualization/dag_visualization.py`
Content:
```
1 # This code is part of Qiskit.
2 #
3 # (C) Copyright IBM 2017, 2018, 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 # pylint: disable=invalid-name
14 
15 """
16 Visualization function for DAG circuit representation.
17 """
18 
19 import os
20 import sys
21 import tempfile
22 
23 from qiskit.dagcircuit.dagnode import DAGOpNode, DAGInNode, DAGOutNode
24 from qiskit.exceptions import MissingOptionalLibraryError
25 from .exceptions import VisualizationError
26 
27 try:
28     from PIL import Image
29 
30     HAS_PIL = True
31 except ImportError:
32     HAS_PIL = False
33 
34 
35 def dag_drawer(dag, scale=0.7, filename=None, style="color"):
36     """Plot the directed acyclic graph (dag) to represent operation dependencies
37     in a quantum circuit.
38 
39     Note this function leverages
40     `pydot <https://github.com/erocarrera/pydot>`_ to generate the graph, which
41     means that having `Graphviz <https://www.graphviz.org/>`_ installed on your
42     system is required for this to work.
43 
44     The current release of Graphviz can be downloaded here: <https://graphviz.gitlab.io/download/>.
45     Download the version of the software that matches your environment and follow the instructions
46     to install Graph Visualization Software (Graphviz) on your operating system.
47 
48     Args:
49         dag (DAGCircuit): The dag to draw.
50         scale (float): scaling factor
51         filename (str): file path to save image to (format inferred from name)
52         style (str): 'plain': B&W graph
53                      'color' (default): color input/output/op nodes
54 
55     Returns:
56         PIL.Image: if in Jupyter notebook and not saving to file,
57             otherwise None.
58 
59     Raises:
60         VisualizationError: when style is not recognized.
61         MissingOptionalLibraryError: when pydot or pillow are not installed.
62 
63     Example:
64         .. jupyter-execute::
65 
66             %matplotlib inline
67             from qiskit import QuantumRegister, ClassicalRegister, QuantumCircuit
68             from qiskit.dagcircuit import DAGCircuit
69             from qiskit.converters import circuit_to_dag
70             from qiskit.visualization import dag_drawer
71 
72             q = QuantumRegister(3, 'q')
73             c = ClassicalRegister(3, 'c')
74             circ = QuantumCircuit(q, c)
75             circ.h(q[0])
76             circ.cx(q[0], q[1])
77             circ.measure(q[0], c[0])
78             circ.rz(0.5, q[1]).c_if(c, 2)
79 
80             dag = circuit_to_dag(circ)
81             dag_drawer(dag)
82     """
83     try:
84         import pydot
85     except ImportError as ex:
86         raise MissingOptionalLibraryError(
87             libname="PyDot",
88             name="dag_drawer",
89             pip_install="pip install pydot",
90         ) from ex
91     # NOTE: use type str checking to avoid potential cyclical import
92     # the two tradeoffs ere that it will not handle subclasses and it is
93     # slower (which doesn't matter for a visualization function)
94     type_str = str(type(dag))
95     if "DAGDependency" in type_str:
96         graph_attrs = {"dpi": str(100 * scale)}
97 
98         def node_attr_func(node):
99             if style == "plain":
100                 return {}
101             if style == "color":
102                 n = {}
103                 n["label"] = str(node.node_id) + ": " + str(node.name)
104                 if node.name == "measure":
105                     n["color"] = "blue"
106                     n["style"] = "filled"
107                     n["fillcolor"] = "lightblue"
108                 if node.name == "barrier":
109                     n["color"] = "black"
110                     n["style"] = "filled"
111                     n["fillcolor"] = "green"
112                 if node.op._directive:
113                     n["color"] = "black"
114                     n["style"] = "filled"
115                     n["fillcolor"] = "red"
116                 if node.op.condition:
117                     n["label"] = str(node.node_id) + ": " + str(node.name) + " (conditional)"
118                     n["color"] = "black"
119                     n["style"] = "filled"
120                     n["fillcolor"] = "lightgreen"
121                 return n
122             else:
123                 raise VisualizationError("Unrecognized style %s for the dag_drawer." % style)
124 
125         edge_attr_func = None
126 
127     else:
128         bit_labels = {
129             bit: f"{reg.name}[{idx}]"
130             for reg in list(dag.qregs.values()) + list(dag.cregs.values())
131             for (idx, bit) in enumerate(reg)
132         }
133 
134         graph_attrs = {"dpi": str(100 * scale)}
135 
136         def node_attr_func(node):
137             if style == "plain":
138                 return {}
139             if style == "color":
140                 n = {}
141                 if isinstance(node, DAGOpNode):
142                     n["label"] = node.name
143                     n["color"] = "blue"
144                     n["style"] = "filled"
145                     n["fillcolor"] = "lightblue"
146                 if isinstance(node, DAGInNode):
147                     n["label"] = bit_labels[node.wire]
148                     n["color"] = "black"
149                     n["style"] = "filled"
150                     n["fillcolor"] = "green"
151                 if isinstance(node, DAGOutNode):
152                     n["label"] = bit_labels[node.wire]
153                     n["color"] = "black"
154                     n["style"] = "filled"
155                     n["fillcolor"] = "red"
156                 return n
157             else:
158                 raise VisualizationError("Invalid style %s" % style)
159 
160         def edge_attr_func(edge):
161             e = {}
162             e["label"] = bit_labels[edge]
163             return e
164 
165     dot_str = dag._multi_graph.to_dot(node_attr_func, edge_attr_func, graph_attrs)
166     dot = pydot.graph_from_dot_data(dot_str)[0]
167 
168     if filename:
169         extension = filename.split(".")[-1]
170         dot.write(filename, format=extension)
171         return None
172     elif ("ipykernel" in sys.modules) and ("spyder" not in sys.modules):
173         if not HAS_PIL:
174             raise MissingOptionalLibraryError(
175                 libname="pillow",
176                 name="dag_drawer",
177                 pip_install="pip install pillow",
178             )
179 
180         with tempfile.TemporaryDirectory() as tmpdirname:
181             tmp_path = os.path.join(tmpdirname, "dag.png")
182             dot.write_png(tmp_path)
183             with Image.open(tmp_path) as test_image:
184                 image = test_image.copy()
185             os.remove(tmp_path)
186             return image
187     else:
188         if not HAS_PIL:
189             raise MissingOptionalLibraryError(
190                 libname="pillow",
191                 name="dag_drawer",
192                 pip_install="pip install pillow",
193             )
194         with tempfile.TemporaryDirectory() as tmpdirname:
195             tmp_path = os.path.join(tmpdirname, "dag.png")
196             dot.write_png(tmp_path)
197             image = Image.open(tmp_path)
198             image.show()
199             os.remove(tmp_path)
200             return None
201
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/qiskit/exceptions.py b/qiskit/exceptions.py
--- a/qiskit/exceptions.py
+++ b/qiskit/exceptions.py
@@ -73,3 +73,7 @@
     def __str__(self) -> str:
         """Return the message."""
         return repr(self.message)
+
+
+class InvalidFileError(QiskitError):
+    """Raised when the file provided is not valid for the specific task."""
diff --git a/qiskit/visualization/dag_visualization.py b/qiskit/visualization/dag_visualization.py
--- a/qiskit/visualization/dag_visualization.py
+++ b/qiskit/visualization/dag_visualization.py
@@ -21,7 +21,7 @@
 import tempfile
 
 from qiskit.dagcircuit.dagnode import DAGOpNode, DAGInNode, DAGOutNode
-from qiskit.exceptions import MissingOptionalLibraryError
+from qiskit.exceptions import MissingOptionalLibraryError, InvalidFileError
 from .exceptions import VisualizationError
 
 try:
@@ -31,6 +31,64 @@
 except ImportError:
     HAS_PIL = False
 
+FILENAME_EXTENSIONS = {
+    "bmp",
+    "canon",
+    "cgimage",
+    "cmap",
+    "cmapx",
+    "cmapx_np",
+    "dot",
+    "dot_json",
+    "eps",
+    "exr",
+    "fig",
+    "gd",
+    "gd2",
+    "gif",
+    "gv",
+    "icns",
+    "ico",
+    "imap",
+    "imap_np",
+    "ismap",
+    "jp2",
+    "jpe",
+    "jpeg",
+    "jpg",
+    "json",
+    "json0",
+    "mp",
+    "pct",
+    "pdf",
+    "pic",
+    "pict",
+    "plain",
+    "plain-ext",
+    "png",
+    "pov",
+    "ps",
+    "ps2",
+    "psd",
+    "sgi",
+    "svg",
+    "svgz",
+    "tga",
+    "tif",
+    "tiff",
+    "tk",
+    "vdx",
+    "vml",
+    "vmlz",
+    "vrml",
+    "wbmp",
+    "webp",
+    "xdot",
+    "xdot1.2",
+    "xdot1.4",
+    "xdot_json",
+}
+
 
 def dag_drawer(dag, scale=0.7, filename=None, style="color"):
     """Plot the directed acyclic graph (dag) to represent operation dependencies
@@ -59,6 +117,7 @@
     Raises:
         VisualizationError: when style is not recognized.
         MissingOptionalLibraryError: when pydot or pillow are not installed.
+        InvalidFileError: when filename provided is not valid
 
     Example:
         .. jupyter-execute::
@@ -166,7 +225,13 @@
     dot = pydot.graph_from_dot_data(dot_str)[0]
 
     if filename:
+        if "." not in filename:
+            raise InvalidFileError("Parameter 'filename' must be in format 'name.extension'")
         extension = filename.split(".")[-1]
+        if extension not in FILENAME_EXTENSIONS:
+            raise InvalidFileError(
+                "Filename extension must be one of: " + " ".join(FILENAME_EXTENSIONS)
+            )
         dot.write(filename, format=extension)
         return None
     elif ("ipykernel" in sys.modules) and ("spyder" not in sys.modules):

{"golden_diff": "diff --git a/qiskit/exceptions.py b/qiskit/exceptions.py\n--- a/qiskit/exceptions.py\n+++ b/qiskit/exceptions.py\n@@ -73,3 +73,7 @@\n     def __str__(self) -> str:\n         \"\"\"Return the message.\"\"\"\n         return repr(self.message)\n+\n+\n+class InvalidFileError(QiskitError):\n+    \"\"\"Raised when the file provided is not valid for the specific task.\"\"\"\ndiff --git a/qiskit/visualization/dag_visualization.py b/qiskit/visualization/dag_visualization.py\n--- a/qiskit/visualization/dag_visualization.py\n+++ b/qiskit/visualization/dag_visualization.py\n@@ -21,7 +21,7 @@\n import tempfile\n \n from qiskit.dagcircuit.dagnode import DAGOpNode, DAGInNode, DAGOutNode\n-from qiskit.exceptions import MissingOptionalLibraryError\n+from qiskit.exceptions import MissingOptionalLibraryError, InvalidFileError\n from .exceptions import VisualizationError\n \n try:\n@@ -31,6 +31,64 @@\n except ImportError:\n     HAS_PIL = False\n \n+FILENAME_EXTENSIONS = {\n+    \"bmp\",\n+    \"canon\",\n+    \"cgimage\",\n+    \"cmap\",\n+    \"cmapx\",\n+    \"cmapx_np\",\n+    \"dot\",\n+    \"dot_json\",\n+    \"eps\",\n+    \"exr\",\n+    \"fig\",\n+    \"gd\",\n+    \"gd2\",\n+    \"gif\",\n+    \"gv\",\n+    \"icns\",\n+    \"ico\",\n+    \"imap\",\n+    \"imap_np\",\n+    \"ismap\",\n+    \"jp2\",\n+    \"jpe\",\n+    \"jpeg\",\n+    \"jpg\",\n+    \"json\",\n+    \"json0\",\n+    \"mp\",\n+    \"pct\",\n+    \"pdf\",\n+    \"pic\",\n+    \"pict\",\n+    \"plain\",\n+    \"plain-ext\",\n+    \"png\",\n+    \"pov\",\n+    \"ps\",\n+    \"ps2\",\n+    \"psd\",\n+    \"sgi\",\n+    \"svg\",\n+    \"svgz\",\n+    \"tga\",\n+    \"tif\",\n+    \"tiff\",\n+    \"tk\",\n+    \"vdx\",\n+    \"vml\",\n+    \"vmlz\",\n+    \"vrml\",\n+    \"wbmp\",\n+    \"webp\",\n+    \"xdot\",\n+    \"xdot1.2\",\n+    \"xdot1.4\",\n+    \"xdot_json\",\n+}\n+\n \n def dag_drawer(dag, scale=0.7, filename=None, style=\"color\"):\n     \"\"\"Plot the directed acyclic graph (dag) to represent operation dependencies\n@@ -59,6 +117,7 @@\n     Raises:\n         VisualizationError: when style is not recognized.\n         MissingOptionalLibraryError: when pydot or pillow are not installed.\n+        InvalidFileError: when filename provided is not valid\n \n     Example:\n         .. jupyter-execute::\n@@ -166,7 +225,13 @@\n     dot = pydot.graph_from_dot_data(dot_str)[0]\n \n     if filename:\n+        if \".\" not in filename:\n+            raise InvalidFileError(\"Parameter 'filename' must be in format 'name.extension'\")\n         extension = filename.split(\".\")[-1]\n+        if extension not in FILENAME_EXTENSIONS:\n+            raise InvalidFileError(\n+                \"Filename extension must be one of: \" + \" \".join(FILENAME_EXTENSIONS)\n+            )\n         dot.write(filename, format=extension)\n         return None\n     elif (\"ipykernel\" in sys.modules) and (\"spyder\" not in sys.modules):\n", "issue": "dag_drawer should check the existence of filename extension\n### Information\r\n\r\n- **Qiskit Terra version**: 0.10.0.dev0+831d942\r\n- **Python version**: 3.7\r\n- **Operating system**: Mac\r\n\r\n### What is the current behavior?\r\n\r\nIf a filename without extension is passed to the function `dag_drawer`, this [line](https://github.com/Qiskit/qiskit-terra/blob/d090eca91dc1afdb68f563885c4ccf13b31de20e/qiskit/visualization/dag_visualization.py#L91) reports two errors:\r\n```\r\nnxpd.pydot.InvocationException: Program terminated with status: 1. stderr follows: Format: \"XXXXX\" not recognized. Use one of: ......\r\nDuring handling of the above exception, another exception occurred:\r\nqiskit.visualization.exceptions.VisualizationError: 'dag_drawer requires GraphViz installed in the system. Check https://www.graphviz.org/download/ for details on how to install GraphViz in your system.'\r\n```\r\n\r\nThis is confusing because the second error thrown by Qiskit is not the cause of the problem.\r\n\r\n### Steps to reproduce the problem\r\n\r\nTry `dag_drawer(dag, filename='abc')`\r\n\r\n### What is the expected behavior? \r\n\r\nMake the error catching better.\r\n\r\n### Suggested solutions\r\n\r\nWe could either catch this error by reading and filtering the error message, or we could check the existence of the filename's extension, and provide a default one.\r\n\n", "before_files": [{"content": "# This code is part of Qiskit.\n#\n# (C) Copyright IBM 2017, 2020.\n#\n# This code is licensed under the Apache License, Version 2.0. You may\n# obtain a copy of this license in the LICENSE.txt file in the root directory\n# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.\n#\n# Any modifications or derivative works of this code must retain this\n# copyright notice, and modified files need to carry a notice indicating\n# that they have been altered from the originals.\n\n\"\"\"Exceptions for errors raised by Qiskit.\"\"\"\n\nfrom typing import Optional\nimport warnings\n\n\nclass QiskitError(Exception):\n    \"\"\"Base class for errors raised by Qiskit.\"\"\"\n\n    def __init__(self, *message):\n        \"\"\"Set the error message.\"\"\"\n        super().__init__(\" \".join(message))\n        self.message = \" \".join(message)\n\n    def __str__(self):\n        \"\"\"Return the message.\"\"\"\n        return repr(self.message)\n\n\nclass QiskitIndexError(QiskitError, IndexError):\n    \"\"\"Raised when a sequence subscript is out of range.\"\"\"\n\n    def __init__(self, *args):\n        \"\"\"Set the error message.\"\"\"\n        warnings.warn(\n            \"QiskitIndexError class is being deprecated and it is going to be remove in the future\",\n            DeprecationWarning,\n            stacklevel=2,\n        )\n        super().__init__(*args)\n\n\nclass QiskitUserConfigError(QiskitError):\n    \"\"\"Raised when an error is encountered reading a user config file.\"\"\"\n\n    message = \"User config invalid\"\n\n\nclass MissingOptionalLibraryError(QiskitError, ImportError):\n    \"\"\"Raised when an optional library is missing.\"\"\"\n\n    def __init__(\n        self, libname: str, name: str, pip_install: Optional[str] = None, msg: Optional[str] = None\n    ) -> None:\n        \"\"\"Set the error message.\n        Args:\n            libname: Name of missing library\n            name: Name of class, function, module that uses this library\n            pip_install: pip install command, if any\n            msg: Descriptive message, if any\n        \"\"\"\n        message = [f\"The '{libname}' library is required to use '{name}'.\"]\n        if pip_install:\n            message.append(f\"You can install it with '{pip_install}'.\")\n        if msg:\n            message.append(f\" {msg}.\")\n\n        super().__init__(\" \".join(message))\n        self.message = \" \".join(message)\n\n    def __str__(self) -> str:\n        \"\"\"Return the message.\"\"\"\n        return repr(self.message)\n", "path": "qiskit/exceptions.py"}, {"content": "# This code is part of Qiskit.\n#\n# (C) Copyright IBM 2017, 2018, 2020.\n#\n# This code is licensed under the Apache License, Version 2.0. You may\n# obtain a copy of this license in the LICENSE.txt file in the root directory\n# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.\n#\n# Any modifications or derivative works of this code must retain this\n# copyright notice, and modified files need to carry a notice indicating\n# that they have been altered from the originals.\n\n# pylint: disable=invalid-name\n\n\"\"\"\nVisualization function for DAG circuit representation.\n\"\"\"\n\nimport os\nimport sys\nimport tempfile\n\nfrom qiskit.dagcircuit.dagnode import DAGOpNode, DAGInNode, DAGOutNode\nfrom qiskit.exceptions import MissingOptionalLibraryError\nfrom .exceptions import VisualizationError\n\ntry:\n    from PIL import Image\n\n    HAS_PIL = True\nexcept ImportError:\n    HAS_PIL = False\n\n\ndef dag_drawer(dag, scale=0.7, filename=None, style=\"color\"):\n    \"\"\"Plot the directed acyclic graph (dag) to represent operation dependencies\n    in a quantum circuit.\n\n    Note this function leverages\n    `pydot <https://github.com/erocarrera/pydot>`_ to generate the graph, which\n    means that having `Graphviz <https://www.graphviz.org/>`_ installed on your\n    system is required for this to work.\n\n    The current release of Graphviz can be downloaded here: <https://graphviz.gitlab.io/download/>.\n    Download the version of the software that matches your environment and follow the instructions\n    to install Graph Visualization Software (Graphviz) on your operating system.\n\n    Args:\n        dag (DAGCircuit): The dag to draw.\n        scale (float): scaling factor\n        filename (str): file path to save image to (format inferred from name)\n        style (str): 'plain': B&W graph\n                     'color' (default): color input/output/op nodes\n\n    Returns:\n        PIL.Image: if in Jupyter notebook and not saving to file,\n            otherwise None.\n\n    Raises:\n        VisualizationError: when style is not recognized.\n        MissingOptionalLibraryError: when pydot or pillow are not installed.\n\n    Example:\n        .. jupyter-execute::\n\n            %matplotlib inline\n            from qiskit import QuantumRegister, ClassicalRegister, QuantumCircuit\n            from qiskit.dagcircuit import DAGCircuit\n            from qiskit.converters import circuit_to_dag\n            from qiskit.visualization import dag_drawer\n\n            q = QuantumRegister(3, 'q')\n            c = ClassicalRegister(3, 'c')\n            circ = QuantumCircuit(q, c)\n            circ.h(q[0])\n            circ.cx(q[0], q[1])\n            circ.measure(q[0], c[0])\n            circ.rz(0.5, q[1]).c_if(c, 2)\n\n            dag = circuit_to_dag(circ)\n            dag_drawer(dag)\n    \"\"\"\n    try:\n        import pydot\n    except ImportError as ex:\n        raise MissingOptionalLibraryError(\n            libname=\"PyDot\",\n            name=\"dag_drawer\",\n            pip_install=\"pip install pydot\",\n        ) from ex\n    # NOTE: use type str checking to avoid potential cyclical import\n    # the two tradeoffs ere that it will not handle subclasses and it is\n    # slower (which doesn't matter for a visualization function)\n    type_str = str(type(dag))\n    if \"DAGDependency\" in type_str:\n        graph_attrs = {\"dpi\": str(100 * scale)}\n\n        def node_attr_func(node):\n            if style == \"plain\":\n                return {}\n            if style == \"color\":\n                n = {}\n                n[\"label\"] = str(node.node_id) + \": \" + str(node.name)\n                if node.name == \"measure\":\n                    n[\"color\"] = \"blue\"\n                    n[\"style\"] = \"filled\"\n                    n[\"fillcolor\"] = \"lightblue\"\n                if node.name == \"barrier\":\n                    n[\"color\"] = \"black\"\n                    n[\"style\"] = \"filled\"\n                    n[\"fillcolor\"] = \"green\"\n                if node.op._directive:\n                    n[\"color\"] = \"black\"\n                    n[\"style\"] = \"filled\"\n                    n[\"fillcolor\"] = \"red\"\n                if node.op.condition:\n                    n[\"label\"] = str(node.node_id) + \": \" + str(node.name) + \" (conditional)\"\n                    n[\"color\"] = \"black\"\n                    n[\"style\"] = \"filled\"\n                    n[\"fillcolor\"] = \"lightgreen\"\n                return n\n            else:\n                raise VisualizationError(\"Unrecognized style %s for the dag_drawer.\" % style)\n\n        edge_attr_func = None\n\n    else:\n        bit_labels = {\n            bit: f\"{reg.name}[{idx}]\"\n            for reg in list(dag.qregs.values()) + list(dag.cregs.values())\n            for (idx, bit) in enumerate(reg)\n        }\n\n        graph_attrs = {\"dpi\": str(100 * scale)}\n\n        def node_attr_func(node):\n            if style == \"plain\":\n                return {}\n            if style == \"color\":\n                n = {}\n                if isinstance(node, DAGOpNode):\n                    n[\"label\"] = node.name\n                    n[\"color\"] = \"blue\"\n                    n[\"style\"] = \"filled\"\n                    n[\"fillcolor\"] = \"lightblue\"\n                if isinstance(node, DAGInNode):\n                    n[\"label\"] = bit_labels[node.wire]\n                    n[\"color\"] = \"black\"\n                    n[\"style\"] = \"filled\"\n                    n[\"fillcolor\"] = \"green\"\n                if isinstance(node, DAGOutNode):\n                    n[\"label\"] = bit_labels[node.wire]\n                    n[\"color\"] = \"black\"\n                    n[\"style\"] = \"filled\"\n                    n[\"fillcolor\"] = \"red\"\n                return n\n            else:\n                raise VisualizationError(\"Invalid style %s\" % style)\n\n        def edge_attr_func(edge):\n            e = {}\n            e[\"label\"] = bit_labels[edge]\n            return e\n\n    dot_str = dag._multi_graph.to_dot(node_attr_func, edge_attr_func, graph_attrs)\n    dot = pydot.graph_from_dot_data(dot_str)[0]\n\n    if filename:\n        extension = filename.split(\".\")[-1]\n        dot.write(filename, format=extension)\n        return None\n    elif (\"ipykernel\" in sys.modules) and (\"spyder\" not in sys.modules):\n        if not HAS_PIL:\n            raise MissingOptionalLibraryError(\n                libname=\"pillow\",\n                name=\"dag_drawer\",\n                pip_install=\"pip install pillow\",\n            )\n\n        with tempfile.TemporaryDirectory() as tmpdirname:\n            tmp_path = os.path.join(tmpdirname, \"dag.png\")\n            dot.write_png(tmp_path)\n            with Image.open(tmp_path) as test_image:\n                image = test_image.copy()\n            os.remove(tmp_path)\n            return image\n    else:\n        if not HAS_PIL:\n            raise MissingOptionalLibraryError(\n                libname=\"pillow\",\n                name=\"dag_drawer\",\n                pip_install=\"pip install pillow\",\n            )\n        with tempfile.TemporaryDirectory() as tmpdirname:\n            tmp_path = os.path.join(tmpdirname, \"dag.png\")\n            dot.write_png(tmp_path)\n            image = Image.open(tmp_path)\n            image.show()\n            os.remove(tmp_path)\n            return None\n", "path": "qiskit/visualization/dag_visualization.py"}], "after_files": [{"content": "# This code is part of Qiskit.\n#\n# (C) Copyright IBM 2017, 2020.\n#\n# This code is licensed under the Apache License, Version 2.0. You may\n# obtain a copy of this license in the LICENSE.txt file in the root directory\n# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.\n#\n# Any modifications or derivative works of this code must retain this\n# copyright notice, and modified files need to carry a notice indicating\n# that they have been altered from the originals.\n\n\"\"\"Exceptions for errors raised by Qiskit.\"\"\"\n\nfrom typing import Optional\nimport warnings\n\n\nclass QiskitError(Exception):\n    \"\"\"Base class for errors raised by Qiskit.\"\"\"\n\n    def __init__(self, *message):\n        \"\"\"Set the error message.\"\"\"\n        super().__init__(\" \".join(message))\n        self.message = \" \".join(message)\n\n    def __str__(self):\n        \"\"\"Return the message.\"\"\"\n        return repr(self.message)\n\n\nclass QiskitIndexError(QiskitError, IndexError):\n    \"\"\"Raised when a sequence subscript is out of range.\"\"\"\n\n    def __init__(self, *args):\n        \"\"\"Set the error message.\"\"\"\n        warnings.warn(\n            \"QiskitIndexError class is being deprecated and it is going to be remove in the future\",\n            DeprecationWarning,\n            stacklevel=2,\n        )\n        super().__init__(*args)\n\n\nclass QiskitUserConfigError(QiskitError):\n    \"\"\"Raised when an error is encountered reading a user config file.\"\"\"\n\n    message = \"User config invalid\"\n\n\nclass MissingOptionalLibraryError(QiskitError, ImportError):\n    \"\"\"Raised when an optional library is missing.\"\"\"\n\n    def __init__(\n        self, libname: str, name: str, pip_install: Optional[str] = None, msg: Optional[str] = None\n    ) -> None:\n        \"\"\"Set the error message.\n        Args:\n            libname: Name of missing library\n            name: Name of class, function, module that uses this library\n            pip_install: pip install command, if any\n            msg: Descriptive message, if any\n        \"\"\"\n        message = [f\"The '{libname}' library is required to use '{name}'.\"]\n        if pip_install:\n            message.append(f\"You can install it with '{pip_install}'.\")\n        if msg:\n            message.append(f\" {msg}.\")\n\n        super().__init__(\" \".join(message))\n        self.message = \" \".join(message)\n\n    def __str__(self) -> str:\n        \"\"\"Return the message.\"\"\"\n        return repr(self.message)\n\n\nclass InvalidFileError(QiskitError):\n    \"\"\"Raised when the file provided is not valid for the specific task.\"\"\"\n", "path": "qiskit/exceptions.py"}, {"content": "# This code is part of Qiskit.\n#\n# (C) Copyright IBM 2017, 2018, 2020.\n#\n# This code is licensed under the Apache License, Version 2.0. You may\n# obtain a copy of this license in the LICENSE.txt file in the root directory\n# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.\n#\n# Any modifications or derivative works of this code must retain this\n# copyright notice, and modified files need to carry a notice indicating\n# that they have been altered from the originals.\n\n# pylint: disable=invalid-name\n\n\"\"\"\nVisualization function for DAG circuit representation.\n\"\"\"\n\nimport os\nimport sys\nimport tempfile\n\nfrom qiskit.dagcircuit.dagnode import DAGOpNode, DAGInNode, DAGOutNode\nfrom qiskit.exceptions import MissingOptionalLibraryError, InvalidFileError\nfrom .exceptions import VisualizationError\n\ntry:\n    from PIL import Image\n\n    HAS_PIL = True\nexcept ImportError:\n    HAS_PIL = False\n\nFILENAME_EXTENSIONS = {\n    \"bmp\",\n    \"canon\",\n    \"cgimage\",\n    \"cmap\",\n    \"cmapx\",\n    \"cmapx_np\",\n    \"dot\",\n    \"dot_json\",\n    \"eps\",\n    \"exr\",\n    \"fig\",\n    \"gd\",\n    \"gd2\",\n    \"gif\",\n    \"gv\",\n    \"icns\",\n    \"ico\",\n    \"imap\",\n    \"imap_np\",\n    \"ismap\",\n    \"jp2\",\n    \"jpe\",\n    \"jpeg\",\n    \"jpg\",\n    \"json\",\n    \"json0\",\n    \"mp\",\n    \"pct\",\n    \"pdf\",\n    \"pic\",\n    \"pict\",\n    \"plain\",\n    \"plain-ext\",\n    \"png\",\n    \"pov\",\n    \"ps\",\n    \"ps2\",\n    \"psd\",\n    \"sgi\",\n    \"svg\",\n    \"svgz\",\n    \"tga\",\n    \"tif\",\n    \"tiff\",\n    \"tk\",\n    \"vdx\",\n    \"vml\",\n    \"vmlz\",\n    \"vrml\",\n    \"wbmp\",\n    \"webp\",\n    \"xdot\",\n    \"xdot1.2\",\n    \"xdot1.4\",\n    \"xdot_json\",\n}\n\n\ndef dag_drawer(dag, scale=0.7, filename=None, style=\"color\"):\n    \"\"\"Plot the directed acyclic graph (dag) to represent operation dependencies\n    in a quantum circuit.\n\n    Note this function leverages\n    `pydot <https://github.com/erocarrera/pydot>`_ to generate the graph, which\n    means that having `Graphviz <https://www.graphviz.org/>`_ installed on your\n    system is required for this to work.\n\n    The current release of Graphviz can be downloaded here: <https://graphviz.gitlab.io/download/>.\n    Download the version of the software that matches your environment and follow the instructions\n    to install Graph Visualization Software (Graphviz) on your operating system.\n\n    Args:\n        dag (DAGCircuit): The dag to draw.\n        scale (float): scaling factor\n        filename (str): file path to save image to (format inferred from name)\n        style (str): 'plain': B&W graph\n                     'color' (default): color input/output/op nodes\n\n    Returns:\n        PIL.Image: if in Jupyter notebook and not saving to file,\n            otherwise None.\n\n    Raises:\n        VisualizationError: when style is not recognized.\n        MissingOptionalLibraryError: when pydot or pillow are not installed.\n        InvalidFileError: when filename provided is not valid\n\n    Example:\n        .. jupyter-execute::\n\n            %matplotlib inline\n            from qiskit import QuantumRegister, ClassicalRegister, QuantumCircuit\n            from qiskit.dagcircuit import DAGCircuit\n            from qiskit.converters import circuit_to_dag\n            from qiskit.visualization import dag_drawer\n\n            q = QuantumRegister(3, 'q')\n            c = ClassicalRegister(3, 'c')\n            circ = QuantumCircuit(q, c)\n            circ.h(q[0])\n            circ.cx(q[0], q[1])\n            circ.measure(q[0], c[0])\n            circ.rz(0.5, q[1]).c_if(c, 2)\n\n            dag = circuit_to_dag(circ)\n            dag_drawer(dag)\n    \"\"\"\n    try:\n        import pydot\n    except ImportError as ex:\n        raise MissingOptionalLibraryError(\n            libname=\"PyDot\",\n            name=\"dag_drawer\",\n            pip_install=\"pip install pydot\",\n        ) from ex\n    # NOTE: use type str checking to avoid potential cyclical import\n    # the two tradeoffs ere that it will not handle subclasses and it is\n    # slower (which doesn't matter for a visualization function)\n    type_str = str(type(dag))\n    if \"DAGDependency\" in type_str:\n        graph_attrs = {\"dpi\": str(100 * scale)}\n\n        def node_attr_func(node):\n            if style == \"plain\":\n                return {}\n            if style == \"color\":\n                n = {}\n                n[\"label\"] = str(node.node_id) + \": \" + str(node.name)\n                if node.name == \"measure\":\n                    n[\"color\"] = \"blue\"\n                    n[\"style\"] = \"filled\"\n                    n[\"fillcolor\"] = \"lightblue\"\n                if node.name == \"barrier\":\n                    n[\"color\"] = \"black\"\n                    n[\"style\"] = \"filled\"\n                    n[\"fillcolor\"] = \"green\"\n                if node.op._directive:\n                    n[\"color\"] = \"black\"\n                    n[\"style\"] = \"filled\"\n                    n[\"fillcolor\"] = \"red\"\n                if node.op.condition:\n                    n[\"label\"] = str(node.node_id) + \": \" + str(node.name) + \" (conditional)\"\n                    n[\"color\"] = \"black\"\n                    n[\"style\"] = \"filled\"\n                    n[\"fillcolor\"] = \"lightgreen\"\n                return n\n            else:\n                raise VisualizationError(\"Unrecognized style %s for the dag_drawer.\" % style)\n\n        edge_attr_func = None\n\n    else:\n        bit_labels = {\n            bit: f\"{reg.name}[{idx}]\"\n            for reg in list(dag.qregs.values()) + list(dag.cregs.values())\n            for (idx, bit) in enumerate(reg)\n        }\n\n        graph_attrs = {\"dpi\": str(100 * scale)}\n\n        def node_attr_func(node):\n            if style == \"plain\":\n                return {}\n            if style == \"color\":\n                n = {}\n                if isinstance(node, DAGOpNode):\n                    n[\"label\"] = node.name\n                    n[\"color\"] = \"blue\"\n                    n[\"style\"] = \"filled\"\n                    n[\"fillcolor\"] = \"lightblue\"\n                if isinstance(node, DAGInNode):\n                    n[\"label\"] = bit_labels[node.wire]\n                    n[\"color\"] = \"black\"\n                    n[\"style\"] = \"filled\"\n                    n[\"fillcolor\"] = \"green\"\n                if isinstance(node, DAGOutNode):\n                    n[\"label\"] = bit_labels[node.wire]\n                    n[\"color\"] = \"black\"\n                    n[\"style\"] = \"filled\"\n                    n[\"fillcolor\"] = \"red\"\n                return n\n            else:\n                raise VisualizationError(\"Invalid style %s\" % style)\n\n        def edge_attr_func(edge):\n            e = {}\n            e[\"label\"] = bit_labels[edge]\n            return e\n\n    dot_str = dag._multi_graph.to_dot(node_attr_func, edge_attr_func, graph_attrs)\n    dot = pydot.graph_from_dot_data(dot_str)[0]\n\n    if filename:\n        if \".\" not in filename:\n            raise InvalidFileError(\"Parameter 'filename' must be in format 'name.extension'\")\n        extension = filename.split(\".\")[-1]\n        if extension not in FILENAME_EXTENSIONS:\n            raise InvalidFileError(\n                \"Filename extension must be one of: \" + \" \".join(FILENAME_EXTENSIONS)\n            )\n        dot.write(filename, format=extension)\n        return None\n    elif (\"ipykernel\" in sys.modules) and (\"spyder\" not in sys.modules):\n        if not HAS_PIL:\n            raise MissingOptionalLibraryError(\n                libname=\"pillow\",\n                name=\"dag_drawer\",\n                pip_install=\"pip install pillow\",\n            )\n\n        with tempfile.TemporaryDirectory() as tmpdirname:\n            tmp_path = os.path.join(tmpdirname, \"dag.png\")\n            dot.write_png(tmp_path)\n            with Image.open(tmp_path) as test_image:\n                image = test_image.copy()\n            os.remove(tmp_path)\n            return image\n    else:\n        if not HAS_PIL:\n            raise MissingOptionalLibraryError(\n                libname=\"pillow\",\n                name=\"dag_drawer\",\n                pip_install=\"pip install pillow\",\n            )\n        with tempfile.TemporaryDirectory() as tmpdirname:\n            tmp_path = os.path.join(tmpdirname, \"dag.png\")\n            dot.write_png(tmp_path)\n            image = Image.open(tmp_path)\n            image.show()\n            os.remove(tmp_path)\n            return None\n", "path": "qiskit/visualization/dag_visualization.py"}]}