@@ -15,6 +15,7 @@ Classes for symbolic functions
1515
1616from ginac cimport *
1717
18+ from sage.rings.integer cimport smallInteger
1819from sage.structure.sage_object cimport SageObject
1920from expression cimport new_Expression_from_GEx, Expression
2021from ring import SR
@@ -809,6 +810,46 @@ cdef class GinacFunction(BuiltinFunction):
809810 BuiltinFunction.__init__ (self , name, nargs, latex_name, conversions,
810811 evalf_params_first = evalf_params_first)
811812
813+ def __call__ (self , *args , **kwds ):
814+ """
815+ Wrapper around ``BuiltinFunction.__call__()`` which converts
816+ Python ``int``s which are returned by Ginac to Sage Integers.
817+
818+ This is needed to fix :trac:`10133`, where Ginac evaluates
819+ ``sin(0)`` to the Python int ``0``::
820+
821+ sage: from sage.symbolic.function import BuiltinFunction
822+ sage: out = BuiltinFunction.__call__(sin, 0)
823+ sage: out, parent(out)
824+ (0, <type 'int'>)
825+
826+ With this wrapper we have::
827+
828+ sage: out = sin(0)
829+ sage: out, parent(out)
830+ (0, Integer Ring)
831+
832+ However, if all inputs are Python types, we do not convert::
833+
834+ sage: out = sin(int(0))
835+ sage: (out, parent(out))
836+ (0, <type 'int'>)
837+ sage: out = arctan2(int(0), float(1))
838+ sage: (out, parent(out))
839+ (0, <type 'int'>)
840+ sage: out = arctan2(int(0), RR(1))
841+ sage: (out, parent(out))
842+ (0, Integer Ring)
843+ """
844+ res = super (GinacFunction, self ).__call__(* args, ** kwds)
845+
846+ # Convert to Integer if the output was of type "int" and any of
847+ # the inputs was a Sage Element
848+ if isinstance (res, int ) and any (isinstance (x, Element) for x in args):
849+ return smallInteger(res)
850+ else :
851+ return res
852+
812853 cdef _is_registered(self ):
813854 # Since this is function is defined in C++, it is already in
814855 # ginac's function registry
0 commit comments