Skip to content

Commit

Permalink
Remove Gap.function_factory()
Browse files Browse the repository at this point in the history
Between 0b02d9c and other changes the need for it seems to be pretty
well obviated.  If there's any use I can sort of think of, it's if
GAP global variables used internally by gappy are rebound by the user
it could break gappy.

But that was already the case if the variable is rebound before it was
possible to create it through function_factory.

The libgap interface in Sage could still provide this in its wrapper
but mark it deprecated.
  • Loading branch information
embray committed Jan 13, 2021
1 parent 0b02d9c commit 6a7d07c
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 68 deletions.
29 changes: 1 addition & 28 deletions gappy/core.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -704,44 +704,17 @@ cdef class Gap:
RuntimeError: Error loading GAP package chevie. You may want to
install gap_packages SPKG.
"""
load_package = self.function_factory('LoadPackage')
# Note: For some reason the default package loading error messages are
# controlled with InfoWarning and not InfoPackageLoading
prev_infolevel = self.InfoLevel(self.InfoWarning)
self.SetInfoLevel(self.InfoWarning, 0)
ret = load_package(pkg)
ret = self.LoadPackage(pkg)
self.SetInfoLevel(self.InfoWarning, prev_infolevel)
if str(ret) == 'fail':
raise RuntimeError(f"Error loading GAP package {pkg}. "
f"You may want to install gap_packages SPKG.")
return ret

def function_factory(self, function_name):
"""
Return a GAP function wrapper
This is almost the same as calling
``gap.eval(function_name)``, but faster and makes it
obvious in your code that you are wrapping a function.
INPUT:
- ``function_name`` -- string. The name of a GAP function.
OUTPUT:
A function wrapper :class:`~gappy.gapobj.GapFunction` for the GAP
function. Calling it from Sage is equivalent to calling the wrapped
function from GAP.
EXAMPLES::
>>> gap.function_factory('Print')
<GAP function "Print">
"""
initialize()
return make_GapFunction(self, gap_eval(function_name))

def set_global(self, variable, value):
"""
Set a GAP global variable
Expand Down
32 changes: 12 additions & 20 deletions gappy/gapobj.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -2175,16 +2175,15 @@ cdef class GapFunction(GapObj):

old_text_theme = None
old_screen_size = None
libgap = self.parent()
gap = self.parent()
width = 80 # TODO: Make this customizable?

try:
GAP_Enter()

HELP_GET_MATCHES = libgap.function_factory('HELP_GET_MATCHES')
SIMPLE_STRING = libgap.function_factory('SIMPLE_STRING')
matches = HELP_GET_MATCHES(libgap.HELP_KNOWN_BOOKS[0],
SIMPLE_STRING(self._name()), True)
matches = gap.HELP_GET_MATCHES(gap.HELP_KNOWN_BOOKS[0],
gap.SIMPLE_STRING(self._name()),
True)

# HELP_GET_MATCHES returns 'exact' matches and 'topic' matches; in
# the latter case we always guess the first match is the one we
Expand All @@ -2194,27 +2193,20 @@ cdef class GapFunction(GapObj):
except StopIteration:
return ''

handler = libgap.HELP_BOOK_HANDLER[book['handler']]
handler = gap.HELP_BOOK_HANDLER[book['handler']]

# Save the old text theme and set it to "none"; in particular to
# strip out terminal control codes
try:
# In the off-chance GAPDoc is not loaded...
SetGAPDocTextTheme = libgap.function_factory(
'SetGAPDocTextTheme')
except GAPError:
pass
else:
old_text_theme = libgap.eval('GAPDocTextTheme')
SetGAPDocTextTheme('none')
if gap.get_global('SetGAPDocTextTheme') is not None:
old_text_theme = gap.GAPDocTextTheme
gap.SetGAPDocTextTheme('none')

# Set the screen width to 80 (otherwise it will produce text with
# lines up to 4096, the hard-coded maximum line length)
# Hard-coding this might be a small problem for other functions
# that depend on screen width, but this seems to be rare...
SizeScreen = libgap.function_factory('SizeScreen')
old_screen_size = SizeScreen()
SizeScreen([width])
old_screen_size = gap.SizeScreen()
gap.SizeScreen([width])

line_info = dict(handler['HelpData'](book, entrynum, 'text'))
# TODO: Add .get() and other dict methods to GapRecord
Expand Down Expand Up @@ -2242,9 +2234,9 @@ cdef class GapFunction(GapObj):
return self._doc
finally:
if old_text_theme is not None:
SetGAPDocTextTheme(old_text_theme)
gap.SetGAPDocTextTheme(old_text_theme)
if old_screen_size is not None:
SizeScreen(old_screen_size)
gap.SizeScreen(old_screen_size)

GAP_Leave()

Expand Down
26 changes: 6 additions & 20 deletions gappy/operations.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,20 +34,7 @@ def __init__(self, obj):

self._obj = obj
self._gap = obj.parent()

# TODO: These functions/globals were originally module-level globals
# instantiated from the global libgap instance.
# Currently that is fine, since there can only ever be one GAP
# interpreter instance at the moment, but with an eye toward supporting
# multiple GAP interpreters and general refactoring, these are moved to
# instance-level variables. However, we could still speed this up by
# caching these somewhere on a per-Gap basis (function_factory is
# already supposed to be cached so that alone might be good enough once
# caching is restored on it).
FlagsType = self._gap.function_factory('FlagsType')
TypeObj = self._gap.function_factory('TypeObj')

self.flags = FlagsType(TypeObj(self.obj))
self.flags = self._gap.FlagsType(self._gap.TypeObj(self.obj))

def __repr__(self):
"""
Expand Down Expand Up @@ -96,13 +83,12 @@ def operations(self):
>>> from gappy.operations import OperationInspector
>>> x = OperationInspector(gap(123))
>>> Unknown = gap.function_factory('Unknown')
>>> Unknown in x.operations()
>>> gap.Unknown in x.operations()
True
"""
IS_SUBSET_FLAGS = self._gap.function_factory('IS_SUBSET_FLAGS')
GET_OPER_FLAGS = self._gap.function_factory('GET_OPER_FLAGS')
OPERATIONS = self._gap.get_global('OPERATIONS')
IS_SUBSET_FLAGS = self._gap.IS_SUBSET_FLAGS
GET_OPER_FLAGS = self._gap.GET_OPER_FLAGS
OPERATIONS = self._gap.OPERATIONS

def mfi(o):
filts = GET_OPER_FLAGS(o)
Expand All @@ -126,7 +112,7 @@ def op_names(self):
>>> 'Sqrt' in x.op_names()
True
"""
NameFunction = self._gap.function_factory('NameFunction')
NameFunction = self._gap.NameFunction
result = set()
for f in self.operations():
name = str(NameFunction(f))
Expand Down

0 comments on commit 6a7d07c

Please sign in to comment.