passagemath-environment 10.4.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- passagemath_environment-10.4.1.data/scripts/sage +1140 -0
- passagemath_environment-10.4.1.data/scripts/sage-env +667 -0
- passagemath_environment-10.4.1.data/scripts/sage-num-threads.py +105 -0
- passagemath_environment-10.4.1.data/scripts/sage-python +2 -0
- passagemath_environment-10.4.1.data/scripts/sage-venv-config +42 -0
- passagemath_environment-10.4.1.data/scripts/sage-version.sh +9 -0
- passagemath_environment-10.4.1.dist-info/METADATA +76 -0
- passagemath_environment-10.4.1.dist-info/RECORD +70 -0
- passagemath_environment-10.4.1.dist-info/WHEEL +5 -0
- passagemath_environment-10.4.1.dist-info/top_level.txt +1 -0
- sage/all__sagemath_environment.py +4 -0
- sage/env.py +496 -0
- sage/features/__init__.py +981 -0
- sage/features/all.py +126 -0
- sage/features/bliss.py +85 -0
- sage/features/cddlib.py +38 -0
- sage/features/coxeter3.py +45 -0
- sage/features/csdp.py +83 -0
- sage/features/cython.py +38 -0
- sage/features/databases.py +302 -0
- sage/features/dvipng.py +40 -0
- sage/features/ecm.py +42 -0
- sage/features/ffmpeg.py +119 -0
- sage/features/four_ti_2.py +55 -0
- sage/features/fricas.py +66 -0
- sage/features/gap.py +86 -0
- sage/features/gfan.py +38 -0
- sage/features/giac.py +30 -0
- sage/features/graph_generators.py +171 -0
- sage/features/graphviz.py +117 -0
- sage/features/igraph.py +44 -0
- sage/features/imagemagick.py +138 -0
- sage/features/interfaces.py +256 -0
- sage/features/internet.py +65 -0
- sage/features/jmol.py +44 -0
- sage/features/join_feature.py +146 -0
- sage/features/kenzo.py +77 -0
- sage/features/latex.py +300 -0
- sage/features/latte.py +85 -0
- sage/features/lrs.py +164 -0
- sage/features/mcqd.py +45 -0
- sage/features/meataxe.py +46 -0
- sage/features/mip_backends.py +114 -0
- sage/features/msolve.py +68 -0
- sage/features/nauty.py +70 -0
- sage/features/normaliz.py +43 -0
- sage/features/palp.py +65 -0
- sage/features/pandoc.py +42 -0
- sage/features/pdf2svg.py +41 -0
- sage/features/phitigra.py +42 -0
- sage/features/pkg_systems.py +195 -0
- sage/features/polymake.py +43 -0
- sage/features/poppler.py +58 -0
- sage/features/rubiks.py +180 -0
- sage/features/sagemath.py +1205 -0
- sage/features/sat.py +103 -0
- sage/features/singular.py +48 -0
- sage/features/sirocco.py +45 -0
- sage/features/sphinx.py +71 -0
- sage/features/standard.py +38 -0
- sage/features/symengine_py.py +44 -0
- sage/features/tdlib.py +38 -0
- sage/features/threejs.py +75 -0
- sage/features/topcom.py +67 -0
- sage/misc/all__sagemath_environment.py +2 -0
- sage/misc/package.py +570 -0
- sage/misc/package_dir.py +621 -0
- sage/misc/temporary_file.py +546 -0
- sage/misc/viewer.py +369 -0
- sage/version.py +5 -0
sage/features/gap.py
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
# sage_setup: distribution = sagemath-environment
|
2
|
+
r"""
|
3
|
+
Features for testing the presence of the SageMath interfaces to ``gap`` and of GAP packages
|
4
|
+
"""
|
5
|
+
# *****************************************************************************
|
6
|
+
# Copyright (C) 2016 Julian Rüth
|
7
|
+
# 2018 Jeroen Demeyer
|
8
|
+
#
|
9
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
10
|
+
# as published by the Free Software Foundation; either version 2 of
|
11
|
+
# the License, or (at your option) any later version.
|
12
|
+
# https://www.gnu.org/licenses/
|
13
|
+
# *****************************************************************************
|
14
|
+
|
15
|
+
from . import Feature, FeatureTestResult, PythonModule
|
16
|
+
from .join_feature import JoinFeature
|
17
|
+
from .sagemath import sage__libs__gap
|
18
|
+
|
19
|
+
class GapPackage(Feature):
|
20
|
+
r"""
|
21
|
+
A :class:`~sage.features.Feature` describing the presence of a GAP package.
|
22
|
+
|
23
|
+
A GAP package is "present" if it *can be* loaded, not if it *has
|
24
|
+
been* loaded.
|
25
|
+
|
26
|
+
.. SEEALSO::
|
27
|
+
|
28
|
+
:class:`Feature sage.libs.gap <~sage.features.sagemath.sage__libs__gap>`
|
29
|
+
|
30
|
+
EXAMPLES::
|
31
|
+
|
32
|
+
sage: from sage.features.gap import GapPackage
|
33
|
+
sage: GapPackage("grape", spkg='gap_packages')
|
34
|
+
Feature('gap_package_grape')
|
35
|
+
"""
|
36
|
+
def __init__(self, package, **kwds):
|
37
|
+
r"""
|
38
|
+
TESTS::
|
39
|
+
|
40
|
+
sage: from sage.features.gap import GapPackage
|
41
|
+
sage: isinstance(GapPackage("grape", spkg='gap_packages'), GapPackage)
|
42
|
+
True
|
43
|
+
"""
|
44
|
+
Feature.__init__(self, f"gap_package_{package}", **kwds)
|
45
|
+
self.package = package
|
46
|
+
|
47
|
+
def _is_present(self):
|
48
|
+
r"""
|
49
|
+
Return whether or not the GAP package is present.
|
50
|
+
|
51
|
+
If the package is installed but not yet loaded, it is loaded
|
52
|
+
first. This does *not* check that the package is functional.
|
53
|
+
|
54
|
+
EXAMPLES::
|
55
|
+
|
56
|
+
sage: from sage.features.gap import GapPackage
|
57
|
+
sage: GapPackage("grape", spkg='gap_packages')._is_present() # optional - gap_package_grape
|
58
|
+
FeatureTestResult('gap_package_grape', True)
|
59
|
+
"""
|
60
|
+
try:
|
61
|
+
from sage.libs.gap.libgap import libgap
|
62
|
+
except ImportError:
|
63
|
+
return FeatureTestResult(self, False,
|
64
|
+
reason="sage.libs.gap is not available")
|
65
|
+
|
66
|
+
# This returns "true" even if the package is already loaded.
|
67
|
+
command = 'LoadPackage("{package}")'.format(package=self.package)
|
68
|
+
presence = libgap.eval(command)
|
69
|
+
|
70
|
+
if presence:
|
71
|
+
return FeatureTestResult(self, True,
|
72
|
+
reason="`{command}` evaluated to `{presence}` in GAP.".format(command=command, presence=presence))
|
73
|
+
else:
|
74
|
+
return FeatureTestResult(self, False,
|
75
|
+
reason="`{command}` evaluated to `{presence}` in GAP.".format(command=command, presence=presence))
|
76
|
+
|
77
|
+
|
78
|
+
def all_features():
|
79
|
+
return [GapPackage("atlasrep", spkg='gap_packages'),
|
80
|
+
GapPackage("design", spkg='gap_packages'),
|
81
|
+
GapPackage("grape", spkg='gap_packages'),
|
82
|
+
GapPackage("guava", spkg='gap_packages'),
|
83
|
+
GapPackage("hap", spkg='gap_packages'),
|
84
|
+
GapPackage("polycyclic", spkg='gap_packages'),
|
85
|
+
GapPackage("qpa", spkg='gap_packages'),
|
86
|
+
GapPackage("quagroup", spkg='gap_packages')]
|
sage/features/gfan.py
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
# sage_setup: distribution = sagemath-environment
|
2
|
+
r"""
|
3
|
+
Features for testing the presence of ``gfan``
|
4
|
+
"""
|
5
|
+
|
6
|
+
# *****************************************************************************
|
7
|
+
# Copyright (C) 2022 Matthias Koeppe
|
8
|
+
#
|
9
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
10
|
+
# as published by the Free Software Foundation; either version 2 of
|
11
|
+
# the License, or (at your option) any later version.
|
12
|
+
# https://www.gnu.org/licenses/
|
13
|
+
# *****************************************************************************
|
14
|
+
|
15
|
+
from . import Executable
|
16
|
+
|
17
|
+
|
18
|
+
class GfanExecutable(Executable):
|
19
|
+
r"""
|
20
|
+
A :class:`~sage.features.Feature` for the :ref:`gfan <spkg_gfan>` executables.
|
21
|
+
"""
|
22
|
+
def __init__(self, cmd=None):
|
23
|
+
r"""
|
24
|
+
TESTS::
|
25
|
+
|
26
|
+
sage: from sage.features.gfan import GfanExecutable
|
27
|
+
sage: isinstance(GfanExecutable('groebnercone'), GfanExecutable)
|
28
|
+
True
|
29
|
+
"""
|
30
|
+
if cmd is None:
|
31
|
+
name = "gfan"
|
32
|
+
else:
|
33
|
+
name = f"gfan_{cmd}"
|
34
|
+
Executable.__init__(self, name, executable=name, spkg='gfan', type='standard')
|
35
|
+
|
36
|
+
|
37
|
+
def all_features():
|
38
|
+
return [GfanExecutable()]
|
sage/features/giac.py
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# sage_setup: distribution = sagemath-environment
|
2
|
+
r"""
|
3
|
+
Feature for testing the presence of ``giac``
|
4
|
+
"""
|
5
|
+
|
6
|
+
from . import Executable, FeatureTestResult
|
7
|
+
|
8
|
+
class Giac(Executable):
|
9
|
+
r"""
|
10
|
+
A :class:`~sage.features.Feature` describing the presence of :ref:`giac <spkg_giac>`.
|
11
|
+
|
12
|
+
EXAMPLES::
|
13
|
+
|
14
|
+
sage: from sage.features.giac import Giac
|
15
|
+
sage: Giac().is_present() # needs giac
|
16
|
+
FeatureTestResult('giac', True)
|
17
|
+
"""
|
18
|
+
def __init__(self):
|
19
|
+
r"""
|
20
|
+
TESTS::
|
21
|
+
|
22
|
+
sage: from sage.features.giac import Giac
|
23
|
+
sage: isinstance(Giac(), Giac)
|
24
|
+
True
|
25
|
+
"""
|
26
|
+
Executable.__init__(self, 'giac', executable='giac',
|
27
|
+
spkg='giac', type='standard')
|
28
|
+
|
29
|
+
def all_features():
|
30
|
+
return [Giac()]
|
@@ -0,0 +1,171 @@
|
|
1
|
+
# sage_setup: distribution = sagemath-environment
|
2
|
+
r"""
|
3
|
+
Features for testing the presence of graph generator programs ``benzene``, ``buckygen``, ``plantri``
|
4
|
+
"""
|
5
|
+
|
6
|
+
# *****************************************************************************
|
7
|
+
# Copyright (C) 2016 Julian Rüth
|
8
|
+
# 2018 Jeroen Demeyer
|
9
|
+
# 2019 Frédéric Chapoton
|
10
|
+
# 2021 Matthias Koeppe
|
11
|
+
# 2021 Kwankyu Lee
|
12
|
+
#
|
13
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
14
|
+
# as published by the Free Software Foundation; either version 2 of
|
15
|
+
# the License, or (at your option) any later version.
|
16
|
+
# https://www.gnu.org/licenses/
|
17
|
+
# *****************************************************************************
|
18
|
+
|
19
|
+
import os
|
20
|
+
import subprocess
|
21
|
+
|
22
|
+
from . import Executable, FeatureTestResult
|
23
|
+
|
24
|
+
|
25
|
+
class Plantri(Executable):
|
26
|
+
r"""
|
27
|
+
A :class:`~sage.features.Feature` which checks for the :ref:`plantri <spkg_plantri>` binary.
|
28
|
+
|
29
|
+
EXAMPLES::
|
30
|
+
|
31
|
+
sage: from sage.features.graph_generators import Plantri
|
32
|
+
sage: Plantri().is_present() # optional - plantri
|
33
|
+
FeatureTestResult('plantri', True)
|
34
|
+
"""
|
35
|
+
def __init__(self):
|
36
|
+
r"""
|
37
|
+
TESTS::
|
38
|
+
|
39
|
+
sage: from sage.features.graph_generators import Plantri
|
40
|
+
sage: isinstance(Plantri(), Plantri)
|
41
|
+
True
|
42
|
+
"""
|
43
|
+
Executable.__init__(self, name='plantri', spkg='plantri',
|
44
|
+
executable='plantri',
|
45
|
+
url='http://users.cecs.anu.edu.au/~bdm/plantri/')
|
46
|
+
|
47
|
+
def is_functional(self):
|
48
|
+
r"""
|
49
|
+
Check whether ``plantri`` works on trivial input.
|
50
|
+
|
51
|
+
EXAMPLES::
|
52
|
+
|
53
|
+
sage: from sage.features.graph_generators import Plantri
|
54
|
+
sage: Plantri().is_functional() # optional - plantri
|
55
|
+
FeatureTestResult('plantri', True)
|
56
|
+
"""
|
57
|
+
command = ["plantri", "4"]
|
58
|
+
try:
|
59
|
+
lines = subprocess.check_output(command, stderr=subprocess.STDOUT)
|
60
|
+
except subprocess.CalledProcessError as e:
|
61
|
+
return FeatureTestResult(self, False,
|
62
|
+
reason="Call `{command}` failed with exit code {e.returncode}".format(command=" ".join(command), e=e))
|
63
|
+
|
64
|
+
expected = b"1 triangulations written"
|
65
|
+
if lines.find(expected) == -1:
|
66
|
+
return FeatureTestResult(self, False,
|
67
|
+
reason="Call `{command}` did not produce output which contains `{expected}`".format(command=" ".join(command), expected=expected))
|
68
|
+
|
69
|
+
return FeatureTestResult(self, True)
|
70
|
+
|
71
|
+
|
72
|
+
class Buckygen(Executable):
|
73
|
+
r"""
|
74
|
+
A :class:`~sage.features.Feature` which checks for the :ref:`buckygen <spkg_buckygen>` binary.
|
75
|
+
|
76
|
+
EXAMPLES::
|
77
|
+
|
78
|
+
sage: from sage.features.graph_generators import Buckygen
|
79
|
+
sage: Buckygen().is_present() # optional - buckygen
|
80
|
+
FeatureTestResult('buckygen', True)
|
81
|
+
"""
|
82
|
+
def __init__(self):
|
83
|
+
r"""
|
84
|
+
TESTS::
|
85
|
+
|
86
|
+
sage: from sage.features.graph_generators import Buckygen
|
87
|
+
sage: isinstance(Buckygen(), Buckygen)
|
88
|
+
True
|
89
|
+
"""
|
90
|
+
Executable.__init__(self, name='buckygen', spkg='buckygen',
|
91
|
+
executable='buckygen',
|
92
|
+
url='http://caagt.ugent.be/buckygen/')
|
93
|
+
|
94
|
+
def is_functional(self):
|
95
|
+
r"""
|
96
|
+
Check whether ``buckygen`` works on trivial input.
|
97
|
+
|
98
|
+
EXAMPLES::
|
99
|
+
|
100
|
+
sage: from sage.features.graph_generators import Buckygen
|
101
|
+
sage: Buckygen().is_functional() # optional - buckygen
|
102
|
+
FeatureTestResult('buckygen', True)
|
103
|
+
"""
|
104
|
+
command = ["buckygen", "-d", "22d"]
|
105
|
+
try:
|
106
|
+
lines = subprocess.check_output(command, stderr=subprocess.STDOUT)
|
107
|
+
except subprocess.CalledProcessError as e:
|
108
|
+
return FeatureTestResult(self, False,
|
109
|
+
reason="Call `{command}` failed with exit code {e.returncode}".format(command=" ".join(command), e=e))
|
110
|
+
|
111
|
+
expected = b"Number of fullerenes generated with 13 vertices: 0"
|
112
|
+
if lines.find(expected) == -1:
|
113
|
+
return FeatureTestResult(self, False,
|
114
|
+
reason="Call `{command}` did not produce output which contains `{expected}`".format(command=" ".join(command), expected=expected))
|
115
|
+
|
116
|
+
return FeatureTestResult(self, True)
|
117
|
+
|
118
|
+
|
119
|
+
class Benzene(Executable):
|
120
|
+
r"""
|
121
|
+
A :class:`~sage.features.Feature` which checks for the :ref:`benzene <spkg_benzene>`
|
122
|
+
binary.
|
123
|
+
|
124
|
+
EXAMPLES::
|
125
|
+
|
126
|
+
sage: from sage.features.graph_generators import Benzene
|
127
|
+
sage: Benzene().is_present() # optional - benzene
|
128
|
+
FeatureTestResult('benzene', True)
|
129
|
+
"""
|
130
|
+
def __init__(self):
|
131
|
+
r"""
|
132
|
+
TESTS::
|
133
|
+
|
134
|
+
sage: from sage.features.graph_generators import Benzene
|
135
|
+
sage: isinstance(Benzene(), Benzene)
|
136
|
+
True
|
137
|
+
"""
|
138
|
+
Executable.__init__(self, name='benzene', spkg='benzene',
|
139
|
+
executable='benzene',
|
140
|
+
url='http://www.grinvin.org/')
|
141
|
+
|
142
|
+
def is_functional(self):
|
143
|
+
r"""
|
144
|
+
Check whether ``benzene`` works on trivial input.
|
145
|
+
|
146
|
+
EXAMPLES::
|
147
|
+
|
148
|
+
sage: from sage.features.graph_generators import Benzene
|
149
|
+
sage: Benzene().is_functional() # optional - benzene
|
150
|
+
FeatureTestResult('benzene', True)
|
151
|
+
"""
|
152
|
+
devnull = open(os.devnull, 'wb')
|
153
|
+
command = ["benzene", "2", "p"]
|
154
|
+
try:
|
155
|
+
lines = subprocess.check_output(command, stderr=devnull)
|
156
|
+
except subprocess.CalledProcessError as e:
|
157
|
+
return FeatureTestResult(self, False,
|
158
|
+
reason="Call `{command}` failed with exit code {e.returncode}".format(command=" ".join(command), e=e))
|
159
|
+
|
160
|
+
expected = b">>planar_code<<"
|
161
|
+
if not lines.startswith(expected):
|
162
|
+
return FeatureTestResult(self, False,
|
163
|
+
reason="Call `{command}` did not produce output that started with `{expected}`.".format(command=" ".join(command), expected=expected))
|
164
|
+
|
165
|
+
return FeatureTestResult(self, True)
|
166
|
+
|
167
|
+
|
168
|
+
def all_features():
|
169
|
+
return [Plantri(),
|
170
|
+
Buckygen(),
|
171
|
+
Benzene()]
|
@@ -0,0 +1,117 @@
|
|
1
|
+
# sage_setup: distribution = sagemath-environment
|
2
|
+
r"""
|
3
|
+
Features for testing the presence of ``graphviz``
|
4
|
+
"""
|
5
|
+
|
6
|
+
# ****************************************************************************
|
7
|
+
# Copyright (C) 2018 Sebastien Labbe <slabqc@gmail.com>
|
8
|
+
# 2021 Matthias Koeppe
|
9
|
+
#
|
10
|
+
# This program is free software: you can redistribute it and/or modify
|
11
|
+
# it under the terms of the GNU General Public License as published by
|
12
|
+
# the Free Software Foundation, either version 2 of the License, or
|
13
|
+
# (at your option) any later version.
|
14
|
+
# https://www.gnu.org/licenses/
|
15
|
+
# ****************************************************************************
|
16
|
+
|
17
|
+
from . import Executable
|
18
|
+
from .join_feature import JoinFeature
|
19
|
+
|
20
|
+
|
21
|
+
class dot(Executable):
|
22
|
+
r"""
|
23
|
+
A :class:`~sage.features.Feature` describing the presence of ``dot``.
|
24
|
+
|
25
|
+
TESTS::
|
26
|
+
|
27
|
+
sage: from sage.features.graphviz import dot
|
28
|
+
sage: dot().is_present() # optional - graphviz
|
29
|
+
FeatureTestResult('dot', True)
|
30
|
+
"""
|
31
|
+
def __init__(self):
|
32
|
+
r"""
|
33
|
+
TESTS::
|
34
|
+
|
35
|
+
sage: from sage.features.graphviz import dot
|
36
|
+
sage: isinstance(dot(), dot)
|
37
|
+
True
|
38
|
+
"""
|
39
|
+
Executable.__init__(self, 'dot', executable='dot',
|
40
|
+
spkg='graphviz',
|
41
|
+
url='https://www.graphviz.org/')
|
42
|
+
|
43
|
+
|
44
|
+
class neato(Executable):
|
45
|
+
r"""
|
46
|
+
A :class:`~sage.features.Feature` describing the presence of ``neato``.
|
47
|
+
|
48
|
+
TESTS:
|
49
|
+
|
50
|
+
sage: from sage.features.graphviz import neato
|
51
|
+
sage: neato().is_present() # optional - graphviz
|
52
|
+
FeatureTestResult('neato', True)
|
53
|
+
"""
|
54
|
+
def __init__(self):
|
55
|
+
r"""
|
56
|
+
TESTS::
|
57
|
+
|
58
|
+
sage: from sage.features.graphviz import neato
|
59
|
+
sage: isinstance(neato(), neato)
|
60
|
+
True
|
61
|
+
"""
|
62
|
+
Executable.__init__(self, 'neato', executable='neato',
|
63
|
+
spkg='graphviz',
|
64
|
+
url='https://www.graphviz.org/')
|
65
|
+
|
66
|
+
|
67
|
+
class twopi(Executable):
|
68
|
+
r"""
|
69
|
+
A :class:`~sage.features.Feature` describing the presence of ``twopi``.
|
70
|
+
|
71
|
+
TESTS::
|
72
|
+
|
73
|
+
sage: from sage.features.graphviz import twopi
|
74
|
+
sage: twopi().is_present() # optional - graphviz
|
75
|
+
FeatureTestResult('twopi', True)
|
76
|
+
"""
|
77
|
+
def __init__(self):
|
78
|
+
r"""
|
79
|
+
TESTS::
|
80
|
+
|
81
|
+
sage: from sage.features.graphviz import twopi
|
82
|
+
sage: isinstance(twopi(), twopi)
|
83
|
+
True
|
84
|
+
"""
|
85
|
+
Executable.__init__(self, 'twopi', executable='twopi',
|
86
|
+
spkg='graphviz',
|
87
|
+
url='https://www.graphviz.org/')
|
88
|
+
|
89
|
+
|
90
|
+
class Graphviz(JoinFeature):
|
91
|
+
r"""
|
92
|
+
A :class:`~sage.features.Feature` describing the presence of
|
93
|
+
the :class:`dot`, :class:`neato`, and :class:`twopi` executables from the
|
94
|
+
:ref:`graphviz <spkg_graphviz>` package.
|
95
|
+
|
96
|
+
EXAMPLES::
|
97
|
+
|
98
|
+
sage: from sage.features.graphviz import Graphviz
|
99
|
+
sage: Graphviz().is_present() # optional - graphviz
|
100
|
+
FeatureTestResult('graphviz', True)
|
101
|
+
"""
|
102
|
+
def __init__(self):
|
103
|
+
r"""
|
104
|
+
TESTS::
|
105
|
+
|
106
|
+
sage: from sage.features.graphviz import Graphviz
|
107
|
+
sage: isinstance(Graphviz(), Graphviz)
|
108
|
+
True
|
109
|
+
"""
|
110
|
+
JoinFeature.__init__(self, 'graphviz',
|
111
|
+
[dot(), neato(), twopi()],
|
112
|
+
spkg='graphviz',
|
113
|
+
url='https://www.graphviz.org/')
|
114
|
+
|
115
|
+
|
116
|
+
def all_features():
|
117
|
+
return [Graphviz()]
|
sage/features/igraph.py
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
# sage_setup: distribution = sagemath-environment
|
2
|
+
r"""
|
3
|
+
Check for igraph
|
4
|
+
"""
|
5
|
+
|
6
|
+
# ****************************************************************************
|
7
|
+
# Copyright (C) 2021 Matthias Koeppe
|
8
|
+
#
|
9
|
+
# This program is free software: you can redistribute it and/or modify
|
10
|
+
# it under the terms of the GNU General Public License as published by
|
11
|
+
# the Free Software Foundation, either version 2 of the License, or
|
12
|
+
# (at your option) any later version.
|
13
|
+
# https://www.gnu.org/licenses/
|
14
|
+
# ****************************************************************************
|
15
|
+
|
16
|
+
from . import PythonModule
|
17
|
+
from .join_feature import JoinFeature
|
18
|
+
|
19
|
+
|
20
|
+
class python_igraph(JoinFeature):
|
21
|
+
r"""
|
22
|
+
A :class:`sage.features.Feature` describing the presence of the
|
23
|
+
Python package :ref:`igraph <spkg_python_igraph>`.
|
24
|
+
|
25
|
+
EXAMPLES::
|
26
|
+
|
27
|
+
sage: from sage.features.igraph import python_igraph
|
28
|
+
sage: python_igraph().is_present() # optional - python_igraph
|
29
|
+
FeatureTestResult('python_igraph', True)
|
30
|
+
"""
|
31
|
+
def __init__(self):
|
32
|
+
r"""
|
33
|
+
TESTS::
|
34
|
+
|
35
|
+
sage: from sage.features.igraph import python_igraph
|
36
|
+
sage: isinstance(python_igraph(), python_igraph)
|
37
|
+
True
|
38
|
+
"""
|
39
|
+
JoinFeature.__init__(self, 'python_igraph',
|
40
|
+
[PythonModule('igraph', spkg='python_igraph',
|
41
|
+
url='http://igraph.org')])
|
42
|
+
|
43
|
+
def all_features():
|
44
|
+
return [python_igraph()]
|
@@ -0,0 +1,138 @@
|
|
1
|
+
# sage_setup: distribution = sagemath-environment
|
2
|
+
r"""
|
3
|
+
Feature for testing the presence of ``imagemagick``
|
4
|
+
|
5
|
+
Currently we only check for the presence of ``convert`` or ``magick``. When needed, other
|
6
|
+
commands like ``magick-script``, ``mogrify``,
|
7
|
+
``identify``, ``composite``, ``montage``, ``compare``, etc. could be also
|
8
|
+
checked in this module.
|
9
|
+
"""
|
10
|
+
|
11
|
+
# ****************************************************************************
|
12
|
+
# Copyright (C) 2018-2022 Sebastien Labbe <slabqc@gmail.com>
|
13
|
+
#
|
14
|
+
# This program is free software: you can redistribute it and/or modify
|
15
|
+
# it under the terms of the GNU General Public License as published by
|
16
|
+
# the Free Software Foundation, either version 2 of the License, or
|
17
|
+
# (at your option) any later version.
|
18
|
+
# https://www.gnu.org/licenses/
|
19
|
+
# ****************************************************************************
|
20
|
+
|
21
|
+
from . import Executable, FeatureTestResult
|
22
|
+
from .join_feature import JoinFeature
|
23
|
+
|
24
|
+
class Magick(Executable):
|
25
|
+
r"""
|
26
|
+
A :class:`~sage.features.Feature` describing the presence of ``magick`` or the deprecated ``convert``.
|
27
|
+
|
28
|
+
EXAMPLES::
|
29
|
+
|
30
|
+
sage: from sage.features.imagemagick import Magick
|
31
|
+
sage: Magick().is_present() # optional - imagemagick
|
32
|
+
FeatureTestResult('magick', True)
|
33
|
+
"""
|
34
|
+
def __init__(self):
|
35
|
+
r"""
|
36
|
+
TESTS::
|
37
|
+
|
38
|
+
sage: from sage.features.imagemagick import Magick
|
39
|
+
sage: isinstance(Magick(), Magick)
|
40
|
+
True
|
41
|
+
"""
|
42
|
+
Executable.__init__(self, 'magick', executable='magick')
|
43
|
+
try:
|
44
|
+
_ = self.absolute_filename()
|
45
|
+
except RuntimeError:
|
46
|
+
Executable.__init__(self, 'magick', executable='convert')
|
47
|
+
|
48
|
+
def is_functional(self):
|
49
|
+
r"""
|
50
|
+
Return whether command ``magick`` or ``convert`` in the path is functional.
|
51
|
+
|
52
|
+
EXAMPLES::
|
53
|
+
|
54
|
+
sage: from sage.features.imagemagick import Magick
|
55
|
+
sage: Magick().is_functional() # optional - imagemagick
|
56
|
+
FeatureTestResult('magick', True)
|
57
|
+
"""
|
58
|
+
# Create the content of 1-pixel png file
|
59
|
+
content = b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x01\x00\x00\x00\x01\x08\x00\x00\x00\x00:~\x9bU\x00\x00\x00\nIDATx\x9cc`\x00\x00\x00\x02\x00\x01H\xaf\xa4q\x00\x00\x00\x00IEND\xaeB`\x82'
|
60
|
+
|
61
|
+
# NOTE:
|
62
|
+
#
|
63
|
+
# This is how the above content of a 1 pixel PNG was created::
|
64
|
+
#
|
65
|
+
# sage: import numpy as np
|
66
|
+
# sage: from PIL import Image
|
67
|
+
# sage: image = Image.fromarray(np.array([[100]], dtype=np.uint8))
|
68
|
+
# sage: image.save('file.png')
|
69
|
+
# sage: with open('file.png', 'rb') as f:
|
70
|
+
# ....: content = f.read()
|
71
|
+
|
72
|
+
# create a png file with the content
|
73
|
+
from sage.misc.temporary_file import tmp_filename
|
74
|
+
base_filename_png = tmp_filename(ext='.png')
|
75
|
+
with open(base_filename_png, 'wb') as f:
|
76
|
+
f.write(content)
|
77
|
+
|
78
|
+
# Set up filenames
|
79
|
+
import os
|
80
|
+
base, filename_png = os.path.split(base_filename_png)
|
81
|
+
filename, _png = os.path.splitext(filename_png)
|
82
|
+
filename_gif = filename + '.gif'
|
83
|
+
|
84
|
+
# running command magick/convert (taken from sage/plot/animate.py)
|
85
|
+
from subprocess import run
|
86
|
+
cmd = [self.executable, '-dispose', 'Background', '-delay', '20',
|
87
|
+
'-loop', '0', filename_png, filename_gif]
|
88
|
+
|
89
|
+
try:
|
90
|
+
result = run(cmd, cwd=base, capture_output=True, text=True)
|
91
|
+
except OSError as e:
|
92
|
+
return FeatureTestResult(self, False, reason='Running command "{}" '
|
93
|
+
'raised an OSError "{}" '.format(' '.join(cmd), e))
|
94
|
+
|
95
|
+
# If an error occurred, return False
|
96
|
+
if result.returncode:
|
97
|
+
return FeatureTestResult(self, False, reason='Running command "{}" '
|
98
|
+
'returned nonzero exit status "{}" with stderr '
|
99
|
+
'"{}" and stdout "{}".'.format(result.args,
|
100
|
+
result.returncode,
|
101
|
+
result.stderr.strip(),
|
102
|
+
result.stdout.strip()))
|
103
|
+
|
104
|
+
# If necessary, run more tests here
|
105
|
+
# ...
|
106
|
+
|
107
|
+
# The command seems functional
|
108
|
+
return FeatureTestResult(self, True)
|
109
|
+
|
110
|
+
|
111
|
+
class ImageMagick(JoinFeature):
|
112
|
+
r"""
|
113
|
+
A :class:`~sage.features.Feature` describing the presence of
|
114
|
+
:ref:`ImageMagick <spkg_imagemagick>`
|
115
|
+
|
116
|
+
Currently, only the availability of the :class:`magick` (or :class:`convert`) program is checked.
|
117
|
+
|
118
|
+
EXAMPLES::
|
119
|
+
|
120
|
+
sage: from sage.features.imagemagick import ImageMagick
|
121
|
+
sage: ImageMagick().is_present() # optional - imagemagick
|
122
|
+
FeatureTestResult('imagemagick', True)
|
123
|
+
"""
|
124
|
+
def __init__(self):
|
125
|
+
r"""
|
126
|
+
TESTS::
|
127
|
+
|
128
|
+
sage: from sage.features.imagemagick import ImageMagick
|
129
|
+
sage: isinstance(ImageMagick(), ImageMagick)
|
130
|
+
True
|
131
|
+
"""
|
132
|
+
JoinFeature.__init__(self, 'imagemagick',
|
133
|
+
[Magick()],
|
134
|
+
spkg='imagemagick',
|
135
|
+
url='https://www.imagemagick.org/')
|
136
|
+
|
137
|
+
def all_features():
|
138
|
+
return [ImageMagick()]
|