Skip to content

Commit

Permalink
Trac #33465: sage.graphs: Use Executable.absolute_filename()
Browse files Browse the repository at this point in the history
This is so that the Sage library becomes fully functional even when not
being run from within sage-env (which sets PATH).

We add `sage.features.nauty` to provide features for nauty executables.

To test:
{{{
$ venv/bin/python3 -c 'from sage.all import graphs;
print(len(list(graphs.fullerenes(60))))'
}}}

URL: https://trac.sagemath.org/33465
Reported by: mkoeppe
Ticket author(s): Matthias Koeppe
Reviewer(s): David Coudert
  • Loading branch information
Release Manager committed Mar 9, 2022
2 parents f9df4f8 + 9107e2c commit 11b44ec
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 12 deletions.
59 changes: 59 additions & 0 deletions src/sage/features/nauty.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
r"""
Features for testing the presence of nauty executables
"""

from sage.env import SAGE_NAUTY_BINS_PREFIX

from . import Executable
from .join_feature import JoinFeature


class NautyExecutable(Executable):
r"""
A :class:`~sage.features.Feature` which checks for nauty executables.
EXAMPLES::
sage: from sage.features.nauty import NautyExecutable
sage: NautyExecutable('converseg').is_present() # optional - nauty
FeatureTestResult('nauty_converseg', True)
"""
def __init__(self, name):
r"""
TESTS::
sage: from sage.features.nauty import NautyExecutable
sage: isinstance(NautyExecutable('geng'), NautyExecutable)
True
"""
Executable.__init__(self, name=f"nauty_{name}",
executable=f"{SAGE_NAUTY_BINS_PREFIX}{name}",
spkg="nauty")


class Nauty(JoinFeature):
r"""
A :class:`~sage.features.Feature` describing the presence of the executables
which comes as a part of ``nauty``.
EXAMPLES::
sage: from sage.features.nauty import Nauty
sage: Nauty().is_present() # optional - nauty
FeatureTestResult('nauty', True)
"""
def __init__(self):
r"""
TESTS::
sage: from sage.features.nauty import Nauty
sage: isinstance(Nauty(), Nauty)
True
"""
JoinFeature.__init__(self, "nauty",
[NautyExecutable(name)
for name in ('directg', 'gentourng', 'geng', 'genbg', 'converseg')])


def all_features():
return [Nauty()]
17 changes: 13 additions & 4 deletions src/sage/graphs/digraph_generators.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@
# http://www.gnu.org/licenses/
################################################################################
from sage.cpython.string import bytes_to_str
from sage.env import SAGE_NAUTY_BINS_PREFIX as nautyprefix

import sys
from sage.misc.randstate import current_randstate
Expand Down Expand Up @@ -528,7 +527,12 @@ def tournaments_nauty(self, n,

nauty_input += " " + str(n) + " "

sp = subprocess.Popen(nautyprefix+"gentourng {0}".format(nauty_input), shell=True,
import shlex
from sage.features.nauty import NautyExecutable
gentourng_path = NautyExecutable("gentourng").absolute_filename()

sp = subprocess.Popen(shlex.quote(gentourng_path) + " {0}".format(nauty_input),
shell=True,
stdin=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.PIPE, close_fds=True)

Expand Down Expand Up @@ -636,8 +640,13 @@ def nauty_directg(self, graphs, options="", debug=False):
options += ' -q'

# Build directg input (graphs6 format)
input = ''.join(g.graph6_string()+'\n' for g in graphs)
sub = subprocess.Popen(nautyprefix+'directg {0}'.format(options),
input = ''.join(g.graph6_string() + '\n' for g in graphs)

import shlex
from sage.features.nauty import NautyExecutable
directg_path = NautyExecutable("directg").absolute_filename()

sub = subprocess.Popen(shlex.quote(directg_path) + ' {0}'.format(options),
shell=True,
stdout=subprocess.PIPE,
stdin=subprocess.PIPE,
Expand Down
20 changes: 14 additions & 6 deletions src/sage/graphs/graph_generators.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
More interestingly, one can get the list of all graphs that Sage knows how to
build by typing ``graphs.`` in Sage and then hitting tab.
"""
from sage.env import SAGE_NAUTY_BINS_PREFIX as nautyprefix

import subprocess

Expand Down Expand Up @@ -956,8 +955,10 @@ def nauty_geng(self, options="", debug=False):
sage: list(graphs.nauty_geng("-c 3", debug=True))
['>A ...geng -cd1D2 n=3 e=2-3\n', Graph on 3 vertices, Graph on 3 vertices]
"""

sp = subprocess.Popen(nautyprefix+"geng {0}".format(options), shell=True,
import shlex
from sage.features.nauty import NautyExecutable
geng_path = NautyExecutable("geng").absolute_filename()
sp = subprocess.Popen(shlex.quote(geng_path) + " {0}".format(options), shell=True,
stdin=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.PIPE, close_fds=True,
encoding='latin-1')
Expand Down Expand Up @@ -1292,7 +1293,9 @@ def fullerenes(self, order, ipr=False):
from sage.features.graph_generators import Buckygen
Buckygen().require()

command = 'buckygen -'+('I' if ipr else '')+'d {0}d'.format(order)
import shlex
command = shlex.quote(Buckygen().absolute_filename())
command += ' -' + ('I' if ipr else '') + 'd {0}d'.format(order)

sp = subprocess.Popen(command, shell=True,
stdin=subprocess.PIPE, stdout=subprocess.PIPE,
Expand Down Expand Up @@ -1379,7 +1382,9 @@ def fusenes(self, hexagon_count, benzenoids=False):
from sage.features.graph_generators import Benzene
Benzene().require()

command = 'benzene '+('b' if benzenoids else '')+' {0} p'.format(hexagon_count)
import shlex
command = shlex.quote(Benzene().absolute_filename())
command += (' b' if benzenoids else '') + ' {0} p'.format(hexagon_count)

sp = subprocess.Popen(command, shell=True,
stdin=subprocess.PIPE, stdout=subprocess.PIPE,
Expand Down Expand Up @@ -1563,7 +1568,10 @@ def plantri_gen(self, options=""):
from sage.features.graph_generators import Plantri
Plantri().require()

sp = subprocess.Popen('plantri {}'.format(options), shell=True,
import shlex
command = '{} {}'.format(shlex.quote(Plantri().absolute_filename()),
options)
sp = subprocess.Popen(command, shell=True,
stdin=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.PIPE, close_fds=True,
encoding='latin-1')
Expand Down
6 changes: 4 additions & 2 deletions src/sage/graphs/hypergraph_generators.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
Functions and methods
---------------------
"""
from sage.env import SAGE_NAUTY_BINS_PREFIX as nautyprefix

class HypergraphGenerators():
r"""
Expand Down Expand Up @@ -149,6 +148,9 @@ def nauty(self, number_of_sets, number_of_vertices,
raise ValueError("cannot have more than 64 sets+vertices")

import subprocess
import shlex
from sage.features.nauty import NautyExecutable
genbgL_path = NautyExecutable("genbgL").absolute_filename()

nauty_input = options

Expand Down Expand Up @@ -181,7 +183,7 @@ def nauty(self, number_of_sets, number_of_vertices,

nauty_input += " " + str(number_of_vertices) + " " + str(number_of_sets) + " "

sp = subprocess.Popen(nautyprefix + "genbgL {0}".format(nauty_input), shell=True,
sp = subprocess.Popen(shlex.quote(genbgL_path) + " {0}".format(nauty_input), shell=True,
stdin=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.PIPE, close_fds=True)

Expand Down

0 comments on commit 11b44ec

Please sign in to comment.