Skip to content

Commit ef0ab12

Browse files
author
Release Manager
committedOct 4, 2020
Trac #30607: Replace use of sage.misc.package.PackageNotFoundError, is_package_installed by features
In this ticket and #30616, we get rid of the remaining uses of `PackageNotFoundError` for dealing with optional extensions etc. by using `sage.features` instead. {{{ $ git grep sage.misc.package src/sage/databases/cremona.py: from sage.misc.package import is_package_installed src/sage/databases/jones.py: from sage.misc.package import PackageNotFoundError src/sage/game_theory/normal_form_game.py: from sage.misc.package import PackageNotFoundError src/sage/game_theory/normal_form_game.py: from sage.misc.package import PackageNotFoundError src/sage/graphs/graph.py: from sage.misc.package import PackageNotFoundError src/sage/graphs/graph.py: from sage.misc.package import PackageNotFoundError src/sage/graphs/graph.py: from sage.misc.package import PackageNotFoundError src/sage/groups/braid.py: from sage.misc.package import PackageNotFoundError src/sage/matrix/matrix_space.py: from sage.misc.package import PackageNotFoundError src/sage/sat/solvers/cryptominisat.py: from sage.misc.package import PackageNotFoundError src/sage/sat/solvers/picosat.py: from sage.misc.package import PackageNotFoundError }}} After this ticket and #30616, only uses for optional packages that do not exist any more remain. {{{ src/sage/interfaces/kash.py: from sage.misc.package import PackageNotFoundError src/sage/rings/polynomial/multi_polynomial_ideal.py: from sage.misc.package import PackageNotFoundError }}} (see #30617 for `ginv`, #25488 for `kash`) URL: https://trac.sagemath.org/30607 Reported by: mkoeppe Ticket author(s): Matthias Koeppe Reviewer(s): Sébastien Labbé
2 parents e8631a7 + ec66d89 commit ef0ab12

File tree

5 files changed

+63
-21
lines changed

5 files changed

+63
-21
lines changed
 

‎src/sage/databases/jones.py

+3-6
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,9 @@
7474

7575
from sage.misc.persist import load, save
7676

77-
from sage.misc.package import PackageNotFoundError
77+
from sage.features.databases import DatabaseJones
7878

79-
JONESDATA = os.path.join(SAGE_SHARE, 'jones')
79+
JONESDATA = os.path.join(SAGE_SHARE, 'jones') # should match the filename set in DatabaseJones
8080

8181

8282
def sortkey(K):
@@ -226,10 +226,7 @@ def get(self, S, var='a'):
226226
ValueError: S must be a list of primes
227227
"""
228228
if self.root is None:
229-
if os.path.exists(JONESDATA + "/jones.sobj"):
230-
self.root = load(JONESDATA + "/jones.sobj")
231-
else:
232-
raise PackageNotFoundError("database_jones_numfield")
229+
self.root = load(DatabaseJones().absolute_path())
233230
try:
234231
S = list(S)
235232
except TypeError:

‎src/sage/features/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ class FeatureNotPresentError(RuntimeError):
252252
def __init__(self, feature, reason=None, resolution=None):
253253
self.feature = feature
254254
self.reason = reason
255-
self.resolution = resolution
255+
self.resolution = resolution or feature.resolution()
256256

257257
def __str__(self):
258258
r"""

‎src/sage/features/databases.py

+22
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,25 @@ def __init__(self, name="cremona", spkg="database_cremona_ellcurve"):
3232
filename=os.path.join("cremona", filename),
3333
spkg=spkg,
3434
url="https://github.com/JohnCremona/ecdata")
35+
36+
class DatabaseJones(StaticFile):
37+
r"""
38+
A :class:`Feature` which describes the presence of John Jones's tables of number fields.
39+
40+
EXAMPLES::
41+
42+
sage: from sage.features.databases import DatabaseJones
43+
sage: bool(DatabaseJones().is_present()) # optional: database_jones_numfield
44+
True
45+
"""
46+
def __init__(self):
47+
r"""
48+
TESTS::
49+
50+
sage: from sage.features.databases import DatabaseJones
51+
sage: isinstance(DatabaseJones(), DatabaseJones)
52+
True
53+
"""
54+
StaticFile.__init__(self, "John Jones's tables of number fields",
55+
filename='jones/jones.sobj',
56+
spkg="database_jones_numfield")

