Skip to content

Commit

Permalink
Trac #29033: Support minimal system Python version 3.6 (for venv)
Browse files Browse the repository at this point in the history
With #27824 it is possible to create a venv over an existing Python 3.7
instead of building the python3 spkg.

This is designed to work with Python 3.7 (and < 3.8) since that's what's
currently used by sage-the-distribution and is best-tested.

However, it turns out an existing Python 3.6 can work just fine as the
minimum Python version with a few small fixes (sage-the-distribution
used Python 3.6 until last year, so the degree to which we diverged from
supporting it was minimal).

This would be a nice-to-have, as it would speed up the build on various
distributions that we still support:
 - `centos-8` (3.6.8),
 - `fedora-26` (3.6.5, but has 3.7.0 too),
https://github.com/mkoeppe/sage/runs/743789829 - clean doctests, but
exceeds 6h
 - `fedora-27` (3.6.6, but has 3.7.0 too),
https://github.com/mkoeppe/sage/runs/743789883 - clean except for
sympow, exceeds 6h
 - `fedora-28` (3.6.5, but has 3.7.3 too),
https://github.com/mkoeppe/sage/runs/743789896 - with `gcc_spkg`, build
errors for gmpy2, cython, pynac
 - `opensuse-leap-15.0` (3.6.5), `-15.1` (3.6.9), `-15.2` (3.6.10),
but not (because python3 is too old):
 - `debian-stretch` (oldstable) (3.5.3),
 - `ubuntu-xenial` (3.5.2)
and not (because a dependency of python3 is too old):
 - `centos-7` (3.6.8): `sqlite` is too old
