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.
Files changed (70) hide show
  1. passagemath_environment-10.4.1.data/scripts/sage +1140 -0
  2. passagemath_environment-10.4.1.data/scripts/sage-env +667 -0
  3. passagemath_environment-10.4.1.data/scripts/sage-num-threads.py +105 -0
  4. passagemath_environment-10.4.1.data/scripts/sage-python +2 -0
  5. passagemath_environment-10.4.1.data/scripts/sage-venv-config +42 -0
  6. passagemath_environment-10.4.1.data/scripts/sage-version.sh +9 -0
  7. passagemath_environment-10.4.1.dist-info/METADATA +76 -0
  8. passagemath_environment-10.4.1.dist-info/RECORD +70 -0
  9. passagemath_environment-10.4.1.dist-info/WHEEL +5 -0
  10. passagemath_environment-10.4.1.dist-info/top_level.txt +1 -0
  11. sage/all__sagemath_environment.py +4 -0
  12. sage/env.py +496 -0
  13. sage/features/__init__.py +981 -0
  14. sage/features/all.py +126 -0
  15. sage/features/bliss.py +85 -0
  16. sage/features/cddlib.py +38 -0
  17. sage/features/coxeter3.py +45 -0
  18. sage/features/csdp.py +83 -0
  19. sage/features/cython.py +38 -0
  20. sage/features/databases.py +302 -0
  21. sage/features/dvipng.py +40 -0
  22. sage/features/ecm.py +42 -0
  23. sage/features/ffmpeg.py +119 -0
  24. sage/features/four_ti_2.py +55 -0
  25. sage/features/fricas.py +66 -0
  26. sage/features/gap.py +86 -0
  27. sage/features/gfan.py +38 -0
  28. sage/features/giac.py +30 -0
  29. sage/features/graph_generators.py +171 -0
  30. sage/features/graphviz.py +117 -0
  31. sage/features/igraph.py +44 -0
  32. sage/features/imagemagick.py +138 -0
  33. sage/features/interfaces.py +256 -0
  34. sage/features/internet.py +65 -0
  35. sage/features/jmol.py +44 -0
  36. sage/features/join_feature.py +146 -0
  37. sage/features/kenzo.py +77 -0
  38. sage/features/latex.py +300 -0
  39. sage/features/latte.py +85 -0
  40. sage/features/lrs.py +164 -0
  41. sage/features/mcqd.py +45 -0
  42. sage/features/meataxe.py +46 -0
  43. sage/features/mip_backends.py +114 -0
  44. sage/features/msolve.py +68 -0
  45. sage/features/nauty.py +70 -0
  46. sage/features/normaliz.py +43 -0
  47. sage/features/palp.py +65 -0
  48. sage/features/pandoc.py +42 -0
  49. sage/features/pdf2svg.py +41 -0
  50. sage/features/phitigra.py +42 -0
  51. sage/features/pkg_systems.py +195 -0
  52. sage/features/polymake.py +43 -0
  53. sage/features/poppler.py +58 -0
  54. sage/features/rubiks.py +180 -0
  55. sage/features/sagemath.py +1205 -0
  56. sage/features/sat.py +103 -0
  57. sage/features/singular.py +48 -0
  58. sage/features/sirocco.py +45 -0
  59. sage/features/sphinx.py +71 -0
  60. sage/features/standard.py +38 -0
  61. sage/features/symengine_py.py +44 -0
  62. sage/features/tdlib.py +38 -0
  63. sage/features/threejs.py +75 -0
  64. sage/features/topcom.py +67 -0
  65. sage/misc/all__sagemath_environment.py +2 -0
  66. sage/misc/package.py +570 -0
  67. sage/misc/package_dir.py +621 -0
  68. sage/misc/temporary_file.py +546 -0
  69. sage/misc/viewer.py +369 -0
  70. sage/version.py +5 -0
