API Documentation

gap: gappy.core.Gap

The default GAP interpreter instance. Most users can run:

>>> from gappy import gap

and immediately begin using GAP from here. However, if you wish to customize the initialization parameters of the GAP interpreter (e.g. set the gap_root path) you can run:

>>> from gappy import Gap
>>> gap = Gap(...)

Note

Upon first using gap, whether to access a global variable run a function, there may be a noticeable delay upon GAP initialization; after the first use it will be faster.

gappy.core

Top-level Python interface to GAP.

class gappy.core.Gap

The GAP interpreter object.

Note

When initializing this class, it does not immediately initialize the underlying GAP interpreter unless passed autoinit=True. Otherwise the GAP interpreter is not initialized until the first Gap.eval call or the first GAP global lookup.

The default interpreter instance gap is initialized with some default parameters, but before its first use you may initialize your own Gap instance with different parameters.

Parameters
  • gap_root (str or pathlib.Path) – Path to the GAP installation (GAP_ROOT) you want to use for the GAP interpreter. This should be the path containing the lib/ and pkg/ directories for the standard GAP libraries. Equivalent to the -l command-line argument to gap.

  • gaprc (str or pathlib.Path) – A GAP “runtime config” file containing GAP commands to run immediately upon GAP interpreter startup. Equivalent to passing a GAP file to gap on the command-line.

  • workspace (str or pathlib.Path) – An existing GAP workspace to restore upon interpreter startup. Equivalent to the -L command-line argument to gap.

  • autoinit (bool) – Immediately initialize the GAP interpreter when initializing this Gap instance. Otherwise the interpreter is initialized “lazily” when the first interaction with the interpreter is needed (either an eval call or global variable lookup) (default: False).

  • autoload (bool) – Automatically load the default recommended GAP packages when starting the GAP interpreter. If False this is equivalent to passing the -A command-line argument to gap (default: False).

supported_builtins

The basic Python types for which gappy has built-in support for conversion to equivalent GAP objects; currently: str, bytes, bool, int, numbers.Integral, numbers.Rational, float, numbers.Real, list, tuple, dict, None.

Type

tuple

Examples

>>> gap.eval('SymmetricGroup(4)')
Sym( [ 1 .. 4 ] )
collect()

Manually run the garbage collector

Examples

>>> a = gap(123)
>>> del a
>>> gap.collect()
convert_from()

Decorator for registering a converter from a Python type to any type of GapObj.

This allows providing converters for objects that do not have a _gap_ or _gap_init_ method. While it is preferable to use the special methods, this allows adapting classes that do not have these methods, without having to subclass or wrap them.

The type must not be one of the types that already have built-in converters; see Gap.supported_builtins.

When converting a Python object to a GAP object, first the built-in converters are tried. Then the registry of converters is checked for an exact type match. If no exact match is found, an isinstance check is performed for each type in the registry.

The converter is any callable which is passed the Gap interpreter instance and the object to convert as its first two arguments, and must return a either GapObj instance or one of the built-in types in Gap.supported_builtins which can be converted to the appropriate GAP object. This frees the converter function from having to directly construct a GapObj itself, but also eliminates the possibility of infinite recursions when performing conversion.

Examples

Say we have a class PermGroup which represents a permutation group as a list of permutation generators, themselves representing permutations as tuples (which happen to have the same syntax as GAP permutations, a fact we can exploit). This example does not give the full implementation of such a class, just the general data structure to demonstrate implementing the converter function:

>>> class PermGroup:
...     def __init__(self, *gens):
...         self.gens = list(gens)
...
>>> @gap.convert_from(PermGroup)
... def PermGroup_to_gap(gap, group):
...     return gap.eval(f'Group({group.gens})')
...
>>> group = PermGroup((1, 2), (1, 2, 3, 4, 5, 6, 7, 8))
>>> gap(group)
Group([ (1,2), (1,2,3,4,5,6,7,8) ])
count_GAP_objects()

Return the number of GAP objects that are being tracked by GAP.

Returns

