-
Notifications
You must be signed in to change notification settings - Fork 2.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve error message in DAGCircuit.draw
for invalid filenames
#7447
Changes from 2 commits
df440b7
9b520b7
27bd229
74aded3
c121767
6fec1c2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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,63 @@ | |
except ImportError: | ||
HAS_PIL = False | ||
|
||
FILENAME_EXTENSIONS = [ | ||
"bmp", | ||
"canon", | ||
"cgimage", | ||
"cmap", | ||
"cmapx", | ||
"cmapx_np", | ||
"dot", | ||
"dot_json", | ||
"eps exr", | ||
jakelishman marked this conversation as resolved.
Show resolved
Hide resolved
|
||
"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 +116,7 @@ def dag_drawer(dag, scale=0.7, filename=None, style="color"): | |
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 +224,14 @@ def edge_attr_func(edge): | |
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: | ||
jakelishman marked this conversation as resolved.
Show resolved
Hide resolved
|
||
raise InvalidFileError( | ||
"Filename extension must be one of: " | ||
+ " ".join([str(elem) for elem in FILENAME_EXTENSIONS]) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. All the elements in |
||
) | ||
dot.write(filename, format=extension) | ||
return None | ||
elif ("ipykernel" in sys.modules) and ("spyder" not in sys.modules): | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,6 +17,7 @@ | |
from qiskit import QuantumRegister, QuantumCircuit | ||
from qiskit.test import QiskitTestCase | ||
from qiskit.tools.visualization import dag_drawer | ||
from qiskit.exceptions import InvalidFileError | ||
from qiskit.visualization.exceptions import VisualizationError | ||
from qiskit.converters import circuit_to_dag | ||
|
||
|
@@ -36,6 +37,32 @@ def test_dag_drawer_invalid_style(self): | |
"""Test dag draw with invalid style.""" | ||
self.assertRaises(VisualizationError, dag_drawer, self.dag, style="multicolor") | ||
|
||
def test_dag_drawer_checks_filename_correct_format(self): | ||
"""filename must contain name and extension""" | ||
try: | ||
dag_drawer(self.dag, filename="aaabc") | ||
self.fail("Expected error not raised!") | ||
except InvalidFileError as exception_instance: | ||
self.assertEqual( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here, and in the next test, a clearer way of writing these tests of exceptions is with self.assertRaisesRegex(InvalidFileError, "Parameter 'filename' must be in format 'name.extension'"):
dag_drawer(self.dag, filename="aaabc") |
||
exception_instance.message, | ||
"Parameter 'filename' must be in format 'name.extension'", | ||
) | ||
|
||
def test_dag_drawer_checks_filename_extension(self): | ||
"""filename must have a valid extension""" | ||
try: | ||
dag_drawer(self.dag, filename="aa.abc") | ||
self.fail("Expected error not raised!") | ||
except InvalidFileError as exception_instance: | ||
self.assertEqual( | ||
exception_instance.message, | ||
"Filename extension must be one of: 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", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We might not want to test that exactly this set of extensions are supported - it'll be ok just to test that the message starts with "Filename extension must be one of:" |
||
) | ||
|
||
|
||
if __name__ == "__main__": | ||
unittest.main(verbosity=2) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where did you find this full list? Perhaps we could cut it down to some more common ones - I think things like
cmapx_np
might be a bit more noise than use.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pydot library was throwing a exception with all those extensions...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, I see - it's the failing output of
dot -Tunknown
.