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 firstGap.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 ownGap
instance with different parameters.- Parameters
gap_root (
str
orpathlib.Path
) – Path to the GAP installation (GAP_ROOT) you want to use for the GAP interpreter. This should be the path containing thelib/
andpkg/
directories for the standard GAP libraries. Equivalent to the-l
command-line argument togap
.gaprc (
str
orpathlib.Path
) – A GAP “runtime config” file containing GAP commands to run immediately upon GAP interpreter startup. Equivalent to passing a GAP file togap
on the command-line.workspace (
str
orpathlib.Path
) – An existing GAP workspace to restore upon interpreter startup. Equivalent to the-L
command-line argument togap
.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 aneval
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 togap
(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
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 eitherGapObj
instance or one of the built-in types inGap.supported_builtins
which can be converted to the appropriate GAP object. This frees the converter function from having to directly construct aGapObj
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
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
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
- Return type
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. PassingNone
is equivalent toGap.unset_global
.
- Returns
A context manager that sets/reverts the given global variable.
- Return type
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, orFalse
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. PassingNone
is equivalent toGap.unset_global
.force (bool) – If
True
, sets the value of the global even if it is read-only; otherwise anAttributeError
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
ifseed=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 asGapObj
instances.The value
livekb + deadkb
will roughly equal the total memory allocated for GAP objects (seegap.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 equalsself
in the prime finite field.- Return type
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
-
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 callprint(<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
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 equalsself
in the integer mod ring.- Return type
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 at1
.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 Pythonlist
:>>> 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
GapObj
s 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
tolist
like:>>> lst2 = list(lst); lst2 [1, 2, 3, 4, 5]
which works since
GapList
is an iterable sequence much likelist
. However, the elements of thelist
are stillGapInteger
s:>>> 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 thegap
instance (the parent of all GAP elements) to convert things intoGapObj
. You must not createGapObj
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 existingGapObj
classes (without subclassing them) with new conversion methods. For example, to add a convert fromGapList
s 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
Examples
>>> gap(True).is_bool() True
-
is_function
()¶ Return whether the wrapped GAP object is a function.
- Returns
- Return type
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
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
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
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
Examples
>>> gap('this is a string').is_string() True
-
parent
()¶ For backwards-compatibility with Sage, returns either the
Gap
interpreter instance associated with thisGapObj
, or the result of coercingx
to aGapObj
.
-
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 anotherGapObj
subclass to some Python class by using theGapObj.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
GapRecord
s 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 aGapRecord
:>>> 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
str
s and values are converted to their Python equivalents, recusively if possible, though anyGapObj
s 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
todict
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 fordict
. However, the keys and values of thedict
are stillGapString
s andGapInteger
s 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
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