Listing Sage packages¶
This module can be used to see which Sage packages are installed and which packages are available for installation.
For more information about creating Sage packages, see the “Packaging Third-Party Code” section of the Sage Developer’s Guide.
Actually installing the packages should be done via the command line, using the following commands:
sage -i PACKAGE_NAME
– install the given packagesage -f PACKAGE_NAME
– re-install the given package, even if it was already installed
To list the packages available, either use in a terminal one of sage
-standard
, sage -optional
or sage -experimental
. Or the following
command inside Sage:
sage: from sage.misc.package import list_packages
sage: pkgs = list_packages(local=True) # optional - sage_spkg
sage: sorted(pkgs.keys()) # optional - sage_spkg, random
['4ti2',
'alabaster',
...
'zlib']
>>> from sage.all import *
>>> from sage.misc.package import list_packages
>>> pkgs = list_packages(local=True) # optional - sage_spkg
>>> sorted(pkgs.keys()) # optional - sage_spkg, random
['4ti2',
'alabaster',
...
'zlib']
Functions¶
- class sage.misc.package.PackageInfo(name: str, type: str | None = None, source: str | None = None, installed_version: str | None = None, remote_version: str | None = None)[source]¶
Bases:
NamedTuple
Represents information about a package.
- name: str¶
Alias for field number 0
- sage.misc.package.installed_packages(exclude_pip=True)[source]¶
Return a dictionary of all installed packages, with version numbers.
INPUT:
exclude_pip
– boolean (default:True
); whether “pip” packages are excluded from the list
EXAMPLES:
Below we test for a standard package without
spkg-configure.m4
script that should be installed inSAGE_LOCAL
. When Sage is installed by the Sage distribution (indicated by featuresage_spkg
), we should have the installation record for this package. (We do not test for installation records of Python packages. OurSAGE_VENV
is not necessarily the main Sage venv; it could be a user-created venv or a venv created by tox.):sage: # optional - sage_spkg sage: from sage.misc.package import installed_packages sage: sorted(installed_packages().keys()) [...'gnulib', ...] sage: installed_packages()['gnulib'] # random 'f9b39c4e337f1dc0dd07c4f3985c476fb875d799'
>>> from sage.all import * >>> # optional - sage_spkg >>> from sage.misc.package import installed_packages >>> sorted(installed_packages().keys()) [...'gnulib', ...] >>> installed_packages()['gnulib'] # random 'f9b39c4e337f1dc0dd07c4f3985c476fb875d799'
See also
- sage.misc.package.is_package_installed(package, exclude_pip=True)[source]¶
Return whether (any version of)
package
is installed.INPUT:
package
– the name of the packageexclude_pip
– boolean (default:True
); whether to consider pip type packages
EXAMPLES:
sage: from sage.misc.package import is_package_installed sage: is_package_installed('gnulib') # optional - sage_spkg True
>>> from sage.all import * >>> from sage.misc.package import is_package_installed >>> is_package_installed('gnulib') # optional - sage_spkg True
Giving just the beginning of the package name is not good enough:
sage: is_package_installed('conway_poly') # optional - sage_spkg False
>>> from sage.all import * >>> is_package_installed('conway_poly') # optional - sage_spkg False
Otherwise, installing “pillow” would cause this function to think that “pil” is installed, for example.
Note
Do not use this function to check whether you can use a feature from an external library. This only checks whether something was installed with
sage -i
but it may have been installed by other means (for example if this copy of Sage has been installed as part of a distribution.) Use the framework provided bysage.features
to check whether a library is installed and functional.
- sage.misc.package.is_package_installed_and_updated(package)[source]¶
Return whether the given package is installed and up-to-date.
INPUT:
package
– the name of the package
EXAMPLES:
sage: from sage.misc.package import is_package_installed_and_updated sage: is_package_installed_and_updated("alabaster") # optional - build, random False
>>> from sage.all import * >>> from sage.misc.package import is_package_installed_and_updated >>> is_package_installed_and_updated("alabaster") # optional - build, random False
- sage.misc.package.list_packages(pkg_sources, local, ignore_URLError, exclude_pip, *pkg_types)[source]¶
Return a dictionary of information about each package.
The keys are package names and values are named tuples with the following keys:
'type'
– either'base
,'standard'
,'optional'
, or'experimental'
'source'
– either'normal', ``'pip'
, or'script'
'installed'
– boolean'installed_version'
–None
or a string'remote_version'
– string
INPUT:
pkg_types
– (optional) a sublist of'base
,'standard'
,'optional'
, or'experimental'
. If provided, list only the packages with the given type(s), otherwise list all packages.pkg_sources
– (optional) a sublist of'normal', ``'pip'
, or'script'
. If provided, list only the packages with the given source(s), otherwise list all packages.local
– boolean (default:False
); if set toTrue
, then do not consult remote (PyPI) repositories for package versions (only applicable for'pip'
type)exclude_pip
– boolean (default:False
); if set toTrue
, then pip packages are not considered. This is the same as removing'pip'
frompkg_sources
ignore_URLError
– boolean (default:False
); if set toTrue
, then connection errors will be ignored
EXAMPLES:
sage: # optional - sage_spkg sage: from sage.misc.package import list_packages sage: L = list_packages('standard') sage: sorted(L.keys()) # random ['alabaster', 'babel', ... 'zlib'] sage: sage_conf_info = L['sage_conf'] sage: sage_conf_info.type 'standard' sage: sage_conf_info.is_installed() True sage: sage_conf_info.source 'script' sage: # optional - sage_spkg internet sage: L = list_packages(pkg_sources=['pip'], local=True) sage: bp_info = L['biopython'] sage: bp_info.type 'optional' sage: bp_info.source 'pip'
>>> from sage.all import * >>> # optional - sage_spkg >>> from sage.misc.package import list_packages >>> L = list_packages('standard') >>> sorted(L.keys()) # random ['alabaster', 'babel', ... 'zlib'] >>> sage_conf_info = L['sage_conf'] >>> sage_conf_info.type 'standard' >>> sage_conf_info.is_installed() True >>> sage_conf_info.source 'script' >>> # optional - sage_spkg internet >>> L = list_packages(pkg_sources=['pip'], local=True) >>> bp_info = L['biopython'] >>> bp_info.type 'optional' >>> bp_info.source 'pip'
Check the option
exclude_pip
:sage: [p for p, d in list_packages('optional', exclude_pip=True).items() # optional - sage_spkg ....: if d.source == 'pip'] []
>>> from sage.all import * >>> [p for p, d in list_packages('optional', exclude_pip=True).items() # optional - sage_spkg ... if d.source == 'pip'] []
- sage.misc.package.package_manifest(package)[source]¶
Return the manifest for
package
.INPUT:
package
– package name
The manifest is written in the file
SAGE_SPKG_INST/package-VERSION
. It is a JSON file containing a dictionary with the package name, version, installation date, list of installed files, etc.EXAMPLES:
sage: # optional - sage_spkg sage: from sage.misc.package import package_manifest sage: manifest = package_manifest('gnulib') sage: manifest['package_name'] == 'gnulib' True sage: 'files' in manifest True
>>> from sage.all import * >>> # optional - sage_spkg >>> from sage.misc.package import package_manifest >>> manifest = package_manifest('gnulib') >>> manifest['package_name'] == 'gnulib' True >>> 'files' in manifest True
Test a nonexistent package:
sage: package_manifest('dummy-package') # optional - sage_spkg Traceback (most recent call last): ... KeyError: 'dummy-package'
>>> from sage.all import * >>> package_manifest('dummy-package') # optional - sage_spkg Traceback (most recent call last): ... KeyError: 'dummy-package'
- sage.misc.package.package_versions(package_type, local=False)[source]¶
Return version information for each Sage package.
INPUT:
package_type
– string; one of'standard'
,'optional'
or'experimental'
local
– boolean (default:False
); only query local data (no internet needed)
For packages of the given type, return a dictionary whose entries are of the form
'package': (installed, latest)
, whereinstalled
is the installed version (orNone
if not installed) andlatest
is the latest available version. If the package has a directory inSAGE_ROOT/build/pkgs/
, thenlatest
is determined by the filepackage-version.txt
in that directory. Iflocal
isFalse
, then Sage’s servers are queried for package information.See also
EXAMPLES:
sage: # optional - sage_spkg sage: from sage.misc.package import package_versions sage: std = package_versions('standard', local=True) sage: 'gap' in std True sage: std['zlib'] # random ('1.2.11.p0', '1.2.11.p0')
>>> from sage.all import * >>> # optional - sage_spkg >>> from sage.misc.package import package_versions >>> std = package_versions('standard', local=True) >>> 'gap' in std True >>> std['zlib'] # random ('1.2.11.p0', '1.2.11.p0')
- sage.misc.package.pip_installed_packages(normalization=None)[source]¶
Return a dictionary \(name->version\) of installed pip packages.
This command returns all pip-installed packages. Not only Sage packages.
INPUT:
normalization
– (default:None
) according to which rule to normalize the package name, eitherNone
(as is) or'spkg'
(format as in the Sage distribution inbuild/pkgs/
), i.e., lowercased and dots and dashes replaced by underscores.
EXAMPLES:
sage: # optional - sage_spkg sage: from sage.misc.package import pip_installed_packages sage: d = pip_installed_packages() sage: 'scipy' in d or 'SciPy' in d # needs scipy True sage: 'beautifulsoup4' in d # needs beautifulsoup4 True sage: 'prompt-toolkit' in d or 'prompt_toolkit' in d # whether - or _ appears in the name depends on the setuptools version used for building the package True sage: d = pip_installed_packages(normalization='spkg') sage: d['prompt_toolkit'] '...' sage: d['scipy'] # needs scipy '...'
>>> from sage.all import * >>> # optional - sage_spkg >>> from sage.misc.package import pip_installed_packages >>> d = pip_installed_packages() >>> 'scipy' in d or 'SciPy' in d # needs scipy True >>> 'beautifulsoup4' in d # needs beautifulsoup4 True >>> 'prompt-toolkit' in d or 'prompt_toolkit' in d # whether - or _ appears in the name depends on the setuptools version used for building the package True >>> d = pip_installed_packages(normalization='spkg') >>> d['prompt_toolkit'] '...' >>> d['scipy'] # needs scipy '...'
- sage.misc.package.pip_remote_version(pkg, pypi_url='https://pypi.org/pypi', ignore_URLError=False)[source]¶
Return the version of this pip package available on PyPI.
INPUT:
pkg
– the packagepypi_url
– string (default: standard PyPI url) an optional Python package repository to useignore_URLError
– boolean (default:False
); if set toTrue
then no error is raised if the connection fails and the function returnsNone
EXAMPLES:
The following test does fail if there is no TLS support (see e.g. Issue #19213):
sage: from sage.misc.package import pip_remote_version sage: pip_remote_version('beautifulsoup4') # optional - internet # not tested '...'
>>> from sage.all import * >>> from sage.misc.package import pip_remote_version >>> pip_remote_version('beautifulsoup4') # optional - internet # not tested '...'
These tests are reliable since the tested package does not exist:
sage: nap = 'hey_this_is_NOT_a_python_package' sage: pypi = 'http://this.is.not.pypi.com/' sage: pip_remote_version(nap, pypi_url=pypi, ignore_URLError=True) # optional - internet doctest:...: UserWarning: failed to fetch the version of pkg='hey_this_is_NOT_a_python_package' at http://this.is.not.pypi.com/.../json sage: pip_remote_version(nap, pypi_url=pypi, ignore_URLError=False) # optional - internet Traceback (most recent call last): ... HTTPError: HTTP Error 404: Not Found
>>> from sage.all import * >>> nap = 'hey_this_is_NOT_a_python_package' >>> pypi = 'http://this.is.not.pypi.com/' >>> pip_remote_version(nap, pypi_url=pypi, ignore_URLError=True) # optional - internet doctest:...: UserWarning: failed to fetch the version of pkg='hey_this_is_NOT_a_python_package' at http://this.is.not.pypi.com/.../json >>> pip_remote_version(nap, pypi_url=pypi, ignore_URLError=False) # optional - internet Traceback (most recent call last): ... HTTPError: HTTP Error 404: Not Found
- sage.misc.package.pkgname_split(name)[source]¶
Split a pkgname into a list of strings, ‘name, version’.
For some packages, the version string might be empty.
EXAMPLES:
sage: from sage.misc.package import pkgname_split sage: pkgname_split('hello_world-1.2') ['hello_world', '1.2']
>>> from sage.all import * >>> from sage.misc.package import pkgname_split >>> pkgname_split('hello_world-1.2') ['hello_world', '1.2']
- sage.misc.package.spkg_type(name)[source]¶
Return the type of the Sage package with the given name.
INPUT:
name
– string giving the subdirectory name of the package underSAGE_PKGS
EXAMPLES:
sage: from sage.misc.package import spkg_type sage: spkg_type('pip') # optional - sage_spkg 'standard'
>>> from sage.all import * >>> from sage.misc.package import spkg_type >>> spkg_type('pip') # optional - sage_spkg 'standard'
OUTPUT:
The type as a string in
('base', 'standard', 'optional', 'experimental')
. If noSPKG
exists with the given name (or the directorySAGE_PKGS
is not available),None
is returned.