Return type

int

Examples

>>> gap.count_GAP_objects()  
5
eval()

Evaluate a gap command and wrap the result.

Parameters

gap_command (str) – A string containing a valid GAP command with or without the trailing semicolon.

Returns

The result of the GAP statement.

Return type

GapObj

Examples

>>> gap.eval('0')
0
>>> gap.eval('"string"')
"string"
gap_function()

Create GAP functions from decorated Python functions.

Examples

The code for the GAP function is actually written in the Python function’s docstring like so:

>>> @gap.gap_function
... def one():
...     '''
...     Returns the multiplicative identity of the ring of integers.
...
...     function()
...         return 1;
...     end;
...     '''
...
>>> one
<GAP function "one">
>>> one()
1

Any text in the docstring before the first line beginning the text function() is used as the function’s docstring. Any following text is considered part of the function definition:

>>> one.help()
'Returns the multiplicative identity of the ring of integers.'

Note that using this decorator does not cause the GAP interpreter to be initialized, so it can be used in module or class-level code. The GAP interpreter will only be initialized (if needed) the first time the function is called.

Any Python code in the function’s body will be disregarded, so this is in effect syntactic sugar for:

>>> one = gap.eval('function() return 1; end;')

with the difference being that it can be used to pre-define GAP functions without invoking the GAP interpreter directly.

This decorator may also be used on methods in classes. In this case the self–the instance of the class on which it is defined, is always passed as the first argument to the GAP function, if it has a conversion to a GAP type:

>>> class MyInt(int):
...     @gap.gap_function
...     def n_partitions(self):
...         '''
...         Compute the number of integer partitions.
...
...         function(n)
...             local np;
...             if n < 0 then
...                 Error("must be a non-negative integer");
...             fi;
...             np:= function(n, m)
...                local i, res;
...                if n = 0 then
...                   return 1;
...                fi;
...                res:= 0;
...                for i in [1..Minimum(n,m)] do
...                   res:= res + np(n-i, i);
...                od;
...                return res;
...             end;
...             return np(n,n);
...         end;
...         '''
...
>>> ten = MyInt(10)
>>> ten.n_partitions()
42
gap_root

The path to the GAP installation being used for this interpreter instance.

Examples

>>> gap.gap_root  
'/path/to/gap_installation'
gaprc

The path to the GAP runtime configuration file being used for this interpreter instance.

Examples

>>> gap.gaprc  
'/path/to/gaprc'
get_global()

Get a GAP global variable

Parameters

variable (str) – The GAP global variable name.

Returns

GapObj wrapping the GAP output. None is returned if there is

no such variable in GAP.

Return type

GapObj or None

Examples

>>> gap.set_global('FooBar', 1)
>>> gap.get_global('FooBar')
1
>>> gap.unset_global('FooBar')
>>> gap.get_global('FooBar') is None
True
global_context()

Temporarily change a global variable

Parameters
  • variable (str) – The GAP global variable name.

  • value – Any GapObj or Python object that can be converted to a GAP object. Passing None is equivalent to Gap.unset_global.

Returns

A context manager that sets/reverts the given global variable.

Return type

GlobalVariableContext

Examples

>>> gap.set_global('FooBar', 1)
>>> with gap.global_context('FooBar', 2):
...     print(gap.get_global('FooBar'))
2
>>> gap.get_global('FooBar')
1
initialize()

Manually initialize the underlying GAP interpreter if it is has not already been automatically initialized.

Returns True if this initialized the GAP interpreter for the first time, or False if the interpreter was already initialized.

load_package()

If loading fails, raise a RuntimeError exception.

Examples

>>> gap.load_package("chevie")
Traceback (most recent call last):
...
RuntimeError: Error loading GAP package chevie.
set_global()

Set a GAP global variable

Parameters
  • variable (str) – The GAP global variable name.

  • value – Any GapObj or Python object that can be converted to a GAP object. Passing None is equivalent to Gap.unset_global.

  • force (bool) – If True, sets the value of the global even if it is read-only; otherwise an AttributeError is raised.

