Most of the hooks used by value have the same general format: if the python object has a particular type, then use a particular function to convert it to a corresponding Macaulay2 thing. This function simplifies the process of adding such a hook.
For example, suppose we would like to convert Fraction objects from the Python fractions module to QQ objects. Without adding a hook, value will do nothing with these objects.
i1 : fractions = import "fractions" o1 = <module 'fractions' from '/usr/lib/python3.10/fractions.py'> o1 : PythonObject of class module |
i2 : x = fractions@@"Fraction"(2, 3) o2 = 2/3 o2 : PythonObject of class fractions.Fraction |
i3 : value x o3 = 2/3 o3 : PythonObject of class fractions.Fraction |
So we write a function to do the conversion and then install the hook using addPyToM2Function.
i4 : toQQ = x -> value x@@"numerator" / value x@@"denominator"; |
i5 : addPyToM2Function("Fraction", toQQ, "Fraction -> QQ");
|
i6 : value x
2
o6 = -
3
o6 : QQ
|
i7 : hooks value
o7 = {0 => (value, PythonObject, Strategy => unknown -> PythonObject) }
{1 => (value, PythonObject, Strategy => function -> FunctionClosure)}
{2 => (value, PythonObject, Strategy => dict -> HashTable) }
{3 => (value, PythonObject, Strategy => set -> Set) }
{4 => (value, PythonObject, Strategy => list -> List) }
{5 => (value, PythonObject, Strategy => tuple -> Sequence) }
{6 => (value, PythonObject, Strategy => str -> String) }
{7 => (value, PythonObject, Strategy => complex -> CC) }
{8 => (value, PythonObject, Strategy => float -> RR) }
{9 => (value, PythonObject, Strategy => int -> ZZ) }
{10 => (value, PythonObject, Strategy => bool -> Boolean) }
{11 => (value, PythonObject, Strategy => Fraction -> QQ) }
o7 : NumberedVerticalList
|
The object addPyToM2Function is a method function.