From 62b5191a07978303de47e5cd3f888e0447420def Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Sun, 28 Sep 2025 11:37:58 +0800 Subject: [PATCH 1/6] Add typing info for _sage_input_ --- src/sage/geometry/cone.py | 7 +++- src/sage/geometry/fan.py | 7 +++- src/sage/geometry/lattice_polytope.py | 27 ++++++------- src/sage/geometry/point_collection.pyx | 4 +- src/sage/geometry/polyhedron/base0.py | 7 +++- src/sage/geometry/toric_lattice.py | 7 +++- src/sage/matrix/matrix1.pyx | 3 +- src/sage/misc/explain_pickle.py | 38 +++++++++---------- src/sage/misc/sage_input.py | 21 +++++----- src/sage/modules/free_module_element.pyx | 3 +- src/sage/rings/complex_interval.pyx | 3 +- src/sage/rings/complex_interval_field.py | 8 ++-- src/sage/rings/complex_mpfr.pyx | 5 ++- .../rings/finite_rings/finite_field_base.pyx | 3 +- src/sage/rings/finite_rings/integer_mod.pyx | 3 +- src/sage/rings/integer.pyx | 4 +- src/sage/rings/integer_ring.pyx | 4 +- .../rings/polynomial/polynomial_element.pyx | 3 +- src/sage/rings/polynomial/polynomial_ring.py | 8 ++-- src/sage/rings/qqbar.py | 15 +++++--- src/sage/rings/rational.pyx | 4 +- src/sage/rings/rational_field.py | 7 +++- src/sage/rings/real_double.pyx | 5 ++- src/sage/rings/real_mpfi.pyx | 5 ++- src/sage/rings/real_mpfr.pyx | 5 ++- src/sage/sets/real_set.py | 25 +++++++----- 26 files changed, 138 insertions(+), 93 deletions(-) diff --git a/src/sage/geometry/cone.py b/src/sage/geometry/cone.py index d1b61d41eb3..fe947945ff5 100644 --- a/src/sage/geometry/cone.py +++ b/src/sage/geometry/cone.py @@ -201,9 +201,9 @@ # (at your option) any later version. # https://www.gnu.org/licenses/ # **************************************************************************** - from collections.abc import Hashable, Iterable, Container from copy import copy +from typing import TYPE_CHECKING, Literal from warnings import warn from sage.misc.lazy_import import lazy_import @@ -241,6 +241,9 @@ lazy_import('ppl', ['ray', 'point'], as_=['PPL_ray', 'PPL_point'], feature=PythonModule("ppl", spkg='pplpy', type='standard')) +if TYPE_CHECKING: + from sage.misc.sage_input import SageInputBuilder, SageInputExpression + def is_Cone(x): r""" @@ -1500,7 +1503,7 @@ def __init__(self, rays=None, lattice=None, if PPL is not None: self._PPL_C_Polyhedron = PPL - def _sage_input_(self, sib, coerced): + def _sage_input_(self, sib: SageInputBuilder, coerced: bool | Literal[2]) -> SageInputExpression: """ Return Sage command to reconstruct ``self``. diff --git a/src/sage/geometry/fan.py b/src/sage/geometry/fan.py index 7af1fa122ee..cf215743f1e 100644 --- a/src/sage/geometry/fan.py +++ b/src/sage/geometry/fan.py @@ -233,9 +233,9 @@ # (at your option) any later version. # https://www.gnu.org/licenses/ # **************************************************************************** - from collections.abc import Callable, Container from copy import copy +from typing import TYPE_CHECKING, Literal from warnings import warn import sage.geometry.abc @@ -262,6 +262,9 @@ from sage.rings.integer_ring import ZZ from sage.rings.rational_field import QQ +if TYPE_CHECKING: + from sage.misc.sage_input import SageInputBuilder, SageInputExpression + def is_Fan(x) -> bool: r""" @@ -1217,7 +1220,7 @@ def __init__(self, cones, rays, lattice, if virtual_rays is not None: self._virtual_rays = PointCollection(virtual_rays, self.lattice()) - def _sage_input_(self, sib, coerced): + def _sage_input_(self, sib: SageInputBuilder, coerced: bool | Literal[2]) -> SageInputExpression: """ Return Sage command to reconstruct ``self``. diff --git a/src/sage/geometry/lattice_polytope.py b/src/sage/geometry/lattice_polytope.py index 5b4a6ec5847..d4c315ea934 100644 --- a/src/sage/geometry/lattice_polytope.py +++ b/src/sage/geometry/lattice_polytope.py @@ -120,24 +120,24 @@ # (at your option) any later version. # https://www.gnu.org/licenses/ # **************************************************************************** +import os +import shlex from collections.abc import Hashable from copyreg import constructor as copyreg_constructor from functools import reduce from io import IOBase, StringIO -from subprocess import Popen, PIPE -from warnings import warn -import os -import shlex +from subprocess import PIPE, Popen +from typing import TYPE_CHECKING, Literal +import sage.geometry.abc from sage.arith.misc import GCD as gcd from sage.features import PythonModule -from sage.features.palp import PalpExecutable from sage.features.databases import DatabaseReflexivePolytopes +from sage.features.palp import PalpExecutable from sage.geometry.cone import _ambient_space_point, integral_length -from sage.geometry.point_collection import (PointCollection, - read_palp_point_collection) -from sage.geometry.toric_lattice import ToricLattice, ToricLattice_generic from sage.geometry.convex_set import ConvexSet_compact +from sage.geometry.point_collection import PointCollection, read_palp_point_collection +from sage.geometry.toric_lattice import ToricLattice, ToricLattice_generic from sage.matrix.constructor import matrix from sage.misc.cachefunc import cached_method from sage.misc.flatten import flatten @@ -149,11 +149,9 @@ from sage.rings.rational_field import QQ from sage.sets.set import Set_generic from sage.structure.element import Matrix -from sage.structure.richcmp import richcmp_method, richcmp +from sage.structure.richcmp import richcmp, richcmp_method from sage.structure.sage_object import SageObject from sage.structure.sequence import Sequence -import sage.geometry.abc - lazy_import("sage.combinat.posets.posets", 'FinitePoset') lazy_import("sage.geometry.hasse_diagram", 'lattice_from_incidences') @@ -167,6 +165,9 @@ lazy_import('ppl', 'point', as_='PPL_point', feature=PythonModule("ppl", spkg='pplpy', type='standard')) +if TYPE_CHECKING: + from sage.misc.sage_input import SageInputBuilder, SageInputExpression + class SetOfAllLatticePolytopesClass(Set_generic): def _repr_(self) -> str: @@ -570,7 +571,7 @@ def __init__(self, points=None, compute_vertices=None, self._ambient_facet_indices = tuple(ambient_facet_indices) self._vertices = ambient.vertices(self._ambient_vertex_indices) - def _sage_input_(self, sib, coerced): + def _sage_input_(self, sib: SageInputBuilder, coerced: bool | Literal[2]) -> SageInputExpression: """ Return Sage command to reconstruct ``self``. @@ -4443,7 +4444,7 @@ def _repr_(self): pass return result - def _sage_input_(self, sib, coerced): + def _sage_input_(self, sib: SageInputBuilder, coerced: bool) -> SageInputExpression: """ Return Sage command to reconstruct ``self``. diff --git a/src/sage/geometry/point_collection.pyx b/src/sage/geometry/point_collection.pyx index 8cebd2fd2d8..752586eb6c5 100644 --- a/src/sage/geometry/point_collection.pyx +++ b/src/sage/geometry/point_collection.pyx @@ -83,6 +83,8 @@ from sage.geometry.toric_lattice import ToricLattice from sage.matrix.constructor import matrix from sage.misc.latex import latex +from sage.misc.sage_input import SageInputBuilder, SageInputExpression + def is_PointCollection(x): r""" @@ -172,7 +174,7 @@ cdef class PointCollection(SageObject): self._points = tuple(points) self._module = self._points[0].parent() if module is None else module - def _sage_input_(self, sib, coerced): + def _sage_input_(self, sib: SageInputBuilder, coerced: bool | Literal[2]) -> SageInputExpression: r""" Return Sage command to reconstruct ``self``. diff --git a/src/sage/geometry/polyhedron/base0.py b/src/sage/geometry/polyhedron/base0.py index c710c5dfa62..fdbb7874b7a 100644 --- a/src/sage/geometry/polyhedron/base0.py +++ b/src/sage/geometry/polyhedron/base0.py @@ -29,12 +29,15 @@ # (at your option) any later version. # https://www.gnu.org/licenses/ # **************************************************************************** - +from typing import TYPE_CHECKING, Literal from sage.misc.cachefunc import cached_method from sage.misc.abstract_method import abstract_method from sage.structure.element import Element import sage.geometry.abc +if TYPE_CHECKING: + from sage.misc.sage_input import SageInputBuilder, SageInputExpression + class Polyhedron_base0(Element, sage.geometry.abc.Polyhedron): """ @@ -296,7 +299,7 @@ def _delete(self): """ self.parent().recycle(self) - def _sage_input_(self, sib, coerced): + def _sage_input_(self, sib: SageInputBuilder, coerced: bool | Literal[2]) -> SageInputExpression: """ Return Sage command to reconstruct ``self``. diff --git a/src/sage/geometry/toric_lattice.py b/src/sage/geometry/toric_lattice.py index 53346206c05..223dc646ecf 100644 --- a/src/sage/geometry/toric_lattice.py +++ b/src/sage/geometry/toric_lattice.py @@ -144,7 +144,7 @@ # # https://www.gnu.org/licenses/ # **************************************************************************** - +from typing import TYPE_CHECKING, Literal from sage.geometry.toric_lattice_element import ToricLatticeElement from sage.misc.lazy_import import lazy_import lazy_import('sage.geometry.toric_plotter', 'ToricPlotter') @@ -162,6 +162,9 @@ from sage.rings.rational_field import QQ from sage.structure.factory import UniqueFactory +if TYPE_CHECKING: + from sage.misc.sage_input import SageInputBuilder, SageInputExpression + def is_ToricLattice(x): r""" @@ -897,7 +900,7 @@ def __init__(self, rank, name, dual_name, latex_name, latex_dual_name): self._latex_name = latex_name self._latex_dual_name = latex_dual_name - def _sage_input_(self, sib, coerced): + def _sage_input_(self, sib: SageInputBuilder, coerced: bool | Literal[2]) -> SageInputExpression: r""" Return Sage command to reconstruct ``self``. diff --git a/src/sage/matrix/matrix1.pyx b/src/sage/matrix/matrix1.pyx index fe4586d5176..a326808868b 100644 --- a/src/sage/matrix/matrix1.pyx +++ b/src/sage/matrix/matrix1.pyx @@ -24,6 +24,7 @@ from cpython.sequence cimport PySequence_Fast import sage.modules.free_module from sage.structure.coerce cimport coercion_model +from sage.misc.sage_input import SageInputBuilder, SageInputExpression cdef class Matrix(Matrix0): ################################################### @@ -622,7 +623,7 @@ cdef class Matrix(Matrix0): matrix._sage_object = self return matrix - def _sage_input_(self, sib, coerce): + def _sage_input_(self, sib: SageInputBuilder, coerced: bool | Literal[2]) -> SageInputExpression: r""" Produce an expression which will reproduce this value when evaluated. diff --git a/src/sage/misc/explain_pickle.py b/src/sage/misc/explain_pickle.py index bd378b35d8f..c6de3ec22b9 100644 --- a/src/sage/misc/explain_pickle.py +++ b/src/sage/misc/explain_pickle.py @@ -152,23 +152,24 @@ # (at your option) any later version. # http://www.gnu.org/licenses/ # ***************************************************************************** - - +import bz2 as comp_other import pickletools import re import sys import types - import zlib as comp -import bz2 as comp_other - from pickletools import genops - -from sage.misc.sage_input import SageInputBuilder, SageInputExpression +from typing import Literal + +from sage.misc.persist import ( + SageUnpickler, + dumps, + register_unpickle_override, + unpickle_global, + unpickle_override, +) from sage.misc.sage_eval import sage_eval -from sage.misc.persist import (unpickle_override, unpickle_global, dumps, - register_unpickle_override, SageUnpickler) - +from sage.misc.sage_input import SageInputBuilder, SageInputExpression # Python 3 does not have a "ClassType". Instead, we ensure that # isinstance(foo, ClassType) will always return False. @@ -358,7 +359,7 @@ def __init__(self, value, expression): self.expression = expression self.immutable = False - def _sage_input_(self, sib, coerced): + def _sage_input_(self, sib: SageInputBuilder, coerced: bool | Literal[2]) -> SageInputExpression: r""" Extracts the expression from a PickleObject, and sets the immutable flag. @@ -845,14 +846,13 @@ def _APPENDS_helper(self, lst, slice): else: for s in slice: self.sib.command(lst, self.sib.name('list').append(lst, self.sib(s))) + elif self.pedantic: + app = self.sib(lst).append + for s in slice: + self.sib.command(lst, app(self.sib(s))) else: - if self.pedantic: - app = self.sib(lst).append - for s in slice: - self.sib.command(lst, app(self.sib(s))) - else: - for s in slice: - self.sib.command(lst, self.sib(lst).append(self.sib(s))) + for s in slice: + self.sib.command(lst, self.sib(lst).append(self.sib(s))) else: self.sib.command(lst, self.sib.name('unpickle_appends')(self.sib(lst), slice_exp)) self.push(lst) @@ -2509,7 +2509,7 @@ def unpickle_extension(code): sage: remove_extension('sage.misc.explain_pickle', 'EmptyNewstyleClass', 42) """ - from copyreg import _inverted_registry, _extension_cache + from copyreg import _extension_cache, _inverted_registry # copied from .get_extension() in pickle.py nil = [] obj = _extension_cache.get(code, nil) diff --git a/src/sage/misc/sage_input.py b/src/sage/misc/sage_input.py index 20a382f8829..6c2a72e7052 100644 --- a/src/sage/misc/sage_input.py +++ b/src/sage/misc/sage_input.py @@ -172,6 +172,7 @@ # (at your option) any later version. # https://www.gnu.org/licenses/ # **************************************************************************** +from typing import Literal from sage.misc.lazy_import import lazy_import @@ -343,7 +344,7 @@ def __init__(self, allow_locals=False, preparse=True): self._next_local = 1 self._locals = {} - def __call__(self, x, coerced=False): + def __call__(self, x, coerced: bool | Literal[2] = False): r""" Try to convert an arbitrary value ``x`` into a :class:`SageInputExpression` (an SIE). @@ -477,11 +478,10 @@ def __call__(self, x, coerced=False): return SIE_literal_stringrep(self, str(x) + 'r') elif self._preparse is False: return self.int(x) + elif x < 0: + return -self.name('int')(self.int(-x)) else: - if x < 0: - return -self.name('int')(self.int(-x)) - else: - return self.name('int')(self.int(x)) + return self.name('int')(self.int(x)) if isinstance(x, float): # floats could often have prettier output, @@ -499,8 +499,8 @@ def __call__(self, x, coerced=False): return -SIE_literal_stringrep(self, str(-x)) else: return SIE_literal_stringrep(self, str(x)) - from sage.rings.real_mpfr import RR from sage.rings.integer_ring import ZZ + from sage.rings.real_mpfr import RR rrx = RR(x) if rrx in ZZ and abs(rrx) < (1 << 53): return self.name('float')(self.int(ZZ(rrx))) @@ -593,7 +593,7 @@ def float_str(self, n): """ return SIE_literal_stringrep(self, n) - def name(self, n): + def name(self, n) -> SageInputExpression: r""" Given a string representing a Python name, produces a :class:`SageInputExpression` for that name. @@ -2228,11 +2228,10 @@ def _sie_format(self, sif): values = [sif.format(val, 0) for val in self._sie_values] if self._sie_is_list: return '[%s]' % ', '.join(values), _prec_atomic + elif len(values) == 1: + return '(%s,)' % values[0], _prec_atomic else: - if len(values) == 1: - return '(%s,)' % values[0], _prec_atomic - else: - return '(%s)' % ', '.join(values), _prec_atomic + return '(%s)' % ', '.join(values), _prec_atomic class SIE_dict(SageInputExpression): diff --git a/src/sage/modules/free_module_element.pyx b/src/sage/modules/free_module_element.pyx index b16e66f1289..62460e7aad8 100644 --- a/src/sage/modules/free_module_element.pyx +++ b/src/sage/modules/free_module_element.pyx @@ -128,6 +128,7 @@ from sage.rings.abc import RealDoubleField, ComplexDoubleField from sage.rings.integer cimport Integer, smallInteger from sage.arith.numerical_approx cimport digits_to_bits +from sage.misc.sage_input import SageInputBuilder, SageInputExpression # For the norm function, we cache Sage integers 1 and 2 __one__ = smallInteger(1) @@ -1258,7 +1259,7 @@ cdef class FreeModuleElement(Vector): # abstract base class return self return self.change_ring(R) - def _sage_input_(self, sib, coerce): + def _sage_input_(self, sib: SageInputBuilder, coerced: bool | Literal[2]) -> SageInputExpression: r""" Produce an expression which will reproduce this value when evaluated. diff --git a/src/sage/rings/complex_interval.pyx b/src/sage/rings/complex_interval.pyx index b0b9f14263b..bdda23de169 100644 --- a/src/sage/rings/complex_interval.pyx +++ b/src/sage/rings/complex_interval.pyx @@ -64,6 +64,7 @@ from sage.libs.flint.fmpz cimport * from sage.libs.mpfr cimport MPFR_RNDU from sage.arith.constants cimport LOG_TEN_TWO_PLUS_EPSILON +from sage.misc.sage_input import SageInputBuilder, SageInputExpression from sage.structure.element cimport FieldElement from sage.structure.parent cimport Parent from sage.rings.complex_mpfr cimport ComplexNumber @@ -1002,7 +1003,7 @@ cdef class ComplexIntervalFieldElement(FieldElement): """ raise TypeError - def _sage_input_(self, sib, coerce): + def _sage_input_(self, sib: SageInputBuilder, coerced: bool | Literal[2]) -> SageInputExpression: r""" Produce an expression which will reproduce this value when evaluated. diff --git a/src/sage/rings/complex_interval_field.py b/src/sage/rings/complex_interval_field.py index c090d6cdae2..d98b0c333cf 100644 --- a/src/sage/rings/complex_interval_field.py +++ b/src/sage/rings/complex_interval_field.py @@ -34,8 +34,7 @@ # (at your option) any later version. # https://www.gnu.org/licenses/ # **************************************************************************** - - +from typing import TYPE_CHECKING, Literal import weakref import sage.rings.abc @@ -48,6 +47,9 @@ from sage.rings.ring import Field from sage.structure.parent import Parent +if TYPE_CHECKING: + from sage.misc.sage_input import SageInputBuilder, SageInputExpression + cache = {} @@ -295,7 +297,7 @@ def _magma_init_(self, magma): """ return "ComplexField(%s : Bits := true)" % self.prec() - def _sage_input_(self, sib, coerce): + def _sage_input_(self, sib: SageInputBuilder, coerced: bool | Literal[2]) -> SageInputExpression: r""" Produce an expression which will reproduce this value when evaluated. diff --git a/src/sage/rings/complex_mpfr.pyx b/src/sage/rings/complex_mpfr.pyx index 11f58008fcf..8e96db12d24 100644 --- a/src/sage/rings/complex_mpfr.pyx +++ b/src/sage/rings/complex_mpfr.pyx @@ -33,6 +33,7 @@ import re import weakref import sage.misc.misc +from sage.misc.sage_input import SageInputBuilder, SageInputExpression from sage.libs.mpfr cimport * @@ -645,7 +646,7 @@ class ComplexField_class(sage.rings.abc.ComplexField): """ return "\\Bold{C}" - def _sage_input_(self, sib, coerce): + def _sage_input_(self, sib: SageInputBuilder, coerced: bool | Literal[2]) -> SageInputExpression: r""" Produce an expression which will reproduce this value when evaluated. @@ -1071,7 +1072,7 @@ cdef class ComplexNumber(sage.structure.element.FieldElement): else: return numpy_object_interface - def _sage_input_(self, sib, coerced): + def _sage_input_(self, sib: SageInputBuilder, coerced: bool | Literal[2]) -> SageInputExpression: r""" Produce an expression which will reproduce this value when evaluated. diff --git a/src/sage/rings/finite_rings/finite_field_base.pyx b/src/sage/rings/finite_rings/finite_field_base.pyx index 3eed6a7e4b8..87ad6bcd430 100644 --- a/src/sage/rings/finite_rings/finite_field_base.pyx +++ b/src/sage/rings/finite_rings/finite_field_base.pyx @@ -39,6 +39,7 @@ from sage.categories.finite_fields import FiniteFields from sage.misc.persist import register_unpickle_override from sage.misc.cachefunc import cached_method from sage.misc.prandom import randrange +from sage.misc.sage_input import SageInputBuilder, SageInputExpression from sage.rings.integer cimport Integer import sage.rings.abc @@ -263,7 +264,7 @@ cdef class FiniteField(Field): return "GF(%s,Variable=>symbol %s)" % (self.order(), self.variable_name()) - def _sage_input_(self, sib, coerced): + def _sage_input_(self, sib: SageInputBuilder, coerced: bool | Literal[2]) -> SageInputExpression: r""" Produce an expression which will reproduce this value when evaluated. diff --git a/src/sage/rings/finite_rings/integer_mod.pyx b/src/sage/rings/finite_rings/integer_mod.pyx index 8fbcea08502..95514577a88 100644 --- a/src/sage/rings/finite_rings/integer_mod.pyx +++ b/src/sage/rings/finite_rings/integer_mod.pyx @@ -110,6 +110,7 @@ from sage.categories.morphism cimport Morphism from sage.categories.map cimport Map from sage.misc.persist import register_unpickle_override +from sage.misc.sage_input import SageInputBuilder, SageInputExpression from sage.structure.parent cimport Parent @@ -611,7 +612,7 @@ cdef class IntegerMod_abstract(FiniteRingElement): _fricas_init_ = _axiom_init_ - def _sage_input_(self, sib, coerced): + def _sage_input_(self, sib: SageInputBuilder, coerced: bool | Literal[2]) -> SageInputExpression: r""" Produce an expression which will reproduce this value when evaluated. diff --git a/src/sage/rings/integer.pyx b/src/sage/rings/integer.pyx index 5fd948c2a83..38a6758b667 100644 --- a/src/sage/rings/integer.pyx +++ b/src/sage/rings/integer.pyx @@ -185,6 +185,8 @@ from sage.structure.richcmp cimport rich_to_bool_sgn from sage.rings import integer_ring +from sage.misc.sage_input import SageInputBuilder, SageInputExpression + cimport gmpy2 gmpy2.import_gmpy2() @@ -6396,7 +6398,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): return 'StringToInteger("%s",16)' % self.str(16) return str(self) - def _sage_input_(self, sib, coerced): + def _sage_input_(self, sib: SageInputBuilder, coerced: bool | Literal[2]) -> SageInputExpression: r""" Produce an expression which will reproduce this value when evaluated. diff --git a/src/sage/rings/integer_ring.pyx b/src/sage/rings/integer_ring.pyx index e6244e3fbc9..d77406b3483 100644 --- a/src/sage/rings/integer_ring.pyx +++ b/src/sage/rings/integer_ring.pyx @@ -65,9 +65,11 @@ from sage.structure.richcmp cimport rich_to_bool from sage.misc.misc_c import prod from sage.misc.randstate cimport randstate, current_randstate, SAGE_RAND_MAX +from sage.misc.sage_input import SageInputBuilder, SageInputExpression from sage.rings.integer cimport Integer + arith = None cdef void late_import() noexcept: # A hack to avoid circular imports. @@ -1525,7 +1527,7 @@ cdef class IntegerRing_class(CommutativeRing): sympy_init() return Integers - def _sage_input_(self, sib, coerced): + def _sage_input_(self, sib: SageInputBuilder, coerced: bool | Literal[2]) -> SageInputExpression: r""" Produce an expression which will reproduce this value when evaluated. diff --git a/src/sage/rings/polynomial/polynomial_element.pyx b/src/sage/rings/polynomial/polynomial_element.pyx index 1a2e1257cb6..f6508b470ec 100644 --- a/src/sage/rings/polynomial/polynomial_element.pyx +++ b/src/sage/rings/polynomial/polynomial_element.pyx @@ -128,6 +128,7 @@ from sage.misc.cachefunc import cached_function from sage.categories.map cimport Map from sage.categories.morphism cimport Morphism +from sage.misc.sage_input import SageInputBuilder, SageInputExpression from sage.misc.superseded import deprecation_cython as deprecation, deprecated_function_alias from sage.misc.cachefunc import cached_method @@ -3298,7 +3299,7 @@ cdef class Polynomial(CommutativePolynomial): return "0" return s[1:].lstrip().rstrip() - def _sage_input_(self, sib, coerced): + def _sage_input_(self, sib: SageInputBuilder, coerced: bool | Literal[2]) -> SageInputExpression: r""" Produce an expression which will reproduce this value when evaluated. diff --git a/src/sage/rings/polynomial/polynomial_ring.py b/src/sage/rings/polynomial/polynomial_ring.py index 08c5a47c252..dc97089cf7e 100644 --- a/src/sage/rings/polynomial/polynomial_ring.py +++ b/src/sage/rings/polynomial/polynomial_ring.py @@ -137,9 +137,8 @@ # (at your option) any later version. # https://www.gnu.org/licenses/ # **************************************************************************** - - import sys +from typing import TYPE_CHECKING, Literal from sage.misc.superseded import deprecation from sage.structure.element import Element @@ -180,6 +179,9 @@ import sage.interfaces.abc +if TYPE_CHECKING: + from sage.misc.sage_input import SageInputBuilder, SageInputExpression + def is_PolynomialRing(x): """ @@ -968,7 +970,7 @@ def _gap_init_(self) -> str: base_ring = self.base_ring()._gap_init_() return 'PolynomialRing(%s, ["%s"])' % (base_ring, self.variable_name()) - def _sage_input_(self, sib, coerced): + def _sage_input_(self, sib: SageInputBuilder, coerced: bool | Literal[2]) -> SageInputExpression: r""" Produce an expression which will reproduce this value when evaluated. diff --git a/src/sage/rings/qqbar.py b/src/sage/rings/qqbar.py index 6e0aadb56f8..7be97c4ddd2 100644 --- a/src/sage/rings/qqbar.py +++ b/src/sage/rings/qqbar.py @@ -579,9 +579,9 @@ - Carl Witty (2007-01-27): initial version - Carl Witty (2007-10-29): massive rewrite to support complex as well as real numbers """ - import itertools import operator +from typing import TYPE_CHECKING, Literal import sage.rings.abc import sage.rings.number_field.number_field_base @@ -629,6 +629,9 @@ ) from sage.structure.sage_object import SageObject +if TYPE_CHECKING: + from sage.misc.sage_input import SageInputBuilder, SageInputExpression + class AlgebraicField_common(sage.rings.abc.AlgebraicField_common): r""" @@ -1200,7 +1203,7 @@ def _latex_(self): """ return "\\mathbf{A}" - def _sage_input_(self, sib, coerce): + def _sage_input_(self, sib: SageInputBuilder, coerced: bool | Literal[2]) -> SageInputExpression: r""" Produce an expression which will reproduce this value when evaluated. @@ -1708,7 +1711,7 @@ def _latex_(self): """ return "\\overline{\\QQ}" - def _sage_input_(self, sib, coerce): + def _sage_input_(self, sib: SageInputBuilder, coerced: bool | Literal[2]) -> SageInputExpression: r""" Produce an expression which will reproduce this value when evaluated. @@ -3915,7 +3918,7 @@ def _latex_(self): return latex(radical) return repr(self).replace('*I', r' \sqrt{-1}') - def _sage_input_(self, sib, coerce): + def _sage_input_(self, sib: SageInputBuilder, coerced: bool | Literal[2]) -> SageInputExpression: r""" Produce an expression which will reproduce this value when evaluated. @@ -3963,7 +3966,7 @@ def _sage_input_(self, sib, coerce): {call: {getattr: {atomic:QQbar}.polynomial_root}({call: {getattr: {atomic:AA}.common_polynomial}({binop:- {binop:** {gen:x {constr_parent: {subscr: {atomic:QQbar}[{atomic:'x'}]} with gens: ('x',)}} {atomic:2}} {atomic:7}})}, {call: {atomic:CIF}({call: {atomic:RIF}({call: {atomic:RR}({atomic:2.6457513110645903})}, {call: {atomic:RR}({atomic:2.6457513110645907})})}, {call: {atomic:RIF}({call: {atomic:RR}({atomic:0})})})})} """ (v, complicated) = \ - self._descr.handle_sage_input(sib, coerce, self.parent() is QQbar) + self._descr.handle_sage_input(sib, coerced, self.parent() is QQbar) if complicated or True: sib.id_cache(self, v, 'v') return v @@ -6978,7 +6981,7 @@ def __reduce__(self): """ return (AlgebraicPolynomialTracker, (self._poly, )) - def _sage_input_(self, sib, coerce): + def _sage_input_(self, sib: SageInputBuilder, coerced: bool | Literal[2]) -> SageInputExpression: r""" Produce an expression which will reproduce this value when evaluated. diff --git a/src/sage/rings/rational.pyx b/src/sage/rings/rational.pyx index 02fe3b23af0..a13e0bf716f 100644 --- a/src/sage/rings/rational.pyx +++ b/src/sage/rings/rational.pyx @@ -77,7 +77,7 @@ from sage.structure.coerce cimport coercion_model, is_numpy_type from sage.structure.element cimport Element from sage.structure.parent cimport Parent from sage.structure.richcmp cimport rich_to_bool_sgn - +from sage.misc.sage_input import SageInputBuilder, SageInputExpression RealNumber_classes = () @@ -3845,7 +3845,7 @@ cdef class Rational(sage.structure.element.FieldElement): """ return '%s/%s' % (self.numerator(), self.denominator()) - def _sage_input_(self, sib, coerced): + def _sage_input_(self, sib: SageInputBuilder, coerced: bool | Literal[2]) -> SageInputExpression: r""" Produce an expression which will reproduce this value when evaluated. diff --git a/src/sage/rings/rational_field.py b/src/sage/rings/rational_field.py index c8c84901607..4a88dd28b09 100644 --- a/src/sage/rings/rational_field.py +++ b/src/sage/rings/rational_field.py @@ -52,7 +52,7 @@ - Anna Haensch (2018-03): Added function ``quadratic_defect()`` """ - +from typing import TYPE_CHECKING, Literal from sage.rings.integer import Integer from sage.rings.rational import Rational @@ -64,6 +64,9 @@ from sage.structure.parent import Parent from sage.structure.sequence import Sequence +if TYPE_CHECKING: + from sage.misc.sage_input import SageInputBuilder, SageInputExpression + class RationalField(Singleton, number_field_base.NumberField): r""" @@ -1594,7 +1597,7 @@ def _sympy_(self): sympy_init() return Rationals - def _sage_input_(self, sib, coerced): + def _sage_input_(self, sib: SageInputBuilder, coerced: bool | Literal[2]) -> SageInputExpression: r""" Produce an expression which will reproduce this value when evaluated. diff --git a/src/sage/rings/real_double.pyx b/src/sage/rings/real_double.pyx index cac66b4ac75..8f2379389eb 100644 --- a/src/sage/rings/real_double.pyx +++ b/src/sage/rings/real_double.pyx @@ -60,6 +60,7 @@ from sage.rings.integer_ring import ZZ from sage.categories.morphism cimport Morphism from sage.structure.coerce cimport is_numpy_type from sage.misc.randstate cimport randstate, current_randstate +from sage.misc.sage_input import SageInputBuilder, SageInputExpression from sage.structure.richcmp cimport rich_to_bool from sage.arith.constants cimport * @@ -172,7 +173,7 @@ cdef class RealDoubleField_class(sage.rings.abc.RealDoubleField): """ return "\\Bold{R}" - def _sage_input_(self, sib, coerced): + def _sage_input_(self, sib: SageInputBuilder, coerced: bool | Literal[2]) -> SageInputExpression: r""" Produce an expression which will reproduce this value when evaluated. @@ -981,7 +982,7 @@ cdef class RealDoubleElement(FieldElement): from sage.rings.real_mpfr import RR return RR(self._value)._mathematica_init_() - def _sage_input_(self, sib, coerced): + def _sage_input_(self, sib: SageInputBuilder, coerced: bool | Literal[2]) -> SageInputExpression: r""" Produce an expression which will reproduce this value when evaluated. diff --git a/src/sage/rings/real_mpfi.pyx b/src/sage/rings/real_mpfi.pyx index 4d8dafa0515..56bd5351ed0 100644 --- a/src/sage/rings/real_mpfi.pyx +++ b/src/sage/rings/real_mpfi.pyx @@ -308,6 +308,7 @@ import operator from sage.cpython.string cimport char_to_str, bytes_to_str from sage.misc.superseded import deprecation +from sage.misc.sage_input import SageInputBuilder, SageInputExpression import sage.rings.infinity # **************************************************************************** @@ -655,7 +656,7 @@ cdef class RealIntervalField_class(sage.rings.abc.RealIntervalField): """ return "\\Bold{I} \\Bold{R}" - def _sage_input_(self, sib, coerce): + def _sage_input_(self, sib: SageInputBuilder, coerced: bool | Literal[2]) -> SageInputExpression: r""" Produce an expression which will reproduce this value when evaluated. @@ -1392,7 +1393,7 @@ cdef class RealIntervalFieldElement(RingElement): """ raise TypeError - def _sage_input_(self, sib, coerce): + def _sage_input_(self, sib: SageInputBuilder, coerced: bool | Literal[2]) -> SageInputExpression: r""" Produce an expression which will reproduce this value when evaluated. diff --git a/src/sage/rings/real_mpfr.pyx b/src/sage/rings/real_mpfr.pyx index 10ff6b8baae..f7fecaf64a9 100644 --- a/src/sage/rings/real_mpfr.pyx +++ b/src/sage/rings/real_mpfr.pyx @@ -142,6 +142,7 @@ from sage.libs.gmp.pylong cimport mpz_set_pylong from sage.libs.mpfr cimport * from sage.libs.mpmath.utils cimport mpfr_to_mpfval from sage.misc.randstate cimport randstate, current_randstate +from sage.misc.sage_input import SageInputBuilder, SageInputExpression from sage.structure.element cimport Element from sage.structure.parent cimport Parent @@ -595,7 +596,7 @@ cdef class RealField_class(sage.rings.abc.RealField): """ return "\\Bold{R}" - def _sage_input_(self, sib, coerce): + def _sage_input_(self, sib: SageInputBuilder, coerced: bool) -> SageInputExpression: r""" Produce an expression which will reproduce this value when evaluated. @@ -1685,7 +1686,7 @@ cdef class RealNumber(sage.structure.element.RingElement): """ return self.str(10, e='*^') - def _sage_input_(self, sib, coerced): + def _sage_input_(self, sib: SageInputBuilder, coerced: bool) -> SageInputExpression: r""" Produce an expression which will reproduce this value when evaluated. diff --git a/src/sage/sets/real_set.py b/src/sage/sets/real_set.py index 7f909c69655..5b6a5f95196 100644 --- a/src/sage/sets/real_set.py +++ b/src/sage/sets/real_set.py @@ -97,17 +97,21 @@ class RealSet. # https://www.gnu.org/licenses/ # **************************************************************************** from heapq import merge +from typing import TYPE_CHECKING, Literal from sage.categories.sets_cat import EmptySetError from sage.categories.topological_spaces import TopologicalSpaces from sage.rings.infinity import infinity, minus_infinity from sage.rings.integer_ring import ZZ -from sage.rings.real_lazy import LazyFieldElement, RLF -from sage.sets.set import Set_base, Set_boolean_operators, Set_add_sub_operators +from sage.rings.real_lazy import RLF, LazyFieldElement +from sage.sets.set import Set_add_sub_operators, Set_base, Set_boolean_operators from sage.structure.parent import Parent from sage.structure.richcmp import richcmp, richcmp_method from sage.structure.unique_representation import UniqueRepresentation +if TYPE_CHECKING: + from sage.misc.sage_input import SageInputBuilder, SageInputExpression + @richcmp_method class InternalRealInterval(UniqueRepresentation, Parent): @@ -456,6 +460,7 @@ def _sympy_(self): Interval.open(0, oo) """ from sympy import Interval + from sage.interfaces.sympy import sympy_init sympy_init() return Interval(self.lower(), self.upper(), @@ -1209,7 +1214,7 @@ def __classcall__(cls, *args, **kwds): elif isinstance(arg, RealSet): intervals.extend(arg._intervals) elif isinstance(arg, Expression) and arg.is_relational(): - from operator import eq, ne, lt, gt, le, ge + from operator import eq, ge, gt, le, lt, ne def rel_to_interval(op, val): """ @@ -1258,7 +1263,9 @@ def rel_to_interval(op, val): else: raise ValueError(str(arg) + ' does not determine real interval') else: - from sage.manifolds.differentiable.examples.real_line import OpenInterval + from sage.manifolds.differentiable.examples.real_line import ( + OpenInterval, + ) from sage.manifolds.subsets.closure import ManifoldSubsetClosure if isinstance(arg, OpenInterval): lower, upper = RealSet._prep(arg.lower_bound(), arg.upper_bound()) @@ -2628,7 +2635,7 @@ def are_pairwise_disjoint(*real_set_collection): overlap_generator = RealSet._scan_to_intervals(scan, lambda i: i > 1) return next(overlap_generator, None) is None - def _sage_input_(self, sib, coerced): + def _sage_input_(self, sib: SageInputBuilder, coerced: bool | Literal[2]) -> SageInputExpression: """ Produce an expression which will reproduce this value when evaluated. @@ -2668,11 +2675,10 @@ def interval_input(i): t = 'RealSet.closed' else: t = 'RealSet.closed_open' + elif i.upper_closed(): + t = 'RealSet.open_closed' else: - if i.upper_closed(): - t = 'RealSet.open_closed' - else: - t = 'RealSet.open' + t = 'RealSet.open' return sib.name(t)(sib(lower), sib(upper)) if self.is_empty(): @@ -2742,6 +2748,7 @@ def _sympy_(self): False """ from sympy import Reals, Union + from sage.interfaces.sympy import sympy_init sympy_init() if self.is_universe(): From c76581b84472e50ed2bafac1cbfa8fa57739b095 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Sat, 4 Oct 2025 22:45:34 +0800 Subject: [PATCH 2/6] Add future annotations import --- src/sage/geometry/cone.py | 2 ++ src/sage/geometry/fan.py | 2 ++ src/sage/geometry/lattice_polytope.py | 2 ++ src/sage/geometry/polyhedron/base0.py | 2 ++ src/sage/geometry/toric_lattice.py | 2 ++ src/sage/misc/explain_pickle.py | 2 ++ src/sage/misc/sage_input.py | 2 ++ src/sage/rings/complex_interval_field.py | 2 ++ src/sage/rings/polynomial/polynomial_ring.py | 2 ++ src/sage/rings/qqbar.py | 2 ++ src/sage/rings/rational_field.py | 2 ++ src/sage/sets/real_set.py | 2 ++ 12 files changed, 24 insertions(+) diff --git a/src/sage/geometry/cone.py b/src/sage/geometry/cone.py index fe947945ff5..c276722d4aa 100644 --- a/src/sage/geometry/cone.py +++ b/src/sage/geometry/cone.py @@ -201,6 +201,8 @@ # (at your option) any later version. # https://www.gnu.org/licenses/ # **************************************************************************** +from __future__ import annotations + from collections.abc import Hashable, Iterable, Container from copy import copy from typing import TYPE_CHECKING, Literal diff --git a/src/sage/geometry/fan.py b/src/sage/geometry/fan.py index cf215743f1e..44be8f765e1 100644 --- a/src/sage/geometry/fan.py +++ b/src/sage/geometry/fan.py @@ -233,6 +233,8 @@ # (at your option) any later version. # https://www.gnu.org/licenses/ # **************************************************************************** +from __future__ import annotations + from collections.abc import Callable, Container from copy import copy from typing import TYPE_CHECKING, Literal diff --git a/src/sage/geometry/lattice_polytope.py b/src/sage/geometry/lattice_polytope.py index d4c315ea934..6fdfd27530f 100644 --- a/src/sage/geometry/lattice_polytope.py +++ b/src/sage/geometry/lattice_polytope.py @@ -120,6 +120,8 @@ # (at your option) any later version. # https://www.gnu.org/licenses/ # **************************************************************************** +from __future__ import annotations + import os import shlex from collections.abc import Hashable diff --git a/src/sage/geometry/polyhedron/base0.py b/src/sage/geometry/polyhedron/base0.py index fdbb7874b7a..eb93ddb0334 100644 --- a/src/sage/geometry/polyhedron/base0.py +++ b/src/sage/geometry/polyhedron/base0.py @@ -29,6 +29,8 @@ # (at your option) any later version. # https://www.gnu.org/licenses/ # **************************************************************************** +from __future__ import annotations + from typing import TYPE_CHECKING, Literal from sage.misc.cachefunc import cached_method from sage.misc.abstract_method import abstract_method diff --git a/src/sage/geometry/toric_lattice.py b/src/sage/geometry/toric_lattice.py index 223dc646ecf..8835c2a1f13 100644 --- a/src/sage/geometry/toric_lattice.py +++ b/src/sage/geometry/toric_lattice.py @@ -144,6 +144,8 @@ # # https://www.gnu.org/licenses/ # **************************************************************************** +from __future__ import annotations + from typing import TYPE_CHECKING, Literal from sage.geometry.toric_lattice_element import ToricLatticeElement from sage.misc.lazy_import import lazy_import diff --git a/src/sage/misc/explain_pickle.py b/src/sage/misc/explain_pickle.py index c6de3ec22b9..9c9604e7b28 100644 --- a/src/sage/misc/explain_pickle.py +++ b/src/sage/misc/explain_pickle.py @@ -152,6 +152,8 @@ # (at your option) any later version. # http://www.gnu.org/licenses/ # ***************************************************************************** +from __future__ import annotations + import bz2 as comp_other import pickletools import re diff --git a/src/sage/misc/sage_input.py b/src/sage/misc/sage_input.py index 6c2a72e7052..8d8d5d24533 100644 --- a/src/sage/misc/sage_input.py +++ b/src/sage/misc/sage_input.py @@ -172,6 +172,8 @@ # (at your option) any later version. # https://www.gnu.org/licenses/ # **************************************************************************** +from __future__ import annotations + from typing import Literal from sage.misc.lazy_import import lazy_import diff --git a/src/sage/rings/complex_interval_field.py b/src/sage/rings/complex_interval_field.py index d98b0c333cf..193469cbddc 100644 --- a/src/sage/rings/complex_interval_field.py +++ b/src/sage/rings/complex_interval_field.py @@ -34,6 +34,8 @@ # (at your option) any later version. # https://www.gnu.org/licenses/ # **************************************************************************** +from __future__ import annotations + from typing import TYPE_CHECKING, Literal import weakref diff --git a/src/sage/rings/polynomial/polynomial_ring.py b/src/sage/rings/polynomial/polynomial_ring.py index dc97089cf7e..c45849c61d2 100644 --- a/src/sage/rings/polynomial/polynomial_ring.py +++ b/src/sage/rings/polynomial/polynomial_ring.py @@ -137,6 +137,8 @@ # (at your option) any later version. # https://www.gnu.org/licenses/ # **************************************************************************** +from __future__ import annotations + import sys from typing import TYPE_CHECKING, Literal diff --git a/src/sage/rings/qqbar.py b/src/sage/rings/qqbar.py index 7be97c4ddd2..144a6d531e5 100644 --- a/src/sage/rings/qqbar.py +++ b/src/sage/rings/qqbar.py @@ -579,6 +579,8 @@ - Carl Witty (2007-01-27): initial version - Carl Witty (2007-10-29): massive rewrite to support complex as well as real numbers """ +from __future__ import annotations + import itertools import operator from typing import TYPE_CHECKING, Literal diff --git a/src/sage/rings/rational_field.py b/src/sage/rings/rational_field.py index 4a88dd28b09..2bff8d61bf4 100644 --- a/src/sage/rings/rational_field.py +++ b/src/sage/rings/rational_field.py @@ -52,6 +52,8 @@ - Anna Haensch (2018-03): Added function ``quadratic_defect()`` """ +from __future__ import annotations + from typing import TYPE_CHECKING, Literal from sage.rings.integer import Integer from sage.rings.rational import Rational diff --git a/src/sage/sets/real_set.py b/src/sage/sets/real_set.py index 5b6a5f95196..dd8226a4094 100644 --- a/src/sage/sets/real_set.py +++ b/src/sage/sets/real_set.py @@ -96,6 +96,8 @@ class RealSet. # (at your option) any later version. # https://www.gnu.org/licenses/ # **************************************************************************** +from __future__ import annotations + from heapq import merge from typing import TYPE_CHECKING, Literal From ea7409d46fd0d063acee22348503853ee19e4b8e Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Wed, 15 Oct 2025 22:10:13 +0800 Subject: [PATCH 3/6] Introduce CoercionMode type --- src/sage/geometry/cone.py | 9 ++++---- src/sage/geometry/fan.py | 16 ++++++------- src/sage/geometry/lattice_polytope.py | 6 ++--- src/sage/geometry/point_collection.pyx | 4 ++-- src/sage/geometry/polyhedron/base0.py | 11 +++++---- src/sage/geometry/toric_lattice.py | 7 +++--- src/sage/matrix/matrix1.pyx | 4 ++-- src/sage/misc/explain_pickle.py | 5 ++-- src/sage/misc/sage_input.py | 3 ++- src/sage/modules/free_module_element.pyx | 4 ++-- src/sage/rings/complex_interval.pyx | 4 ++-- src/sage/rings/complex_interval_field.py | 6 ++--- src/sage/rings/complex_mpfr.pyx | 6 ++--- .../rings/finite_rings/finite_field_base.pyx | 4 ++-- src/sage/rings/finite_rings/integer_mod.pyx | 4 ++-- src/sage/rings/integer.pyx | 4 ++-- src/sage/rings/integer_ring.pyx | 4 ++-- .../rings/polynomial/polynomial_element.pyx | 4 ++-- src/sage/rings/polynomial/polynomial_ring.py | 6 ++--- src/sage/rings/qqbar.py | 12 +++++----- src/sage/rings/rational.pyx | 4 ++-- src/sage/rings/rational_field.py | 23 ++++++++++--------- src/sage/rings/real_double.pyx | 6 ++--- src/sage/rings/real_mpfi.pyx | 6 ++--- src/sage/rings/real_mpfr.pyx | 4 ++-- src/sage/sets/real_set.py | 6 ++--- 26 files changed, 88 insertions(+), 84 deletions(-) diff --git a/src/sage/geometry/cone.py b/src/sage/geometry/cone.py index c276722d4aa..c344b15eff5 100644 --- a/src/sage/geometry/cone.py +++ b/src/sage/geometry/cone.py @@ -244,7 +244,7 @@ feature=PythonModule("ppl", spkg='pplpy', type='standard')) if TYPE_CHECKING: - from sage.misc.sage_input import SageInputBuilder, SageInputExpression + from sage.misc.sage_input import CoercionMode, SageInputBuilder, SageInputExpression def is_Cone(x): @@ -1505,7 +1505,7 @@ def __init__(self, rays=None, lattice=None, if PPL is not None: self._PPL_C_Polyhedron = PPL - def _sage_input_(self, sib: SageInputBuilder, coerced: bool | Literal[2]) -> SageInputExpression: + def _sage_input_(self, sib: SageInputBuilder, coerced: CoercionMode) -> SageInputExpression: """ Return Sage command to reconstruct ``self``. @@ -4323,8 +4323,9 @@ def semigroup_generators(self): # recursively N = self.lattice() if not self.is_simplicial(): - from sage.geometry.triangulation.point_configuration \ - import PointConfiguration + from sage.geometry.triangulation.point_configuration import ( + PointConfiguration, + ) origin = self.nrays() # last one in pc pc = PointConfiguration(tuple(self.rays()) + (N(0),), star=origin) triangulation = pc.triangulate() diff --git a/src/sage/geometry/fan.py b/src/sage/geometry/fan.py index 44be8f765e1..e342dc3055f 100644 --- a/src/sage/geometry/fan.py +++ b/src/sage/geometry/fan.py @@ -237,12 +237,10 @@ from collections.abc import Callable, Container from copy import copy -from typing import TYPE_CHECKING, Literal +from typing import TYPE_CHECKING from warnings import warn import sage.geometry.abc - -from sage.structure.richcmp import richcmp_method, richcmp from sage.misc.lazy_import import lazy_import lazy_import('sage.combinat.combination', 'Combinations') lazy_import('sage.combinat.posets.posets', 'FinitePoset') @@ -265,7 +263,7 @@ from sage.rings.rational_field import QQ if TYPE_CHECKING: - from sage.misc.sage_input import SageInputBuilder, SageInputExpression + from sage.misc.sage_input import CoercionMode, SageInputBuilder, SageInputExpression def is_Fan(x) -> bool: @@ -1222,7 +1220,7 @@ def __init__(self, cones, rays, lattice, if virtual_rays is not None: self._virtual_rays = PointCollection(virtual_rays, self.lattice()) - def _sage_input_(self, sib: SageInputBuilder, coerced: bool | Literal[2]) -> SageInputExpression: + def _sage_input_(self, sib: SageInputBuilder, coerced: CoercionMode) -> SageInputExpression: """ Return Sage command to reconstruct ``self``. @@ -2492,8 +2490,8 @@ def is_polytopal(self) -> bool: """ if not self.is_complete(): raise ValueError('to be polytopal, the fan should be complete') - from sage.geometry.triangulation.point_configuration import PointConfiguration from sage.geometry.polyhedron.constructor import Polyhedron + from sage.geometry.triangulation.point_configuration import PointConfiguration pc = PointConfiguration(self.rays()) v_pc = [tuple(p) for p in pc] pc_to_indices = {tuple(p):i for i, p in enumerate(pc)} @@ -2762,8 +2760,10 @@ def is_isomorphic(self, other) -> bool: sage: fan1.is_isomorphic(fan1) True """ - from sage.geometry.fan_isomorphism import \ - fan_isomorphic_necessary_conditions, fan_isomorphism_generator + from sage.geometry.fan_isomorphism import ( + fan_isomorphic_necessary_conditions, + fan_isomorphism_generator, + ) if not fan_isomorphic_necessary_conditions(self, other): return False if self.lattice_dim() == 2: diff --git a/src/sage/geometry/lattice_polytope.py b/src/sage/geometry/lattice_polytope.py index 6fdfd27530f..a87ed219639 100644 --- a/src/sage/geometry/lattice_polytope.py +++ b/src/sage/geometry/lattice_polytope.py @@ -129,7 +129,7 @@ from functools import reduce from io import IOBase, StringIO from subprocess import PIPE, Popen -from typing import TYPE_CHECKING, Literal +from typing import TYPE_CHECKING import sage.geometry.abc from sage.arith.misc import GCD as gcd @@ -168,7 +168,7 @@ feature=PythonModule("ppl", spkg='pplpy', type='standard')) if TYPE_CHECKING: - from sage.misc.sage_input import SageInputBuilder, SageInputExpression + from sage.misc.sage_input import CoercionMode, SageInputBuilder, SageInputExpression class SetOfAllLatticePolytopesClass(Set_generic): @@ -573,7 +573,7 @@ def __init__(self, points=None, compute_vertices=None, self._ambient_facet_indices = tuple(ambient_facet_indices) self._vertices = ambient.vertices(self._ambient_vertex_indices) - def _sage_input_(self, sib: SageInputBuilder, coerced: bool | Literal[2]) -> SageInputExpression: + def _sage_input_(self, sib: SageInputBuilder, coerced: CoercionMode) -> SageInputExpression: """ Return Sage command to reconstruct ``self``. diff --git a/src/sage/geometry/point_collection.pyx b/src/sage/geometry/point_collection.pyx index 752586eb6c5..a84594fa666 100644 --- a/src/sage/geometry/point_collection.pyx +++ b/src/sage/geometry/point_collection.pyx @@ -83,7 +83,7 @@ from sage.geometry.toric_lattice import ToricLattice from sage.matrix.constructor import matrix from sage.misc.latex import latex -from sage.misc.sage_input import SageInputBuilder, SageInputExpression +from sage.misc.sage_input import CoercionMode, SageInputBuilder, SageInputExpression def is_PointCollection(x): @@ -174,7 +174,7 @@ cdef class PointCollection(SageObject): self._points = tuple(points) self._module = self._points[0].parent() if module is None else module - def _sage_input_(self, sib: SageInputBuilder, coerced: bool | Literal[2]) -> SageInputExpression: + def _sage_input_(self, sib: SageInputBuilder, coerced: CoercionMode) -> SageInputExpression: r""" Return Sage command to reconstruct ``self``. diff --git a/src/sage/geometry/polyhedron/base0.py b/src/sage/geometry/polyhedron/base0.py index eb93ddb0334..e7214d71188 100644 --- a/src/sage/geometry/polyhedron/base0.py +++ b/src/sage/geometry/polyhedron/base0.py @@ -31,14 +31,15 @@ # **************************************************************************** from __future__ import annotations -from typing import TYPE_CHECKING, Literal -from sage.misc.cachefunc import cached_method +from typing import TYPE_CHECKING + +import sage.geometry.abc from sage.misc.abstract_method import abstract_method +from sage.misc.cachefunc import cached_method from sage.structure.element import Element -import sage.geometry.abc if TYPE_CHECKING: - from sage.misc.sage_input import SageInputBuilder, SageInputExpression + from sage.misc.sage_input import CoercionMode, SageInputBuilder, SageInputExpression class Polyhedron_base0(Element, sage.geometry.abc.Polyhedron): @@ -301,7 +302,7 @@ def _delete(self): """ self.parent().recycle(self) - def _sage_input_(self, sib: SageInputBuilder, coerced: bool | Literal[2]) -> SageInputExpression: + def _sage_input_(self, sib: SageInputBuilder, coerced: CoercionMode) -> SageInputExpression: """ Return Sage command to reconstruct ``self``. diff --git a/src/sage/geometry/toric_lattice.py b/src/sage/geometry/toric_lattice.py index 8835c2a1f13..da434eb826e 100644 --- a/src/sage/geometry/toric_lattice.py +++ b/src/sage/geometry/toric_lattice.py @@ -146,7 +146,8 @@ # **************************************************************************** from __future__ import annotations -from typing import TYPE_CHECKING, Literal +from typing import TYPE_CHECKING + from sage.geometry.toric_lattice_element import ToricLatticeElement from sage.misc.lazy_import import lazy_import lazy_import('sage.geometry.toric_plotter', 'ToricPlotter') @@ -165,7 +166,7 @@ from sage.structure.factory import UniqueFactory if TYPE_CHECKING: - from sage.misc.sage_input import SageInputBuilder, SageInputExpression + from sage.misc.sage_input import CoercionMode, SageInputBuilder, SageInputExpression def is_ToricLattice(x): @@ -902,7 +903,7 @@ def __init__(self, rank, name, dual_name, latex_name, latex_dual_name): self._latex_name = latex_name self._latex_dual_name = latex_dual_name - def _sage_input_(self, sib: SageInputBuilder, coerced: bool | Literal[2]) -> SageInputExpression: + def _sage_input_(self, sib: SageInputBuilder, coerced: CoercionMode) -> SageInputExpression: r""" Return Sage command to reconstruct ``self``. diff --git a/src/sage/matrix/matrix1.pyx b/src/sage/matrix/matrix1.pyx index a326808868b..a5b40bffcbe 100644 --- a/src/sage/matrix/matrix1.pyx +++ b/src/sage/matrix/matrix1.pyx @@ -24,7 +24,7 @@ from cpython.sequence cimport PySequence_Fast import sage.modules.free_module from sage.structure.coerce cimport coercion_model -from sage.misc.sage_input import SageInputBuilder, SageInputExpression +from sage.misc.sage_input import CoercionMode, SageInputBuilder, SageInputExpression cdef class Matrix(Matrix0): ################################################### @@ -623,7 +623,7 @@ cdef class Matrix(Matrix0): matrix._sage_object = self return matrix - def _sage_input_(self, sib: SageInputBuilder, coerced: bool | Literal[2]) -> SageInputExpression: + def _sage_input_(self, sib: SageInputBuilder, coerced: CoercionMode) -> SageInputExpression: r""" Produce an expression which will reproduce this value when evaluated. diff --git a/src/sage/misc/explain_pickle.py b/src/sage/misc/explain_pickle.py index 9c9604e7b28..f0c289db9c2 100644 --- a/src/sage/misc/explain_pickle.py +++ b/src/sage/misc/explain_pickle.py @@ -161,7 +161,6 @@ import types import zlib as comp from pickletools import genops -from typing import Literal from sage.misc.persist import ( SageUnpickler, @@ -171,7 +170,7 @@ unpickle_override, ) from sage.misc.sage_eval import sage_eval -from sage.misc.sage_input import SageInputBuilder, SageInputExpression +from sage.misc.sage_input import CoercionMode, SageInputBuilder, SageInputExpression # Python 3 does not have a "ClassType". Instead, we ensure that # isinstance(foo, ClassType) will always return False. @@ -361,7 +360,7 @@ def __init__(self, value, expression): self.expression = expression self.immutable = False - def _sage_input_(self, sib: SageInputBuilder, coerced: bool | Literal[2]) -> SageInputExpression: + def _sage_input_(self, sib: SageInputBuilder, coerced: CoercionMode) -> SageInputExpression: r""" Extracts the expression from a PickleObject, and sets the immutable flag. diff --git a/src/sage/misc/sage_input.py b/src/sage/misc/sage_input.py index 8d8d5d24533..fe5146e74aa 100644 --- a/src/sage/misc/sage_input.py +++ b/src/sage/misc/sage_input.py @@ -181,6 +181,7 @@ lazy_import('sage.rings.real_mpfi', 'RealIntervalFieldElement') lazy_import('sage.rings.complex_interval', 'ComplexIntervalFieldElement') +CoercionMode = bool | Literal[2] def sage_input(x, preparse=True, verify=False, allow_locals=False): r""" @@ -346,7 +347,7 @@ def __init__(self, allow_locals=False, preparse=True): self._next_local = 1 self._locals = {} - def __call__(self, x, coerced: bool | Literal[2] = False): + def __call__(self, x, coerced: CoercionMode = False): r""" Try to convert an arbitrary value ``x`` into a :class:`SageInputExpression` (an SIE). diff --git a/src/sage/modules/free_module_element.pyx b/src/sage/modules/free_module_element.pyx index 62460e7aad8..688cf5e30a8 100644 --- a/src/sage/modules/free_module_element.pyx +++ b/src/sage/modules/free_module_element.pyx @@ -128,7 +128,7 @@ from sage.rings.abc import RealDoubleField, ComplexDoubleField from sage.rings.integer cimport Integer, smallInteger from sage.arith.numerical_approx cimport digits_to_bits -from sage.misc.sage_input import SageInputBuilder, SageInputExpression +from sage.misc.sage_input import CoercionMode, SageInputBuilder, SageInputExpression # For the norm function, we cache Sage integers 1 and 2 __one__ = smallInteger(1) @@ -1259,7 +1259,7 @@ cdef class FreeModuleElement(Vector): # abstract base class return self return self.change_ring(R) - def _sage_input_(self, sib: SageInputBuilder, coerced: bool | Literal[2]) -> SageInputExpression: + def _sage_input_(self, sib: SageInputBuilder, coerced: CoercionMode) -> SageInputExpression: r""" Produce an expression which will reproduce this value when evaluated. diff --git a/src/sage/rings/complex_interval.pyx b/src/sage/rings/complex_interval.pyx index bdda23de169..e137d8fa7c2 100644 --- a/src/sage/rings/complex_interval.pyx +++ b/src/sage/rings/complex_interval.pyx @@ -64,7 +64,7 @@ from sage.libs.flint.fmpz cimport * from sage.libs.mpfr cimport MPFR_RNDU from sage.arith.constants cimport LOG_TEN_TWO_PLUS_EPSILON -from sage.misc.sage_input import SageInputBuilder, SageInputExpression +from sage.misc.sage_input import CoercionMode, SageInputBuilder, SageInputExpression from sage.structure.element cimport FieldElement from sage.structure.parent cimport Parent from sage.rings.complex_mpfr cimport ComplexNumber @@ -1003,7 +1003,7 @@ cdef class ComplexIntervalFieldElement(FieldElement): """ raise TypeError - def _sage_input_(self, sib: SageInputBuilder, coerced: bool | Literal[2]) -> SageInputExpression: + def _sage_input_(self, sib: SageInputBuilder, coerced: CoercionMode) -> SageInputExpression: r""" Produce an expression which will reproduce this value when evaluated. diff --git a/src/sage/rings/complex_interval_field.py b/src/sage/rings/complex_interval_field.py index 193469cbddc..6ecef453c4c 100644 --- a/src/sage/rings/complex_interval_field.py +++ b/src/sage/rings/complex_interval_field.py @@ -36,8 +36,8 @@ # **************************************************************************** from __future__ import annotations -from typing import TYPE_CHECKING, Literal import weakref +from typing import TYPE_CHECKING import sage.rings.abc from sage.misc.cachefunc import cached_method @@ -50,7 +50,7 @@ from sage.structure.parent import Parent if TYPE_CHECKING: - from sage.misc.sage_input import SageInputBuilder, SageInputExpression + from sage.misc.sage_input import CoercionMode, SageInputBuilder, SageInputExpression cache = {} @@ -299,7 +299,7 @@ def _magma_init_(self, magma): """ return "ComplexField(%s : Bits := true)" % self.prec() - def _sage_input_(self, sib: SageInputBuilder, coerced: bool | Literal[2]) -> SageInputExpression: + def _sage_input_(self, sib: SageInputBuilder, coerced: CoercionMode) -> SageInputExpression: r""" Produce an expression which will reproduce this value when evaluated. diff --git a/src/sage/rings/complex_mpfr.pyx b/src/sage/rings/complex_mpfr.pyx index 8e96db12d24..1af71d838ff 100644 --- a/src/sage/rings/complex_mpfr.pyx +++ b/src/sage/rings/complex_mpfr.pyx @@ -33,7 +33,7 @@ import re import weakref import sage.misc.misc -from sage.misc.sage_input import SageInputBuilder, SageInputExpression +from sage.misc.sage_input import CoercionMode, SageInputBuilder, SageInputExpression from sage.libs.mpfr cimport * @@ -646,7 +646,7 @@ class ComplexField_class(sage.rings.abc.ComplexField): """ return "\\Bold{C}" - def _sage_input_(self, sib: SageInputBuilder, coerced: bool | Literal[2]) -> SageInputExpression: + def _sage_input_(self, sib: SageInputBuilder, coerced: CoercionMode) -> SageInputExpression: r""" Produce an expression which will reproduce this value when evaluated. @@ -1072,7 +1072,7 @@ cdef class ComplexNumber(sage.structure.element.FieldElement): else: return numpy_object_interface - def _sage_input_(self, sib: SageInputBuilder, coerced: bool | Literal[2]) -> SageInputExpression: + def _sage_input_(self, sib: SageInputBuilder, coerced: CoercionMode) -> SageInputExpression: r""" Produce an expression which will reproduce this value when evaluated. diff --git a/src/sage/rings/finite_rings/finite_field_base.pyx b/src/sage/rings/finite_rings/finite_field_base.pyx index 87ad6bcd430..2246aa04459 100644 --- a/src/sage/rings/finite_rings/finite_field_base.pyx +++ b/src/sage/rings/finite_rings/finite_field_base.pyx @@ -39,7 +39,7 @@ from sage.categories.finite_fields import FiniteFields from sage.misc.persist import register_unpickle_override from sage.misc.cachefunc import cached_method from sage.misc.prandom import randrange -from sage.misc.sage_input import SageInputBuilder, SageInputExpression +from sage.misc.sage_input import CoercionMode, SageInputBuilder, SageInputExpression from sage.rings.integer cimport Integer import sage.rings.abc @@ -264,7 +264,7 @@ cdef class FiniteField(Field): return "GF(%s,Variable=>symbol %s)" % (self.order(), self.variable_name()) - def _sage_input_(self, sib: SageInputBuilder, coerced: bool | Literal[2]) -> SageInputExpression: + def _sage_input_(self, sib: SageInputBuilder, coerced: CoercionMode) -> SageInputExpression: r""" Produce an expression which will reproduce this value when evaluated. diff --git a/src/sage/rings/finite_rings/integer_mod.pyx b/src/sage/rings/finite_rings/integer_mod.pyx index 95514577a88..ff54f7cebf6 100644 --- a/src/sage/rings/finite_rings/integer_mod.pyx +++ b/src/sage/rings/finite_rings/integer_mod.pyx @@ -110,7 +110,7 @@ from sage.categories.morphism cimport Morphism from sage.categories.map cimport Map from sage.misc.persist import register_unpickle_override -from sage.misc.sage_input import SageInputBuilder, SageInputExpression +from sage.misc.sage_input import CoercionMode, SageInputBuilder, SageInputExpression from sage.structure.parent cimport Parent @@ -612,7 +612,7 @@ cdef class IntegerMod_abstract(FiniteRingElement): _fricas_init_ = _axiom_init_ - def _sage_input_(self, sib: SageInputBuilder, coerced: bool | Literal[2]) -> SageInputExpression: + def _sage_input_(self, sib: SageInputBuilder, coerced: CoercionMode) -> SageInputExpression: r""" Produce an expression which will reproduce this value when evaluated. diff --git a/src/sage/rings/integer.pyx b/src/sage/rings/integer.pyx index 38a6758b667..f062c0c1bfd 100644 --- a/src/sage/rings/integer.pyx +++ b/src/sage/rings/integer.pyx @@ -185,7 +185,7 @@ from sage.structure.richcmp cimport rich_to_bool_sgn from sage.rings import integer_ring -from sage.misc.sage_input import SageInputBuilder, SageInputExpression +from sage.misc.sage_input import CoercionMode, SageInputBuilder, SageInputExpression cimport gmpy2 gmpy2.import_gmpy2() @@ -6398,7 +6398,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): return 'StringToInteger("%s",16)' % self.str(16) return str(self) - def _sage_input_(self, sib: SageInputBuilder, coerced: bool | Literal[2]) -> SageInputExpression: + def _sage_input_(self, sib: SageInputBuilder, coerced: CoercionMode) -> SageInputExpression: r""" Produce an expression which will reproduce this value when evaluated. diff --git a/src/sage/rings/integer_ring.pyx b/src/sage/rings/integer_ring.pyx index d77406b3483..471db987f2c 100644 --- a/src/sage/rings/integer_ring.pyx +++ b/src/sage/rings/integer_ring.pyx @@ -65,7 +65,7 @@ from sage.structure.richcmp cimport rich_to_bool from sage.misc.misc_c import prod from sage.misc.randstate cimport randstate, current_randstate, SAGE_RAND_MAX -from sage.misc.sage_input import SageInputBuilder, SageInputExpression +from sage.misc.sage_input import CoercionMode, SageInputBuilder, SageInputExpression from sage.rings.integer cimport Integer @@ -1527,7 +1527,7 @@ cdef class IntegerRing_class(CommutativeRing): sympy_init() return Integers - def _sage_input_(self, sib: SageInputBuilder, coerced: bool | Literal[2]) -> SageInputExpression: + def _sage_input_(self, sib: SageInputBuilder, coerced: CoercionMode) -> SageInputExpression: r""" Produce an expression which will reproduce this value when evaluated. diff --git a/src/sage/rings/polynomial/polynomial_element.pyx b/src/sage/rings/polynomial/polynomial_element.pyx index f6508b470ec..4df47c6f445 100644 --- a/src/sage/rings/polynomial/polynomial_element.pyx +++ b/src/sage/rings/polynomial/polynomial_element.pyx @@ -128,7 +128,7 @@ from sage.misc.cachefunc import cached_function from sage.categories.map cimport Map from sage.categories.morphism cimport Morphism -from sage.misc.sage_input import SageInputBuilder, SageInputExpression +from sage.misc.sage_input import CoercionMode, SageInputBuilder, SageInputExpression from sage.misc.superseded import deprecation_cython as deprecation, deprecated_function_alias from sage.misc.cachefunc import cached_method @@ -3299,7 +3299,7 @@ cdef class Polynomial(CommutativePolynomial): return "0" return s[1:].lstrip().rstrip() - def _sage_input_(self, sib: SageInputBuilder, coerced: bool | Literal[2]) -> SageInputExpression: + def _sage_input_(self, sib: SageInputBuilder, coerced: CoercionMode) -> SageInputExpression: r""" Produce an expression which will reproduce this value when evaluated. diff --git a/src/sage/rings/polynomial/polynomial_ring.py b/src/sage/rings/polynomial/polynomial_ring.py index c45849c61d2..a7db4a64d40 100644 --- a/src/sage/rings/polynomial/polynomial_ring.py +++ b/src/sage/rings/polynomial/polynomial_ring.py @@ -140,7 +140,7 @@ from __future__ import annotations import sys -from typing import TYPE_CHECKING, Literal +from typing import TYPE_CHECKING from sage.misc.superseded import deprecation from sage.structure.element import Element @@ -182,7 +182,7 @@ import sage.interfaces.abc if TYPE_CHECKING: - from sage.misc.sage_input import SageInputBuilder, SageInputExpression + from sage.misc.sage_input import CoercionMode, SageInputBuilder, SageInputExpression def is_PolynomialRing(x): @@ -972,7 +972,7 @@ def _gap_init_(self) -> str: base_ring = self.base_ring()._gap_init_() return 'PolynomialRing(%s, ["%s"])' % (base_ring, self.variable_name()) - def _sage_input_(self, sib: SageInputBuilder, coerced: bool | Literal[2]) -> SageInputExpression: + def _sage_input_(self, sib: SageInputBuilder, coerced: CoercionMode) -> SageInputExpression: r""" Produce an expression which will reproduce this value when evaluated. diff --git a/src/sage/rings/qqbar.py b/src/sage/rings/qqbar.py index 144a6d531e5..db1f4029180 100644 --- a/src/sage/rings/qqbar.py +++ b/src/sage/rings/qqbar.py @@ -583,7 +583,7 @@ import itertools import operator -from typing import TYPE_CHECKING, Literal +from typing import TYPE_CHECKING import sage.rings.abc import sage.rings.number_field.number_field_base @@ -632,7 +632,7 @@ from sage.structure.sage_object import SageObject if TYPE_CHECKING: - from sage.misc.sage_input import SageInputBuilder, SageInputExpression + from sage.misc.sage_input import CoercionMode, SageInputBuilder, SageInputExpression class AlgebraicField_common(sage.rings.abc.AlgebraicField_common): @@ -1205,7 +1205,7 @@ def _latex_(self): """ return "\\mathbf{A}" - def _sage_input_(self, sib: SageInputBuilder, coerced: bool | Literal[2]) -> SageInputExpression: + def _sage_input_(self, sib: SageInputBuilder, coerced: CoercionMode) -> SageInputExpression: r""" Produce an expression which will reproduce this value when evaluated. @@ -1713,7 +1713,7 @@ def _latex_(self): """ return "\\overline{\\QQ}" - def _sage_input_(self, sib: SageInputBuilder, coerced: bool | Literal[2]) -> SageInputExpression: + def _sage_input_(self, sib: SageInputBuilder, coerced: CoercionMode) -> SageInputExpression: r""" Produce an expression which will reproduce this value when evaluated. @@ -3920,7 +3920,7 @@ def _latex_(self): return latex(radical) return repr(self).replace('*I', r' \sqrt{-1}') - def _sage_input_(self, sib: SageInputBuilder, coerced: bool | Literal[2]) -> SageInputExpression: + def _sage_input_(self, sib: SageInputBuilder, coerced: CoercionMode) -> SageInputExpression: r""" Produce an expression which will reproduce this value when evaluated. @@ -6983,7 +6983,7 @@ def __reduce__(self): """ return (AlgebraicPolynomialTracker, (self._poly, )) - def _sage_input_(self, sib: SageInputBuilder, coerced: bool | Literal[2]) -> SageInputExpression: + def _sage_input_(self, sib: SageInputBuilder, coerced: CoercionMode) -> SageInputExpression: r""" Produce an expression which will reproduce this value when evaluated. diff --git a/src/sage/rings/rational.pyx b/src/sage/rings/rational.pyx index a13e0bf716f..e729aa9da30 100644 --- a/src/sage/rings/rational.pyx +++ b/src/sage/rings/rational.pyx @@ -77,7 +77,7 @@ from sage.structure.coerce cimport coercion_model, is_numpy_type from sage.structure.element cimport Element from sage.structure.parent cimport Parent from sage.structure.richcmp cimport rich_to_bool_sgn -from sage.misc.sage_input import SageInputBuilder, SageInputExpression +from sage.misc.sage_input import CoercionMode, SageInputBuilder, SageInputExpression RealNumber_classes = () @@ -3845,7 +3845,7 @@ cdef class Rational(sage.structure.element.FieldElement): """ return '%s/%s' % (self.numerator(), self.denominator()) - def _sage_input_(self, sib: SageInputBuilder, coerced: bool | Literal[2]) -> SageInputExpression: + def _sage_input_(self, sib: SageInputBuilder, coerced: CoercionMode) -> SageInputExpression: r""" Produce an expression which will reproduce this value when evaluated. diff --git a/src/sage/rings/rational_field.py b/src/sage/rings/rational_field.py index 2bff8d61bf4..d9b6d649e10 100644 --- a/src/sage/rings/rational_field.py +++ b/src/sage/rings/rational_field.py @@ -54,20 +54,21 @@ """ from __future__ import annotations -from typing import TYPE_CHECKING, Literal +from typing import TYPE_CHECKING + from sage.rings.integer import Integer from sage.rings.rational import Rational ZZ = None -import sage.rings.number_field.number_field_base as number_field_base from sage.misc.fast_methods import Singleton from sage.misc.superseded import deprecated_function_alias +from sage.rings.number_field import number_field_base from sage.structure.parent import Parent from sage.structure.sequence import Sequence if TYPE_CHECKING: - from sage.misc.sage_input import SageInputBuilder, SageInputExpression + from sage.misc.sage_input import CoercionMode, SageInputBuilder, SageInputExpression class RationalField(Singleton, number_field_base.NumberField): @@ -695,13 +696,12 @@ def places(self, all_complex=False, prec=None): from sage.rings.qqbar import QQbar as domain else: from sage.rings.qqbar import AA as domain + elif all_complex: + from sage.rings.complex_mpfr import ComplexField + domain = ComplexField(prec) else: - if all_complex: - from sage.rings.complex_mpfr import ComplexField - domain = ComplexField(prec) - else: - from sage.rings.real_mpfr import RealField - domain = RealField(prec) + from sage.rings.real_mpfr import RealField + domain = RealField(prec) return [self.hom([domain(1)])] def complex_embedding(self, prec=53): @@ -1594,12 +1594,13 @@ def _sympy_(self): sage: QQ._sympy_() # needs sympy Rationals """ - from sage.interfaces.sympy import sympy_init from sympy import Rationals + + from sage.interfaces.sympy import sympy_init sympy_init() return Rationals - def _sage_input_(self, sib: SageInputBuilder, coerced: bool | Literal[2]) -> SageInputExpression: + def _sage_input_(self, sib: SageInputBuilder, coerced: CoercionMode) -> SageInputExpression: r""" Produce an expression which will reproduce this value when evaluated. diff --git a/src/sage/rings/real_double.pyx b/src/sage/rings/real_double.pyx index 8f2379389eb..d27591efbb0 100644 --- a/src/sage/rings/real_double.pyx +++ b/src/sage/rings/real_double.pyx @@ -60,7 +60,7 @@ from sage.rings.integer_ring import ZZ from sage.categories.morphism cimport Morphism from sage.structure.coerce cimport is_numpy_type from sage.misc.randstate cimport randstate, current_randstate -from sage.misc.sage_input import SageInputBuilder, SageInputExpression +from sage.misc.sage_input import CoercionMode, SageInputBuilder, SageInputExpression from sage.structure.richcmp cimport rich_to_bool from sage.arith.constants cimport * @@ -173,7 +173,7 @@ cdef class RealDoubleField_class(sage.rings.abc.RealDoubleField): """ return "\\Bold{R}" - def _sage_input_(self, sib: SageInputBuilder, coerced: bool | Literal[2]) -> SageInputExpression: + def _sage_input_(self, sib: SageInputBuilder, coerced: CoercionMode) -> SageInputExpression: r""" Produce an expression which will reproduce this value when evaluated. @@ -982,7 +982,7 @@ cdef class RealDoubleElement(FieldElement): from sage.rings.real_mpfr import RR return RR(self._value)._mathematica_init_() - def _sage_input_(self, sib: SageInputBuilder, coerced: bool | Literal[2]) -> SageInputExpression: + def _sage_input_(self, sib: SageInputBuilder, coerced: CoercionMode) -> SageInputExpression: r""" Produce an expression which will reproduce this value when evaluated. diff --git a/src/sage/rings/real_mpfi.pyx b/src/sage/rings/real_mpfi.pyx index 56bd5351ed0..063b7fac678 100644 --- a/src/sage/rings/real_mpfi.pyx +++ b/src/sage/rings/real_mpfi.pyx @@ -308,7 +308,7 @@ import operator from sage.cpython.string cimport char_to_str, bytes_to_str from sage.misc.superseded import deprecation -from sage.misc.sage_input import SageInputBuilder, SageInputExpression +from sage.misc.sage_input import CoercionMode, SageInputBuilder, SageInputExpression import sage.rings.infinity # **************************************************************************** @@ -656,7 +656,7 @@ cdef class RealIntervalField_class(sage.rings.abc.RealIntervalField): """ return "\\Bold{I} \\Bold{R}" - def _sage_input_(self, sib: SageInputBuilder, coerced: bool | Literal[2]) -> SageInputExpression: + def _sage_input_(self, sib: SageInputBuilder, coerced: CoercionMode) -> SageInputExpression: r""" Produce an expression which will reproduce this value when evaluated. @@ -1393,7 +1393,7 @@ cdef class RealIntervalFieldElement(RingElement): """ raise TypeError - def _sage_input_(self, sib: SageInputBuilder, coerced: bool | Literal[2]) -> SageInputExpression: + def _sage_input_(self, sib: SageInputBuilder, coerced: CoercionMode) -> SageInputExpression: r""" Produce an expression which will reproduce this value when evaluated. diff --git a/src/sage/rings/real_mpfr.pyx b/src/sage/rings/real_mpfr.pyx index f7fecaf64a9..e8a1b6d90ea 100644 --- a/src/sage/rings/real_mpfr.pyx +++ b/src/sage/rings/real_mpfr.pyx @@ -142,7 +142,7 @@ from sage.libs.gmp.pylong cimport mpz_set_pylong from sage.libs.mpfr cimport * from sage.libs.mpmath.utils cimport mpfr_to_mpfval from sage.misc.randstate cimport randstate, current_randstate -from sage.misc.sage_input import SageInputBuilder, SageInputExpression +from sage.misc.sage_input import CoercionMode, SageInputBuilder, SageInputExpression from sage.structure.element cimport Element from sage.structure.parent cimport Parent @@ -596,7 +596,7 @@ cdef class RealField_class(sage.rings.abc.RealField): """ return "\\Bold{R}" - def _sage_input_(self, sib: SageInputBuilder, coerced: bool) -> SageInputExpression: + def _sage_input_(self, sib: SageInputBuilder, coerced: CoercionMode) -> SageInputExpression: r""" Produce an expression which will reproduce this value when evaluated. diff --git a/src/sage/sets/real_set.py b/src/sage/sets/real_set.py index dd8226a4094..8b4d8747109 100644 --- a/src/sage/sets/real_set.py +++ b/src/sage/sets/real_set.py @@ -99,7 +99,7 @@ class RealSet. from __future__ import annotations from heapq import merge -from typing import TYPE_CHECKING, Literal +from typing import TYPE_CHECKING from sage.categories.sets_cat import EmptySetError from sage.categories.topological_spaces import TopologicalSpaces @@ -112,7 +112,7 @@ class RealSet. from sage.structure.unique_representation import UniqueRepresentation if TYPE_CHECKING: - from sage.misc.sage_input import SageInputBuilder, SageInputExpression + from sage.misc.sage_input import CoercionMode, SageInputBuilder, SageInputExpression @richcmp_method @@ -2637,7 +2637,7 @@ def are_pairwise_disjoint(*real_set_collection): overlap_generator = RealSet._scan_to_intervals(scan, lambda i: i > 1) return next(overlap_generator, None) is None - def _sage_input_(self, sib: SageInputBuilder, coerced: bool | Literal[2]) -> SageInputExpression: + def _sage_input_(self, sib: SageInputBuilder, coerced: CoercionMode) -> SageInputExpression: """ Produce an expression which will reproduce this value when evaluated. From 71f7484d15593bedd256405716c15f60dadff9fb Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Wed, 15 Oct 2025 23:32:49 +0800 Subject: [PATCH 4/6] Add almost complete typing in sage_input --- src/sage/misc/sage_input.py | 304 +++++++++++++++++++++--------------- 1 file changed, 175 insertions(+), 129 deletions(-) diff --git a/src/sage/misc/sage_input.py b/src/sage/misc/sage_input.py index fe5146e74aa..11a16d0f232 100644 --- a/src/sage/misc/sage_input.py +++ b/src/sage/misc/sage_input.py @@ -174,16 +174,20 @@ # **************************************************************************** from __future__ import annotations -from typing import Literal +from typing import Any, Literal from sage.misc.lazy_import import lazy_import +from sage.structure.element import parent lazy_import('sage.rings.real_mpfi', 'RealIntervalFieldElement') lazy_import('sage.rings.complex_interval', 'ComplexIntervalFieldElement') CoercionMode = bool | Literal[2] -def sage_input(x, preparse=True, verify=False, allow_locals=False): + +def sage_input( + x, preparse: bool | None = True, verify: bool = False, allow_locals: bool = False +) -> SageInputAnswer: r""" Return a sequence of commands that can be used to rebuild the object ``x``. @@ -281,7 +285,7 @@ def sage_input(x, preparse=True, verify=False, allow_locals=False): ans_l[0] = '# Verified\n' + ans_l[0] final_answer = SageInputAnswer(*ans_l) - return final_answer + return final_answer # pyright: ignore[reportPossiblyUnboundVariable] class SageInputBuilder: @@ -309,7 +313,9 @@ class SageInputBuilder: (3 + 4)*(5 + 6) """ - def __init__(self, allow_locals=False, preparse=True): + def __init__( + self, allow_locals: bool = False, preparse: bool | None = True + ) -> None: r""" Initialize an instance of :class:`SageInputBuilder`. @@ -338,16 +344,16 @@ def __init__(self, allow_locals=False, preparse=True): sage: SageInputBuilder(preparse=False).preparse() False """ - self._allow_locals = allow_locals - self._preparse = preparse - self._cached_types = set() - self._cache = {} - self._id_cache = {} - self._parent_gens = {} - self._next_local = 1 - self._locals = {} + self._allow_locals: bool = allow_locals + self._preparse: bool | None = preparse + self._cached_types: set[type] = set() + self._cache: dict[tuple[Any, Any], SageInputExpression] = {} + self._id_cache: dict[int, tuple[Any, SageInputExpression]] = {} + self._parent_gens: dict[Any, list[SIE_gen]] = {} + self._next_local: int = 1 + self._locals: dict[str, Any] = {} - def __call__(self, x, coerced: CoercionMode = False): + def __call__(self, x: Any, coerced: CoercionMode = False) -> SageInputExpression: r""" Try to convert an arbitrary value ``x`` into a :class:`SageInputExpression` (an SIE). @@ -450,7 +456,6 @@ def __call__(self, x, coerced: CoercionMode = False): # However, we don't want to assume that hashing x is always # efficient, so we only try the lookup if some value of the same # type as x has been cached. - from sage.structure.element import parent if type(x) in self._cached_types: v = self._cache.get((parent(x), x)) @@ -530,7 +535,7 @@ def __call__(self, x, coerced: CoercionMode = False): else: raise ValueError("cannot convert {} to sage_input form".format(x)) - def preparse(self): + def preparse(self) -> bool | None: r""" Check the preparse status. @@ -552,7 +557,7 @@ def preparse(self): """ return self._preparse - def int(self, n): + def int(self, n) -> SIE_unary | SIE_literal_stringrep: r""" Return a raw SIE from the integer ``n``. @@ -580,7 +585,7 @@ def int(self, n): else: return SIE_literal_stringrep(self, n) - def float_str(self, n): + def float_str(self, n) -> SIE_literal_stringrep: r""" Given a string representing a floating-point number, produces a :class:`SageInputExpression` that formats as that @@ -596,7 +601,7 @@ def float_str(self, n): """ return SIE_literal_stringrep(self, n) - def name(self, n) -> SageInputExpression: + def name(self, n: str) -> SIE_literal_stringrep: r""" Given a string representing a Python name, produces a :class:`SageInputExpression` for that name. @@ -611,7 +616,7 @@ def name(self, n) -> SageInputExpression: """ return SIE_literal_stringrep(self, n) - def cache(self, x, sie, name): + def cache(self, x: Any, sie: SageInputExpression, name: str) -> None: r""" INPUT: @@ -652,13 +657,11 @@ def cache(self, x, sie, name): GF_101 = GF(101) GF_101(42) + GF_101(43) """ - from sage.structure.element import parent - self._cached_types.add(type(x)) self._cache[(parent(x), x)] = sie sie._sie_preferred_varname = name - def id_cache(self, x, sie, name): + def id_cache(self, x: Any, sie: SageInputExpression, name: str) -> None: r""" INPUT: @@ -718,7 +721,9 @@ def id_cache(self, x, sie, name): self._id_cache[id(x)] = (x, sie) sie._sie_preferred_varname = name - def import_name(self, module, name, alt_name=None): + def import_name( + self, module: str, name: str, alt_name: str | None = None + ) -> SIE_import_name: r""" INPUT: @@ -751,7 +756,7 @@ def import_name(self, module, name, alt_name=None): """ return SIE_import_name(self, module, name, alt_name) - def assign(self, e, val): + def assign(self, e: SageInputExpression, val: SageInputExpression) -> SIE_assign: r""" Construct a command that performs the assignment ``e=val``. @@ -778,7 +783,7 @@ def assign(self, e, val): return SIE_assign(self, e, val) - def command(self, v, cmd): + def command(self, v: SageInputExpression, cmd: SageInputExpression) -> None: r""" INPUT: @@ -806,7 +811,11 @@ def command(self, v, cmd): v._sie_commands.append(cmd) - def dict(self, entries): + def dict( + self, + entries: dict[SageInputExpression, SageInputExpression] + | list[tuple[SageInputExpression, SageInputExpression]], + ) -> SIE_dict: r""" Given a dictionary, or a list of (key, value) pairs, produces a :class:`SageInputExpression` representing @@ -827,7 +836,7 @@ def dict(self, entries): entries = [(self(key), self(val)) for (key, val) in entries] return SIE_dict(self, entries) - def getattr(self, sie, attr): + def getattr(self, sie: SageInputExpression, attr: str) -> SIE_getattr: r""" Given a :class:`SageInputExpression` representing ``foo`` and an attribute name bar, produce a :class:`SageInputExpression` @@ -848,7 +857,7 @@ def getattr(self, sie, attr): """ return SIE_getattr(self, self(sie), attr) - def empty_subscript(self, parent): + def empty_subscript(self, parent: SageInputExpression) -> SIE_subscript: r""" Given a :class:`SageInputExpression` representing ``foo``, produces a :class:`SageInputExpression` representing ``foo[]``. @@ -871,7 +880,7 @@ def empty_subscript(self, parent): """ return SIE_subscript(self, parent, None) - def use_variable(self, sie, name): + def use_variable(self, sie: SageInputExpression, name: str): r""" Marks the :class:`SageInputExpression` ``sie`` to use a variable even if it is only referenced once. (If ``sie`` is the final @@ -1008,7 +1017,7 @@ def parent_with_gens(self, parent, sie, gen_names, name, gens_syntax=None): v._sie_gens = gens return v - def gen(self, parent, n=0): + def gen(self, parent: Any, n=0) -> SIE_gen: r""" Given a parent, returns a :class:`SageInputExpression` for the `n`-th (default: 0) generator of the parent. @@ -1150,7 +1159,7 @@ def sum(self, terms, simplify=False): sum = sum + term return sum - def result(self, e): + def result(self, e: SageInputExpression) -> SageInputAnswer: r""" Given a :class:`SageInputExpression` constructed using ``self``, returns a tuple of a list of commands and an expression @@ -1236,7 +1245,7 @@ class SageInputExpression: way, that reveals the internal structure of the expression tree. """ - def __init__(self, sib): + def __init__(self, sib: SageInputBuilder) -> None: r""" Initialize a :class:`SageInputExpression`. @@ -1250,17 +1259,17 @@ def __init__(self, sib): sage: sie._sie_builder is sib True """ - self._sie_refcount = 0 - self._sie_builder = sib - self._sie_context = None - self._sie_preferred_varname = None + self._sie_refcount: int = 0 + self._sie_builder: SageInputBuilder = sib + self._sie_context: SageInputFormatter | None = None + self._sie_preferred_varname: str | None = None self._sie_varname = None - self._sie_request_use_var = False + self._sie_request_use_var: bool = False self._sie_use_var = False self._sie_requested_varname = False - self._sie_commands = [] + self._sie_commands: list[SageInputExpression] = [] - def _sie_is_simple(self): + def _sie_is_simple(self) -> bool: r""" Return ``True`` if this :class:`SageInputExpression` is simple enough that duplicate uses are not worth caching. Normally @@ -1277,7 +1286,7 @@ def _sie_is_simple(self): """ return False - def _sie_referenced(self): + def _sie_referenced(self) -> list[SageInputExpression]: r""" Return a list of the immediate subexpressions of this :class:`SageInputExpression`. @@ -1293,7 +1302,7 @@ def _sie_referenced(self): """ return [] - def _sie_prepare(self, sif): + def _sie_prepare(self, sif: SageInputFormatter) -> None: r""" We traverse the entire expression DAG to prepare for printing. Here, we notice nodes with more than one parent, and mark them @@ -1334,7 +1343,7 @@ def _sie_prepare(self, sif): for r in self._sie_commands: r._sie_prepare(sif) - def _sie_require_varname(self, sif): + def _sie_require_varname(self, sif: SageInputFormatter) -> None: r""" Mark this :class:`SageInputExpression` as requiring a variable name, and register it with a :class:`SageInputFormatter` (which will @@ -1355,7 +1364,7 @@ def _sie_require_varname(self, sif): self._sie_requested_varname = True self._sie_generated = False - def _sie_get_varname(self, sif): + def _sie_get_varname(self, sif: SageInputFormatter) -> str: r""" Get the variable name that the :class:`SageInputFormatter` allocated for this :class:`SageInputExpression`. @@ -1375,7 +1384,7 @@ def _sie_get_varname(self, sif): return self._sie_varname - def _sie_is_negation(self): + def _sie_is_negation(self) -> bool: r""" Test whether a :class:`SageInputExpression` is a negation. @@ -1394,7 +1403,9 @@ def _sie_is_negation(self): """ return False - def __call__(self, *args, **kwargs): + def __call__( + self, *args: SageInputExpression, **kwargs: dict[str, SageInputExpression] + ) -> SIE_call: r""" Given a :class:`SageInputExpression`, build a new :class:`SageInputExpression` representing a function call node @@ -1413,7 +1424,7 @@ def __call__(self, *args, **kwargs): for key, val in kwargs.items()} return SIE_call(self._sie_builder, self, new_args, new_kwargs) - def __getitem__(self, key): + def __getitem__(self, key: SageInputExpression) -> SIE_subscript: r""" Given a :class:`SageInputExpression`, build a new :class:`SageInputExpression` representing a subscript expression @@ -1434,7 +1445,7 @@ def __getitem__(self, key): skey = self._sie_builder(key) return SIE_subscript(self._sie_builder, self, skey) - def __getattr__(self, attr): + def __getattr__(self, attr: str) -> SIE_getattr: r""" Given a :class:`SageInputExpression`, build a new :class:`SageInputExpression` representing an attribute access. @@ -1451,7 +1462,7 @@ def __getattr__(self, attr): """ return SIE_getattr(self._sie_builder, self, attr) - def _rich_repr_(self, display_manager, **kwds): + def _rich_repr_(self, display_manager, **kwds) -> None: """ Disable rich output. @@ -1469,7 +1480,7 @@ def _rich_repr_(self, display_manager, **kwds): """ return None - def __pow__(self, other): + def __pow__(self, other: SageInputExpression) -> SIE_binary: r""" Compute an expression tree for ``self ** other``. @@ -1483,7 +1494,7 @@ def __pow__(self, other): """ return self._sie_binop('**', other) - def __mul__(self, other): + def __mul__(self, other: SageInputExpression) -> SIE_binary: r""" Compute an expression tree for ``self * other``. @@ -1497,7 +1508,7 @@ def __mul__(self, other): """ return self._sie_binop('*', other) - def __truediv__(self, other): + def __truediv__(self, other: SageInputExpression) -> SIE_binary: r""" Compute an expression tree for ``self / other``. @@ -1511,7 +1522,7 @@ def __truediv__(self, other): """ return self._sie_binop('/', other) - def __add__(self, other): + def __add__(self, other: SageInputExpression) -> SIE_binary: r""" Compute an expression tree for ``self + other``. @@ -1525,7 +1536,7 @@ def __add__(self, other): """ return self._sie_binop('+', other) - def __sub__(self, other): + def __sub__(self, other: SageInputExpression) -> SIE_binary: r""" Compute an expression tree for ``self - other``. @@ -1539,7 +1550,7 @@ def __sub__(self, other): """ return self._sie_binop('-', other) - def _sie_binop(self, op, other): + def _sie_binop(self, op: str, other: SageInputExpression) -> SIE_binary: r""" Compute an expression tree for ``self OP other``, where OP is a string representing a binary operator (such as @@ -1559,7 +1570,7 @@ def _sie_binop(self, op, other): """ return SIE_binary(self._sie_builder, op, self, self._sie_builder(other)) - def __neg__(self): + def __neg__(self) -> SIE_unary: r""" Compute an expression tree for ``-self``. @@ -1573,7 +1584,7 @@ def __neg__(self): """ return self._sie_unop('-') - def __pos__(self): + def __pos__(self) -> SIE_unary: r""" Compute an expression tree for ``+self``. @@ -1587,7 +1598,7 @@ def __pos__(self): """ return self._sie_unop('+') - def __invert__(self): + def __invert__(self) -> SIE_unary: r""" Compute an expression tree for ``~self``. @@ -1601,7 +1612,7 @@ def __invert__(self): """ return self._sie_unop('~') - def __abs__(self): + def __abs__(self) -> SIE_call: r""" Compute an expression tree for ``abs(self)``. @@ -1615,7 +1626,7 @@ def __abs__(self): """ return self._sie_builder.name('abs')(self) - def _sie_unop(self, op): + def _sie_unop(self, op: str) -> SIE_unary: r""" Compute an expression tree for ``OP self``, where OP is a string representing a unary operator (such as @@ -1636,7 +1647,7 @@ def _sie_unop(self, op): """ return SIE_unary(self._sie_builder, op, self) - def _sie_format(self, sif): + def _sie_format(self, sif: SageInputFormatter) -> tuple[str, int]: r""" Return the formatted string value of this expression, and the precedence of the top-level operator in the expression. @@ -1668,7 +1679,7 @@ def _sie_format(self, sif): """ raise NotImplementedError - def _sie_format_statement(self, sif): + def _sie_format_statement(self, sif: SageInputFormatter): r""" Return the formatted string value of this expression, when used as a statement. @@ -1767,7 +1778,7 @@ class SIE_literal_stringrep(SIE_literal): {atomic:False} """ - def __init__(self, sib, n): + def __init__(self, sib: SageInputBuilder, n: str) -> None: r""" Initialize a :class:`SIE_literal_stringrep` value. @@ -1791,7 +1802,7 @@ def __init__(self, sib, n): self._sie_value = str(n) self._sie_share = False - def __repr__(self): + def __repr__(self) -> str: r""" Return a string representing this :class:`SIE_literal_stringrep` value. @@ -1808,7 +1819,7 @@ def __repr__(self): """ return "{atomic:%s}" % self._sie_value - def _sie_format(self, sif): + def _sie_format(self, sif: SageInputFormatter) -> tuple[str, int]: r""" Return the formatted string value of this expression, and an indication that it is ``atomic`` (never needs to be parenthesized). @@ -1842,7 +1853,13 @@ class SIE_call(SageInputExpression): {call: {atomic:GF}({atomic:49})} """ - def __init__(self, sib, func, args, kwargs): + def __init__( + self, + sib: SageInputBuilder, + func: SageInputExpression, + args: list[SageInputExpression], + kwargs: dict[str, SageInputExpression], + ) -> None: r""" Initialize an instance of :class:`SIE_call`. @@ -1870,7 +1887,7 @@ def __init__(self, sib, func, args, kwargs): self._sie_args = args self._sie_kwargs = kwargs - def __repr__(self): + def __repr__(self) -> str: r""" Return a string representing this :class:`SIE_call` value. @@ -1888,7 +1905,7 @@ def __repr__(self): all_args = ', '.join(args + kwargs) return "{call: %s(%s)}" % (func, all_args) - def _sie_referenced(self): + def _sie_referenced(self) -> list[SageInputExpression]: r""" Return a list of the immediate subexpressions of this :class:`SIE_call`. @@ -1906,7 +1923,7 @@ def _sie_referenced(self): refs.extend(self._sie_kwargs.values()) return refs - def _sie_format(self, sif): + def _sie_format(self, sif: SageInputFormatter) -> tuple[str, int]: r""" Return the formatted string value of this expression, and an indication that it is a function call. @@ -1945,7 +1962,12 @@ class SIE_subscript(SageInputExpression): {subscr: {atomic:QQ}[{atomic:'x,y'}]} """ - def __init__(self, sib, coll, key): + def __init__( + self, + sib: SageInputBuilder, + coll: SageInputExpression, + key: SageInputExpression | None, + ) -> None: r""" Initialize an instance of :class:`SIE_subscript`. @@ -1977,7 +1999,7 @@ def __init__(self, sib, coll, key): self._sie_coll = coll self._sie_key = key - def __repr__(self): + def __repr__(self) -> str: r""" Return a string representing this :class:`SIE_subscript` value. @@ -1996,7 +2018,7 @@ def __repr__(self): key = repr(self._sie_key) return "{subscr: %s[%s]}" % (coll, key) - def _sie_referenced(self): + def _sie_referenced(self) -> list[SageInputExpression]: r""" Return a list of the immediate subexpressions of this :class:`SIE_subscript`. @@ -2015,7 +2037,7 @@ def _sie_referenced(self): refs.append(self._sie_key) return refs - def _sie_format(self, sif): + def _sie_format(self, sif: SageInputFormatter) -> tuple[str, int]: r""" Return the formatted string value of this expression, and an indication that it is a subscript. @@ -2053,7 +2075,7 @@ class SIE_getattr(SageInputExpression): sage: sie {call: {getattr: {atomic:CC}.gen}()} """ - def __init__(self, sib, obj, attr): + def __init__(self, sib: SageInputBuilder, obj: SageInputExpression, attr: str) -> None: r""" Initialize an instance of :class:`SIE_getattr`. @@ -2092,7 +2114,7 @@ def __repr__(self): obj = repr(self._sie_obj) return "{getattr: %s.%s}" % (obj, self._sie_attr) - def _sie_referenced(self): + def _sie_referenced(self) -> list[SageInputExpression]: r""" Return a list of the immediate subexpressions of this :class:`SIE_subscript`. @@ -2108,7 +2130,7 @@ def _sie_referenced(self): """ return [self._sie_obj] - def _sie_format(self, sif): + def _sie_format(self, sif: SageInputFormatter) -> tuple[str, int]: r""" Return the formatted string value of this expression, and an indication that it is an attribute reference. @@ -2144,7 +2166,9 @@ class SIE_tuple(SageInputExpression): {list: ({atomic:'lists'})} """ - def __init__(self, sib, values, is_list): + def __init__( + self, sib: SageInputBuilder, values: list[SageInputExpression], is_list: bool + ) -> None: r""" Initialize an instance of :class:`SIE_tuple`. @@ -2169,10 +2193,10 @@ def __init__(self, sib, values, is_list): {list: ({atomic:'Hello'}, {atomic:'world'})} """ super().__init__(sib) - self._sie_values = values - self._sie_is_list = is_list + self._sie_values: list[SageInputExpression] = values + self._sie_is_list: bool = is_list - def __repr__(self): + def __repr__(self) -> str: r""" Return a string representing this :class:`SIE_tuple` value. @@ -2190,7 +2214,7 @@ def __repr__(self): return "{%s: (%s)}" % \ (kind, ', '.join(repr(v) for v in self._sie_values)) - def _sie_referenced(self): + def _sie_referenced(self) -> list[SageInputExpression]: r""" Return a list of the immediate subexpressions of this :class:`SIE_tuple`. @@ -2206,7 +2230,7 @@ def _sie_referenced(self): """ return self._sie_values - def _sie_format(self, sif): + def _sie_format(self, sif: SageInputFormatter) -> tuple[str, int]: r""" Return the formatted string value of this tuple or list, and an indication that it is atomic (never needs to be parenthesized). @@ -2255,7 +2279,11 @@ class SIE_dict(SageInputExpression): {atomic:0}:{atomic:32}, {atomic:100}:{atomic:212}}} """ - def __init__(self, sib, entries): + def __init__( + self, + sib: SageInputBuilder, + entries: list[tuple[SageInputExpression, SageInputExpression]], + ) -> None: r""" Initialize an instance of :class:`SIE_dict`. @@ -2279,7 +2307,7 @@ def __init__(self, sib, entries): super().__init__(sib) self._sie_entries = entries - def __repr__(self): + def __repr__(self) -> str: r""" Return a string representing this :class:`SIE_dict` value. @@ -2295,7 +2323,7 @@ def __repr__(self): ', '.join(repr(key) + ':' + repr(val) for key, val in self._sie_entries) - def _sie_referenced(self): + def _sie_referenced(self) -> list[SageInputExpression]: r""" Return a list of the immediate subexpressions of this :class:`SIE_dict`. @@ -2311,7 +2339,7 @@ def _sie_referenced(self): """ return [k for k, v in self._sie_entries] + [v for k, v in self._sie_entries] - def _sie_format(self, sif): + def _sie_format(self, sif: SageInputFormatter) -> tuple[str, int]: r""" Return the formatted string value of this dict, and an indication that it is atomic (never needs to be parenthesized). @@ -2345,7 +2373,13 @@ class SIE_binary(SageInputExpression): {binop:+ {atomic:3} {atomic:5}} """ - def __init__(self, sib, op, lhs, rhs): + def __init__( + self, + sib: SageInputBuilder, + op: str, + lhs: SageInputExpression, + rhs: SageInputExpression, + ) -> None: r""" Initialize an instance of :class:`SIE_binary`. @@ -2385,7 +2419,7 @@ def __repr__(self): """ return "{binop:%s %s %s}" % (self._sie_op, repr(self._sie_operands[0]), repr(self._sie_operands[1])) - def _sie_referenced(self): + def _sie_referenced(self) -> tuple[SageInputExpression, SageInputExpression]: r""" Return a tuple of the immediate subexpressions of this :class:`SIE_binary`. @@ -2401,7 +2435,7 @@ def _sie_referenced(self): """ return self._sie_operands - def _sie_format(self, sif): + def _sie_format(self, sif: SageInputFormatter) -> tuple[str, int]: r""" Return the formatted string value of this expression, and the precedence of the top-level operator in the expression. @@ -2495,7 +2529,9 @@ class SIE_unary(SageInputExpression): {unop:- {atomic:256}} """ - def __init__(self, sib, op, operand): + def __init__( + self, sib: SageInputBuilder, op: str, operand: SageInputExpression + ) -> None: r""" Initialize an instance of :class:`SIE_unary`. @@ -2517,7 +2553,7 @@ def __init__(self, sib, op, operand): """ super().__init__(sib) self._sie_op = op - self._sie_operand = operand + self._sie_operand: SageInputExpression = operand def __repr__(self): r""" @@ -2533,7 +2569,7 @@ def __repr__(self): """ return "{unop:%s %s}" % (self._sie_op, repr(self._sie_operand)) - def _sie_referenced(self): + def _sie_referenced(self) -> list[SageInputExpression]: r""" Return a list of the immediate subexpressions of this :class:`SIE_unary`. @@ -2549,7 +2585,7 @@ def _sie_referenced(self): """ return [self._sie_operand] - def _sie_format(self, sif): + def _sie_format(self, sif: SageInputFormatter) -> tuple[str, int]: r""" Return the formatted string value of this expression, and the precedence of the top-level operator in the expression. @@ -2631,7 +2667,7 @@ def _sie_format(self, sif): return '%s%s' % (fop, sif.format(self._sie_operand, prec)), rprec - def _sie_is_negation(self): + def _sie_is_negation(self) -> bool: r""" Test whether a :class:`SageInputExpression` is a negation. @@ -2682,7 +2718,13 @@ class SIE_gens_constructor(SageInputExpression): {constr_parent: {subscr: {atomic:QQ}[{atomic:'x'}]} with gens: ('x',)} """ - def __init__(self, sib, constr, gen_names, gens_syntax=None): + def __init__( + self, + sib: SageInputBuilder, + constr: SageInputExpression, + gen_names: tuple[str, ...], + gens_syntax: SageInputExpression | None = None, + ) -> None: r""" Initialize an instance of :class:`SIE_gens_constructor`. @@ -2710,10 +2752,10 @@ def __init__(self, sib, constr, gen_names, gens_syntax=None): {constr_parent: {subscr: {atomic:QQ}[{atomic:'x'}]} with gens: ('x',)} """ super().__init__(sib) - self._sie_constr = constr - self._sie_gen_names = gen_names - self._sie_gens = None # will be overwritten from .parent_with_gens() - self._sie_gens_constr = gens_syntax + self._sie_constr: SageInputExpression = constr + self._sie_gen_names: tuple[str, ...] = gen_names + self._sie_gens: list[SIE_gen] | None = None # will be overwritten from .parent_with_gens() + self._sie_gens_constr: SageInputExpression | None = gens_syntax self._sie_assign_gens = False self._sie_generated = False @@ -2734,7 +2776,7 @@ def __repr__(self): """ return "{constr_parent: %s with gens: %s}" % (repr(self._sie_constr), self._sie_gen_names) - def _sie_referenced(self): + def _sie_referenced(self) -> list[SageInputExpression]: r""" Return a list of the immediate subexpressions of this :class:`SIE_gens_constructor`. @@ -2757,7 +2799,7 @@ def _sie_referenced(self): # self._sie_gens_constr also occur in self._sie_constr. return [self._sie_constr] - def _sie_gens_referenced(self, sif): + def _sie_gens_referenced(self, sif: SageInputFormatter) -> None: r""" Mark that at least one of the generators in this :class:`SIE_gens_constructor` is used. (This means we will actually @@ -2784,7 +2826,7 @@ def _sie_gens_referenced(self, sif): for gen in self._sie_gens: gen._sie_require_varname(sif) - def _sie_add_command(self, sif): + def _sie_add_command(self,sif: SageInputFormatter) -> None: r""" Build commands to construct this parent and (if necessary) its associated generators. @@ -2862,7 +2904,7 @@ def _sie_add_command(self, sif): sif._commands += '%s = %s.gens()\n' % (','.join(g._sie_get_varname(sif) for g in self._sie_gens), self._sie_get_varname(sif)) self._sie_generated = True - def _sie_format(self, sif): + def _sie_format(self, sif: SageInputFormatter) -> tuple[str, int]: r""" Return the formatted string value of this parent-construction expression, and its precedence. @@ -2908,7 +2950,9 @@ class SIE_gen(SageInputExpression): {gen:x {constr_parent: {subscr: {atomic:ZZ}[{atomic:'x'}]} with gens: ('x',)}} """ - def __init__(self, sib, parent, name): + def __init__( + self, sib: SageInputBuilder, parent: SIE_gens_constructor, name: str + ) -> None: r""" Initialize an instance of :class:`SIE_gen`. @@ -2932,7 +2976,7 @@ def __init__(self, sib, parent, name): self._sie_parent = parent self._sie_preferred_varname = name - def __repr__(self): + def __repr__(self) -> str: r""" Return a string representing this :class:`SIE_gen` value. @@ -2960,7 +3004,7 @@ def _sie_is_simple(self): """ return True - def _sie_prepare(self, sif): + def _sie_prepare(self, sif: SageInputFormatter) -> None: r""" We override the \method{_sie_prepare} method from :class:`SageInputExpression` to additionally mark the parent of this @@ -2982,7 +3026,7 @@ def _sie_prepare(self, sif): super()._sie_prepare(sif) self._sie_parent._sie_gens_referenced(sif) - def _sie_format(self, sif): + def _sie_format(self, sif: SageInputFormatter) -> tuple[str, int]: r""" Return the formatted string value of this named generator, and an indication that it is atomic. @@ -3006,7 +3050,7 @@ def _sie_format(self, sif): self._sie_parent._sie_add_command(sif) return self._sie_get_varname(sif), _prec_atomic - def _sie_got_preferred(self, sif): + def _sie_got_preferred(self, sif: SageInputFormatter) -> bool: r""" Check whether the :class:`SageInputFormatter` assigned us a variable name which is the same as the name of the generator @@ -3060,7 +3104,9 @@ class SIE_import_name(SageInputExpression): {import:sage.foo/happy as sad} """ - def __init__(self, sib, module, name, alt_name=None): + def __init__( + self, sib: SageInputBuilder, module: str, name: str, alt_name: str | None = None + ) -> None: r""" Initialize an instance of :class:`SIE_import_name`. @@ -3094,7 +3140,7 @@ def __init__(self, sib, module, name, alt_name=None): else: self._sie_preferred_varname = alt_name - def __repr__(self): + def __repr__(self) -> str: r""" Return a string representing this :class:`SIE_import_name` value. @@ -3111,7 +3157,7 @@ def __repr__(self): return "{import:%s/%s%s}" % (self._sie_module_name, self._sie_object_name, "" if self._sie_object_name == self._sie_preferred_varname else " as %s" % self._sie_preferred_varname) - def _sie_is_simple(self): + def _sie_is_simple(self) -> Literal[True]: r""" Report that :class:`SIE_import_name` values are single tokens. @@ -3125,7 +3171,7 @@ def _sie_is_simple(self): """ return True - def _sie_prepare(self, sif): + def _sie_prepare(self, sif: SageInputFormatter) -> None: r""" We override the \method{_sie_prepare} method from :class:`SageInputExpression` to request a variable name. @@ -3146,7 +3192,7 @@ def _sie_prepare(self, sif): super()._sie_prepare(sif) self._sie_require_varname(sif) - def _sie_format(self, sif): + def _sie_format(self, sif: SageInputFormatter) -> tuple[str, int]: r""" Return the formatted string value of this import, and an indication that it is atomic. @@ -3194,7 +3240,7 @@ class SIE_assign(SageInputExpression): {assign: {getattr: {atomic:foo}.x} {atomic:pi}} """ - def __init__(self, sib, lhs, rhs): + def __init__(self, sib: SageInputBuilder, lhs: SageInputExpression, rhs: SageInputExpression) -> None: r""" Initialize an instance of :class:`SIE_assign`. @@ -3215,8 +3261,8 @@ def __init__(self, sib, lhs, rhs): {assign: {getattr: {atomic:foo}.x} {atomic:pi}} """ super().__init__(sib) - self._sie_lhs = lhs - self._sie_rhs = rhs + self._sie_lhs: SageInputExpression = lhs + self._sie_rhs: SageInputExpression = rhs def __repr__(self): r""" @@ -3232,7 +3278,7 @@ def __repr__(self): """ return "{assign: %s %s}" % (repr(self._sie_lhs), repr(self._sie_rhs)) - def _sie_referenced(self): + def _sie_referenced(self) -> list[SageInputExpression]: r""" Return a list of the immediate subexpressions of this :class:`SIE_assign`. @@ -3248,7 +3294,7 @@ def _sie_referenced(self): """ return [self._sie_lhs, self._sie_rhs] - def _sie_format(self, sif): + def _sie_format(self, sif: SageInputFormatter) -> tuple[str, int]: r""" Return the formatted string value of this :class:`SIE_assign` as an expression. Since an assignment is a statement, not @@ -3269,7 +3315,7 @@ def _sie_format(self, sif): """ raise ValueError("Cannot format SIE_assign as expression") - def _sie_format_statement(self, sif): + def _sie_format_statement(self, sif: SageInputFormatter) -> str: r""" Return the formatted string of this :class:`SIE_assign` as a statement. @@ -3303,11 +3349,11 @@ def __init__(self): sage: from sage.misc.sage_input import SageInputFormatter sage: sif = SageInputFormatter() """ - self._commands = '' - self._names = set() - self._dup_names = {} + self._commands: str = '' + self._names: set[str] = set() + self._dup_names: dict[str, int] = {} - def format(self, e, prec): + def format(self, e: SageInputExpression, prec: int) -> str: r""" Format a Sage input expression into a string. @@ -3384,7 +3430,7 @@ def format(self, e, prec): return formatted - def register_name(self, name): + def register_name(self, name: str | None) -> None: r""" Register that some value would like to use a given name. If only one request for a name is received, then we will use the @@ -3417,7 +3463,7 @@ def register_name(self, name): else: self._names.add(name) - def get_name(self, name): + def get_name(self, name: str | None) -> str: r""" Return a name corresponding to a given requested name. If only one request for a name is received, then we will use the @@ -3451,7 +3497,7 @@ def get_name(self, name): return name -def verify_same(a, b): +def verify_same(a, b) -> None: r""" Verify that two Sage values are the same. This is an extended equality test; it checks that the values are equal and that their parents are equal. @@ -3508,7 +3554,7 @@ def verify_same(a, b): raise AssertionError("Expected %r == %r" % (a, b)) -def verify_si_answer(x, answer, preparse): +def verify_si_answer(x: Any, answer: SageInputAnswer, preparse: bool | None): r""" Verify that evaluating ``answer`` gives a value equal to ``x`` (with the same parent/type). If ``preparse`` is ``True`` or @@ -3545,7 +3591,7 @@ def verify_si_answer(x, answer, preparse): verify_same(x, sage_eval(answer, preparse=preparse)) -class SageInputAnswer(tuple): +class SageInputAnswer(tuple[str, str, dict[str, Any]]): r""" This class inherits from tuple, so it acts like a tuple when passed to :func:`sage_eval`; but it prints as a sequence of commands. @@ -3576,7 +3622,7 @@ class SageInputAnswer(tuple): {'sin': } """ - def __new__(cls, cmds, expr, locals=None): + def __new__(cls, cmds: str, expr: str, locals: dict[str, Any] | None = None): r""" Construct an instance of :class:`SageInputAnswer`. @@ -3599,7 +3645,7 @@ def __new__(cls, cmds, expr, locals=None): else: return tuple.__new__(cls, (cmds, expr)) - def __repr__(self): + def __repr__(self) -> str: r""" Return a string representation for a :class:`SageInputAnswer`, such that if you evaluate this :class:`SageInputAnswer` at the From d147b4f3dcac6cca66bcb805ebdc514009576b98 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Wed, 15 Oct 2025 23:45:56 +0800 Subject: [PATCH 5/6] Add more typing for SageInputBuilder usages --- src/sage/misc/explain_pickle.py | 10 ++++++++-- src/sage/rings/infinity.py | 4 +++- src/sage/rings/qqbar.py | 10 +++++----- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/sage/misc/explain_pickle.py b/src/sage/misc/explain_pickle.py index f0c289db9c2..cdf4ce1d223 100644 --- a/src/sage/misc/explain_pickle.py +++ b/src/sage/misc/explain_pickle.py @@ -426,8 +426,14 @@ class PickleExplainer: symbolically and constructs :class:`SageInputExpression` objects instead of directly constructing values. """ - def __init__(self, sib, in_current_sage=False, default_assumptions=False, - pedantic=False): + + def __init__( + self, + sib: SageInputBuilder, + in_current_sage=False, + default_assumptions=False, + pedantic=False, + ): r""" Initialize a PickleExplainer interpreter for the pickle virtual machine. diff --git a/src/sage/rings/infinity.py b/src/sage/rings/infinity.py index ecf711d5fff..f588d1d5cf4 100644 --- a/src/sage/rings/infinity.py +++ b/src/sage/rings/infinity.py @@ -230,6 +230,8 @@ lazy_import('sage.rings.integer', 'Integer') +if TYPE_CHECKING: + from sage.misc.sage_input import CoercionMode, SageInputBuilder, SageInputExpression _obj = {} @@ -542,7 +544,7 @@ def lcm(self, x): else: return abs(self) - def _sage_input_(self, sib, coerced): + def _sage_input_(self, sib: SageInputBuilder, coerced: CoercionMode) -> SageInputExpression: """ Produce an expression which will reproduce this value when evaluated. diff --git a/src/sage/rings/qqbar.py b/src/sage/rings/qqbar.py index db1f4029180..a46c3324f60 100644 --- a/src/sage/rings/qqbar.py +++ b/src/sage/rings/qqbar.py @@ -6664,7 +6664,7 @@ def _repr_(self): """ return repr(self._value) - def handle_sage_input(self, sib, coerce, is_qqbar): + def handle_sage_input(self, sib: SageInputBuilder, coerce: CoercionMode, is_qqbar): r""" Produce an expression which will reproduce this value when evaluated, and an indication of whether this value is worth sharing (always @@ -7231,7 +7231,7 @@ def _repr_(self): """ return 'Root %s of %s' % (self._interval, self._poly) - def handle_sage_input(self, sib, coerce, is_qqbar): + def handle_sage_input(self, sib: SageInputBuilder, coerce: CoercionMode, is_qqbar): r""" Produce an expression which will reproduce this value when evaluated, and an indication of whether this value is worth sharing (always ``True`` @@ -7908,7 +7908,7 @@ def _repr_(self): sgen, self._generator._interval_fast(53)) - def handle_sage_input(self, sib, coerce, is_qqbar): + def handle_sage_input(self, sib: SageInputBuilder, coerce: CoercionMode, is_qqbar): r""" Produce an expression which will reproduce this value when evaluated, and an indication of whether this value is worth sharing (always ``True`` @@ -8359,7 +8359,7 @@ def __reduce__(self): """ return (ANUnaryExpr, (self._arg, self._op)) - def handle_sage_input(self, sib, coerce, is_qqbar): + def handle_sage_input(self, sib: SageInputBuilder, coerce: CoercionMode, is_qqbar): r""" Produce an expression which will reproduce this value when evaluated, and an indication of whether this value is worth sharing (always @@ -8617,7 +8617,7 @@ def __reduce__(self): """ return (ANBinaryExpr, (self._left, self._right, self._op)) - def handle_sage_input(self, sib, coerce, is_qqbar): + def handle_sage_input(self, sib: SageInputBuilder, coerce: CoercionMode, is_qqbar): r""" Produce an expression which will reproduce this value when evaluated, and an indication of whether this value is worth sharing (always From 98cbe9fd0384550580a3a29fdd4f51a22148a3d9 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Thu, 16 Oct 2025 17:09:28 +0800 Subject: [PATCH 6/6] Fix imports in sage/rings/infinity --- src/sage/rings/infinity.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/sage/rings/infinity.py b/src/sage/rings/infinity.py index f588d1d5cf4..4a365034638 100644 --- a/src/sage/rings/infinity.py +++ b/src/sage/rings/infinity.py @@ -214,8 +214,10 @@ # (at your option) any later version. # https://www.gnu.org/licenses/ # **************************************************************************** +from __future__ import annotations from sys import maxsize +from typing import TYPE_CHECKING import sage.rings.abc