Skip to content

Commit 315aa5c

Browse files
committed
Add type annotations for rings and parents
1 parent 5c8d9e9 commit 315aa5c

File tree

9 files changed

+560
-45
lines changed

9 files changed

+560
-45
lines changed

src/sage/categories/map.pyi

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
from __future__ import annotations
2+
3+
from typing import Any, Callable, Generic, Iterator, Mapping, Self, Sequence, TypeVar
4+
5+
from sage.categories.category import Category
6+
from sage.structure.element import Element
7+
from sage.structure.parent import Parent
8+
9+
DomainElementT_contra = TypeVar("DomainElementT_contra", contravariant=True)
10+
CodomainElementT_co = TypeVar("CodomainElementT_co", covariant=True)
11+
SectionDomainT = TypeVar("SectionDomainT")
12+
SectionCodomainT = TypeVar("SectionCodomainT")
13+
CompositeDomainT = TypeVar("CompositeDomainT")
14+
CompositeCodomainT = TypeVar("CompositeCodomainT")
15+
16+
class Map(Element, Generic[DomainElementT_contra, CodomainElementT_co]):
17+
_coerce_cost: int
18+
_is_coercion: bool
19+
_repr_type_str: str | None
20+
_category_for: Category | None
21+
domain: Callable[[], Parent[Any] | None]
22+
codomain: Callable[[], Parent[Any]]
23+
_codomain: Parent[Any]
24+
25+
def __init__(self, parent: Any, codomain: Parent[Any] | None = ...) -> None: ...
26+
def __copy__(self) -> Self: ...
27+
def parent(self) -> Any: ...
28+
def _make_weak_references(self) -> None: ...
29+
def _make_strong_references(self) -> None: ...
30+
def _update_slots(self, slots: Mapping[str, Any]) -> None: ...
31+
def _update_slots_test(self, _slots: Mapping[str, Any]) -> None: ...
32+
def _extra_slots(self) -> dict[str, Any]: ...
33+
def _extra_slots_test(self) -> dict[str, Any]: ...
34+
def __reduce__(self) -> tuple[Any, tuple[Any, ...]]: ...
35+
def _repr_type(self) -> str: ...
36+
def _repr_defn(self) -> str: ...
37+
def _repr_(self) -> str: ...
38+
def _default_repr_(self) -> str: ...
39+
def domains(self) -> Iterator[Parent[Any] | None]: ...
40+
def category_for(self) -> Category: ...
41+
def __call__(
42+
self, x: DomainElementT_contra, *args: Any, **kwds: Any
43+
) -> CodomainElementT_co: ...
44+
def _call_(self, x: DomainElementT_contra) -> CodomainElementT_co: ...
45+
def _call_with_args(
46+
self,
47+
x: DomainElementT_contra,
48+
args: Sequence[Any] = ...,
49+
kwds: Mapping[str, Any] | None = ...,
50+
) -> CodomainElementT_co: ...
51+
def __mul__(self, right: Map[Any, Any]) -> Map[Any, Any]: ...
52+
def _composition(self, right: Map[Any, Any]) -> Map[Any, Any]: ...
53+
def _composition_(self, right: Map[Any, Any], homset: Any) -> Map[Any, Any]: ...
54+
def pre_compose(self, right: Map[Any, Any]) -> Map[Any, Any]: ...
55+
def post_compose(self, left: Map[Any, Any]) -> Map[Any, Any]: ...
56+
def extend_domain(self, new_domain: Any) -> Map[Any, Any]: ...
57+
def extend_codomain(self, new_codomain: Any) -> Map[Any, Any]: ...
58+
def is_surjective(self) -> bool: ...
59+
def _pow_int(self, n: int) -> Map[Any, Any]: ...
60+
def section(self) -> Map[Any, Any] | None: ...
61+
def __hash__(self) -> int: ...
62+
63+
class Section(
64+
Map[SectionCodomainT, SectionDomainT], Generic[SectionDomainT, SectionCodomainT]
65+
):
66+
_inverse: Map[SectionDomainT, SectionCodomainT]
67+
68+
def __init__(self, map: Map[SectionDomainT, SectionCodomainT]) -> None: ...
69+
def _extra_slots(self) -> dict[str, Any]: ...
70+
def _update_slots(self, slots: Mapping[str, Any]) -> None: ...
71+
def _repr_type(self) -> str: ...
72+
def inverse(self) -> Map[SectionDomainT, SectionCodomainT]: ...
73+
74+
class FormalCompositeMap(
75+
Map[CompositeDomainT, CompositeCodomainT],
76+
Generic[CompositeDomainT, CompositeCodomainT],
77+
):
78+
__list: Sequence[Map[Any, Any]]
79+
80+
def __init__(
81+
self,
82+
parent: Any,
83+
first: Map[Any, Any] | Sequence[Map[Any, Any]],
84+
second: Map[Any, Any] | None = ...,
85+
) -> None: ...
86+
def __copy__(self) -> Self: ...
87+
def _update_slots(self, slots: Mapping[str, Any]) -> None: ...
88+
def _extra_slots(self) -> dict[str, Any]: ...
89+
def __richcmp__(self, other: Any, op: int) -> bool: ...
90+
def __hash__(self) -> int: ...
91+
def __getitem__(self, i: int) -> Map[Any, Any]: ...
92+
def _call_(self, x: CompositeDomainT) -> CompositeCodomainT: ...
93+
def _call_with_args(
94+
self,
95+
x: CompositeDomainT,
96+
args: Sequence[Any] = ...,
97+
kwds: Mapping[str, Any] | None = ...,
98+
) -> CompositeCodomainT: ...
99+
def _repr_type(self) -> str: ...
100+
def _repr_defn(self) -> str: ...
101+
def first(self) -> Map[Any, Any]: ...
102+
def then(self) -> Map[Any, Any]: ...
103+
def is_injective(self) -> bool: ...
104+
def is_surjective(self) -> bool: ...
105+
def domains(self) -> Iterator[Parent[Any] | None]: ...
106+
def section(self) -> Map[Any, Any] | None: ...
107+
108+
def unpickle_map(
109+
_class: type[Map[Any, Any]],
110+
parent: Any,
111+
_dict: Mapping[str, Any],
112+
_slots: Mapping[str, Any],
113+
) -> Map[Any, Any]: ...
114+
def is_Map(x: Any) -> bool: ...
Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
1-
from typing import Any
2-
3-
from sage.structure.element import Element
41
from sage.categories.map import Map
2+
from sage.rings.complex_double import ComplexDoubleElement
3+
from sage.rings.complex_mpfr import ComplexNumber
54