(https://github.com/mkoeppe/sage/runs/743789990)

(All this is according to https://repology.org/project/python/versions
as of 2020-06-05, not verified.)

Maybe since Sage is less tested with 3.6, there could be a warning
against using it.

See also: #27754 (Upgrade: Python 3.8.x)

URL: https://trac.sagemath.org/29033
Reported by: embray
Ticket author(s): Erik Bray, Matthias Koeppe
Reviewer(s): Matthias Koeppe, Michael Orlitzky
  • Loading branch information
Release Manager committed Jun 21, 2020
2 parents afedaa5 + abb5607 commit 7b7fee5
Show file tree
Hide file tree
Showing 8 changed files with 30 additions and 18 deletions.
4 changes: 3 additions & 1 deletion build/bin/sage-spkg
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,9 @@
#*****************************************************************************

# Avoid surprises with character ranges [a-z] in regular expressions
export LC_ALL=C
# See Trac #15791; some locales can produce different results for
# character ranges (use C.UTF-8 to ensure UTF-8 default encoding in Python)
export LC_ALL=C.UTF-8

usage()
{
Expand Down
8 changes: 4 additions & 4 deletions build/pkgs/python3/spkg-configure.m4
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ SAGE_SPKG_CONFIGURE([python3], [
dnl Using Python 3 for Sage. Check if we can do venv with a system python3
dnl instead of building our own copy.
check_modules="sqlite3, ctypes, math, hashlib, crypt, readline, socket, zlib, distutils.core"
AC_CACHE_CHECK([for python3 >= 3.7.3, < 3.8 with modules $check_modules], [ac_cv_path_PYTHON3], [
AC_CACHE_CHECK([for python3 >= 3.6, < 3.8 with modules $check_modules], [ac_cv_path_PYTHON3], [
AC_MSG_RESULT([])
AC_PATH_PROGS_FEATURE_CHECK([PYTHON3], [python3.7 python3], [
AC_PATH_PROGS_FEATURE_CHECK([PYTHON3], [python3.7 python3.6 python3], [
AC_MSG_CHECKING([... whether $ac_path_PYTHON3 is good])
python3_version=`"$ac_path_PYTHON3" --version 2>&1 \
| $SED -n -e 's/\([[0-9]]*\.[[0-9]]*\.[[0-9]]*\).*/\1/p'`
AS_IF([test -n "$python3_version"], [
AX_COMPARE_VERSION([$python3_version], [ge], [3.7.3], [
AX_COMPARE_VERSION([$python3_version], [ge], [3.6.0], [
AX_COMPARE_VERSION([$python3_version], [lt], [3.8.0], [
dnl Because the system python is not used directly but rather in a venv without site-packages,
dnl we test whether the module will be available in a venv.
Expand Down Expand Up @@ -118,7 +118,7 @@ EOF
ac_path_PYTHON3_found=:
AC_MSG_RESULT([yes])
dnl introduction for AC_MSG_RESULT printed by AC_CACHE_CHECK
AC_MSG_CHECKING([for python3 >= 3.7.3, < 3.8 with modules $check_modules])
AC_MSG_CHECKING([for python3 >= 3.6, < 3.8 with modules $check_modules])
], [
AC_MSG_RESULT([no, the version is in the supported range, and the modules can be imported, but distutils cannot build a C++ 11 extension])
])
Expand Down
2 changes: 1 addition & 1 deletion src/sage/all.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
....: 'IPython', 'prompt_toolkit', 'jedi', # sage dependencies
....: 'threading', 'multiprocessing', # doctest dependencies
....: '__main__', 'sage.doctest', # doctesting
....: 'signal', 'enum', # may appear in Python 3
....: 'signal', 'enum', 'types' # may appear in Python 3
....: ]
sage: def is_not_allowed(frame):
....: module = inspect.getmodule(frame)
Expand Down
17 changes: 16 additions & 1 deletion src/sage/combinat/subset.py
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,22 @@ def cardinality(self):
"""
return Integer(1) << self._s.cardinality()

__len__ = cardinality
def __len__(self):
r"""
Equivalent to ``self.cardinality()``.
TESTS::
``__len__`` should return a Python int; in Python 3.7+ this happens
automatically, but not on Python 3.6.
sage: S = Subsets(Set([1,2,3]))
sage: len(S)
8
sage: type(len(S)) is int
True
"""
return int(self.cardinality())

def first(self):
"""
Expand Down
1 change: 1 addition & 0 deletions src/sage/graphs/views.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -611,6 +611,7 @@ cdef class EdgesView:
elif i < 0:
return list(self)[i]
else:
i = int(i) # For Python < 3.7 where islice doesn't support non-int
try:
return next(islice(self, i, i + 1, 1))
except StopIteration:
Expand Down
2 changes: 1 addition & 1 deletion src/sage/misc/sagedoc.py
Original file line number Diff line number Diff line change
Expand Up @@ -1064,7 +1064,7 @@ def search_src(string, extra1='', extra2='', extra3='', extra4='',
sage: print(search_src(" fetch(", "def", interact=False)) # py3
Traceback (most recent call last):
...
re.error: missing ), unterminated subpattern at position 6
error: missing ), unterminated subpattern at position 6
To fix this, *escape* the parenthesis with a backslash::
Expand Down
6 changes: 2 additions & 4 deletions src/sage/misc/sageinspect.py
Original file line number Diff line number Diff line change
Expand Up @@ -1723,10 +1723,8 @@ def sage_formatargspec(args, varargs=None, varkw=None, defaults=None,
sage: defaults = [3]
sage: sage_formatargspec(args, defaults=defaults)
'(a, b, c=3)'
sage: formatargspec(args, defaults=defaults) == sage_formatargspec(args, defaults=defaults) # py2
True
sage: formatargspec(args, defaults=defaults) == sage_formatargspec(args, defaults=defaults) # py3
doctest:...: DeprecationWarning: `formatargspec` is deprecated since Python 3.5. Use `signature` and the `Signature` object directly
sage: import warnings; warnings.simplefilter('ignore') # py3: ignore DeprecationWarning
sage: formatargspec(args, defaults=defaults) == sage_formatargspec(args, defaults=defaults)
True
"""
def formatargandannotation(arg):
Expand Down
8 changes: 2 additions & 6 deletions src/sage/symbolic/expression.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -5869,14 +5869,10 @@ cdef class Expression(CommutativeRingElement):
Indexing directly with ``t[1]`` causes problems with numpy types.
sage: t[1] # py2
sage: t[1]
Traceback (most recent call last):
...
TypeError: 'sage.symbolic.expression.Expression' object does not support indexing
sage: t[1] # py3
Traceback (most recent call last):
...
TypeError: 'sage.symbolic.expression.Expression' object is not subscriptable
TypeError: 'sage.symbolic.expression.Expression' object ...
"""
if (is_a_symbol(self._gobj) or is_a_constant(self._gobj) or
is_a_numeric(self._gobj)):
Expand Down

0 comments on commit 7b7fee5

Please sign in to comment.