Skip to content
This repository was archived by the owner on Nov 19, 2018. It is now read-only.

Commit c8fe7ce

Browse files
committed
Support Graphviz installed from Conda
Graphviz installed using Conda is using .bat scripts to correctly setup running it on Windows.
1 parent 197ea7d commit c8fe7ce

File tree

3 files changed

+113
-74
lines changed

3 files changed

+113
-74
lines changed

pydot_ng/__init__.py

+31-18
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,25 @@ def graph_from_incidence_matrix(matrix, node_prefix='', directed=False):
398398
return graph
399399

400400

401+
def is_quoted(path):
402+
return path.startswith('"') and path.endswith('"')
403+
404+
405+
def is_windows():
406+
return os.name == 'nt'
407+
408+
409+
def is_anacoda():
410+
return os.path.exists(os.path.join(sys.prefix, 'conda-meta'))
411+
412+
413+
def get_executable_extension():
414+
if is_windows():
415+
return '.bat' if is_anacoda() else '.exe'
416+
else:
417+
return ''
418+
419+
401420
def __find_executables(path):
402421
"""Used by find_graphviz
403422
@@ -409,7 +428,8 @@ def __find_executables(path):
409428
Otherwise returns None
410429
"""
411430

412-
success = False
431+
any_found = False
432+
413433
progs = {
414434
"dot": "",
415435
"twopi": "",
@@ -419,11 +439,12 @@ def __find_executables(path):
419439
"sfdp": "",
420440
}
421441

422-
was_quoted = False
423442
path = path.strip()
424-
if path.startswith('"') and path.endswith('"'):
443+
path_template = "{}"
444+
445+
if is_quoted(path):
425446
path = path[1:-1]
426-
was_quoted = True
447+
path_template = "\"{}\""
427448

428449
if not os.path.isdir(path):
429450
return None
@@ -432,22 +453,14 @@ def __find_executables(path):
432453
if progs[prg]:
433454
continue
434455

435-
prg_path = os.path.join(path, prg)
436-
prg_exe_path = prg_path + ".exe"
456+
ext = get_executable_extension()
457+
prg_path = os.path.join(path, prg + ext)
437458

438459
if os.path.exists(prg_path):
439-
if was_quoted:
440-
prg_path = "\"{}\"".format(prg_path)
441-
progs[prg] = prg_path
442-
success = True
443-
444-
elif os.path.exists(prg_exe_path):
445-
if was_quoted:
446-
prg_exe_path = "\"{}\"".format(prg_exe_path)
447-
progs[prg] = prg_exe_path
448-
success = True
449-
450-
if success:
460+
any_found = True
461+
progs[prg] = path_template.format(prg_path)
462+
463+
if any_found:
451464
return progs
452465

453466
return None

test/test_find_executables.py

