Skip to content
/ sage Public
  • Sponsor
  • Notifications You must be signed in to change notification settings
  • Fork 574

Commit 9a3f818

Browse files
committedJan 3, 2025·
Require Python 3.11 or newer; remove outdated workarounds
1 parent c9dd1e8 commit 9a3f818

23 files changed

+38
-496
lines changed
 

‎.github/workflows/dist.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ jobs:
188188
#
189189
CIBW_ARCHS: ${{ matrix.arch }}
190190
# https://cibuildwheel.readthedocs.io/en/stable/options/#requires-python
191-
CIBW_PROJECT_REQUIRES_PYTHON: ">=3.9, <3.13"
191+
CIBW_PROJECT_REQUIRES_PYTHON: ">=3.11, <3.13"
192192
# Environment during wheel build
193193
CIBW_ENVIRONMENT: "PATH=$(pwd)/prefix/bin:$PATH CPATH=$(pwd)/prefix/include:$CPATH LIBRARY_PATH=$(pwd)/prefix/lib:$LIBRARY_PATH LD_LIBRARY_PATH=$(pwd)/prefix/lib:$LD_LIBRARY_PATH PKG_CONFIG_PATH=$(pwd)/prefix/share/pkgconfig:$PKG_CONFIG_PATH ACLOCAL_PATH=/usr/share/aclocal PIP_CONSTRAINT=$(pwd)/constraints.txt PIP_FIND_LINKS=file://$(pwd)/wheelhouse SAGE_NUM_THREADS=6"
194194
# Use 'build', not 'pip wheel'

‎.gitignore

-1
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,6 @@ __pycache__/
161161
/src/sage/modular/arithgroup/farey_symbol.h
162162
# List of C and C++ files that are actual source files,
163163
# NOT generated by Cython. The same list appears in src/MANIFEST.in
164-
!/src/sage/cpython/debugimpl.c
165164
!/src/sage/graphs/base/boost_interface.cpp
166165
!/src/sage/graphs/cliquer/cl.c
167166
!/src/sage/graphs/graph_decompositions/sage_tdlib.cpp

‎README.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ in the Installation Guide.
222222
more details.
223223

224224
- Python 3.4 or later, or Python 2.7, a full installation including
225-
`urllib`; but ideally version 3.9.x, 3.10.x, 3.11.x, 3.12.x, which
225+
`urllib`; but ideally version 3.11.x or later, which
226226
will avoid having to build Sage's own copy of Python 3.
227227
See [build/pkgs/python3/SPKG.rst](build/pkgs/python3/SPKG.rst)
228228
for more details.
@@ -551,11 +551,11 @@ SAGE_ROOT Root directory (create by git clone)
551551
│ │ ├── installed/
552552
│ │ │ Records of installed non-Python packages
553553
│ │ ├── scripts/ Scripts for uninstalling installed packages
554-
│ │ └── venv-python3.9 (SAGE_VENV)
554+
│ │ └── venv-python (SAGE_VENV)
555555
│ │ │ Installation hierarchy (virtual environment)
556556
│ │ │ for Python packages
557557
│ │ ├── bin/ Executables and installed scripts
558-
│ │ ├── lib/python3.9/site-packages/
558+
│ │ ├── lib/python/site-packages/
559559
│ │ │ Python modules/packages are installed here
560560
│ │ └── var/lib/sage/
561561
│ │ └── wheels/

‎pyproject.toml

+1-3
Original file line numberDiff line numberDiff line change
@@ -70,15 +70,13 @@ classifiers = [
7070
"Operating System :: POSIX",
7171
"Operating System :: MacOS :: MacOS X",
7272
"Programming Language :: Python :: 3 :: Only",
73-
"Programming Language :: Python :: 3.9",
74-
"Programming Language :: Python :: 3.10",
7573
"Programming Language :: Python :: 3.11",
7674
"Programming Language :: Python :: 3.12",
7775
"Programming Language :: Python :: Implementation :: CPython",
7876
"Topic :: Scientific/Engineering :: Mathematics",
7977
]
8078
urls = {Homepage = "https://www.sagemath.org"}
81-
requires-python = ">=3.9, <3.13"
79+
requires-python = ">=3.11, <3.13"
8280

8381
[project.optional-dependencies]
8482
R = [

‎pyrightconfig.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"root": "src"
88
}
99
],
10-
"pythonVersion": "3.9",
10+
"pythonVersion": "3.11",
1111
"exclude": ["venv"],
1212
"venvPath": "./venv/",
1313
"venv": "./",