Examples

>>> gap.set_global('FooBar', 1)
>>> gap.get_global('FooBar')
1
>>> gap.unset_global('FooBar')
>>> gap.get_global('FooBar') is None
True
>>> gap.set_global('FooBar', 1)
>>> gap.get_global('FooBar')
1
>>> gap.set_global('FooBar', None)
>>> gap.get_global('FooBar') is None
True
set_seed()

Reseed the standard GAP pseudo-random sources with the given seed.

Uses a random 128-bit integer as the seed given by GMP’s mpz_rrandomm if seed=None. Otherwise the seed should be an integer.

Examples

>>> gap.set_seed(0)
0
>>> [gap.Random(1, 10) for i in range(5)]
[2, 3, 3, 4, 2]
show()

Return statistics about the GAP owned object list

This includes the total memory allocated by GAP as returned by gap.eval('TotalMemoryAllocated()'), as well as garbage collection / object count statistics as returned by ``gap.eval('GasmanStatistics'), and finally the total number of GAP objects held by gappy as GapObj instances.

The value livekb + deadkb will roughly equal the total memory allocated for GAP objects (see gap.eval('TotalMemoryAllocated()')).

Note

Slight complication is that we want to do it without accessing GAP objects, so we don’t create new GapObjs as a side effect.

Examples

>>> a = gap(123)
>>> b = gap(456)
>>> c = gap(789)
>>> del b
>>> gap.collect()
>>> gap.show()  
{'gasman_stats': {'full': {'cumulative': 110,
   'deadbags': 321400,
   'deadkb': 12967,
   'freekb': 15492,
   'livebags': 396645,
   'livekb': 37730,
   'time': 110,
   'totalkb': 65536},
  'nfull': 1,
  'npartial': 1},
 'nelements': 23123,
 'total_alloc': 3234234}
unset_global()

Remove a GAP global variable

Parameters

variable (str) – The GAP global variable name.

Examples

>>> gap.set_global('FooBar', 1)
>>> gap.get_global('FooBar')
1
>>> gap.unset_global('FooBar')
>>> gap.get_global('FooBar') is None
True
workspace

The path to the GAP workspace loaded by this interpreter instance at startup.

Examples

>>> gap.workspace  
'/path/to/gaprc'
class gappy.core.ObjWrapper

Wrapper for GAP master pointers

Examples

>>> from gappy.core import ObjWrapper
>>> x = ObjWrapper()
>>> y = ObjWrapper()
>>> x == y
True
gappy.core.get_owned_objects()

Helper to access the refcount dictionary from Python code

gappy.gapobj

GAP object wrappers.

This document describes the individual wrappers for various GAP objects.

class gappy.gapobj.GapBoolean

Derived class of GapObj for GAP boolean values.

Examples

>>> b = gap(True)
>>> type(b)
<class 'gappy.gapobj.GapBoolean'>
python()

self != 0

class gappy.gapobj.GapCyclotomic

Derived class of GapObj for GAP universal cyclotomics.

Examples

>>> gap.eval('E(3)')
E(3)
>>> type(_)
<class 'gappy.gapobj.GapCyclotomic'>
class gappy.gapobj.GapFiniteField

Derived class of GapObj for GAP finite field elements.

Examples

>>> gap.eval('Z(5)^2')
Z(5)^2
>>> type(_)
<class 'gappy.gapobj.GapFiniteField'>
lift()

Return an integer lift.

Returns

The smallest positive GapInteger that equals self in the prime finite field.

Return type

GapInteger

Examples

>>> n = gap.eval('Z(5)^2')
>>> n.lift()
4
>>> type(_)
<class 'gappy.gapobj.GapInteger'>
>>> n = gap.eval('Z(25)')
>>> n.lift()
Traceback (most recent call last):
TypeError: not in prime subfield
class gappy.gapobj.GapFloat

Derived class of GapObj for GAP floating point numbers.

Examples

