Skip to content

Commit

Permalink
Add Features to check the environment at runtime
Browse files Browse the repository at this point in the history
Eventually this should replace is_package_installed()
checks which are annoying for packagers.
  • Loading branch information
saraedum authored and jdemeyer committed Mar 13, 2018
1 parent 9bf9f05 commit 8e4c504
Show file tree
Hide file tree
Showing 13 changed files with 1,123 additions and 93 deletions.
8 changes: 3 additions & 5 deletions src/sage/game_theory/normal_form_game.py
Original file line number Diff line number Diff line change
Expand Up @@ -618,7 +618,6 @@
from sage.structure.sage_object import SageObject
from sage.matrix.constructor import matrix
from sage.matrix.constructor import vector
from sage.misc.package import is_package_installed, PackageNotFoundError
from sage.misc.temporary_file import tmp_filename
from sage.numerical.mip import MixedIntegerLinearProgram

Expand Down Expand Up @@ -1633,18 +1632,17 @@ def obtain_nash(self, algorithm=False, maximization=True, solver=None):
if not self._is_complete():
raise ValueError("utilities have not been populated")

from sage.misc.feature_test import Lrs
if not algorithm:
if self.is_constant_sum():
algorithm = "lp"
elif is_package_installed('lrslib'):
elif Lrs().is_present():
algorithm = "lrs"
else:
algorithm = "enumeration"

if algorithm == "lrs":
if not is_package_installed('lrslib'):
raise PackageNotFoundError("lrslib")

Lrs().require()
return self._solve_lrs(maximization)

if algorithm == "LCP":
Expand Down
4 changes: 1 addition & 3 deletions src/sage/geometry/polyhedron/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
from sage.structure.richcmp import rich_to_bool, op_NE

from sage.misc.all import cached_method, prod
from sage.misc.package import is_package_installed, PackageNotFoundError
from sage.misc.randstate import current_randstate