‎ruff.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# https://docs.astral.sh/ruff/configuration/#config-file-discovery
22

3-
# Assume Python 3.9
4-
target-version = "py39"
3+
# Python 3.11 is the minimum supported version
4+
target-version = "py311"
55

66
lint.select = [
77
"E", # pycodestyle errors - https://docs.astral.sh/ruff/rules/#error-e

‎src/MANIFEST.in

-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ global-exclude *.cpp
2323
# List of C and C++ files that are actual source files,
2424
# NOT generated by Cython. The same list appears in SAGE_ROOT/.gitignore
2525
#
26-
include sage/cpython/debugimpl.c
2726
include sage/graphs/base/boost_interface.cpp
2827
include sage/graphs/cliquer/cl.c
2928
include sage/libs/eclib/wrap.cpp

‎src/doc/en/developer/coding_in_python.rst

+11-26
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,14 @@ Sage.
1212
Python language standard
1313
========================
1414

15-
Sage library code needs to be compatible with all versions of Python
16-
that Sage supports. The information regarding the supported versions
17-
can be found in the files ``build/pkgs/python3/spkg-configure.m4`` and
18-
``src/setup.cfg.m4``.
19-
20-
Python 3.9 is the oldest supported version. Hence,
21-
all language and library features that are available in Python 3.9 can
22-
be used; but features introduced in Python 3.10 cannot be used. If a
23-
feature is deprecated in a newer supported version, it must be ensured
24-
that deprecation warnings issued by Python do not lead to failures in
25-
doctests.
15+
Sage follows the time window-based support policy
16+
`SPEC 0 — Minimum Supported Dependencies <https://scientific-python.org/specs/spec-0000/>`_
17+
for Python versions.
18+
The current minimum supported Python version can be found in the
19+
``pyproject.toml`` file. Accordingly, only language and library features
20+
available in this version can be used. If a feature is deprecated in a newer
21+
supported version, it must be ensured that deprecation warnings issued by
22+
Python do not lead to failures in doctests.
2623

2724
Some key language and library features have been backported to older Python versions
2825
using one of two mechanisms:
@@ -34,21 +31,9 @@ using one of two mechanisms:
3431
of annotations). All Sage library code that uses type annotations
3532
should include this ``__future__`` import and follow PEP 563.
3633

37-
- Backport packages
38-
39-
- `importlib_metadata <../reference/spkg/importlib_metadata>`_
40-
(to be used in place of ``importlib.metadata``),
41-
- `importlib_resources <../reference/spkg/importlib_resources>`_
42-
(to be used in place of ``importlib.resources``),
43-
- `typing_extensions <../reference/spkg/typing_extensions>`_
44-
(to be used in place of ``typing``).
45-
46-
The Sage library declares these packages as dependencies and ensures that
47-
versions that provide features of Python 3.11 are available.
48-
49-
Meta :issue:`29756` keeps track of newer Python features and serves
50-
as a starting point for discussions on how to make use of them in the
51-
Sage library.
34+
- The `typing_extensions <../reference/spkg/typing_extensions>`_ package
35+
is used to backport features from newer versions of the ``typing`` module.
36+
The Sage library declares this package as a dependency.
5237

5338

5439
Design

‎src/doc/en/installation/conda.rst

+9-9
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ Create a new conda environment containing SageMath, either with ``mamba`` or ``c
5050
5151
$ conda create -n sage sage python=X
5252
53-
where ``X`` is version of Python, e.g. ``3.9``.
53+
where ``X`` is version of Python, e.g. ``3.12``.
5454

5555
To use Sage from there,
5656

@@ -86,22 +86,22 @@ Here we assume that you are using a git checkout.
8686

8787
.. code-block:: shell
8888
89-
$ mamba env create --file environment-3.11-linux.yml --name sage-dev
89+
$ mamba env create --file environment-3.12-linux.yml --name sage-dev
9090
$ conda activate sage-dev
9191
9292
.. tab:: conda
9393

9494
.. code-block:: shell
9595
96-
$ conda env create --file environment-3.11-linux.yml --name sage-dev
96+
$ conda env create --file environment-3.12-linux.yml --name sage-dev
9797
$ conda activate sage-dev
9898
99-
Alternatively, you can use ``environment-3.11-linux.yml`` or
100-
``environment-optional-3.11-linux.yml``, which will only install standard
99+
Alternatively, you can use ``environment-3.12-linux.yml`` or
100+
``environment-optional-3.12-linux.yml``, which will only install standard
101101
(and optional) packages without any additional developer tools.
102102