>>> i = gap(123.5)
>>> type(i)
<class 'gappy.gapobj.GapFloat'>
>>> i
123.5
>>> float(i)
123.5
python()

Convert to a Python float.

Examples

>>> float(gap.eval("Float(3.5)"))
3.5
class gappy.gapobj.GapFunction

Derived class of GapObj for GAP functions.

To show the GAP documentation for this function, use the <func>? syntax in IPython/Jupyter or call print(<func>.help()), where <func> is this function.

Examples

>>> f = gap.Cycles
>>> type(f)
<class 'gappy.gapobj.GapFunction'>
help()

Return the GAP help text for the function, if any exists.

Roughly equivalent to calling ?FuncName in GAP, but returns the result as a string.

Examples

>>> print(gap.SymmetricGroup.help())
50.1-... SymmetricGroup

‣ SymmetricGroup( [filt, ]deg ) ─────────────────────────────────── function
‣ SymmetricGroup( [filt, ]dom ) ─────────────────────────────────── function
...
Note  that  permutation  groups  provide  special treatment of
symmetric and alternating groups, see 43.4.
class gappy.gapobj.GapInteger

Derived class of GapObj for GAP integers.

Examples

>>> i = gap(123)
>>> type(i)
<class 'gappy.gapobj.GapInteger'>
>>> i
123
is_C_int()

Return whether the wrapped GAP object is a immediate GAP integer.

An immediate integer is one that is stored as a C integer, and is subject to the usual size limits. Larger integers are stored in GAP as GMP integers.

Returns

Return type

bool

Examples

>>> n = gap(1)
>>> type(n)
<class 'gappy.gapobj.GapInteger'>
>>> n.is_C_int()
True
>>> n.IsInt()
true
>>> N = gap(2**130)
>>> type(N)
<class 'gappy.gapobj.GapInteger'>
>>> N.is_C_int()
False
>>> N.IsInt()
true
python()

Convert a GAP integer to a Python int.

Examples

>>> int(gap(3))
3
>>> type(_)
<class 'int'>
>>> int(gap(-3))
-3
>>> type(_)
<class 'int'>
>>> int(gap(2**128))
340282366920938463463374607431768211456
>>> type(_)
<class 'int'>
>>> int(gap(-2**128))
-340282366920938463463374607431768211456
>>> type(_)
<class 'int'>
class gappy.gapobj.GapIntegerMod

Derived class of GapObj for GAP integers modulo an integer.

Examples

>>> i = gap.eval('One(ZmodnZ(123)) * 13'); i
ZmodnZObj( 13, 123 )
>>> type(i)
<class 'gappy.gapobj.GapIntegerMod'>
lift()

Return an integer lift.

Returns

A GapInteger that equals self in the integer mod ring.

Return type

GapInteger

Examples

>>> n = gap.eval('One(ZmodnZ(123)) * 13')
>>> n.lift()
13
>>> type(_)
<class 'gappy.gapobj.GapInteger'>
class gappy.gapobj.GapList

Derived class of GapObj for GAP Lists.

Note

Lists are indexed by 0..len(l)-1, as expected from Python. This differs from the GAP convention where lists start at 1.

Examples

>>> lst = gap.SymmetricGroup(3).List(); lst
[ (), (1,3), (1,2,3), (2,3), (1,3,2), (1,2) ]
>>> type(lst)
<class 'gappy.gapobj.GapList'>
>>> len(lst)
6
>>> lst[3]
(2,3)

We can easily convert a GAP List object into a Python list:

>>> list(lst)
[(), (1,3), (1,2,3), (2,3), (1,3,2), (1,2)]
>>> type(_)
<... 'list'>

Range checking is performed:

>>> lst[10]
Traceback (most recent call last):
...
IndexError: index out of range
python()

Convert a GAP list to a Python list.

List elements are converted recusively if possible, though any GapObjs that cannot be converted to Python equivalents will remain as-is.

Examples

>>> lst = gap.eval('[1, 2, 3, 4, 5]')

You can convert a GapList to list like:

>>> lst2 = list(lst); lst2
[1, 2, 3, 4, 5]

