-
-
Notifications
You must be signed in to change notification settings - Fork 674
Developer guide: Improve discussion of backport packages #37654
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from all commits
eb940a3
c06c478
25482db
f729262
c5530c5
7c52361
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,8 +14,8 @@ Python language standard | |
|
||
Sage library code needs to be compatible with all versions of Python | ||
that Sage supports. The information regarding the supported versions | ||
can be found in the files ``build/pkgs/python3/spkg-configure.m4`` and | ||
``src/setup.cfg.m4``. | ||
can be found in the files :sage_root:`build/pkgs/python3/spkg-configure.m4` and | ||
:sage_root:`src/setup.cfg.m4`. | ||
|
||
Python 3.9 is the oldest supported version. Hence, | ||
all language and library features that are available in Python 3.9 can | ||
|
@@ -37,14 +37,36 @@ using one of two mechanisms: | |
- Backport packages | ||
|
||
- `importlib_metadata <../reference/spkg/importlib_metadata>`_ | ||
(to be used in place of ``importlib.metadata``), | ||
(to be used in place of ``importlib.metadata`` when Python older | ||
than 3.11 is in use if you need a newer feature), | ||
- `importlib_resources <../reference/spkg/importlib_resources>`_ | ||
(to be used in place of ``importlib.resources``), | ||
(to be used in place of ``importlib.resources`` when Python older than | ||
3.11 is in use if you need a newer feature), | ||
- `typing_extensions <../reference/spkg/typing_extensions>`_ | ||
(to be used in place of ``typing``). | ||
(to be used in place of ``typing`` when Python older than | ||
3.11 is in use and any of the features introduced after Python | ||
3.9.0 are used). | ||
|
||
The Sage library declares these packages as dependencies and ensures that | ||
versions that provide features of Python 3.11 are available. | ||
The Sage library declares these backport packages as conditional | ||
dependencies for use with Python older than 3.11 and ensures that | ||
versions of the packages that provide features of Python 3.11 | ||
are available. | ||
|
||
The backport packages should not be imported unconditionally. | ||
For example, on Linux distributions that only ship newer versions | ||
of Python, the backport packages may not be available as | ||
system packages. Hence, if there is a need to use the backport | ||
packages, they should be imported like this: | ||
|
||
.. CODE-BLOCK:: python | ||
|
||
import sys | ||
kwankyu marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
if sys.version_info < (3, 11): | ||
# Use backport package providing Python 3.11 features | ||
from importlib_resources import files | ||
else: | ||
from importlib.resources import files | ||
Comment on lines
+64
to
+69
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This gives the impression that we recommend using the backport packages. IMO, we should discourage the backport packages. Right now, afaict, nothing in the sage library requires the backport packages and we should keep it that way. The risk is that if someone uses the backport packages it might use a newer feature not available on current python. We've already pointed out that distros are not shipping some of the backport packages. Please remove this suggestion. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's documenting the status quo, which was established by positively reviewed PRs in the past. |
||
|
||
Meta :issue:`29756` keeps track of newer Python features and serves | ||
as a starting point for discussions on how to make use of them in the | ||
|
@@ -60,29 +82,29 @@ into the structure of Sage. In particular, much of Sage is implemented | |
in the object-oriented language Python, and there is a hierarchy of | ||
classes that organize code and functionality. For example, if you | ||
implement elements of a ring, your class should derive from | ||
``sage.structure.element.RingElement``, rather than starting from | ||
:class:`sage.structure.element.RingElement`, rather than starting from | ||
scratch. Try to figure out how your code should fit in with other Sage | ||
code, and design it accordingly. | ||
|
||
|
||
Special Sage functions | ||
====================== | ||
|
||
Functions with leading and trailing double underscores ``__XXX__`` are | ||
Functions with leading and trailing double underscores :meth:`__XXX__` are | ||
all predefined by Python. Functions with leading and trailing single | ||
underscores ``_XXX_`` are defined for Sage. Functions with a single | ||
underscores :meth:`_XXX_` are defined for Sage. Functions with a single | ||
leading underscore are meant to be semi-private, and those with a | ||
double leading underscore are considered really private. Users can | ||
create functions with leading and trailing underscores. | ||
|
||
Just as Python has many standard special methods for objects, Sage | ||
also has special methods. They are typically of the form ``_XXX_``. | ||
also has special methods. They are typically of the form :meth:`_XXX_`. | ||
In a few cases, the trailing underscore is not included, but this will | ||
eventually be changed so that the trailing underscore is always | ||
included. This section describes these special methods. | ||
|
||
All objects in Sage should derive from the Cython extension class | ||
``SageObject``: | ||
:class:`SageObject`: | ||
|
||
.. CODE-BLOCK:: python | ||
|
||
|
@@ -100,7 +122,7 @@ or from some other already existing Sage class: | |
class MyFavoriteAlgebra(Parent): | ||
... | ||
|
||
You should implement the ``_latex_`` and ``_repr_`` method for every | ||
You should implement the :meth:`_latex_` and :meth:`_repr_` method for every | ||
object. The other methods depend on the nature of the object. | ||
|
||
|
||
|
@@ -110,18 +132,18 @@ LaTeX representation | |
Every object ``x`` in Sage should support the command ``latex(x)``, so | ||
that any Sage object can be easily and accurately displayed via | ||
LaTeX. Here is how to make a class (and therefore its instances) | ||
support the command ``latex``. | ||
support the command :func:`latex`. | ||
|
||
#. Define a method ``_latex_(self)`` that returns a LaTeX | ||
representation of your object. It should be something that can be | ||
typeset correctly within math mode. Do not include opening and | ||
closing $'s. | ||
|
||
#. Often objects are built up out of other Sage objects, and these | ||
components should be typeset using the ``latex`` function. For | ||
components should be typeset using :func:`latex` function. For | ||
example, if ``c`` is a coefficient of your object, and you want to | ||
typeset ``c`` using LaTeX, use ``latex(c)`` instead of | ||
``c._latex_()``, since ``c`` might not have a ``_latex_`` method, | ||
``c._latex_()``, since ``c`` might not have a :meth:`_latex_` method, | ||
and ``latex(c)`` knows how to deal with this. | ||
|
||
#. Do not forget to include a docstring and an example that | ||
|
@@ -130,7 +152,7 @@ support the command ``latex``. | |
#. You can use any macros included in ``amsmath``, ``amssymb``, or | ||
``amsfonts``, or the ones defined in :mod:`sage.misc.latex_macros`. | ||
|
||
An example template for a ``_latex_`` method follows. Note that the | ||
An example template for a :meth:`_latex_` method follows. Note that the | ||
``.. skip`` line should not be included in your code; it is here to | ||
prevent doctests from running on this fake example. | ||
|
||
|
@@ -168,8 +190,8 @@ preferable because if you only define ``_repr_(self)`` and not | |
they like. Also, some objects should print differently depending on | ||
the context. | ||
|
||
Here is an example of the ``_latex_`` and ``_repr_`` functions for the | ||
``Pi`` class. It is from the file | ||
Here is an example of the :meth:`_latex_` and :meth:`_repr_` methods for the | ||
:class:`Pi` class. It is from the file | ||
:sage_root:`src/sage/symbolic/constants.py`: | ||
|
||
.. CODE-BLOCK:: python | ||
|
@@ -196,8 +218,8 @@ Here is an example of the ``_latex_`` and ``_repr_`` functions for the | |
Matrix or vector from object | ||
============================ | ||
|
||
Provide a ``_matrix_`` method for an object that can be coerced to a | ||
matrix over a ring `R`. Then the Sage function ``matrix`` will work | ||
Provide a :meth:`_matrix_` method for an object that can be coerced to a | ||
matrix over a ring `R`. Then the Sage function :func:`matrix` will work | ||
for this object. | ||
|
||
The following is from | ||
|
@@ -217,8 +239,8 @@ The following is from | |
def adjacency_matrix(self, sparse=None, boundary_first=False): | ||
... | ||
|
||
Similarly, provide a ``_vector_`` method for an object that can be | ||
coerced to a vector over a ring `R`. Then the Sage function ``vector`` | ||
Similarly, provide a :meth:`_vector_` method for an object that can be | ||
coerced to a vector over a ring `R`. Then the Sage function :func:`vector` | ||
will work for this object. The following is from the file | ||
:sage_root:`src/sage/modules/free_module_element.pyx`: | ||
|
||
|
@@ -238,7 +260,7 @@ Sage preparsing | |
To make Python even more usable interactively, there are a number of | ||
tweaks to the syntax made when you use Sage from the commandline or | ||
via the notebook (but not for Python code in the Sage | ||
library). Technically, this is implemented by a ``preparse()`` | ||
library). Technically, this is implemented by a :func:`preparse` | ||
function that rewrites the input string. Most notably, the following | ||
replacements are made: | ||
|
||
|
@@ -279,7 +301,7 @@ replacements are made: | |
are very small. Large Sage integers are much more efficient than | ||
Python integers since they are implemented using the GMP C library. | ||
|
||
Consult the file ``preparser.py`` for more details about Sage | ||
Consult :mod:`sage.repl.preparse` for more details about Sage | ||
preparsing, more examples involving raw literals, etc. | ||
|
||
When a file ``foo.sage`` is loaded or attached in a Sage session, a | ||
|
@@ -312,7 +334,7 @@ The Sage coercion model | |
|
||
The primary goal of coercion is to be able to transparently do | ||
arithmetic, comparisons, etc. between elements of distinct sets. For | ||
example, when one writes `3 + 1/2`, one wants to perform arithmetic on | ||
example, when one writes ``3 + 1/2``, one wants to perform arithmetic on | ||
the operands as rational numbers, despite the left term being an | ||
integer. This makes sense given the obvious and natural inclusion of | ||
the integers into the rational numbers. The goal of the coercion | ||
|
@@ -342,29 +364,28 @@ scope variable. | |
.. {Put a tutorial on this here} | ||
|
||
Certain objects, e.g. matrices, may start out mutable and become | ||
immutable later. See the file | ||
:sage_root:`src/sage/structure/mutability.py`. | ||
immutable later. See :mod:`sage.structure.mutability`. | ||
|
||
|
||
The __hash__ special method | ||
============================ | ||
|
||
Here is the definition of ``__hash__`` from the Python reference | ||
Here is the definition of :meth:`__hash__` from the Python reference | ||
manual: | ||
|
||
Called by built-in function ``hash()`` and for operations on members | ||
of hashed collections including ``set``, ``frozenset``, and | ||
``dict``. ``__hash__()`` should return an integer. The only required | ||
Called by built-in function :func:`hash` and for operations on members | ||
of hashed collections including :class:`set`, :class:`frozenset`, and | ||
:class:`dict`. :meth:`__hash__` should return an integer. The only required | ||
property is that objects which compare equal have the same hash | ||
value; it is advised to mix together the hash values of the | ||
components of the object that also play a part in comparison of | ||
objects by packing them into a tuple and hashing the tuple. | ||
|
||
If a class does not define an ``__eq__()`` method it should not define | ||
a ``__hash__()`` operation either; if it defines ``__eq__()`` but not | ||
``__hash__()``, its instances will not be usable as items in hashable | ||
If a class does not define an :meth:`__eq__` method, it should not define | ||
a :meth:`__hash__` operation either; if it defines :meth:`__eq__` but not | ||
:meth:`__hash__`, its instances will not be usable as items in hashable | ||
collections. If a class defines mutable objects and implements an | ||
``__eq__()`` method, it should not implement ``__hash__()``, since the | ||
:meth:`__eq__` method, it should not implement :meth:`__hash__`, since the | ||
implementation of hashable collections requires that a key’s hash | ||
value is immutable (if the object’s hash value changes, it will be | ||
in the wrong hash bucket). | ||
|
@@ -417,7 +438,7 @@ Unfortunately, in Sage we simply cannot require | |
|
||
because serious mathematics is simply too complicated for this | ||
rule. For example, the equalities ``z == Mod(z, 2)`` and | ||
``z == Mod(z, 3)`` would force ``hash()`` to be constant on the | ||
``z == Mod(z, 3)`` would force :func:`hash` to be constant on the | ||
integers. | ||
|
||
The only way we could "fix" this problem for good would be to abandon | ||
|
@@ -456,7 +477,7 @@ Please avoid catch-all code like this: | |
more_code() | ||
|
||
If you do not have any exceptions explicitly listed (as a tuple), your | ||
code will catch absolutely anything, including ``ctrl-C``, typos in | ||
code will catch absolutely anything, including :kbd:`Ctrl` + :kbd:`C`, typos in | ||
the code, and alarms, and this will lead to confusion. Also, this | ||
might catch real errors which should be propagated to the user. | ||
|
||
|
@@ -513,7 +534,7 @@ to explore the resulting integers' number-theoretic properties | |
such as prime factorization. Exceptions should be made when | ||
there are good reasons such as performance or compatibility | ||
with Python code, for instance in methods such as | ||
``__hash__``, ``__len__``, and ``__int__``. | ||
:meth:`__hash__`, :meth:`__len__`, and :meth:`__int__`. | ||
|
||
To return a Python integer ``i`` as a Sage integer, use: | ||
|
||
|
@@ -522,7 +543,7 @@ To return a Python integer ``i`` as a Sage integer, use: | |
from sage.rings.integer import Integer | ||
return Integer(i) | ||
|
||
To return a Sage integer ``i`` as a Python ineger, use: | ||
To return a Sage integer ``i`` as a Python integer, use: | ||
|
||
.. CODE-BLOCK:: python | ||
|
||
|
Uh oh!
There was an error while loading. Please reload this page.