103-
A different Python version can be selected by replacing ``3.11`` by ``3.9``
104-
or ``3.10`` in these commands.
103+
A different Python version can be selected by replacing ``3.12`` with the
104+
desired version.
105105

106106
- Bootstrap the source tree and install the build prerequisites and the Sage library::
107107

@@ -137,7 +137,7 @@ After editing any Cython files, rebuild the Sage library using::
137137

138138
In order to update the conda environment later, you can run::
139139

140-
$ mamba env update --file environment-3.11-linux.yml --name sage-dev
140+
$ mamba env update --file environment-3.12-linux.yml --name sage-dev
141141

142142
To build the documentation, use::
143143

@@ -156,5 +156,5 @@ To build the documentation, use::
156156

157157
You can update the conda lock files by running
158158
``.github/workflows/conda-lock-update.py`` or by running
159-
``conda-lock --platform linux-64 --filename environment-3.11-linux.yml --lockfile environment-3.11-linux.lock``
159+
``conda-lock --platform linux-64 --filename environment-3.12-linux.yml --lockfile environment-3.12-linux.lock``
160160
manually.

‎src/doc/en/installation/launching.rst

+2-3
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,8 @@ Sage uses the following environment variables when it runs:
6767

6868
- See
6969
https://docs.python.org/3/using/cmdline.html#environment-variables
70-
for more variables used by Python (not an exhaustive list). With
71-
Python 3.11 or later, a brief summary can also be obtained by
72-
running `python3 --help-env`.
70+
for more variables used by Python (not an exhaustive list).
71+
A brief summary can also be obtained by running `python3 --help-env`.
7372

7473
Using a Jupyter Notebook remotely
7574
---------------------------------

‎src/sage/all__sagemath_repl.py

-6
Original file line numberDiff line numberDiff line change
@@ -100,12 +100,6 @@
100100
message=r"Pickle, copy, and deepcopy support will be "
101101
r"removed from itertools in Python 3.14.")
102102

103-
# triggered in Python 3.9 on Redhat-based distributions
104-
# https://github.com/sagemath/sage/issues/37863
105-
# https://github.com/networkx/networkx/issues/7101
106-
warnings.filterwarnings('ignore', category=RuntimeWarning,
107-
message="networkx backend defined more than once: nx-loopback")
108-
109103
from sage.all__sagemath_objects import *
110104
from sage.all__sagemath_environment import *
111105

‎src/sage/cpython/atexit.pyx

-25
Original file line numberDiff line numberDiff line change
@@ -148,8 +148,6 @@ from cpython.ref cimport PyObject
148148
# Implement "_atexit_callbacks()" for each supported python version
149149
cdef extern from *:
150150
"""
151-
#if PY_VERSION_HEX >= 0x030a0000
152-
/********** Python 3.10 **********/
153151
#define Py_BUILD_CORE
154152
#undef _PyGC_FINALIZED
155153
#include "internal/pycore_interp.h"
@@ -163,29 +161,6 @@ cdef extern from *:
163161
struct atexit_state state = interp->atexit;
164162
return state.callbacks;
165163
}
166-
#else
167-
/********** Python < 3.10 **********/
168-
/* Internal structures defined in the CPython source in
169-
* Modules/atexitmodule.c and subject to (but unlikely to) change. Watch
170-
* https://bugs.python.org/issue32082 for a request to (eventually)
171-
* re-expose more of the atexit module's internals to Python
172-
* typedef struct
173-
*/
174-
typedef struct {
175-
PyObject *func;
176-
PyObject *args;
177-
PyObject *kwargs;
178-
} atexit_callback;
179-
typedef struct {
180-
atexit_callback **atexit_callbacks;
181-
int ncallbacks;
182-
int callback_len;
183-
} atexitmodule_state;
184-
static atexit_callback ** _atexit_callbacks(PyObject *self) {
185-
atexitmodule_state *state = PyModule_GetState(self);
186-
return state->atexit_callbacks;
187-
}
188-
#endif
189164
"""
190165
ctypedef struct atexit_callback:
191166
PyObject* func

‎src/sage/cpython/cython_metaclass.h

-9
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,6 @@
88
* http://www.gnu.org/licenses/
99
*****************************************************************************/
1010

