Repository: sympy/sympy

Issue:
Wrong result for a limit
I tried out a calculus exercise on SymPy and surprisingly it just failed to give the right answer, rather than timed out or throw an exception.
The problem is a bit confusing for human, though. But there must be something wrong that caused this fault.

```
In [2]: x = symbols('x', real = True)
In [3]: expr = (1+1/x)**(x**2)/exp(x)
In [4]: limit(expr, x, oo)
Out[4]: 1
```

The correct answer is `exp(-1/2)`.

Discussion:
sympy-bot: :white_check_mark:

Hi, I am the [SymPy bot](https://github.com/sympy/sympy-bot). I'm here to help you write a release notes entry. Please read the [guide on how to write release notes](https://github.com/sympy/sympy/wiki/Writing-Release-Notes).



* No release notes entry will be added for this pull request.

<details><summary>Click here to see the pull request description that was parsed.</summary>

    <!-- Your title above should be a short description of what
    was changed. Do not include the issue number in the title. -->

    #### References to other Issues or PRs
    <!-- If this pull request fixes an issue, write "Fixes #NNNN" in that exact
    format, e.g. "Fixes #1234" (see
    https://tinyurl.com/auto-closing for more information). Also, please
    write a comment on that issue linking back to this pull request once it is
    open. -->

    fixes 325885

    #### Brief description of what is fixed or changed


    #### Other comments

    This checks for any infinite value for exponent, not only `+oo`

    #### Release Notes

    <!-- Write the release notes for this release below between the BEGIN and END
    statements. The basic format is a bulleted list with the name of the subpackage
    and the release note for this PR. For example:

    * solvers
      * Added a new solver for logarithmic equations.

    * functions
      * Fixed a bug with log of integers. Formerly, `log(-x)` incorrectly gave `-log(x)`.

    * physics.units
      * Corrected a semantical error in the conversion between volt and statvolt which
        reported the volt as being larger than the statvolt.

    or if no release note(s) should be included use:

    NO ENTRY

    See https://github.com/sympy/sympy/wiki/Writing-Release-Notes for more
    information on how to write release notes. The bot will check your release
    notes automatically to see if they are formatted correctly. -->

    <!-- BEGIN RELEASE NOTES -->
    NO ENTRY
    <!-- END RELEASE NOTES -->


</details><p>

smichr: ping @arnabnandikgp , could you check this, please?
oscarbenjamin: > fixes 325885

What issue is this for?

github-actions[bot]: Benchmark results from GitHub Actions

Lower numbers are good, higher numbers are bad. A ratio less than 1
means a speed up and greater than 1 means a slowdown. Green lines
beginning with `+` are slowdowns (the PR is slower then master or
master is slower than the previous release). Red lines beginning
with `-` are speedups.

Significantly changed benchmark results (PR vs master)
```diff

```
Significantly changed benchmark results (master vs previous release)
```diff
| Change   | Before [a00718ba]    | After [7319239e]    |   Ratio | Benchmark (Parameter)                                                |
|----------|----------------------|---------------------|---------|----------------------------------------------------------------------|
| -        | 68.0±0.6ms           | 43.2±0.4ms          |    0.63 | integrate.TimeIntegrationRisch02.time_doit_risch(10)                 |
| +        | 17.5±0.2μs           | 29.6±0.2μs          |    1.69 | integrate.TimeIntegrationRisch03.time_doit(1)                        |
| -        | 5.23±0.04ms          | 2.85±0.03ms         |    0.54 | logic.LogicSuite.time_load_file                                      |
| -        | 71.3±0.6ms           | 28.2±0.3ms          |    0.39 | polys.TimeGCD_GaussInt.time_op(1, 'dense')                           |
| -        | 25.7±0.1ms           | 17.0±0.3ms          |    0.66 | polys.TimeGCD_GaussInt.time_op(1, 'expr')                            |
| -        | 72.3±0.3ms           | 28.4±0.1ms          |    0.39 | polys.TimeGCD_GaussInt.time_op(1, 'sparse')                          |
| -        | 249±0.6ms            | 123±0.4ms           |    0.5  | polys.TimeGCD_GaussInt.time_op(2, 'dense')                           |
| -        | 250±0.9ms            | 124±1ms             |    0.5  | polys.TimeGCD_GaussInt.time_op(2, 'sparse')                          |
| -        | 644±3ms              | 373±3ms             |    0.58 | polys.TimeGCD_GaussInt.time_op(3, 'dense')                           |
| -        | 648±5ms              | 374±3ms             |    0.58 | polys.TimeGCD_GaussInt.time_op(3, 'sparse')                          |
| -        | 487±3μs              | 284±4μs             |    0.58 | polys.TimeGCD_LinearDenseQuadraticGCD.time_op(1, 'dense')            |
| -        | 1.77±0.02ms          | 1.02±0.01ms         |    0.58 | polys.TimeGCD_LinearDenseQuadraticGCD.time_op(2, 'dense')            |
| -        | 5.70±0.03ms          | 3.03±0.03ms         |    0.53 | polys.TimeGCD_LinearDenseQuadraticGCD.time_op(3, 'dense')            |
| -        | 445±3μs              | 230±4μs             |    0.52 | polys.TimeGCD_QuadraticNonMonicGCD.time_op(1, 'dense')               |
| -        | 1.43±0.01ms          | 664±1μs             |    0.47 | polys.TimeGCD_QuadraticNonMonicGCD.time_op(2, 'dense')               |
| -        | 4.75±0.03ms          | 1.61±0.01ms         |    0.34 | polys.TimeGCD_QuadraticNonMonicGCD.time_op(3, 'dense')               |
| -        | 373±2μs              | 204±0.8μs           |    0.55 | polys.TimeGCD_SparseGCDHighDegree.time_op(1, 'dense')                |
| -        | 2.41±0.02ms          | 1.21±0.01ms         |    0.5  | polys.TimeGCD_SparseGCDHighDegree.time_op(3, 'dense')                |
| -        | 9.76±0.05ms          | 4.29±0.02ms         |    0.44 | polys.TimeGCD_SparseGCDHighDegree.time_op(5, 'dense')                |
| -        | 355±2μs              | 165±2μs             |    0.47 | polys.TimeGCD_SparseNonMonicQuadratic.time_op(1, 'dense')            |
| -        | 2.47±0.01ms          | 885±5μs             |    0.36 | polys.TimeGCD_SparseNonMonicQuadratic.time_op(3, 'dense')            |
| -        | 9.54±0.03ms          | 2.62±0.01ms         |    0.27 | polys.TimeGCD_SparseNonMonicQuadratic.time_op(5, 'dense')            |
| -        | 1.02±0.01ms          | 415±3μs             |    0.41 | polys.TimePREM_LinearDenseQuadraticGCD.time_op(3, 'dense')           |
| -        | 1.70±0.01ms          | 515±2μs             |    0.3  | polys.TimePREM_LinearDenseQuadraticGCD.time_op(3, 'sparse')          |
| -        | 5.63±0.04ms          | 1.74±0.01ms         |    0.31 | polys.TimePREM_LinearDenseQuadraticGCD.time_op(5, 'dense')           |
| -        | 8.22±0.03ms          | 1.51±0.01ms         |    0.18 | polys.TimePREM_LinearDenseQuadraticGCD.time_op(5, 'sparse')          |
| -        | 283±0.6μs            | 62.3±0.3μs          |    0.22 | polys.TimePREM_QuadraticNonMonicGCD.time_op(1, 'sparse')             |
| -        | 3.31±0.01ms          | 382±2μs             |    0.12 | polys.TimePREM_QuadraticNonMonicGCD.time_op(3, 'dense')              |
| -        | 3.82±0.01ms          | 283±1μs             |    0.07 | polys.TimePREM_QuadraticNonMonicGCD.time_op(3, 'sparse')             |
| -        | 6.69±0.04ms          | 1.23±0.01ms         |    0.18 | polys.TimePREM_QuadraticNonMonicGCD.time_op(5, 'dense')              |
| -        | 8.41±0.05ms          | 848±10μs            |    0.1  | polys.TimePREM_QuadraticNonMonicGCD.time_op(5, 'sparse')             |
| -        | 5.00±0.03ms          | 3.07±0.01ms         |    0.61 | polys.TimeSUBRESULTANTS_LinearDenseQuadraticGCD.time_op(2, 'sparse') |
| -        | 11.7±0.05ms          | 6.31±0.04ms         |    0.54 | polys.TimeSUBRESULTANTS_LinearDenseQuadraticGCD.time_op(3, 'dense')  |
| -        | 22.0±0.08ms          | 9.32±0.04ms         |    0.42 | polys.TimeSUBRESULTANTS_LinearDenseQuadraticGCD.time_op(3, 'sparse') |
| -        | 5.31±0.02ms          | 878±6μs             |    0.17 | polys.TimeSUBRESULTANTS_QuadraticNonMonicGCD.time_op(1, 'sparse')    |
| -        | 12.6±0.07ms          | 7.17±0.02ms         |    0.57 | polys.TimeSUBRESULTANTS_QuadraticNonMonicGCD.time_op(2, 'sparse')    |
| -        | 97.7±0.4ms           | 25.4±0.2ms          |    0.26 | polys.TimeSUBRESULTANTS_QuadraticNonMonicGCD.time_op(3, 'dense')     |
| -        | 166±1ms              | 56.1±0.2ms          |    0.34 | polys.TimeSUBRESULTANTS_QuadraticNonMonicGCD.time_op(3, 'sparse')    |
| -        | 170±2μs              | 109±0.3μs           |    0.64 | polys.TimeSUBRESULTANTS_SparseGCDHighDegree.time_op(1, 'dense')      |
| -        | 361±2μs              | 214±1μs             |    0.59 | polys.TimeSUBRESULTANTS_SparseGCDHighDegree.time_op(1, 'sparse')     |
| -        | 4.22±0.03ms          | 823±5μs             |    0.2  | polys.TimeSUBRESULTANTS_SparseGCDHighDegree.time_op(3, 'dense')      |
| -        | 5.12±0.01ms          | 383±1μs             |    0.07 | polys.TimeSUBRESULTANTS_SparseGCDHighDegree.time_op(3, 'sparse')     |
| -        | 19.1±0.05ms          | 2.74±0.03ms         |    0.14 | polys.TimeSUBRESULTANTS_SparseGCDHighDegree.time_op(5, 'dense')      |
| -        | 22.1±0.2ms           | 633±2μs             |    0.03 | polys.TimeSUBRESULTANTS_SparseGCDHighDegree.time_op(5, 'sparse')     |
| -        | 479±3μs              | 134±1μs             |    0.28 | polys.TimeSUBRESULTANTS_SparseNonMonicQuadratic.time_op(1, 'sparse') |
| -        | 4.60±0.04ms          | 615±2μs             |    0.13 | polys.TimeSUBRESULTANTS_SparseNonMonicQuadratic.time_op(3, 'dense')  |
| -        | 5.11±0.02ms          | 137±1μs             |    0.03 | polys.TimeSUBRESULTANTS_SparseNonMonicQuadratic.time_op(3, 'sparse') |
| -        | 12.6±0.06ms          | 1.26±0ms            |    0.1  | polys.TimeSUBRESULTANTS_SparseNonMonicQuadratic.time_op(5, 'dense')  |
| -        | 13.5±0.1ms           | 139±1μs             |    0.01 | polys.TimeSUBRESULTANTS_SparseNonMonicQuadratic.time_op(5, 'sparse') |
| -        | 134±0.5μs            | 75.4±0.5μs          |    0.56 | solve.TimeMatrixOperations.time_rref(3, 0)                           |
| -        | 251±2μs              | 89.5±0.8μs          |    0.36 | solve.TimeMatrixOperations.time_rref(4, 0)                           |
| -        | 24.1±0.04ms          | 10.1±0.1ms          |    0.42 | solve.TimeSolveLinSys189x49.time_solve_lin_sys                       |

```
Full benchmark results can be found as artifacts in GitHub Actions
(click on checks at the top of the PR).

Patch:
diff --git a/sympy/series/gruntz.py b/sympy/series/gruntz.py
index 3743f1e7e6..8711074f3f 100644
--- a/sympy/series/gruntz.py
+++ b/sympy/series/gruntz.py
@@ -275,11 +275,10 @@ def mrv(e, x):
         if b1 == 1:
             return SubsSet(), b1
         if e1.has(x):
-            base_lim = limitinf(b1, x)
-            exp_lim = limitinf(e1, x)
-            if base_lim is S.One and exp_lim is S.Infinity:
-                return mrv(exp(e1 * (b1 - 1)), x)
-            return mrv(exp(e1 * log(b1)), x)
+            if limitinf(b1, x) is S.One:
+                if limitinf(e1, x).is_infinite is False:
+                    return mrv(exp(e1*(b1 - 1)), x)
+            return mrv(exp(e1*log(b1)), x)
         else:
             s, expr = mrv(b1, x)
             return s, expr**e1


Test patch:
diff --git a/.github/workflows/runtests.yml b/.github/workflows/runtests.yml
index 0a34b08a13..4482b009ef 100644
--- a/.github/workflows/runtests.yml
+++ b/.github/workflows/runtests.yml
@@ -41,10 +41,11 @@ jobs:
       - name: Test all modules are listed in setup.py
         run: bin/test_setup.py
 
-      - run: pip install slotscheck . 
+      - run: sudo apt install xorg-dev libglu1-mesa libgl1-mesa-dev xvfb libxinerama1 libxcursor1
+      - run: pip install slotscheck pyglet . 
 
       - name: Check for incorrect use of ``__slots__`` using slotscheck
-        run: python -m slotscheck --exclude-modules "(sympy.parsing.autolev._antlr.*|sympy.parsing.latex._antlr.*|sympy.galgebra|sympy.plotting.pygletplot.*)" sympy
+        run: xvfb-run -a -s "-screen 0 1400x900x24 +extension RANDR" -- python -m slotscheck --exclude-modules "(sympy.parsing.autolev._antlr.*|sympy.parsing.latex._antlr.*|sympy.galgebra)" sympy
 
       # -- temporarily disabled -- #
       # These checks were too difficult for new contributors. They will
diff --git a/sympy/series/tests/test_gruntz.py b/sympy/series/tests/test_gruntz.py
index b6d2910f0d..4565c87608 100644
--- a/sympy/series/tests/test_gruntz.py
+++ b/sympy/series/tests/test_gruntz.py
@@ -475,5 +475,8 @@ def test_issue_7096():
     from sympy.functions import sign
     assert gruntz(x**-pi, x, 0, dir='-') == oo*sign((-1)**(-pi))
 
-def test_issue_24210():
-    assert gruntz(exp(x)/((1+1/x)**(x**2)),x,+oo) == sqrt(E)
+def test_issue_24210_25885():
+    eq = exp(x)/(1+1/x)**x**2
+    ans = sqrt(E)
+    assert gruntz(eq, x, oo) == ans
+    assert gruntz(1/eq, x, oo) == 1/ans