‎src/sage/game_theory/normal_form_game.py

+4-3
Original file line numberDiff line numberDiff line change
@@ -1765,9 +1765,10 @@ def _solve_lrs(self, maximization=True):
17651765
process = Popen(['lrsnash', g1_name, g2_name],
17661766
stdout=PIPE,
17671767
stderr=PIPE)
1768-
except OSError:
1769-
from sage.misc.package import PackageNotFoundError
1770-
raise PackageNotFoundError("lrslib")
1768+
except OSError as e:
1769+
from sage.features.lrs import Lrs
1770+
from sage.features import FeatureNotPresentError
1771+
raise FeatureNotPresentError(Lrs(), reason=f'Calling lrsnash failed with {e}')
17711772

17721773
lrs_output = [bytes_to_str(row) for row in process.stdout]
17731774
process.terminate()

‎src/sage/misc/package.py

+33-11
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,8 @@
4949
import os
5050
import subprocess
5151
import sys
52-
try:
53-
# Python 3.3+
54-
from urllib.request import urlopen
55-
from urllib.error import URLError
56-
except ImportError:
57-
# Python 2.7
58-
from urllib2 import urlopen, URLError
52+
from urllib.request import urlopen
53+
from urllib.error import URLError
5954

6055
DEFAULT_PYPI = 'https://pypi.org/pypi'
6156

@@ -546,14 +541,40 @@ class PackageNotFoundError(RuntimeError):
546541
- The required optional package is installed, but the relevant
547542
interface to that package is unable to detect the package.
548543
544+
Raising a ``PackageNotFoundError`` is deprecated. Use
545+
:class:`sage.features.FeatureNotPresentError` instead.
546+
547+
User code can continue to catch ``PackageNotFoundError`` exceptions
548+
for compatibility with older versions of the Sage library.
549+
This does not cause deprecation warnings.
550+
549551
EXAMPLES::
550552
551553
sage: from sage.misc.package import PackageNotFoundError
552-
sage: raise PackageNotFoundError("my_package")
553-
Traceback (most recent call last):
554-
...
555-
PackageNotFoundError: the package 'my_package' was not found. You can install it by running 'sage -i my_package' in a shell
554+
sage: try:
555+
....: pass
556+
....: except PackageNotFoundError:
557+
....: pass
558+
556559
"""
560+
561+
def __init__(self, *args):
562+
"""
563+
TESTS::
564+
565+
sage: from sage.misc.package import PackageNotFoundError
566+
sage: raise PackageNotFoundError("my_package")
567+
Traceback (most recent call last):
568+
...
569+
PackageNotFoundError: the package 'my_package' was not found. You can install it by running 'sage -i my_package' in a shell
570+
"""
571+
super().__init__(*args)
572+
# We do not deprecate the whole class because we want
573+
# to allow user code to handle this exception without causing
574+
# a deprecation warning.
575+
from sage.misc.superseded import deprecation
576+
deprecation(30607, "Instead of raising PackageNotFoundError, raise sage.features.FeatureNotPresentError")
577+
557578
def __str__(self):
558579
"""
559580
Return the actual error message.
@@ -562,6 +583,7 @@ def __str__(self):
562583
563584
sage: from sage.misc.package import PackageNotFoundError
564585
sage: str(PackageNotFoundError("my_package"))
586+
doctest:warning...
565587
"the package 'my_package' was not found. You can install it by running 'sage -i my_package' in a shell"
566588
"""
567589
return ("the package {0!r} was not found. "

0 commit comments

Comments
 (0)
Please sign in to comment.