from sage.rings.all import QQ, ZZ, AA
Expand Down Expand Up @@ -4281,8 +4280,7 @@ def _volume_lrs(self, verbose=False):
David Avis's lrs program.
"""
if not is_package_installed('lrslib'):
raise PackageNotFoundError('lrslib')
Lrs().require()

from sage.misc.temporary_file import tmp_filename
from subprocess import Popen, PIPE
Expand Down
1 change: 0 additions & 1 deletion src/sage/graphs/bliss.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ cdef extern from "bliss/graph.hh" namespace "bliss":
const unsigned int*), void*)

cdef cppclass Digraph(AbstractGraph):

Digraph(const unsigned int)
void add_edge(const unsigned int, const unsigned int)
void find_automorphisms(Stats&, void (*)(void* , unsigned int,
Expand Down
8 changes: 3 additions & 5 deletions src/sage/graphs/generators/classical_geometries.py
Original file line number Diff line number Diff line change
Expand Up @@ -1284,12 +1284,10 @@ def CossidentePenttilaGraph(q):
if k==0 or p==2:
raise ValueError('q(={}) must be an odd prime power'.format(q))

from sage.libs.gap.libgap import libgap
from sage.misc.package import is_package_installed, PackageNotFoundError

if not is_package_installed('gap_packages'):
raise PackageNotFoundError('gap_packages')
from sage.misc.feature_test import GapPackage
GapPackage("grape", spkg="gap_packages").require()

from sage.libs.gap.libgap import libgap
adj_list=libgap.function_factory("""function(q)
local z, e, so, G, nu, G1, G0, B, T, s, O1, O2, x;
LoadPackage("grape");
Expand Down
16 changes: 6 additions & 10 deletions src/sage/graphs/generic_graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -8462,7 +8462,6 @@ def flow(self, x, y, value_only=True, integer=False, use_edge_labels=True, verte
sage: abs(flow_ff-flow_igraph) < 0.00001 # optional python_igraph
True
"""
from sage.misc.package import is_package_installed, PackageNotFoundError
self._scream_if_not_simple(allow_loops=True)
if vertex_bound and algorithm in ["FF", "igraph"]:
raise ValueError("This method does not support both " +
Expand All @@ -8478,9 +8477,10 @@ def flow(self, x, y, value_only=True, integer=False, use_edge_labels=True, verte
capacity=lambda x: 1

if algorithm is None:
from sage.misc.feature_test import Module
if vertex_bound:
algorithm = "LP"
elif is_package_installed("python_igraph"):
elif Module(module="igraph", spkg="python_igraph", url="http://igraph.org").is_present():
algorithm = "igraph"
else:
algorithm = "FF"
Expand Down Expand Up @@ -21845,11 +21845,8 @@ def automorphism_group(self, partition=None, verbosity=0,
[Subgroup of (Permutation Group with generators [(0,7)(1,4)(2,3)(6,8)]) generated by [()],
Subgroup of (Permutation Group with generators [(0,7)(1,4)(2,3)(6,8)]) generated by [(0,7)(1,4)(2,3)(6,8)]]
"""
try:
from sage.graphs.bliss import automorphism_group
have_bliss = True
except ImportError:
have_bliss = False
from sage.features.bliss import Bliss
have_bliss = Bliss().is_present()

# See trac #21704
if self.has_multiple_edges():
Expand All @@ -21864,10 +21861,9 @@ def automorphism_group(self, partition=None, verbosity=0,
if edge_labels:
raise ValueError("bliss cannot be used when edge_labels is True")

if not have_bliss:
from sage.misc.package import PackageNotFoundError
raise PackageNotFoundError("bliss")
Bliss().require()

from sage.graphs.bliss import automorphism_group
A = automorphism_group(self, partition)

# If the user only wants the automorphism group, lets return it
Expand Down
64 changes: 24 additions & 40 deletions src/sage/graphs/graph_generators.py
Original file line number Diff line number Diff line change
Expand Up @@ -1210,23 +1210,22 @@ def fullerenes(self, order, ipr=False):
.. [buckygen] \G. Brinkmann, J. Goedgebeur and B.D. McKay, Generation of Fullerenes,
Journal of Chemical Information and Modeling, 52(11):2910-2918, 2012.
"""
from sage.misc.package import is_package_installed, PackageNotFoundError
if not is_package_installed("buckygen"):
raise PackageNotFoundError("buckygen")

# number of vertices should be positive
if order < 0:
raise ValueError("Number of vertices should be positive.")
raise ValueError("number of vertices should be non-negative")

# buckygen can only output fullerenes on up to 254 vertices
if order > 254:
raise ValueError("Number of vertices should be at most 254.")
raise ValueError("number of vertices should be at most 254")

# fullerenes only exist for an even number of vertices, larger than 20
# and different from 22
if order % 2 == 1 or order < 20 or order == 22:
return

from sage.misc.feature_test import Buckygen
Buckygen().require()

command = 'buckygen -'+('I' if ipr else '')+'d {0}d'.format(order)

import subprocess
Expand Down Expand Up @@ -1295,17 +1294,12 @@ def fusenes(self, hexagon_count, benzenoids=False):
.. [benzene] \G. Brinkmann, G. Caporossi and P. Hansen, A Constructive Enumeration of Fusenes and Benzenoids,
Journal of Algorithms, 45:155-166, 2002.
"""
from sage.misc.package import is_package_installed, PackageNotFoundError
if not is_package_installed("benzene"):
raise PackageNotFoundError("benzene")

# number of hexagons should be positive
if hexagon_count < 0:
raise ValueError("Number of hexagons should be positive.")
raise ValueError("number of hexagons should be non-negative")

# benzene is only built for fusenes with up to 30 hexagons
if hexagon_count > 30:
raise ValueError("Number of hexagons should be at most 30.")
raise ValueError("number of hexagons should be at most 30")

# there are no fusenes with 0 hexagons
if hexagon_count == 0:
Expand All @@ -1319,6 +1313,9 @@ def fusenes(self, hexagon_count, benzenoids=False):
yield(G)
return

from sage.misc.feature_test import Benzene
Benzene().require()

command = 'benzene '+('b' if benzenoids else '')+' {0} p'.format(hexagon_count)

import subprocess
Expand Down Expand Up @@ -1448,22 +1445,16 @@ def planar_graphs(self, order, minimum_degree=None,
.. [plantri] \G. Brinkmann and B.D. McKay, Fast generation of planar graphs,
MATCH-Communications in Mathematical and in Computer Chemistry, 58(2):323-357, 2007.
"""
from sage.misc.package import is_package_installed, PackageNotFoundError
if not is_package_installed("plantri"):
raise PackageNotFoundError("plantri")

# number of vertices should be positive
if order < 0:
raise ValueError("Number of vertices should be positive.")
raise ValueError("number of vertices should be non-negative")

# plantri can only output general planar graphs on up to 64 vertices
if order > 64:
raise ValueError("Number of vertices should be at most 64.")
raise ValueError("number of vertices should be at most 64")

if exact_connectivity and minimum_connectivity is None:
raise ValueError("Minimum connectivity must be specified to use the exact_connectivity option.")

# minimum connectivity should be None or a number between 1 and 3
if minimum_connectivity is not None and not (1 <= minimum_connectivity <= 3):
raise ValueError("Minimum connectivity should be a number between 1 and 3.")

Expand Down Expand Up @@ -1511,6 +1502,9 @@ def planar_graphs(self, order, minimum_degree=None,
yield(G)
return

from sage.misc.feature_test import Plantri
Plantri().require()

cmd = 'plantri -p{}m{}c{}{}{} {}'
command = cmd.format('b' if only_bipartite else '',
minimum_degree,
Expand Down Expand Up @@ -1647,26 +1641,19 @@ def triangulations(self, order, minimum_degree=None, minimum_connectivity=None,
sage: [g.size() for g in graphs.triangulations(6, minimum_connectivity=3)] # optional plantri
[12, 12]
"""
from sage.misc.package import is_package_installed, PackageNotFoundError
if not is_package_installed("plantri"):
raise PackageNotFoundError("plantri")

# number of vertices should be positive
if order < 0:
raise ValueError("Number of vertices should be positive.")
raise ValueError("number of vertices should be non-negative")

# plantri can only output planar triangulations on up to 64 vertices
if order > 64:
raise ValueError("Number of vertices should be at most 64.")
raise ValueError("number of vertices should be at most 64")

if exact_connectivity and minimum_connectivity is None:
raise ValueError("Minimum connectivity must be specified to use the exact_connectivity option.")

# minimum connectivity should be None or a number between 3 and 5
if minimum_connectivity is not None and not (3 <= minimum_connectivity <= 5):
raise ValueError("Minimum connectivity should be None or a number between 3 and 5.")

# minimum degree should be None or a number between 3 and 5
if minimum_degree is not None and not (3 <= minimum_degree <= 5):
raise ValueError("Minimum degree should be None or a number between 3 and 5.")

Expand Down Expand Up @@ -1698,6 +1685,9 @@ def triangulations(self, order, minimum_degree=None, minimum_connectivity=None,
if only_eulerian and order < 6:
return

from sage.misc.feature_test import Plantri
Plantri().require()

cmd = 'plantri -{}m{}c{}{}{} {}'
command = cmd.format('b' if only_eulerian else '',
minimum_degree,
Expand Down Expand Up @@ -1801,23 +1791,16 @@ def quadrangulations(self, order, minimum_degree=None, minimum_connectivity=None
sage: [len(g) for g in graphs.quadrangulations(12, no_nonfacial_quadrangles=True, dual=True)] # optional plantri
[10, 10]
"""
from sage.misc.package import is_package_installed, PackageNotFoundError
if not is_package_installed("plantri"):
raise PackageNotFoundError("plantri")

# number of vertices should be positive
if order < 0:
raise ValueError("Number of vertices should be positive.")
raise ValueError("number of vertices should be non-negative")

# plantri can only output planar quadrangulations on up to 64 vertices
if order > 64:
raise ValueError("Number of vertices should be at most 64.")
raise ValueError("number of vertices should be at most 64")

# minimum connectivity should be None, 2 or 3
if minimum_connectivity not in {None, 2, 3}:
raise ValueError("Minimum connectivity should be None, 2 or 3.")

# minimum degree should be None, 2 or 3
if minimum_degree not in {None, 2, 3}:
raise ValueError("Minimum degree should be None, 2 or 3.")

Expand Down Expand Up @@ -1846,6 +1829,8 @@ def quadrangulations(self, order, minimum_degree=None, minimum_connectivity=None
# for plantri -q the option -c4 means 3-connected with no non-facial quadrangles
minimum_connectivity = 4

from sage.misc.feature_test import Plantri
Plantri().require()

cmd = 'plantri -qm{}c{}{} {}'
command = cmd.format(minimum_degree,
Expand Down Expand Up @@ -2516,6 +2501,5 @@ def check_aut_edge(aut_gens, cut_edge, i, j, n, dig=False):
if not dig and new_perm[cut_edge[0]] == j and new_perm[cut_edge[1]] == i:
yield new_perm


# Easy access to the graph generators from the command line:
graphs = GraphGenerators()
8 changes: 3 additions & 5 deletions src/sage/graphs/lovasz_theta.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,17 +64,15 @@ def lovasz_theta(graph):
from networkx import write_edgelist
from sage.misc.temporary_file import tmp_filename
import os, subprocess
from sage.env import SAGE_LOCAL
from sage.misc.package import is_package_installed, PackageNotFoundError

if not is_package_installed('csdp'):
raise PackageNotFoundError("csdp")
from sage.misc.feature import CSDP
CSDP().require()

g = graph.relabel(inplace=False, perm=range(1,n+1)).networkx_graph()
tf_name = tmp_filename()
tf = open(tf_name, 'wb')
tf.write(str(n)+'\n'+str(g.number_of_edges())+'\n')
write_edgelist(g, tf, data=False)
tf.close()
lines = subprocess.check_output([os.path.join(SAGE_LOCAL, 'bin', 'theta'), tf_name])
lines = subprocess.check_output(['theta', tf_name])
return float(lines.split()[-1])
6 changes: 3 additions & 3 deletions src/sage/groups/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -1406,15 +1406,15 @@ def structure_description(G, latex=False):
'A8'
"""
import re
from sage.misc.package import is_package_installed, PackageNotFoundError
def correct_dihedral_degree(match):
return "%sD%d" % (match.group(1), int(match.group(2))/2)

try:
description = str(G._gap_().StructureDescription())
except RuntimeError:
if not is_package_installed('database_gap'):
raise PackageNotFoundError("database_gap")
from sage.misc.feature_test import SmallGroupsLibrary
SmallGroupsLibrary().require()
# the Small Groups Library is installed. The command failed for a different reason
raise

description = re.sub(r"(\A|\W)D(\d+)", correct_dihedral_degree, description)
Expand Down

0 comments on commit 8e4c504

Please sign in to comment.