-
-
Notifications
You must be signed in to change notification settings - Fork 657
Description
Update: The successor to this ticket is #31404 which offers a different approach by using gappy directly in Sage rather than providing Sage-specific wrappers. I think it is overall a better approach for now.
Package tarball: see checksums.ini
; use ./configure --enable-download-from-upstream-url
to test.
gappy is a new !Python/Cython package providing a Python interface to GAP using its public "libgap" API (to the extent possible).
It is the result of extracting Sage's sage.libs.gap
package into a standalone package without a dependency on Sage, so it still bears some of the legacy of that package (which will continue to be cleaned up and improved on).
One particular improvement is the help system for GAP functions--as before it is possible to extract documentation (when it exists) from the GAP docs, but this is faster now (previously the pexpect interface was still required) and can usually extract only the documentation for the queried function (previously it would also append the entire rest of the documentation chapter). It may also introduce some minor performance improvements in some areas, but it will be interesting to test this with some non-trivial examples.
This ticket is to attempt to convert sage.libs.gap
to a wrapper around gappy (rather than replace it entirely). The main reason a wrapper is still needed, is in order to participate in Sage's coercion model.
The GAP interpreter wrapper class sage.libs.gap.libgap.Gap
is a Parent
, and its elements are instances of GapElement
and subclasses thereof which are subclasses of Element
.
This presents a challenge which makes wrapping gappy less straightforward than one would hope: Because the classes gappy.Gap
and gappy.GapObj
(its equivalent of GapElement
) are cdef classes, as well as Parent
and Element
, it is not possible to use multiple inheritance like
class GapElement(GapObj, Element):
...
because their base structs are incompatible. The current workaround to this is that GapElement
is a wrapper for a GapObj
(which in turn wraps C-level GAP Obj
pointers). This creates a bit of unfortunate overhead, albeit not much; by using cdef
and cpdef
methods, Cython can make the call to wrapped objects reasonably fast in many cases.
TODO
-
Rework the
sage.libs.gap.assigned_names
andsage.libs.gap.all_documented_functions
modules. -
Fix more uses within sage of the deprecated
Gap.function_factory
method. -
Fix more tests; all test are passing in
sage.libs.gap
as well as all insage.groups.perm_gps
, but some tests elsewhere are failing. -
There are miscellaneous other functions in
sage.libs.gap
that can probably be deprecated or removed.
Food for thought...
There are some other possible workarounds to this issue I would like to explore in the future.
The first is to change how gappy works: Rather than Gap
and GapObj
being cdef
classes, they could be pure-Python wrappers around some cdef
classes. This would again create some overhead, but hopefully not too much. Then they can participate in multiple inheritance with Sage's Parent
and Element
classes.
The other two, which would be much more disruptive, but also possibly useful for other packages that would like to integrate with Sage without explicitly depending on it, and have been discussed before:
-
Create a relatively Sage "base" package with little to no mathematical functionality but that provides base classes for some of Sage's structural classes such as
SageObject
,Parent
, andElement
(maybe alsoCategoryObject
?). These base classes need not replicate the full functionality found in Sage, but just enough to provide some bootstrapping. If the package is relatively small and easily pip-installable, packages like gappy can use it as a dependency without requiring all of Sage. See Modularization of sagelib: Break out separate packages sagemath-objects, sagemath-categories #29865 for an in-progress viable prototype of this. -
A similar but subtly different option is to make classes like
SageObject
,Parent
, andElement
into Abstract Base Classes. Classes in other packages can then be registered as psuedo-subclasses of these ABCs without directly subclassing them, so long as they implement the necessary interfaces. This option is appealing to me since it means classes from other packages can more easily interface with Sage without requiring any additional dependencies. However, it is potentially more disruptive: There isn't a way to ensure that classes which register to an ABC to provide the same C-level interface (C methods and attributes). So Cython-level code that types variables asParent
orElement
won't work here, and would have to provide a separate (typically slower) code path for handle ABC pseudo-subclasses. Fortunately there is not a ton of code like this in Sage, but there is some, especially in code related to the coercion model, unsurprisingly.
Component: interfaces
Keywords: gap libgap gappy
Work Issues: release gappy 0.1.0 final and update spkg version before merging
Author: Erik Bray
Branch/Commit: u/embray/gappy @ 82e7e56
Reviewer: Dima Pasechnik
Issue created by migration from https://trac.sagemath.org/ticket/31297