6-
class CCtoCDF(Map):
7-
def _call_(self, x: Element) -> Element:
8-
...
5+
class CCtoCDF(Map[ComplexNumber, ComplexDoubleElement]):
6+
def _call_(self, x: ComplexNumber) -> ComplexDoubleElement: ...

src/sage/rings/complex_interval_field.py

Lines changed: 28 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,10 @@
3434
# (at your option) any later version.
3535
# https://www.gnu.org/licenses/
3636
# ****************************************************************************
37-
37+
from __future__ import annotations
3838

3939
import weakref
40+
from typing import Literal
4041

4142
import sage.rings.abc
4243
from sage.misc.cachefunc import cached_method
@@ -48,10 +49,10 @@
4849
from sage.rings.ring import Field
4950
from sage.structure.parent import Parent
5051

51-
cache = {}
52+
cache: dict[int, weakref.ReferenceType[ComplexIntervalField_class]] = {}
5253

5354

54-
def ComplexIntervalField(prec=53, names=None):
55+
def ComplexIntervalField(prec=53, names=None) -> ComplexIntervalField_class:
5556
"""
5657
Return the complex interval field with real and imaginary parts having
5758
``prec`` *bits* of precision.
@@ -180,9 +181,10 @@ class ComplexIntervalField_class(sage.rings.abc.ComplexIntervalField):
180181
- :class:`sage.rings.complex_arb.ComplexBallField` (alternative
181182
implementation of complex intervals, with more features)
182183
"""
184+
183185
Element = complex_interval.ComplexIntervalFieldElement
184186

185-
def __init__(self, prec=53):
187+
def __init__(self, prec=53) -> None:
186188
"""
187189
Initialize ``self``.
188190
@@ -195,9 +197,11 @@ def __init__(self, prec=53):
195197
"""
196198
self._prec = int(prec)
197199
from sage.categories.fields import Fields
198-
Field.__init__(self, self.real_field(), ("I",), False,
199-
category=Fields().Infinite())
200-
self._populate_coercion_lists_(convert_method_name='_complex_mpfi_')
200+
201+
Field.__init__(
202+
self, self.real_field(), ("I",), False, category=Fields().Infinite()
203+
)
204+
self._populate_coercion_lists_(convert_method_name="_complex_mpfi_")
201205

202206
def __reduce__(self):
203207
"""
@@ -208,7 +212,7 @@ def __reduce__(self):
208212
sage: loads(dumps(CIF)) == CIF
209213
True
210214
"""
211-
return ComplexIntervalField, (self._prec, )
215+
return ComplexIntervalField, (self._prec,)
212216

213217
def construction(self):
214218
"""
@@ -241,9 +245,10 @@ def construction(self):
241245
Univariate Polynomial Ring in x over Complex Interval Field with 53 bits of precision
242246
"""
243247
from sage.categories.pushout import AlgebraicClosureFunctor
248+
244249
return (AlgebraicClosureFunctor(), self.real_field())
245250

