Skip to content

Commit

Permalink
Trac #34804: Deprecate sage.interfaces is_...Element functions
Browse files Browse the repository at this point in the history
Introducing a module `sage.interfaces.abc` with abstract base classes
for `isinstance` testing (see
https://doc.sagemath.org/html/en/developer/packaging_sage_library.html
#module-level-runtime-dependencies)

Part of #32414

URL: https://trac.sagemath.org/34804
Reported by: mkoeppe
Ticket author(s): Matthias Koeppe, Dima Pasechnik
Reviewer(s): Dima Pasechnik
  • Loading branch information
Release Manager committed Jan 2, 2023
2 parents 80f8f95 + b9eac04 commit 8a0b16d
Show file tree
Hide file tree
Showing 29 changed files with 346 additions and 84 deletions.
1 change: 1 addition & 0 deletions src/doc/en/reference/interfaces/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ and testing to make sure nothing funny is going on).
sage/interfaces/interface
sage/interfaces/expect
sage/interfaces/sagespawn
sage/interfaces/abc
sage/interfaces/axiom
sage/interfaces/ecm
sage/interfaces/four_ti_2
Expand Down
5 changes: 3 additions & 2 deletions src/sage/algebras/commutative_dga.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@
from sage.rings.quotient_ring_element import QuotientRingElement
from sage.misc.cachefunc import cached_function

import sage.interfaces.abc


def sorting_keys(element):
r"""
Expand Down Expand Up @@ -1262,8 +1264,7 @@ def _element_constructor_(self, x, coerce=True):
R = self.cover_ring()
x = R(x)

from sage.interfaces.singular import is_SingularElement
if is_SingularElement(x):
if isinstance(x, sage.interfaces.abc.SingularElement):
# self._singular_().set_ring()
x = self.element_class(self, x.sage_poly(self.cover_ring()))
return x
Expand Down
5 changes: 2 additions & 3 deletions src/sage/groups/perm_gps/permgroup.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,7 @@
from sage.groups.group import FiniteGroup

from sage.rings.all import QQ, Integer
from sage.interfaces.expect import is_ExpectElement
from sage.interfaces.gap import GapElement
from sage.interfaces.abc import ExpectElement, GapElement
from sage.libs.gap.libgap import libgap
from sage.libs.gap.element import GapElement as LibGapElement
from sage.groups.perm_gps.permgroup_element import PermutationGroupElement
Expand Down Expand Up @@ -385,7 +384,7 @@ def PermutationGroup(gens=None, *args, **kwds):
See https://trac.sagemath.org/31510 for details.
"""
if not is_ExpectElement(gens) and hasattr(gens, '_permgroup_'):
if not isinstance(gens, ExpectElement) and hasattr(gens, '_permgroup_'):
return gens._permgroup_()
if gens is not None and not isinstance(gens, (tuple, list, GapElement)):
raise TypeError("gens must be a tuple, list, or GapElement")
Expand Down
7 changes: 4 additions & 3 deletions src/sage/groups/perm_gps/permgroup_element.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,9 @@ from sage.sets.finite_enumerated_set import FiniteEnumeratedSet
import sage.structure.coerce as coerce
from sage.structure.richcmp cimport richcmp_not_equal, rich_to_bool
from sage.structure.coerce cimport coercion_model
from sage.interfaces.gap import GapElement as PExpectGapElement
from sage.interfaces.gp import GpElement
from sage.interfaces.abc import GpElement

import sage.interfaces.abc