which works since GapList is an iterable sequence much like list. However, the elements of the list are still GapIntegers:

>>> type(lst2[0])
<class 'gappy.gapobj.GapInteger'>

Whereas GapList.python will recursively convert to Python equivalents (by calling .python() on each element) if possible:

>>> lst3 = lst.python(); lst3
[1, 2, 3, 4, 5]
>>> type(lst3[0])
<class 'int'>
class gappy.gapobj.GapMethodProxy

Helper class returned by GapObj.__getattr__.

Like its wrapped GapFunction, you can call instances to implement function call syntax. The only difference is that a fixed first argument is prepended to the argument list.

Examples

>>> lst = gap([])
>>> lst.Add
<GAP function "Add">
>>> type(_)
<class 'gappy.gapobj.GapMethodProxy'>
>>> lst.Add(1)
>>> lst
[ 1 ]
class gappy.gapobj.GapObj

Wrapper for all GAP objects.

Note

In order to create GapObjs you should use the gap instance (the parent of all GAP elements) to convert things into GapObj. You must not create GapObj instances manually.

Examples

>>> gap(0)
0

If GAP finds an error while evaluating, a GAPError exception is raised:

>>> gap.eval('1/0')
Traceback (most recent call last):
...
gappy.exceptions.GAPError: Error, Rational operations: <divisor> must
not be zero

Also, a GAPError is raised if the input is not a simple expression:

>>> gap.eval('1; 2; 3')
Traceback (most recent call last):
...
gappy.exceptions.GAPError: can only evaluate a single statement
convert_to()

Decorator allowing GapObj and subclasses thereof to be converted to equivalent Python types.

E.g. for GapObj subclasses that do not have an equivalent .python() converter, you can instrument it with your own converter.

Examples

>>> from gappy.gapobj import GapPermutation
>>> class MyPerm:
...     def __init__(self, perm):
...         '''
...         Initialize the permutation from the image of the positive
...         integers under permutation.
...         '''
...         self.perm = perm
...     def __repr__(self):
...         return f'<MyPerm({self.perm!r})>'
...
>>> @GapPermutation.convert_to('python')
... def gap_to_myperm(obj):
...     return MyPerm(obj.ListPerm().python())
...
>>> perm = gap.eval('(3, 1, 2)')
>>> myperm = perm.python()
>>> myperm
<MyPerm([2, 3, 1])>

Additionally, you can register new converters for GapObj subclasses that have an existing .python() method, but in a new “domain”. This allows instrumenting the existing GapObj classes (without subclassing them) with new conversion methods. For example, to add a convert from GapLists to NumPy arrays you might implement something like:

>>> from gappy.gapobj import GapList
>>> import numpy as np
>>> @GapList.convert_to('numpy')
... def gap_to_numpy(obj):
...     return np.asarray(obj.python())
...
>>> lst = gap([[1, 2, 3], [4, 5, 6]])
>>> type(lst)
<class 'gappy.gapobj.GapList'>
>>> lst.numpy()
array([[1, 2, 3],
       [4, 5, 6]])

Warning

When picking names for conversion “domains” try not to overlap with existing global functions in GAP, or at least those that may operate on GAP objects of the type being converted. Otherwise the conversion method will overshadow the GAP method. Usually picking an all lower-case name (the standard naming scheme for Python recommended by PEP 8) will suffice, since most GAP globals use CamelCase naming.

The name should also not overlap a method defined on the class, otherwise the existing method will take precedence.

Note

Realistically this is an inefficient conversion to NumPy, and a more performant implementation should be implemented in C/Cython and include converters for numeric types as well. This just demonstrates the basic principle.

deepcopy()

Return a deepcopy of this GAP object

Note that this is the same thing as calling StructuralCopy but much faster.

Parameters

mut (bool) – Whether or not to return a mutable copy.

Examples

