Skip to content

Commit

Permalink
Trac #31296: sage.features.Executable: Prepend $SAGE_VENV/bin:$SAGE_L…
Browse files Browse the repository at this point in the history
…OCAL/bin to PATH

Follow-up from #22731.

This is so that Sage becomes fully functional even when not being run
from within `sage-env` (which sets `PATH`)

Of course, `PATH` is not actually manipulated, only `Executable` finds
the executable in more places.

As an illustration, we update `sage.interfaces.four_ti_2` and
`sage.interfaces.latte` to use `Executable.absolute_filename()` from
#31292. Then, after `sage -i 4ti2 latte_int`, the following works with
this ticket:
{{{
$ venv/bin/python3 -c 'import sage.all; from sage.interfaces.four_ti_2
import four_ti_2; print(four_ti_2.groebner(lat=[[1,2,3],[1,1,1]]))'
$ venv/bin/python3 -c 'from sage.all import *; print(Polyhedron([[-3,
0], [0, 9]]).volume(measure="induced_rational"))'
3
}}}

In follow-up tickets, other code that calls executables needs to be
updated to use `Executable.absolute_path()` from #31292. The first
tickets to do so are #33440, #33465, #33466, #32645, #33467, #33405.

This is work towards:
- #30818 Meta-ticket: Set environment for subprocesses invoked by Sage
- #31295 Meta-ticket: Replace imports from deprecated distutils

URL: https://trac.sagemath.org/31296
Reported by: mkoeppe
Ticket author(s): Matthias Koeppe
Reviewer(s): Dima Pasechnik, Tobias Diez
  • Loading branch information
Release Manager committed Mar 8, 2022
2 parents 20577cc + 160e9af commit 6376bce
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 28 deletions.
17 changes: 16 additions & 1 deletion src/sage/features/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,9 @@

import os
import shutil
from pathlib import Path

from sage.env import SAGE_SHARE
from sage.env import SAGE_SHARE, SAGE_LOCAL, SAGE_VENV