@@ -0,0 +1,114 @@
1
+ # sage_setup: distribution = sagemath-environment
2
+ r"""
3
+ Features for testing the presence of :class:`MixedIntegerLinearProgram` backends
4
+ """
5
+
6
+ # *****************************************************************************
7
+ # Copyright (C) 2021-2022 Matthias Koeppe
8
+ # 2021 Kwankyu Lee
9
+ #
10
+ # Distributed under the terms of the GNU General Public License (GPL)
11
+ # as published by the Free Software Foundation; either version 2 of
12
+ # the License, or (at your option) any later version.
13
+ # https://www.gnu.org/licenses/
14
+ # *****************************************************************************
15
+
16
+ from . import Feature, PythonModule, FeatureTestResult
17
+ from .join_feature import JoinFeature
18
+
19
+
20
+ class MIPBackend(Feature):
21
+ r"""
22
+ A :class:`~sage.features.Feature` describing whether a :class:`MixedIntegerLinearProgram` backend is available.
23
+ """
24
+ def _is_present(self):
25
+ r"""
26
+ Test for the presence of a :class:`MixedIntegerLinearProgram` backend.
27
+
28
+ EXAMPLES::
29
+
30
+ sage: from sage.features.mip_backends import CPLEX
31
+ sage: CPLEX()._is_present() # optional - cplex
32
+ FeatureTestResult('cplex', True)
33
+ """
34
+ try:
35
+ from sage.numerical.mip import MixedIntegerLinearProgram
36
+ MixedIntegerLinearProgram(solver=self.name)
37
+ return FeatureTestResult(self, True)
38
+ except Exception:
39
+ return FeatureTestResult(self, False)
40
+
41
+
42
+ class CPLEX(MIPBackend):
43
+ r"""
44
+ A :class:`~sage.features.Feature` describing whether the :class:`MixedIntegerLinearProgram` backend ``CPLEX`` is available.
45
+ """
46
+ def __init__(self):
47
+ r"""
48
+ TESTS::
49
+
50
+ sage: from sage.features.mip_backends import CPLEX
51
+ sage: CPLEX()._is_present() # optional - cplex
52
+ FeatureTestResult('cplex', True)
53
+ """
54
+ MIPBackend.__init__(self, 'cplex',
55
+ spkg='sage_numerical_backends_cplex')
56
+
57
+
58
+ class Gurobi(MIPBackend):
59
+ r"""
60
+ A :class:`~sage.features.Feature` describing whether the :class:`MixedIntegerLinearProgram` backend ``Gurobi`` is available.
61
+ """
62
+ def __init__(self):
63
+ r"""
64
+ TESTS::
65
+
66
+ sage: from sage.features.mip_backends import Gurobi
67
+ sage: Gurobi()._is_present() # optional - gurobi
68
+ FeatureTestResult('gurobi', True)
69
+ """
70
+ MIPBackend.__init__(self, 'gurobi',
71
+ spkg='sage_numerical_backends_gurobi')
72
+
73
+
74
+ class COIN(JoinFeature):
75
+ r"""
76
+ A :class:`~sage.features.Feature` describing whether the :class:`MixedIntegerLinearProgram` backend ``COIN`` is available.
77
+ """
78
+ def __init__(self):
79
+ r"""
80
+ TESTS::
81
+
82
+ sage: from sage.features.mip_backends import COIN
83
+ sage: COIN()._is_present() # optional - sage_numerical_backends_coin
84
+ FeatureTestResult('sage_numerical_backends_coin', True)
85
+ """
86
+ JoinFeature.__init__(self, 'sage_numerical_backends_coin',
87
+ [MIPBackend('coin')],
88
+ spkg='sage_numerical_backends_coin')
89
+
90
+
91
+ class CVXOPT(JoinFeature):
92
+ r"""
93
+ A :class:`~sage.features.Feature` describing whether the :class:`MixedIntegerLinearProgram` backend ``CVXOPT`` is available.
94
+ """
95
+ def __init__(self):
96
+ r"""
97
+ TESTS::
98
+
99
+ sage: from sage.features.mip_backends import CVXOPT
100
+ sage: CVXOPT()._is_present() # optional - cvxopt
101
+ FeatureTestResult('cvxopt', True)
102
+ """
103
+ JoinFeature.__init__(self, 'cvxopt',
104
+ [MIPBackend('CVXOPT'),
105
+ PythonModule('cvxopt')],
106
+ spkg='cvxopt',
107
+ type='standard')
108
+
109
+
110
+ def all_features():
111
+ return [CPLEX(),
112
+ Gurobi(),
113
+ COIN(),
114
+ CVXOPT()]
@@ -0,0 +1,68 @@
1
+ # sage_setup: distribution = sagemath-environment
2
+ r"""
3
+ Feature for testing the presence of msolve
4
+
5
+ `msolve <https://msolve.lip6.fr/>`_ is a multivariate polynomial system solver.
6
+
7
+ .. SEEALSO::
8
+
9
+ - :mod:`sage.rings.polynomial.msolve`
10
+ """
11
+
12
+ # *****************************************************************************
13
+ # Copyright (C) 2022 Marc Mezzarobba
14
+ #
15
+ # Distributed under the terms of the GNU General Public License (GPL)
16
+ # as published by the Free Software Foundation; either version 2 of
17
+ # the License, or (at your option) any later version.
18
+ # https://www.gnu.org/licenses/
19
+ # *****************************************************************************
20
+
21
+ import subprocess
22
+ from . import Executable
23
+ from . import FeatureTestResult
24
+
25
+ class msolve(Executable):
26
+ r"""
27
+ A :class:`~sage.features.Feature` describing the presence of :ref:`msolve <spkg_msolve>`.
28
+
29
+ EXAMPLES::
30
+
31
+ sage: from sage.features.msolve import msolve
32
+ sage: msolve().is_present() # optional - msolve
33
+ FeatureTestResult('msolve', True)
34
+ """
35
+ def __init__(self):
36
+ r"""
37
+ TESTS::
38
+
39
+ sage: from sage.features.msolve import msolve
40
+ sage: isinstance(msolve(), msolve)
41
+ True
42
+ """
43
+ Executable.__init__(self, "msolve", executable='msolve',
44
+ url='https://msolve.lip6.fr/')
45
+
46
+ def is_functional(self):
47
+ r"""
48
+ Test if our installation of msolve is working.
49
+
50
+ TESTS::
51
+
52
+ sage: from sage.features.msolve import msolve
53
+ sage: msolve().is_functional() # optional - msolve
54
+ FeatureTestResult('msolve', True)
55
+ """
56
+ msolve_out = subprocess.run(["msolve", "-h"], capture_output=True)
57
+
58
+ # if msolve_out.returncode != 0:
59
+ # return FeatureTestResult(self, False, reason="msolve -h returned "
60
+ # f"nonzero exit status {msolve_out.returncode}")
61
+ if (msolve_out.stdout[:46] !=
62
+ b'\nmsolve library for polynomial system solving\n'):
63
+ return FeatureTestResult(self, False,
64
+ reason="output of msolve -h not recognized")
65
+ return FeatureTestResult(self, True)
66
+
67
+ def all_features():
68
+ return [msolve()]
sage/features/nauty.py ADDED
@@ -0,0 +1,70 @@
1
+ # sage_setup: distribution = sagemath-environment
2
+ r"""
3
+ Features for testing the presence of nauty executables
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 sage.env import SAGE_NAUTY_BINS_PREFIX
16
+
17
+ from . import Executable
18
+ from .join_feature import JoinFeature
19
+
20
+
21
+ class NautyExecutable(Executable):
22
+ r"""
23
+ A :class:`~sage.features.Feature` which checks for executables from the :ref:`nauty <spkg_nauty>` package.
24
+
25
+ EXAMPLES::
26
+
27
+ sage: from sage.features.nauty import NautyExecutable
28
+ sage: NautyExecutable('converseg').is_present() # needs nauty
29
+ FeatureTestResult('nauty_converseg', True)
30
+ """
31
+ def __init__(self, name):
32
+ r"""
33
+ TESTS::
34
+
35
+ sage: from sage.features.nauty import NautyExecutable
36
+ sage: isinstance(NautyExecutable('geng'), NautyExecutable)
37
+ True
38
+ """
39
+ Executable.__init__(self, name=f"nauty_{name}",
40
+ executable=f"{SAGE_NAUTY_BINS_PREFIX}{name}",
41
+ spkg='nauty',
42
+ type='standard')
43
+
44
+
45
+ class Nauty(JoinFeature):
46
+ r"""
47
+ A :class:`~sage.features.Feature` describing the presence of the executables
48
+ which comes as a part of :ref:`nauty <spkg_nauty>`.
49
+
50
+ EXAMPLES::
51
+
52
+ sage: from sage.features.nauty import Nauty
53
+ sage: Nauty().is_present() # needs nauty
54
+ FeatureTestResult('nauty', True)
55
+ """
56
+ def __init__(self):
57
+ r"""
58
+ TESTS::
59
+
60
+ sage: from sage.features.nauty import Nauty
61
+ sage: isinstance(Nauty(), Nauty)
62
+ True
63
+ """
64
+ JoinFeature.__init__(self, "nauty",
65
+ [NautyExecutable(name)
66
+ for name in ('directg', 'gentourng', 'geng', 'genbg', 'gentreeg', 'genktreeg')])
67
+
68
+
69
+ def all_features():
70
+ return [Nauty()]
@@ -0,0 +1,43 @@
1
+ # sage_setup: distribution = sagemath-environment
2
+ r"""
3
+ Feature for testing the presence of ``pynormaliz``
4
+ """
5
+
6
+ # *****************************************************************************
7
+ # Copyright (C) 2021 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 PythonModule
16
+ from .join_feature import JoinFeature
17
+
18
+
19
+ class PyNormaliz(JoinFeature):
20
+ r"""
21
+ A :class:`~sage.features.Feature` describing the presence of the
22
+ Python package :ref:`PyNormaliz <spkg_pynormaliz>`.
23
+
24
+ EXAMPLES::
25
+
26
+ sage: from sage.features.normaliz import PyNormaliz
27
+ sage: PyNormaliz().is_present() # optional - pynormaliz
28
+ FeatureTestResult('pynormaliz', True)
29
+ """
30
+ def __init__(self):
31
+ r"""
32
+ TESTS::
33
+
34
+ sage: from sage.features.normaliz import PyNormaliz
35
+ sage: isinstance(PyNormaliz(), PyNormaliz)
36
+ True
37
+ """
38
+ JoinFeature.__init__(self, 'pynormaliz',
39
+ [PythonModule('PyNormaliz', spkg='pynormaliz')])
40
+
41
+
42
+ def all_features():
43
+ return [PyNormaliz()]
sage/features/palp.py ADDED
@@ -0,0 +1,65 @@
1
+ # sage_setup: distribution = sagemath-environment
2
+ r"""
3
+ Feature for testing the presence of ``palp``
4
+ """
5
+ # ****************************************************************************
6
+ # Copyright (C) 2022 Matthias Koeppe
7
+ #
8
+ # This program is free software: you can redistribute it and/or modify
9
+ # it under the terms of the GNU General Public License as published by
10
+ # the Free Software Foundation, either version 2 of the License, or
11
+ # (at your option) any later version.
12
+ # https://www.gnu.org/licenses/
13
+ # ****************************************************************************
14
+
15
+ from . import Executable
16
+ from .join_feature import JoinFeature
17
+
18
+
19
+ class PalpExecutable(Executable):
20
+ r"""
21
+ A :class:`~sage.features.Feature` describing the presence of a :ref:`PALP <spkg_palp>` executable.
22
+
23
+ INPUT:
24
+
25
+ - ``palpprog`` -- string, one of ``'poly'``, ``'class'``, ``'nef'``, ``'cws'``
26
+
27
+ - ``suff`` -- string or ``None``
28
+ """
29
+ def __init__(self, palpprog, suff=None):
30
+ r"""
31
+ TESTS::
32
+
33
+ sage: from sage.features.palp import PalpExecutable
34
+ sage: isinstance(PalpExecutable("poly", 5), PalpExecutable)
35
+ True
36
+ """
37
+ if suff:
38
+ Executable.__init__(self, f"palp_{palpprog}_{suff}d",
39
+ executable=f"{palpprog}-{suff}d.x",
40
+ spkg='palp', type='standard')
41
+ else:
42
+ Executable.__init__(self, f"palp_{palpprog}",
43
+ executable=f"{palpprog}.x",
44
+ spkg='palp', type='standard')
45
+
46
+ class Palp(JoinFeature):
47
+ r"""
48
+ A :class:`~sage.features.Feature` describing the presence of :ref:`PALP <spkg_palp>`.
49
+ """
50
+ def __init__(self):
51
+ r"""
52
+ TESTS::
53
+
54
+ sage: from sage.features.palp import Palp
55
+ sage: isinstance(Palp(), Palp)
56
+ True
57
+ """
58
+ JoinFeature.__init__(self, "palp",
59
+ [PalpExecutable(palpprog, suff)
60
+ for palpprog in ("poly", "class", "nef", "cws")
61
+ for suff in (None, 4, 5, 6, 11)],
62
+ description='PALP')
63
+
64
+ def all_features():
65
+ return [Palp()]
@@ -0,0 +1,42 @@
1
+ # sage_setup: distribution = sagemath-environment
2
+ r"""
3
+ Feature for testing the presence of ``pandoc``
4
+ """
5
+ # ****************************************************************************
6
+ # Copyright (C) 2018 Thierry Monteil <sage!lma.metelu.net>
7
+ # 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 Executable
17
+
18
+
19
+ class Pandoc(Executable):
20
+ r"""
21
+ A :class:`~sage.features.Feature` describing the presence of :ref:`pandoc <spkg_pandoc>`.
22
+
23
+ EXAMPLES::
24
+
25
+ sage: from sage.features.pandoc import Pandoc
26
+ sage: Pandoc().is_present() # optional - pandoc
27
+ FeatureTestResult('pandoc', True)
28
+ """
29
+ def __init__(self):
30
+ r"""
31
+ TESTS::
32
+
33
+ sage: from sage.features.pandoc import Pandoc
34
+ sage: isinstance(Pandoc(), Pandoc)
35
+ True
36
+ """
37
+ Executable.__init__(self, "pandoc", executable='pandoc',
38
+ url='https://pandoc.org/')
39
+
40
+
41
+ def all_features():
42
+ return [Pandoc()]
@@ -0,0 +1,41 @@
1
+ # sage_setup: distribution = sagemath-environment
2
+ r"""
3
+ Feature for testing the presence of ``pdf2svg``
4
+ """
5
+ # ****************************************************************************
6
+ # Copyright (C) 2021 Sebastien Labbe <slabqc@gmail.com>
7
+ #
8
+ # This program is free software: you can redistribute it and/or modify
9
+ # it under the terms of the GNU General Public License as published by
10
+ # the Free Software Foundation, either version 2 of the License, or
11
+ # (at your option) any later version.
12
+ # https://www.gnu.org/licenses/
13
+ # ****************************************************************************
14
+
15
+ from . import Executable
16
+
17
+ class pdf2svg(Executable):
18
+ r"""
19
+ A :class:`~sage.features.Feature` describing the presence of :ref:`pdf2svg <spkg_pdf2svg>`.
20
+
21
+ EXAMPLES::
22
+
23
+ sage: from sage.features.pdf2svg import pdf2svg
24
+ sage: pdf2svg().is_present() # optional - pdf2svg
25
+ FeatureTestResult('pdf2svg', True)
26
+ """
27
+ def __init__(self):
28
+ r"""
29
+ TESTS::
30
+
31
+ sage: from sage.features.pdf2svg import pdf2svg
32
+ sage: isinstance(pdf2svg(), pdf2svg)
33
+ True
34
+ """
35
+ Executable.__init__(self, "pdf2svg", executable='pdf2svg',
36
+ spkg='pdf2svg',
37
+ url='http://www.cityinthesky.co.uk/opensource/pdf2svg/')
38
+
39
+
40
+ def all_features():
41
+ return [pdf2svg()]
@@ -0,0 +1,42 @@
1
+ # sage_setup: distribution = sagemath-environment
2
+ r"""
3
+ Check for ``phitigra``
4
+ """
5
+
6
+ # *****************************************************************************
7
+ # Copyright (C) 2022 Jean-Florent Raymond
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 PythonModule
16
+
17
+
18
+ class Phitigra(PythonModule):
19
+ r"""
20
+ A :class:`sage.features.Feature` describing the presence of :ref:`phitigra <spkg_phitigra>`.
21
+
22
+ Phitigra is provided by an optional package in the Sage distribution.
23
+
24
+ EXAMPLES::
25
+
26
+ sage: from sage.features.phitigra import Phitigra
27
+ sage: Phitigra().is_present() # optional - phitigra
28
+ FeatureTestResult('phitigra', True)
29
+ """
30
+ def __init__(self):
31
+ r"""
32
+ TESTS::
33
+
34
+ sage: from sage.features.phitigra import Phitigra
35
+ sage: isinstance(Phitigra(), Phitigra)
36
+ True
37
+ """
38
+ PythonModule.__init__(self, 'phitigra', spkg='phitigra')
39
+
40
+
41
+ def all_features():
42
+ return [Phitigra()]
@@ -0,0 +1,195 @@
1
+ # sage_setup: distribution = sagemath-environment
2
+ r"""
3
+ Features for testing the presence of package systems ``sage_spkg``, ``conda``, ``pip``, ``debian``, ``fedora`` etc.
4
+ """
5
+
6
+ # *****************************************************************************
7
+ # Copyright (C) 2021-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 Feature
16
+
17
+
18
+ class PackageSystem(Feature):
19
+ r"""
20
+ A :class:`Feature` describing a system package manager.
21
+
22
+ EXAMPLES::
23
+
24
+ sage: from sage.features.pkg_systems import PackageSystem
25
+ sage: PackageSystem('conda')
26
+ Feature('conda')
27
+ """
28
+ def _is_present(self):
29
+ r"""
30
+ Test whether ``self`` appears in the list of available package systems.
31
+
32
+ EXAMPLES::
33
+
34
+ sage: from sage.features.pkg_systems import PackageSystem
35
+ sage: debian = PackageSystem('debian')
36
+ sage: debian.is_present() # indirect doctest, random
37
+ True
38
+ """
39
+ from . import package_systems
40
+ return self in package_systems()
41
+
42
+ def spkg_installation_hint(self, spkgs, *, prompt=" !", feature=None):
43
+ r"""
44
+ Return a string that explains how to install ``feature``.
45
+
46
+ EXAMPLES::
47
+
48
+ sage: from sage.features.pkg_systems import PackageSystem
49
+ sage: homebrew = PackageSystem('homebrew')
50
+ sage: homebrew.spkg_installation_hint('openblas') # optional - SAGE_ROOT
51
+ 'To install openblas using the homebrew package manager, you can try to run:\n!brew install openblas'
52
+ """
53
+ if isinstance(spkgs, (tuple, list)):
54
+ spkgs = ' '.join(spkgs)
55
+ if feature is None:
56
+ feature = spkgs
57
+ return self._spkg_installation_hint(spkgs, prompt, feature)
58
+
59
+ def _spkg_installation_hint(self, spkgs, prompt, feature):
60
+ r"""
61
+ Return a string that explains how to install ``feature``.
62
+
63
+ Override this method in derived classes.
64
+
65
+ EXAMPLES::
66
+
67
+ sage: from sage.features.pkg_systems import PackageSystem
68
+ sage: fedora = PackageSystem('fedora')
69
+ sage: fedora.spkg_installation_hint('openblas') # optional - SAGE_ROOT
70
+ 'To install openblas using the fedora package manager, you can try to run:\n!sudo yum install openblas-devel'
71
+ """
72
+ from subprocess import run, CalledProcessError, PIPE
73
+ lines = []
74
+ system = self.name
75
+ try:
76
+ proc = run(f'sage-get-system-packages {system} {spkgs}',
77
+ shell=True, capture_output=True, text=True, check=True)
78
+ system_packages = proc.stdout.strip()
79
+ print_sys = f'sage-print-system-package-command {system} --verbose --sudo --prompt="{prompt}"'
80
+ command = f'{print_sys} update && {print_sys} install {system_packages}'
81
+ proc = run(command, shell=True, capture_output=True, text=True, check=True)
82
+ command = proc.stdout.strip()
83
+ if command:
84
+ lines.append(f'To install {feature} using the {system} package manager, you can try to run:')
85
+ lines.append(command)
86
+ return '\n'.join(lines)
87
+ except CalledProcessError:
88
+ pass
89
+ return f'No equivalent system packages for {system} are known to Sage.'
90
+
91
+
92
+ class SagePackageSystem(PackageSystem):
93
+ r"""
94
+ A :class:`Feature` describing the package manager of the SageMath distribution.
95
+
96
+ EXAMPLES::
97
+
98
+ sage: from sage.features.pkg_systems import SagePackageSystem
99
+ sage: SagePackageSystem()
100
+ Feature('sage_spkg')
101
+ """
102
+ @staticmethod
103
+ def __classcall__(cls):
104
+ r"""
105
+ Normalize initargs.
106
+
107
+ TESTS::
108
+
109
+ sage: from sage.features.pkg_systems import SagePackageSystem
110
+ sage: SagePackageSystem() is SagePackageSystem() # indirect doctest
111
+ True
112
+ """
113
+ return PackageSystem.__classcall__(cls, "sage_spkg")
114
+
115
+ def _is_present(self):
116
+ r"""
117
+ Test whether ``sage-spkg`` is available.
118
+
119
+ EXAMPLES::
120
+
121
+ sage: from sage.features.pkg_systems import SagePackageSystem
122
+ sage: bool(SagePackageSystem().is_present()) # indirect doctest, optional - sage_spkg
123
+ True
124
+ """
125
+ from subprocess import run, DEVNULL, CalledProcessError
126
+ try:
127
+ # "sage -p" is a fast way of checking whether sage-spkg is available.
128
+ run('sage -p', shell=True, stdout=DEVNULL, stderr=DEVNULL, check=True)
129
+ except CalledProcessError:
130
+ return False
131
+ # Check if there are any installation records.
132
+ try:
133
+ from sage.misc.package import installed_packages
134
+ except ImportError:
135
+ return False
136
+ for pkg in installed_packages(exclude_pip=True):
137
+ return True
138
+ return False
139
+
140
+ def _spkg_installation_hint(self, spkgs, prompt, feature):
141
+ r"""
142
+ Return a string that explains how to install ``feature``.
143
+
144
+ EXAMPLES::
145
+
146
+ sage: from sage.features.pkg_systems import SagePackageSystem
147
+ sage: print(SagePackageSystem().spkg_installation_hint(['foo', 'bar'], prompt="### ", feature='foobarability')) # indirect doctest
148
+ To install foobarability using the Sage package manager, you can try to run:
149
+ ### sage -i foo bar
150
+ """
151
+ lines = []
152
+ lines.append(f'To install {feature} using the Sage package manager, you can try to run:')
153
+ lines.append(f'{prompt}sage -i {spkgs}')
154
+ return '\n'.join(lines)
155
+
156
+
157
+ class PipPackageSystem(PackageSystem):
158
+ r"""
159
+ A :class:`Feature` describing the Pip package manager.
160
+
161
+ EXAMPLES::
162
+
163
+ sage: from sage.features.pkg_systems import PipPackageSystem
164
+ sage: PipPackageSystem()
165
+ Feature('pip')
166
+ """
167
+ @staticmethod
168
+ def __classcall__(cls):
169
+ r"""
170
+ Normalize initargs.
171
+
172
+ TESTS::
173
+
174
+ sage: from sage.features.pkg_systems import PipPackageSystem
175
+ sage: PipPackageSystem() is PipPackageSystem() # indirect doctest
176
+ True
177
+ """
178
+ return PackageSystem.__classcall__(cls, "pip")
179
+
180
+ def _is_present(self):
181
+ r"""
182
+ Test whether ``pip`` is available.
183
+
184
+ EXAMPLES::
185
+
186
+ sage: from sage.features.pkg_systems import PipPackageSystem
187
+ sage: bool(PipPackageSystem().is_present()) # indirect doctest
188
+ True
189
+ """
190
+ from subprocess import run, DEVNULL, CalledProcessError
191
+ try:
192
+ run('sage -pip --version', shell=True, stdout=DEVNULL, stderr=DEVNULL, check=True)
193
+ return True
194
+ except CalledProcessError:
195
+ return False