>>> a = gap([[0,1],[2,3]])
>>> b = a.deepcopy(1)
>>> b[0,0] = 5
>>> a
[ [ 0, 1 ], [ 2, 3 ] ]
>>> b
[ [ 5, 1 ], [ 2, 3 ] ]
>>> l = gap([0,1])
>>> l.deepcopy(0).IsMutable()
false
>>> l.deepcopy(1).IsMutable()
true
is_bool()

Return whether the wrapped GAP object is a GAP boolean.

Returns

Return type

bool

Examples

>>> gap(True).is_bool()
True
is_function()

Return whether the wrapped GAP object is a function.

Returns

Return type

bool

Examples

>>> a = gap.eval("NormalSubgroups")
>>> a.is_function()
True
>>> a = gap(2/3)
>>> a.is_function()
False
is_list()

Return whether the wrapped GAP object is a GAP List.

Returns

Return type

bool

Examples

>>> gap.eval('[1, 2,,,, 5]').is_list()
True
>>> gap.eval('3/2').is_list()
False
is_permutation()

Return whether the wrapped GAP object is a GAP permutation.

Returns

Return type

bool

Examples

>>> perm = gap.PermList([1, 5, 2, 3, 4]); perm
(2,5,4,3)
>>> perm.is_permutation()
True
>>> gap('this is a string').is_permutation()
False
is_record()

Return whether the wrapped GAP object is a GAP record.

Returns

Return type

bool

Examples

>>> gap.eval('[1, 2,,,, 5]').is_record()
False
>>> gap.eval('rec(a:=1, b:=3)').is_record()
True
is_string()

Return whether the wrapped GAP object is a GAP string.

Returns

Return type

bool

Examples

>>> gap('this is a string').is_string()
True
parent()

For backwards-compatibility with Sage, returns either the Gap interpreter instance associated with this GapObj, or the result of coercing x to a GapObj.

python()

Convert to an equivalent plain Python type, if one exists.

Examples

>>> lst = gap.eval('["first",,,"last"]')   # a sparse list
>>> lst[0]
"first"
>>> lst[0].python()
'first'
>>> lst[1]
NULL
>>> lst[1].python() is None
True

GAP objects with “obvious” equivalents to Python built-ins have .python() implementations, whereas others may not:

>>> cyc = gap.eval('E(3)')
>>> type(cyc)
<class 'gappy.gapobj.GapCyclotomic'>
>>> cyc.python()
Traceback (most recent call last):
...
NotImplementedError: cannot construct equivalent Python object

However, you may register a custom converter from GapCyclotomic or another GapObj subclass to some Python class by using the GapObj.convert_to decorator with the “python” domain. See its documentation for examples.

class gappy.gapobj.GapPermutation

Derived class of GapObj for GAP permutations.

Note

Permutations in GAP act on the numbers starting with 1.

Examples

>>> perm = gap.eval('(1,5,2)(4,3,8)')
>>> type(perm)
<class 'gappy.gapobj.GapPermutation'>
class gappy.gapobj.GapRational

Derived class of GapObj for GAP rational numbers.

Examples

>>> from fractions import Fraction
>>> r = gap(Fraction(123, 456))
>>> type(r)
<class 'gappy.gapobj.GapRational'>
python()

Convert from a GAP rational to a Python fractions.Fraction.

Examples

>>> x = gap.eval('1 / 2')
>>> x.python()
Fraction(1, 2)
class gappy.gapobj.GapRecord

Derived class of GapObj for GAP records.

Examples

>>> rec = gap.eval('rec(a:=123, b:=456)')
>>> type(rec)
<class 'gappy.gapobj.GapRecord'>
>>> len(rec)
2
>>> rec['a']
123

GapRecords also support dot notation for item lookups in order to mimic GAP syntax:

>>> rec.a
123

Except in the rare case where this would be shadowed by a Python builtin attribute or method of GapRecord, in which case the item getter [] syntax should be used:

>>> rec2 = gap({'names': ['a', 'b'], 'a': 1, 'b': 2})
>>> rec2.names
<built-in method names of gappy.gapobj.GapRecord object at 0x...>
>>> rec2['names']
[ "a", "b" ]
>>> rec2.a
1