+81
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import mock
2+
import pytest
3+
4+
import pydot_ng as pydot
5+
6+
7+
def touch(path):
8+
f = open(path, "w")
9+
f.close()
10+
11+
12+
def test_find_executables_fake_path():
13+
assert pydot.__find_executables("/fake/path/") is None
14+
15+
16+
def test_find_executables_real_path_no_programs(tmpdir):
17+
assert pydot.__find_executables(str(tmpdir)) is None
18+
19+
20+
def test_find_executables_path_needs_strip(tmpdir):
21+
path = tmpdir.mkdir("subdir")
22+
prog_path = str(path.join("dot"))
23+
24+
path_with_spaces = " {} ".format(path)
25+
26+
with open(prog_path, "w"):
27+
progs = pydot.__find_executables(path_with_spaces)
28+
assert progs["dot"] == prog_path
29+
assert sorted(
30+
("dot", "twopi", "neato", "circo", "fdp", "sfdp")
31+
) == sorted(progs)
32+
33+
34+
@pytest.mark.parametrize("quoted", (True, False), ids=("quoted", "unqoted"))
35+
@pytest.mark.parametrize(
36+
"windows,conda,extension",
37+
(
38+
(True, True, "bat"),
39+
(True, False, "exe"),
40+
(False, False, "unix"),
41+
(False, True, "unix"),
42+
),
43+
)
44+
@pytest.mark.parametrize(
45+
"program", ("dot", "twopi", "neato", "circo", "fdp", "sfdp")
46+
)
47+
@mock.patch.object(pydot, "is_anacoda")
48+
@mock.patch.object(pydot, "is_windows")
49+
def test_f_e(
50+
mock_win, mock_conda, tmpdir, windows, conda, extension, program, quoted
51+
):
52+
path = tmpdir.mkdir("PYDOT is_da best!")
53+
54+
mock_win.return_value = windows
55+
mock_conda.return_value = conda
56+
57+
unix_path = str(path.join(program))
58+
touch(unix_path)
59+
60+
exe_path = str(path.join(program + ".exe"))
61+
touch(exe_path)
62+
63+
bat_path = str(path.join(program + ".bat"))
64+
touch(bat_path)
65+
66+
if quoted:
67+
path = '"{}"'.format(path)
68+
unix_path = '"{}"'.format(unix_path)
69+
bat_path = '"{}"'.format(bat_path)
70+
exe_path = '"{}"'.format(exe_path)
71+
72+
progs = pydot.__find_executables(str(path))
73+
74+
if extension == "bat":
75+
assert progs[program] == bat_path
76+
elif extension == "exe":
77+
assert progs[program] == exe_path
78+
elif extension == "unix":
79+
assert progs[program] == unix_path
80+
else:
81+
raise Exception("Unknown extension {}".format(extension))

test/test_pydot.py

+1-56
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
import warnings
99
from textwrap import dedent
1010

11-
import mock
1211
import pytest
12+
import mock
1313

1414
import pydot_ng as pydot
1515

@@ -279,58 +279,3 @@ def test_dotparser_import_warning():
279279
del sys.modules["pydot_ng"]
280280
warnings.simplefilter("always")
281281
import pydot_ng # noqa: F401
282-
283-
284-
def test_find_executables_fake_path():
285-
assert pydot.__find_executables("/fake/path/") is None
286-
287-
288-
def test_find_executables_real_path_no_programs(tmpdir):
289-
assert pydot.__find_executables(str(tmpdir)) is None
290-
291-
292-
def test_find_executables_path_needs_strip(tmpdir):
293-
path = tmpdir.mkdir("subdir")
294-
prog_path = str(path.join("dot"))
295-
296-
path_with_spaces = " {} ".format(path)
297-
298-
with open(prog_path, "w"):
299-
progs = pydot.__find_executables(path_with_spaces)
300-
assert progs["dot"] == prog_path
301-
assert sorted(
302-
("dot", "twopi", "neato", "circo", "fdp", "sfdp")
303-
) == sorted(progs)
304-
305-
306-
def test_find_executables_unix_and_exe_exists(tmpdir):
307-
path = str(tmpdir)
308-
prog_unix_path = str(tmpdir.join("dot"))
309-
prog_exe_path = str(tmpdir.join("dot.exe"))
310-
311-
with open(prog_unix_path, "w"):
312-
with open(prog_exe_path, "w"):
313-
progs = pydot.__find_executables(path)
314-
assert progs["dot"] == prog_unix_path
315-
assert progs["dot"] != prog_exe_path
316-
317-
318-
@pytest.mark.parametrize("quoted", (True, False), ids=("quoted", "unqoted"))
319-
@pytest.mark.parametrize("extension", ("", ".exe"))
320-
@pytest.mark.parametrize(
321-
"program", ("dot", "twopi", "neato", "circo", "fdp", "sfdp")
322-
)
323-
def test_find_executables(tmpdir, program, extension, quoted):
324-
path = tmpdir.mkdir("PYDOT is_da best!")
325-
prog_path = str(path.join(program + extension))
326-
327-
with open(prog_path, "w"):
328-
if quoted:
329-
path = "\"{}\"".format(path)
330-
prog_path = "\"{}\"".format(prog_path)
331-
332-
progs = pydot.__find_executables(str(path))
333-
assert progs[program] == prog_path
334-
assert sorted(
335-
("dot", "twopi", "neato", "circo", "fdp", "sfdp")
336-
) == sorted(progs)

0 commit comments

Comments
 (0)