Sympy results are int, not Integer
m-f-h opened this issue · comments
TL;DR: Since sympy.factor(1)
returns sympy.Integer(1)
, it's inconsistent that sympy.divisors(1)
(and even sympy.divisors(sympy.Integer(1))
) does not return [sympy.Integer(1)]
, but [int(1)]
.
I noticed something potentially confusing that should at least be better documented, if not changed:
I was programming a function involving something along the lines of sum(divisor_sigma(n/d)) for d in divisors(n)
. Instead of a list of a few integers, the result was horribly long and looked like:
[..., divisor_sigma(1.0) + divisor_sigma(3.0) - 3, divisor_sigma(2.0) + divisor_sigma(4.0) - 4, ...]
Obviously, because I should have used integer division //
instead of /
. But on a second thought, users should have the right to expect that results of sympy
functions should be sympy
objects, unless told otherwise. If the result of the divisors()
function was a list of elements of type sympy.Integer
, then the result would have been as expected.
Now I understand well that it could be a big performance hit, in some situations, to always return unconditionally (and consistently) sympy.Integer
s instead of int
s.
So, IMO, the best would be to provide an option to keep the current behaviour if desired (e.g., for performance reasons -- I guess there isn't any other reason?), or (which IMO should be the default -- maybe after some depreciation period), to return sympy
objects as result.
If that isn't feasable / desired, then the documentation of the functions that don't return sympy
objects should clearly say so (in the documentation of every instance), because IMO it's an inconsistency: For example, sympy.factor(1)
returns sympy.Integer(1)
, so "why" doesn't sympy.divisors(1)
(and even sympy.divisors(sympy.Integer(1))
) return [sympy.Integer(1)]
, but [int(1)]
? Looking at the documentation (help()
) of the two functions, nothing lets guess that it would be that way. [Yes, I know that factorint
also returns a dict
of int
. And I understand that the result of factor()
is (in general) a polynomial, even if it may happen to be just an integer. But again, isn't it inconsistent that sympy
functions don't return sympy
objects in general, unless otherwise mentioned?]
Things could be better documented but some functions are intended to operate with plain Python types rather than symbolic expressions. This is true of most ntheory functions and I don't think they should be changed because they are useful separately from all of sympy's symbolics. Potentially it would have made sense to have separate functions in different modules that handle this differently e.g. like having a divisor_sigma
symbolic function in sympy.functions
and a corresponding function for plain integers in sympy.ntheory
. The flat import design of sympy where everything is imported at top-level makes this difficult though.