246-
def is_exact(self):
251+
def is_exact(self) -> Literal[False]:
247252
"""
248253
The complex interval field is not exact.
249254
@@ -254,7 +259,7 @@ def is_exact(self):
254259
"""
255260
return False
256261

257-
def prec(self):
262+
def prec(self) -> int:
258263
"""
259264
Return the precision of ``self`` (in bits).
260265
@@ -267,7 +272,7 @@ def prec(self):
267272
"""
268273
return self._prec
269274

270-
def to_prec(self, prec):
275+
def to_prec(self, prec) -> ComplexIntervalField_class:
271276
"""
272277
Return a complex interval field with the given precision.
273278
@@ -282,7 +287,7 @@ def to_prec(self, prec):
282287
"""
283288
return ComplexIntervalField(prec)
284289

285-
def _magma_init_(self, magma):
290+
def _magma_init_(self, magma) -> str:
286291
r"""
287292
Return a string representation of ``self`` in the Magma language.
288293
@@ -321,10 +326,10 @@ def _sage_input_(self, sib, coerce):
321326
{call: {atomic:ComplexIntervalField}({atomic:2})}
322327
"""
323328
if self.prec() == 53:
324-
return sib.name('CIF')
329+
return sib.name("CIF")
325330

326-
v = sib.name('ComplexIntervalField')(sib.int(self.prec()))
327-
name = 'CIF%d' % self.prec()
331+
v = sib.name("ComplexIntervalField")(sib.int(self.prec()))
332+
name = "CIF%d" % self.prec()
328333
sib.cache(self, v, name)
329334
return v
330335

@@ -386,7 +391,7 @@ def __eq__(self, other):
386391
return False
387392
return self._prec == other._prec
388393

389-
def __hash__(self):
394+
def __hash__(self) -> int:
390395
"""
391396
Return the hash.
392397
@@ -400,7 +405,7 @@ def __hash__(self):
400405
"""
401406
return hash((self.__class__, self._prec))
402407

403-
def __ne__(self, other):
408+
def __ne__(self, other) -> bool:
404409
"""
405410
Test whether ``self`` is not equal to ``other``.
406411
@@ -521,8 +526,7 @@ def _coerce_map_from_(self, S):
521526
# Direct and efficient conversions
522527
if S is ZZ or S is QQ or S is int:
523528
return True
524-
if isinstance(S, (ComplexIntervalField_class,
525-
RealIntervalField_class)):
529+
if isinstance(S, (ComplexIntervalField_class, RealIntervalField_class)):
526530
return S.precision() >= self._prec
527531

528532
# If coercion to CC is possible and there is a _complex_mpfi_
@@ -532,7 +536,7 @@ def _coerce_map_from_(self, S):
532536
if f is not None:
533537
return f
534538

535-
return self._coerce_map_via( (self.real_field(),), S)
539+
return self._coerce_map_via((self.real_field(),), S)
536540

537541
def _repr_(self):
538542
"""
@@ -650,7 +654,7 @@ def ngens(self):
650654
"""
651655
return 1
652656

653-
def zeta(self, n=2):
657+
def zeta(self, n: int = 2):
654658
r"""
655659
Return a primitive `n`-th root of unity.
656660
@@ -673,6 +677,7 @@ def zeta(self, n=2):
673677
0.309016994374948? + 0.9510565162951536?*I
674678
"""
675679
from .integer import Integer
680+
676681
n = Integer(n)
677682
if n == 1:
678683
x = self.element_class(self, 1)
@@ -683,10 +688,10 @@ def zeta(self, n=2):
683688
# e^(2*pi*i/n) = cos(2pi/n) + i *sin(2pi/n)
684689
RIF = self.real_field()
685690
pi = RIF.pi()
686-
z = 2*pi/n
691+
z = 2 * pi / n
687692
x = self.element_class(self, z.cos(), z.sin())
688693
# Uncomment after implemented
689-
#x._set_multiplicative_order( n )
694+
# x._set_multiplicative_order( n )
690695
return x
691696

692697
def scientific_notation(self, status=None):

src/sage/rings/morphism.pyi

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
1-
from sage.rings.integer import Integer
2-
from sage.structure.element import Element
3-
from sage.structure.parent import Parent
1+
from typing import Any
2+
43
from sage.categories.map import Map
54
from sage.categories.morphism import Morphism
5+
from sage.rings.integer import Integer
6+
from sage.structure.parent import Parent
67

78
class RingMap(Morphism):
89
pass
910

1011
class RingMap_lift(RingMap):
11-
S: Parent
12-
to_S: Map
12+
S: Parent[Any]
13+
to_S: Map[Any, Any]
1314

1415
class RingHomomorphism(RingMap):
1516
_lift: Morphism

0 commit comments

Comments
 (0)