class TrivialClasscallMetaClass(type):
Expand Down Expand Up @@ -517,6 +518,10 @@ class Executable(FileFeature):
r"""
A feature describing an executable in the ``PATH``.
In an installation of Sage with ``SAGE_LOCAL`` different from ``SAGE_VENV``, the
executable is searched first in ``SAGE_VENV/bin``, then in ``SAGE_LOCAL/bin``,
then in ``PATH``.
.. NOTE::
Overwrite :meth:`is_functional` if you also want to check whether
Expand Down Expand Up @@ -594,6 +599,16 @@ def absolute_filename(self) -> str:
sage.features.FeatureNotPresentError: does-not-exist is not available.
Executable 'does-not-exist-xxxxyxyyxyy' not found on PATH.
"""
if SAGE_LOCAL:
if Path(SAGE_VENV).resolve() != Path(SAGE_LOCAL).resolve():
# As sage.env currently gives SAGE_LOCAL a fallback value from SAGE_VENV,
# SAGE_LOCAL is never unset. So we only use it if it differs from SAGE_VENV.
search_path = ':'.join([os.path.join(SAGE_VENV, 'bin'),
os.path.join(SAGE_LOCAL, 'bin')])
path = shutil.which(self.executable, path=search_path)
if path is not None:
return path
# Now look up in the regular PATH.
path = shutil.which(self.executable)
if path is not None:
return path
Expand Down
10 changes: 5 additions & 5 deletions src/sage/geometry/polyhedron/base_QQ.py
Original file line number Diff line number Diff line change
Expand Up @@ -734,31 +734,31 @@ def _ehrhart_polynomial_latte(self, verbose=False, dual=None,
sage: p = P._ehrhart_polynomial_latte(maxdet=5, verbose=True) # optional - latte_int
This is LattE integrale ...
...
Invocation: count --ehrhart-polynomial '--redundancy-check=none' --cdd '--maxdet=5' /dev/stdin
Invocation: ...count --ehrhart-polynomial '--redundancy-check=none' --cdd '--maxdet=5' /dev/stdin
...
sage: p # optional - latte_int
1/2*t^2 + 3/2*t + 1
sage: p = P._ehrhart_polynomial_latte(dual=True, verbose=True) # optional - latte_int
This is LattE integrale ...
...
Invocation: count --ehrhart-polynomial '--redundancy-check=none' --cdd --dual /dev/stdin
Invocation: ...count --ehrhart-polynomial '--redundancy-check=none' --cdd --dual /dev/stdin
...
sage: p # optional - latte_int
1/2*t^2 + 3/2*t + 1
sage: p = P._ehrhart_polynomial_latte(irrational_primal=True, verbose=True) # optional - latte_int
This is LattE integrale ...
...
Invocation: count --ehrhart-polynomial '--redundancy-check=none' --cdd --irrational-primal /dev/stdin
Invocation: ...count --ehrhart-polynomial '--redundancy-check=none' --cdd --irrational-primal /dev/stdin
...
sage: p # optional - latte_int
1/2*t^2 + 3/2*t + 1
sage: p = P._ehrhart_polynomial_latte(irrational_all_primal=True, verbose=True) # optional - latte_int
This is LattE integrale ...
...
Invocation: count --ehrhart-polynomial '--redundancy-check=none' --cdd --irrational-all-primal /dev/stdin
Invocation: ...count --ehrhart-polynomial '--redundancy-check=none' --cdd --irrational-all-primal /dev/stdin
...
sage: p # optional - latte_int
1/2*t^2 + 3/2*t + 1
Expand All @@ -770,7 +770,7 @@ def _ehrhart_polynomial_latte(self, verbose=False, dual=None,
...
RuntimeError: LattE integrale program failed (exit code 1):
...
Invocation: count --ehrhart-polynomial '--redundancy-check=none' --cdd '--bim-bam-boum=19' /dev/stdin
Invocation: ...count --ehrhart-polynomial '--redundancy-check=none' --cdd '--bim-bam-boum=19' /dev/stdin
Unknown command/option --bim-bam-boum=19
"""

Expand Down
10 changes: 5 additions & 5 deletions src/sage/geometry/polyhedron/base_ZZ.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,31 +194,31 @@ def _ehrhart_polynomial_latte(self, verbose=False, dual=None,
sage: p = P._ehrhart_polynomial_latte(maxdet=5, verbose=True) # optional - latte_int
This is LattE integrale ...
...
Invocation: count --ehrhart-polynomial '--redundancy-check=none' --cdd '--maxdet=5' /dev/stdin
Invocation: ...count --ehrhart-polynomial '--redundancy-check=none' --cdd '--maxdet=5' /dev/stdin
...
sage: p # optional - latte_int
1/2*t^2 + 3/2*t + 1
sage: p = P._ehrhart_polynomial_latte(dual=True, verbose=True) # optional - latte_int
This is LattE integrale ...
...
Invocation: count --ehrhart-polynomial '--redundancy-check=none' --cdd --dual /dev/stdin
Invocation: ...count --ehrhart-polynomial '--redundancy-check=none' --cdd --dual /dev/stdin
...
sage: p # optional - latte_int
1/2*t^2 + 3/2*t + 1
sage: p = P._ehrhart_polynomial_latte(irrational_primal=True, verbose=True) # optional - latte_int
This is LattE integrale ...
...
Invocation: count --ehrhart-polynomial '--redundancy-check=none' --cdd --irrational-primal /dev/stdin
Invocation: ...count --ehrhart-polynomial '--redundancy-check=none' --cdd --irrational-primal /dev/stdin
...
sage: p # optional - latte_int
1/2*t^2 + 3/2*t + 1
sage: p = P._ehrhart_polynomial_latte(irrational_all_primal=True, verbose=True) # optional - latte_int
This is LattE integrale ...
...
Invocation: count --ehrhart-polynomial '--redundancy-check=none' --cdd --irrational-all-primal /dev/stdin
Invocation: ...count --ehrhart-polynomial '--redundancy-check=none' --cdd --irrational-all-primal /dev/stdin
...
sage: p # optional - latte_int
1/2*t^2 + 3/2*t + 1
Expand All @@ -230,7 +230,7 @@ def _ehrhart_polynomial_latte(self, verbose=False, dual=None,
...
RuntimeError: LattE integrale program failed (exit code 1):
...
Invocation: count --ehrhart-polynomial '--redundancy-check=none' --cdd '--bim-bam-boum=19' /dev/stdin
Invocation: ...count --ehrhart-polynomial '--redundancy-check=none' --cdd '--bim-bam-boum=19' /dev/stdin
Unknown command/option --bim-bam-boum=19
"""
# note: the options below are explicitly written in the function
Expand Down
6 changes: 3 additions & 3 deletions src/sage/interfaces/four_ti_2.py
Original file line number Diff line number Diff line change
Expand Up @@ -295,11 +295,11 @@ def call(self, command, project, verbose=True, *, options=()):
[-5 3 0]
"""
import subprocess
import shlex
feature = FourTi2Executable(command)
feature.require()
executable = feature.executable
executable = feature.absolute_filename()
options = " ".join(options)
cmd = f'{executable} {options} {project}'
cmd = f'{shlex.quote(executable)} {options} {project}'
if verbose is False:
cmd += " > /dev/null 2> /dev/null"
subprocess.call(cmd, shell=True, cwd=self.directory())
Expand Down
18 changes: 6 additions & 12 deletions src/sage/interfaces/latte.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from subprocess import Popen, PIPE
from sage.misc.misc import SAGE_TMP
from sage.rings.integer import Integer
from sage.features.latte import Latte
from sage.features.latte import Latte_count, Latte_integrate


def count(arg, ehrhart_polynomial=False, multivariate_generating_function=False, raw_output=False, verbose=False, **kwds):
Expand Down Expand Up @@ -95,7 +95,7 @@ def count(arg, ehrhart_polynomial=False, multivariate_generating_function=False,
sage: n = count(cddin, cdd=True, verbose=True, raw_output=True) # optional - latte_int
This is LattE integrale ...
...
Invocation: count '--redundancy-check=none' --cdd /dev/stdin
Invocation: ...count '--redundancy-check=none' --cdd /dev/stdin
...
Total Unimodular Cones: ...
Maximum number of simplicial cones in memory at once: ...
Expand All @@ -122,12 +122,9 @@ def count(arg, ehrhart_polynomial=False, multivariate_generating_function=False,
...
The polyhedron is unbounded.
"""
# Check that LattE is present
Latte().require()

arg = str_to_bytes(arg)

args = ['count']
args = [Latte_count().absolute_filename()]
if ehrhart_polynomial and multivariate_generating_function:
raise ValueError
if ehrhart_polynomial:
Expand Down Expand Up @@ -274,7 +271,7 @@ def integrate(arg, polynomial=None, algorithm='triangulate', raw_output=False, v
sage: ans = integrate(cddin, f, cdd=True, verbose=True, raw_output=True) # optional - latte_int
This is LattE integrale ...
...
Invocation: integrate --valuation=integrate --triangulate --redundancy-check=none --cdd --monomials=... /dev/stdin
Invocation: ...integrate --valuation=integrate --triangulate --redundancy-check=none --cdd --monomials=... /dev/stdin
...
Testing triangulate algorithm::
Expand Down Expand Up @@ -316,7 +313,7 @@ def integrate(arg, polynomial=None, algorithm='triangulate', raw_output=False, v
sage: ans = integrate(cddin, cdd=True, raw_output=True, verbose=True) # optional - latte_int
This is LattE integrale ...
...
Invocation: integrate --valuation=volume --triangulate --redundancy-check=none --cdd /dev/stdin
Invocation: ...integrate --valuation=volume --triangulate --redundancy-check=none --cdd /dev/stdin
...
Testing the runtime error::
Expand All @@ -330,14 +327,11 @@ def integrate(arg, polynomial=None, algorithm='triangulate', raw_output=False, v
...
determinant: nonsquare matrix
"""
# Check that LattE is present
Latte().require()

arg = str_to_bytes(arg)

from sage.rings.rational import Rational

args = ['integrate']
args = [Latte_integrate().absolute_filename()]

got_polynomial = True if polynomial is not None else False

Expand Down
5 changes: 3 additions & 2 deletions src/sage/sandpiles/sandpile.py
Original file line number Diff line number Diff line change
Expand Up @@ -5173,8 +5173,9 @@ def _set_linear_system(self):
# compute
try:
import os
path_to_zsolve = FourTi2Executable('zsolve').executable
os.system(path_to_zsolve + ' -q ' + lin_sys + ' > ' + lin_sys_log)
import shlex
path_to_zsolve = FourTi2Executable('zsolve').absolute_filename()
os.system(shlex.quote(path_to_zsolve) + ' -q ' + lin_sys + ' > ' + lin_sys_log)
# process the results
zhom_file = open(lin_sys_zhom,'r')
except IOError:
Expand Down

0 comments on commit 6376bce

Please sign in to comment.