from sage.libs.gap.libgap import libgap
from sage.libs.gap.gap_includes cimport (UInt, UInt2, UInt4, T_PERM2, T_PERM4,
Expand Down Expand Up @@ -478,7 +479,7 @@ cdef class PermutationGroupElement(MultiplicativeGroupElement):
self._set_list_images(g.sage(), convert)
else:
raise ValueError("invalid data to initialize a permutation")
elif isinstance(g, PExpectGapElement):
elif isinstance(g, sage.interfaces.abc.GapElement):
if g.IsPerm():
self._set_list_images(g.ListPerm(), False)
else:
Expand Down
135 changes: 135 additions & 0 deletions src/sage/interfaces/abc.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,138 @@
r"""
Abstract base classes for interface elements
"""

class AxiomElement:
r"""
Abstract base class for :class:`~sage.interfaces.axiom.AxiomElement`.
This class is defined for the purpose of ``isinstance`` tests. It should not be
instantiated.
EXAMPLES:
By design, there is a unique direct subclass::
sage: len(sage.interfaces.abc.AxiomElement.__subclasses__()) <= 1
True
"""
pass


class ExpectElement:
r"""
Abstract base class for :class:`~sage.interfaces.expect.ExpectElement`.
This class is defined for the purpose of ``isinstance`` tests. It should not be
instantiated.
EXAMPLES:
By design, there is a unique direct subclass::
sage: len(sage.interfaces.abc.ExpectElement.__subclasses__()) <= 1
True
"""
pass


class FriCASElement:
r"""
Abstract base class for :class:`~sage.interfaces.fricas.FriCASElement`.
This class is defined for the purpose of ``isinstance`` tests. It should not be
instantiated.
EXAMPLES:
By design, there is a unique direct subclass::
sage: len(sage.interfaces.abc.FriCASElement.__subclasses__()) <= 1
True
"""
pass


class GapElement:
r"""
Abstract base class for :class:`~sage.interfaces.gap.GapElement`.
This class is defined for the purpose of ``isinstance`` tests. It should not be
instantiated.
EXAMPLES:
By design, there is a unique direct subclass::
sage: len(sage.interfaces.abc.GapElement.__subclasses__()) <= 1
True
"""
pass


class GpElement:
r"""
Abstract base class for :class:`~sage.interfaces.gp.GpElement`.
This class is defined for the purpose of ``isinstance`` tests. It should not be
instantiated.
EXAMPLES:
By design, there is a unique direct subclass::
sage: len(sage.interfaces.abc.GpElement.__subclasses__()) <= 1
True
"""
pass


class Macaulay2Element:
r"""
Abstract base class for :class:`~sage.interfaces.macaulay2.Macaulay2Element`.
This class is defined for the purpose of ``isinstance`` tests. It should not be
instantiated.
EXAMPLES:
By design, there is a unique direct subclass::
sage: len(sage.interfaces.abc.Macaulay2Element.__subclasses__()) <= 1
True
"""
pass


class MagmaElement:
r"""
Abstract base class for :class:`~sage.interfaces.magma.MagmaElement`.
This class is defined for the purpose of ``isinstance`` tests. It should not be
instantiated.
EXAMPLES:
By design, there is a unique direct subclass::
sage: len(sage.interfaces.abc.MagmaElement.__subclasses__()) <= 1
True
"""
pass


class SingularElement:
r"""
Abstract base class for :class:`~sage.interfaces.singular.SingularElement`.
This class is defined for the purpose of ``isinstance`` tests. It should not be
instantiated.
EXAMPLES:
By design, there is a unique direct subclass::
sage: len(sage.interfaces.abc.SingularElement.__subclasses__()) <= 1
True
"""
pass
16 changes: 12 additions & 4 deletions src/sage/interfaces/axiom.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,8 @@
import os
import re

import sage.interfaces.abc

from .expect import Expect, ExpectElement, FunctionElement, ExpectFunction
from sage.env import DOT_SAGE
from pexpect import EOF
Expand Down Expand Up @@ -555,7 +557,7 @@ def console(self):


@instancedoc
class PanAxiomElement(ExpectElement):
class PanAxiomElement(ExpectElement, sage.interfaces.abc.AxiomElement):
def __call__(self, x):
"""
EXAMPLES::
Expand Down Expand Up @@ -944,18 +946,24 @@ def __init__(self, parent, name):

def is_AxiomElement(x):
"""
Returns True of x is of type AxiomElement.
Return True if ``x`` is of type :class:`AxiomElement`.
EXAMPLES::
sage: from sage.interfaces.axiom import is_AxiomElement
sage: is_AxiomElement(axiom(2)) #optional - axiom
True
sage: is_AxiomElement(2)
doctest:...: DeprecationWarning: the function is_AxiomElement is deprecated; use isinstance(x, sage.interfaces.abc.AxiomElement) instead
See https://trac.sagemath.org/34804 for details.
False
sage: is_AxiomElement(axiom(2)) # optional - axiom
True
"""
from sage.misc.superseded import deprecation
deprecation(34804, "the function is_AxiomElement is deprecated; use isinstance(x, sage.interfaces.abc.AxiomElement) instead")

return isinstance(x, AxiomElement)


#Instances
axiom = Axiom(name='axiom')

Expand Down
20 changes: 19 additions & 1 deletion src/sage/interfaces/expect.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@

import pexpect
from pexpect import ExceptionPexpect
import sage.interfaces.abc
from sage.interfaces.sagespawn import SageSpawn
from sage.interfaces.interface import (Interface, InterfaceElement,
InterfaceFunction, InterfaceFunctionElement)
Expand Down Expand Up @@ -1465,11 +1466,28 @@ class FunctionElement(InterfaceFunctionElement):


def is_ExpectElement(x):
"""
Return True if ``x`` is of type :class:`ExpectElement`
This function is deprecated; use :func:`isinstance`
(of :class:`sage.interfaces.abc.ExpectElement`) instead.
EXAMPLES::
sage: from sage.interfaces.expect import is_ExpectElement
sage: is_ExpectElement(2)
doctest:...: DeprecationWarning: the function is_ExpectElement is deprecated; use isinstance(x, sage.interfaces.abc.ExpectElement) instead
See https://trac.sagemath.org/34804 for details.
False
"""
from sage.misc.superseded import deprecation
deprecation(34804, "the function is_ExpectElement is deprecated; use isinstance(x, sage.interfaces.abc.ExpectElement) instead")

return isinstance(x, ExpectElement)


@instancedoc
class ExpectElement(InterfaceElement):
class ExpectElement(InterfaceElement, sage.interfaces.abc.ExpectElement):
"""
Expect element.
"""
Expand Down
19 changes: 13 additions & 6 deletions src/sage/interfaces/fricas.py
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,9 @@

import re
import os

import sage.interfaces.abc

from sage.interfaces.tab_completion import ExtraTabCompletion
from sage.interfaces.expect import Expect, ExpectElement, FunctionElement, ExpectFunction
from sage.env import DOT_SAGE, LOCAL_IDENTIFIER
Expand Down Expand Up @@ -995,7 +998,7 @@ def console(self):


@instancedoc
class FriCASElement(ExpectElement):
class FriCASElement(ExpectElement, sage.interfaces.abc.FriCASElement):
"""
Instances of this class represent objects in FriCAS.
Expand Down Expand Up @@ -2106,12 +2109,17 @@ def is_FriCASElement(x):
EXAMPLES::
sage: from sage.interfaces.fricas import is_FriCASElement # optional - fricas
sage: from sage.interfaces.fricas import is_FriCASElement
sage: is_FriCASElement(2)
doctest:...: DeprecationWarning: the function is_FriCASElement is deprecated; use isinstance(x, sage.interfaces.abc.FriCASElement) instead
See https://trac.sagemath.org/34804 for details.
False
sage: is_FriCASElement(fricas(2)) # optional - fricas
True
sage: is_FriCASElement(2) # optional - fricas
False
"""
from sage.misc.superseded import deprecation
deprecation(34804, "the function is_FriCASElement is deprecated; use isinstance(x, sage.interfaces.abc.FriCASElement) instead")

return isinstance(x, FriCASElement)


Expand All @@ -2120,8 +2128,7 @@ def is_FriCASElement(x):

def reduce_load_fricas():
"""
Return the FriCAS interface object defined in
:sage.interfaces.fricas.
Return the FriCAS interface object defined in :mod:`sage.interfaces.fricas`.
EXAMPLES::
Expand Down
13 changes: 11 additions & 2 deletions src/sage/interfaces/gp.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@
from sage.libs.pari.all import pari
import sage.rings.complex_mpfr
from sage.misc.instancedoc import instancedoc
import sage.interfaces.abc


class Gp(ExtraTabCompletion, Expect):
Expand Down Expand Up @@ -821,7 +822,7 @@ def new_with_bits_prec(self, s, precision=0):


@instancedoc
class GpElement(ExpectElement):
class GpElement(ExpectElement, sage.interfaces.abc.GpElement):
"""
EXAMPLES: This example illustrates dumping and loading GP elements
to compressed strings.
Expand Down Expand Up @@ -1036,16 +1037,24 @@ def _tab_completion(self):

def is_GpElement(x):
"""
Returns True of x is a GpElement.
Return True if ``x`` is of type :class:`GpElement`
This function is deprecated; use :func:`isinstance`
(of :class:`sage.interfaces.abc.GpElement`) instead.
EXAMPLES::
sage: from sage.interfaces.gp import is_GpElement
sage: is_GpElement(gp(2))
doctest:...: DeprecationWarning: the function is_GpElement is deprecated; use isinstance(x, sage.interfaces.abc.GpElement) instead
See https://trac.sagemath.org/34804 for details.
True
sage: is_GpElement(2)
False
"""
from sage.misc.superseded import deprecation
deprecation(34804, "the function is_GpElement is deprecated; use isinstance(x, sage.interfaces.abc.GpElement) instead")

return isinstance(x, GpElement)


Expand Down
Loading

0 comments on commit 8a0b16d

Please sign in to comment.