11-
/* Compatibility for python 3.8, can be removed later */
12-
#if PY_VERSION_HEX < 0x030900A4 && !defined(Py_SET_TYPE)
13-
static inline void _Py_SET_TYPE(PyObject *ob, PyTypeObject *type)
14-
{ ob->ob_type = type; }
15-
#define Py_SET_TYPE(ob, type) _Py_SET_TYPE((PyObject*)(ob), type)
16-
#endif
17-
1811
/* Tuple (None, None, None), initialized as needed */
1912
static PyObject* NoneNoneNone;
2013

@@ -52,15 +45,13 @@ static CYTHON_INLINE int Sage_PyType_Ready(PyTypeObject* t)
5245
if (r < 0)
5346
return r;
5447

55-
#if PY_VERSION_HEX >= 0x03050000
5648
// Cython 3 sets Py_TPFLAGS_HEAPTYPE before calling PyType_Ready,
5749
// and resets just after the call. We need to reset it earlier,
5850
// since otherwise the call to metaclass.__init__ below may have
5951
// illegal memory accesses.
6052
// See also:
6153
// https://github.com/cython/cython/issues/3603
6254
t->tp_flags &= ~Py_TPFLAGS_HEAPTYPE;
63-
#endif
6455

6556
/* Set or get metaclass (the type of t) */
6657
PyTypeObject* metaclass;

‎src/sage/cpython/debug.pyx

-5
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,6 @@ cdef extern from "Python.h":
1919
# Helper to get a pointer to an object's __dict__ slot, if any
2020
PyObject** _PyObject_GetDictPtr(obj)
2121

22-
cdef extern from "debugimpl.c":
23-
void _type_debug(PyTypeObject*)
24-
2522
from sage.cpython.getattr cimport AttributeErrorMessage
2623

2724

@@ -303,5 +300,3 @@ def type_debug(cls):
303300
"""
304301
if not isinstance(cls, type):
305302
raise TypeError(f"{cls!r} is not a type")
306-
307-
_type_debug(<PyTypeObject*>cls)

‎src/sage/cpython/debugimpl.c

-348
This file was deleted.

‎src/sage/cpython/pycore_long.h

+2-5
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@
22
#include <stdbool.h>
33

44
#if PY_VERSION_HEX >= 0x030C00A5
5+
// For Python 3.12 compatibility
56
#define ob_digit(o) (((PyLongObject*)o)->long_value.ob_digit)
67
#else
78
#define ob_digit(o) (((PyLongObject*)o)->ob_digit)
89
#endif
910

1011
#if PY_VERSION_HEX >= 0x030C00A7
12+
// For Python 3.12 compatibility
1113
// taken from cpython:Include/internal/pycore_long.h @ 3.12
1214

1315
/* Long value tag bits:
@@ -87,12 +89,7 @@ _PyLong_DigitCount(const PyLongObject *op)
8789
static inline void
8890
_PyLong_SetSignAndDigitCount(PyLongObject *op, int sign, Py_ssize_t size)
8991
{
90-
#if (PY_MAJOR_VERSION == 3) && (PY_MINOR_VERSION < 9)
91-
// The function Py_SET_SIZE is defined starting with python 3.9.
92-
Py_SIZE(op) = size;
93-
#else
9492
Py_SET_SIZE(op, sign < 0 ? -size : size);
95-
#endif
9693
}
9794

9895
#endif

‎src/sage/doctest/forker.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1082,7 +1082,7 @@ def compile_and_execute(self, example, compiler, globs):
10821082
False
10831083
sage: doctests, extras = FDS.create_doctests(globs)
10841084
sage: ex0 = doctests[0].examples[0]
1085-
sage: flags = 32768 if sys.version_info.minor < 8 else 524288
1085+
sage: flags = 524288
10861086
sage: def compiler(ex):
10871087
....: return compile(ex.source, '<doctest sage.doctest.forker[0]>',
10881088
....: 'single', flags, 1)

‎src/sage/libs/gmp/pylong.pyx

-8
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,6 @@ from sage.cpython.pycore_long cimport (ob_digit, _PyLong_IsNegative,
3232
from sage.libs.gmp.mpz cimport *
3333

3434
cdef extern from *:
35-
"""
36-
/* Compatibility for python 3.8, can be removed later */
37-
#if PY_VERSION_HEX < 0x030900A4 && !defined(Py_SET_SIZE)
38-
static inline void _Py_SET_SIZE(PyVarObject *ob, Py_ssize_t size)
39-
{ ob->ob_size = size; }
40-
#define Py_SET_SIZE(ob, size) _Py_SET_SIZE((PyVarObject*)(ob), size)
41-
#endif
42-
"""
4335
void Py_SET_SIZE(object, Py_ssize_t)
4436
int hash_bits """
4537
#ifdef _PyHASH_BITS

