-
-
Notifications
You must be signed in to change notification settings - Fork 711
Add type annotations for rings and parents #41232
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,114 @@ | ||
| from __future__ import annotations | ||
|
|
||
| from typing import Any, Callable, Generic, Iterator, Mapping, Self, Sequence, TypeVar | ||
|
|
||
| from sage.categories.category import Category | ||
| from sage.structure.element import Element | ||
| from sage.structure.parent import Parent | ||
|
|
||
| DomainElementT_contra = TypeVar("DomainElementT_contra", contravariant=True) | ||
| CodomainElementT_co = TypeVar("CodomainElementT_co", covariant=True) | ||
| SectionDomainT = TypeVar("SectionDomainT") | ||
| SectionCodomainT = TypeVar("SectionCodomainT") | ||
| CompositeDomainT = TypeVar("CompositeDomainT") | ||
| CompositeCodomainT = TypeVar("CompositeCodomainT") | ||
|
|
||
| class Map(Element, Generic[DomainElementT_contra, CodomainElementT_co]): | ||
| _coerce_cost: int | ||
| _is_coercion: bool | ||
| _repr_type_str: str | None | ||
| _category_for: Category | None | ||
| domain: Callable[[], Parent[Any] | None] | ||
| codomain: Callable[[], Parent[Any]] | ||
| _codomain: Parent[Any] | ||
|
|
||
| def __init__(self, parent: Any, codomain: Parent[Any] | None = ...) -> None: ... | ||
| def __copy__(self) -> Self: ... | ||
| def parent(self) -> Any: ... | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why isn't this annotated to return |
||
| def _make_weak_references(self) -> None: ... | ||
| def _make_strong_references(self) -> None: ... | ||
| def _update_slots(self, slots: Mapping[str, Any]) -> None: ... | ||
| def _update_slots_test(self, _slots: Mapping[str, Any]) -> None: ... | ||
| def _extra_slots(self) -> dict[str, Any]: ... | ||
| def _extra_slots_test(self) -> dict[str, Any]: ... | ||
| def __reduce__(self) -> tuple[Any, tuple[Any, ...]]: ... | ||
| def _repr_type(self) -> str: ... | ||
| def _repr_defn(self) -> str: ... | ||
| def _repr_(self) -> str: ... | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Shouldn't the type annotation for If I'm correct about the behaviour of type annotations with inheritance, that would mean that we would get the most value for the amount of work by annotating classes higher up in the inheritance hierarchy (like you've done in this PR). |
||
| def _default_repr_(self) -> str: ... | ||
| def domains(self) -> Iterator[Parent[Any] | None]: ... | ||
| def category_for(self) -> Category: ... | ||
| def __call__( | ||
| self, x: DomainElementT_contra, *args: Any, **kwds: Any | ||
| ) -> CodomainElementT_co: ... | ||
| def _call_(self, x: DomainElementT_contra) -> CodomainElementT_co: ... | ||
| def _call_with_args( | ||
| self, | ||
| x: DomainElementT_contra, | ||
| args: Sequence[Any] = ..., | ||
| kwds: Mapping[str, Any] | None = ..., | ||
| ) -> CodomainElementT_co: ... | ||
| def __mul__(self, right: Map[Any, Any]) -> Map[Any, Any]: ... | ||
| def _composition(self, right: Map[Any, Any]) -> Map[Any, Any]: ... | ||
| def _composition_(self, right: Map[Any, Any], homset: Any) -> Map[Any, Any]: ... | ||
| def pre_compose(self, right: Map[Any, Any]) -> Map[Any, Any]: ... | ||
| def post_compose(self, left: Map[Any, Any]) -> Map[Any, Any]: ... | ||
| def extend_domain(self, new_domain: Any) -> Map[Any, Any]: ... | ||
| def extend_codomain(self, new_codomain: Any) -> Map[Any, Any]: ... | ||
| def is_surjective(self) -> bool: ... | ||
| def _pow_int(self, n: int) -> Map[Any, Any]: ... | ||
| def section(self) -> Map[Any, Any] | None: ... | ||
| def __hash__(self) -> int: ... | ||
|
|
||
| class Section( | ||
| Map[SectionCodomainT, SectionDomainT], Generic[SectionDomainT, SectionCodomainT] | ||
| ): | ||
| _inverse: Map[SectionDomainT, SectionCodomainT] | ||
|
|
||
| def __init__(self, map: Map[SectionDomainT, SectionCodomainT]) -> None: ... | ||
| def _extra_slots(self) -> dict[str, Any]: ... | ||
| def _update_slots(self, slots: Mapping[str, Any]) -> None: ... | ||
| def _repr_type(self) -> str: ... | ||
| def inverse(self) -> Map[SectionDomainT, SectionCodomainT]: ... | ||
|
|
||
| class FormalCompositeMap( | ||
| Map[CompositeDomainT, CompositeCodomainT], | ||
| Generic[CompositeDomainT, CompositeCodomainT], | ||
| ): | ||
| __list: Sequence[Map[Any, Any]] | ||
|
|
||
| def __init__( | ||
| self, | ||
| parent: Any, | ||
| first: Map[Any, Any] | Sequence[Map[Any, Any]], | ||
| second: Map[Any, Any] | None = ..., | ||
| ) -> None: ... | ||
| def __copy__(self) -> Self: ... | ||
| def _update_slots(self, slots: Mapping[str, Any]) -> None: ... | ||
| def _extra_slots(self) -> dict[str, Any]: ... | ||
| def __richcmp__(self, other: Any, op: int) -> bool: ... | ||
| def __hash__(self) -> int: ... | ||
| def __getitem__(self, i: int) -> Map[Any, Any]: ... | ||
| def _call_(self, x: CompositeDomainT) -> CompositeCodomainT: ... | ||
| def _call_with_args( | ||
| self, | ||
| x: CompositeDomainT, | ||
| args: Sequence[Any] = ..., | ||
| kwds: Mapping[str, Any] | None = ..., | ||
| ) -> CompositeCodomainT: ... | ||
| def _repr_type(self) -> str: ... | ||
| def _repr_defn(self) -> str: ... | ||
| def first(self) -> Map[Any, Any]: ... | ||
| def then(self) -> Map[Any, Any]: ... | ||
| def is_injective(self) -> bool: ... | ||
| def is_surjective(self) -> bool: ... | ||
| def domains(self) -> Iterator[Parent[Any] | None]: ... | ||
| def section(self) -> Map[Any, Any] | None: ... | ||
|
|
||
| def unpickle_map( | ||
| _class: type[Map[Any, Any]], | ||
| parent: Any, | ||
| _dict: Mapping[str, Any], | ||
| _slots: Mapping[str, Any], | ||
| ) -> Map[Any, Any]: ... | ||
| def is_Map(x: Any) -> bool: ... | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,8 +1,6 @@ | ||
| from typing import Any | ||
|
|
||
| from sage.structure.element import Element | ||
| from sage.categories.map import Map | ||
| from sage.rings.complex_double import ComplexDoubleElement | ||
| from sage.rings.complex_mpfr import ComplexNumber | ||
|
|
||
| class CCtoCDF(Map): | ||
| def _call_(self, x: Element) -> Element: | ||
| ... | ||
| class CCtoCDF(Map[ComplexNumber, ComplexDoubleElement]): | ||
| def _call_(self, x: ComplexNumber) -> ComplexDoubleElement: ... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've seen contravariant and covariant in the Python docs before but haven't really seen them used. For the sake of helping me review this, could you briefly explain what these are doing?