We can easily convert a GAP record object into a Python dict:

>>> dict(rec)
{"b": 456, "a": 123}
>>> type(_)
<... 'dict'>

We can also convert a Python dict to a GapRecord:

>>> rec = gap({'a': 123, 'b': 456})
>>> rec
rec( a := 123, b := 456 )

Key checking is performed:

>>> rec['no_such_element']
Traceback (most recent call last):
...
KeyError: 'no_such_element'
names()

Returns the list of names in the record.

Examples

>>> rec = gap.eval('rec(a:=123, b:=456, S3:=SymmetricGroup(3))')
>>> rec.names()
['b', 'a', 'S3']
python()

Convert a GAP record to a Python dict.

Keys are converted to Python strs and values are converted to their Python equivalents, recusively if possible, though any GapObjs that cannot be converted to Python equivalents will remain as-is.

Examples

>>> rec = gap.eval('rec( a:= 1, b := 2, c := 3 )')

You can convert a GapRecord to dict like:

>>> dct1 = dict(rec); dct1
{"b": 2, "a": 1, "c": 3}

which works since GapRecord is an iterable sequence of (key, value) pairs, one of the possible constructor values for dict. However, the keys and values of the dict are still GapStrings and GapIntegers respectively:

>>> type(next(iter(dct1.keys())))
<class 'gappy.gapobj.GapString'>
>>> type(next(iter(dct1.values())))
<class 'gappy.gapobj.GapInteger'>

Whereas GapRecord.python will recursively convert to Python equivalents (by calling .python() on each element) if possible:

>>> dct2 = rec.python(); dct2
{'b': 2, 'a': 1, 'c': 3}
>>> type(next(iter(dct2.keys())))
<class 'str'>
>>> type(next(iter(dct2.values())))
<class 'int'>
class gappy.gapobj.GapRing

Derived class of GapObj for GAP rings (parents of ring elements).

Examples

>>> i = gap.Integers
>>> type(i)
<class 'gappy.gapobj.GapRing'>
class gappy.gapobj.GapString

Derived class of GapObj for GAP strings.

Examples

>>> s = gap('string')
>>> type(s)
<class 'gappy.gapobj.GapString'>
>>> s
"string"
>>> print(s)
string
python()

Convert this GapString to a Python string.

Returns

Return type

str

Examples

>>> s = gap.eval(' "string" '); s
"string"
>>> type(_)
<class 'gappy.gapobj.GapString'>
>>> str(s)
'string'
>>> type(_)
<class 'str'>

gappy.exceptions

exception gappy.exceptions.GAPError

Exceptions raised by the GAP library.

gappy.context_managers

Context Managers for gappy.

This module implements a context manager for global variables. This is useful since the behavior of GAP is sometimes controlled by global variables, which you might want to switch to a different value for a computation. Here is an example how you are suppose to use it from your code. First, let us set a dummy global variable for our example:

>>> gap.set_global('FooBar', 123)

Then, if you want to switch the value momentarily you can write:

>>> with gap.global_context('FooBar', 'test'):
...     print(gap.get_global('FooBar'))
test

Afterward, the global variable reverts to the previous value:

>>> print(gap.get_global('FooBar'))
123

The value is reset even if exceptions occur:

>>> with gap.global_context('FooBar', 'test'):
...     print(gap.get_global('FooBar'))
...     raise ValueError(gap.get_global('FooBar'))
Traceback (most recent call last):
...
ValueError: test
>>> print(gap.get_global('FooBar'))
123
class gappy.context_managers.GlobalVariableContext(gap, variable, value)

Context manager for GAP global variables.

It is recommended that you use the global_context() method and not construct objects of this class manually.

Parameters
  • variable (str) – The GAP variable name.

  • value – Anything that defines or can be converted to a GAP object.

Examples

>>> gap.set_global('FooBar', 1)
>>> with gap.global_context('FooBar', 2):
...     print(gap.get_global('FooBar'))
2
>>> gap.get_global('FooBar')
1