‎src/sage/misc/fpickle.pyx

+3-8
Original file line numberDiff line numberDiff line change
@@ -44,18 +44,13 @@ def reduce_code(co):
4444
raise ValueError("Cannot pickle code objects from closures")
4545

4646
co_args = (co.co_argcount,)
47-
if sys.version_info.minor >= 8:
48-
co_args += (co.co_posonlyargcount,)
47+
co_args += (co.co_posonlyargcount,)
4948
co_args += (co.co_kwonlyargcount, co.co_nlocals,
5049
co.co_stacksize, co.co_flags, co.co_code,
5150
co.co_consts, co.co_names, co.co_varnames, co.co_filename,
5251
co.co_name)
53-
if sys.version_info.minor >= 11:
54-
co_args += (co.co_qualname, co.co_firstlineno,
55-
co.co_linetable, co.co_exceptiontable)
56-
else:
57-
co_args += (co.co_firstlineno, co.co_lnotab)
58-
52+
co_args += (co.co_qualname, co.co_firstlineno,
53+
co.co_linetable, co.co_exceptiontable)
5954
return (code_ctor, co_args)
6055

6156

‎src/sage/misc/inherit_comparison_impl.c

-6
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,8 @@
88
static CYTHON_INLINE void inherit_comparison(PyTypeObject* dst, const PyTypeObject* src)
99
{
1010
/* Do nothing if "dst" already has comparison defined */
11-
#if (PY_MAJOR_VERSION < 3)
12-
if (dst->tp_compare) return;
13-
#endif
1411
if (dst->tp_richcompare) return;
1512

1613
/* Copy comparison method(s) */
17-
#if (PY_MAJOR_VERSION < 3)
18-
dst->tp_compare = src->tp_compare;
19-
#endif
2014
dst->tp_richcompare = src->tp_richcompare;
2115
}

‎src/sage_docbuild/ext/sage_autodoc.py

-22
Original file line numberDiff line numberDiff line change
@@ -1969,28 +1969,6 @@ def get_doc(self) -> list[list[str]] | None:
19691969
if isinstance(self.object, TypeVar):
19701970
if self.object.__doc__ == TypeVar.__doc__:
19711971
return []
1972-
# ------------------------------------------------------------------
1973-
# This section is kept for compatibility with python 3.9
1974-
# see https://github.com/sagemath/sage/pull/38549#issuecomment-2327790930
1975-
if sys.version_info[:2] < (3, 10):
1976-
if inspect.isNewType(self.object) or isinstance(self.object, TypeVar):
1977-
parts = self.modname.strip('.').split('.')
1978-
orig_objpath = self.objpath
1979-
for i in range(len(parts)):
1980-
new_modname = '.'.join(parts[:len(parts) - i])
1981-
new_objpath = parts[len(parts) - i:] + orig_objpath
1982-
try:
1983-
analyzer = ModuleAnalyzer.for_module(new_modname)
1984-
analyzer.analyze()
1985-
key = ('', new_objpath[-1])
1986-
comment = list(analyzer.attr_docs.get(key, []))
1987-
if comment:
1988-
self.objpath = new_objpath
1989-
self.modname = new_modname
1990-
return [comment]
1991-
except PycodeError:
1992-
pass
1993-
# ------------------------------------------------------------------
19941972
if self.doc_as_attr:
19951973
# Don't show the docstring of the class when it is an alias.
19961974
if self.get_variable_comment():

‎src/sage_setup/command/sage_build_cython.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,7 @@ def finalize_options(self):
104104
('force', 'force')]
105105

106106
# Python 3.5 now has a parallel option as well
107-
if sys.version_info[:2] >= (3, 5):
108-
inherit_opts.append(('parallel', 'parallel'))
107+
inherit_opts.append(('parallel', 'parallel'))
109108

110109
self.set_undefined_options('build_ext', *inherit_opts)
111110

‎src/setup.cfg.m4

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ license_files = LICENSE.txt
99
include(`setup_cfg_metadata.m4')dnl'
1010

1111
[options]
12-
python_requires = >=3.9, <3.13
12+
python_requires = >=3.11, <3.13
1313
install_requires =
1414
SPKG_INSTALL_REQUIRES_six
1515
dnl From build/pkgs/sagelib/dependencies

0 commit comments

Comments
 (0)
Please sign in to comment.