Repository: diofant/diofant

Issue:
Wrong test test_sympyissue_21785()
See https://github.com/sympy/sympy/issues/21785

In fact, there should be something like `exp(I*pi*floor(arg(-1/(x**2 - 1))/(2*pi)))*I`.  For example, consider `x=1+I` (answer `I`) and `x=1-I` (answer `-I`).  The first answer is valid for real symbols too (`x!=1`), by symbols aren't real by default (in SymPy too).

There is a different issue for non-symbolic `x` (note, in SymPy these series are correct):
```
In [6]: sqrt((-a**2 + x**2)/(1 - x**2)).subs({x:1+I, a: 1-a}).series(a, n=1).evalf().expand()
Out[6]: -1.0⋅ⅈ + O(a)

In [7]: sqrt((-a**2 + x**2)/(1 - x**2)).subs({x:1+I, a: 1-a}).expand().series(a, n=1)  # correct
Out[7]: ⅈ + O(a)

In [8]: sqrt((-a**2 + x**2)/(1 - x**2)).subs({x:1-I, a: 1-a}).series(a, n=1).evalf().expand()
Out[8]: 1.0⋅ⅈ + O(a)

In [9]: sqrt((-a**2 + x**2)/(1 - x**2)).subs({x:1-I, a: 1-a}).expand().series(a, n=1)  # correct
Out[9]: -ⅈ + O(a)
```

@jksuom , I think that https://github.com/sympy/sympy/issues/21785 is still valid for the SymPy.


Discussion:

Resolving patch:
diff --git a/diofant/core/power.py b/diofant/core/power.py
--- a/diofant/core/power.py
+++ b/diofant/core/power.py
@@ -695,6 +695,10 @@ def _eval_expand_power_base(self, **hints):
             nc = [Mul(*nc)]
 
         # sift the commutative bases
+        sifted = sift(cargs, lambda x: x.is_extended_real)
+        maybe_real = sifted[True] + sifted[None]
+        other = sifted[False]
+
         def pred(x):
             if x is I:
                 return I
@@ -703,9 +707,10 @@ def pred(x):
                 return True
             if polar is None:
                 return fuzzy_or([x.is_nonnegative, (1/x).is_nonnegative])
-        sifted = sift(cargs, pred)
+
+        sifted = sift(maybe_real, pred)
         nonneg = sifted[True]
-        other = sifted[None]
+        other += sifted[None]
         neg = sifted[False]
         imag = sifted[I]
         if imag:
@@ -1190,9 +1195,13 @@ def _eval_nseries(self, x, n, logx):
             pow_series += Order(t**n, x)
             # branch handling
             if c.is_negative:
+                if t.is_Order:
+                    return self._eval_nseries(x, n + 1, logx)
                 l = floor(arg(t.removeO()*c)/(2*pi)).limit(x, 0)
-                assert l.is_finite
-                factor *= exp(2*pi*I*self.exp*l)
+                if l.is_finite:
+                    factor *= exp(2*pi*I*self.exp*l)
+                else:
+                    raise NotImplementedError
         pow_series = expand_mul(factor*pow_series)
         return powsimp(pow_series, deep=True, combine='exp')
 


Test patch:
diff --git a/diofant/tests/calculus/test_gruntz.py b/diofant/tests/calculus/test_gruntz.py
--- a/diofant/tests/calculus/test_gruntz.py
+++ b/diofant/tests/calculus/test_gruntz.py
@@ -10,11 +10,11 @@
 import pytest
 
 from diofant import (Add, E, Ei, EulerGamma, GoldenRatio, I, Integer, Li,
-                     Limit, Max, Min, Mul, Pow, Rational, Symbol, acosh, acot,
-                     airyai, airybi, atan, binomial, cbrt, cos, cosh, coth,
-                     digamma, erf, exp, factorial, fibonacci, gamma, li, limit,
-                     log, loggamma, oo, pi, root, sign, sin, sinh, sqrt, tan,
-                     tanh, zeta)
+                     Limit, Max, Min, Mul, Pow, Rational, Symbol, acos, acosh,
+                     acot, airyai, airybi, atan, binomial, cbrt, cos, cosh,
+                     coth, digamma, erf, exp, factorial, fibonacci, gamma, li,
+                     limit, log, loggamma, oo, pi, root, sign, sin, sinh, sqrt,
+                     tan, tanh, zeta)
 from diofant.abc import a, n, y
 from diofant.calculus.gruntz import compare, leadterm, mrv, rewrite, signinf
 
@@ -392,6 +392,9 @@ def test_branch_cuts():
     assert limit(atan(2*I - x), x, 0, -1) == I*log(3)/2 - pi/2
     assert limit(atan(2*I - x), x, 0, +1) == I*log(3)/2 + pi/2
 
+    assert limit(acos(2 + I*x), x, 0, -1) == I*log(-sqrt(3) + 2)
+    assert limit(acos(2 + I*x), x, 0, +1) == I*log(+sqrt(3) + 2)
+
 
 def test_aseries_trig():
     assert limit(1/log(atan(x)), x, oo) == -1/(-log(pi) + log(2))
diff --git a/diofant/tests/calculus/test_limits.py b/diofant/tests/calculus/test_limits.py
--- a/diofant/tests/calculus/test_limits.py
+++ b/diofant/tests/calculus/test_limits.py
@@ -6,11 +6,12 @@
 
 from diofant import (E, Float, Function, I, Integral, Lambda, Limit, O,
                      Piecewise, PoleError, Rational, Reals, RootSum, Sum,
-                     Symbol, acos, acosh, acoth, asin, atan, besselk, binomial,
-                     cbrt, ceiling, cos, cosh, cot, diff, digamma, erf, erfc,
-                     erfi, exp, factorial, false, floor, gamma, integrate,
-                     limit, log, nan, oo, pi, polygamma, root, sign, simplify,
-                     sin, sinh, sqrt, subfactorial, symbols, tan, true)
+                     Symbol, acos, acosh, acoth, arg, asin, atan, besselk,
+                     binomial, cbrt, ceiling, cos, cosh, cot, diff, digamma,
+                     erf, erfc, erfi, exp, factorial, false, floor, gamma,
+                     integrate, limit, log, nan, oo, pi, polygamma, root, sign,
+                     simplify, sin, sinh, sqrt, subfactorial, symbols, tan,
+                     true)
 from diofant.abc import a, b, c, k, n, x, y, z
 from diofant.calculus.limits import heuristics
 
@@ -946,7 +947,12 @@ def test_sympyissue_21756():
 
 
 def test_sympyissue_21785():
-    assert sqrt((-a**2 + x**2)/(1 - x**2)).limit(a, 1, 1) == I
+    e = Limit(sqrt((-a**2 + x**2)/(1 - x**2)), a, 1, 1)
+
+    assert e.doit() == exp(I*pi*floor(arg(-1/(x**2 - 1))/(2*pi)))*I
+
+    assert e.subs({x: 1 + I}).doit() == +I
+    assert e.subs({x: 1 - I}).doit() == -I
 
 
 def test_sympyissue_22220():