Repository: sympy/sympy

Issue:
Deprecate source
We ought to deprecate the `source` function. It is just a small wrapper around `inspect.getsource`, and for most users, using `??` in IPython/Jupyter is preferable. 

If someone wants to fix this issue, you need to add the SymPyDeprecationWarning to the `source` function, referencing this issue. See https://github.com/sympy/sympy/wiki/Deprecating-policy

Discussion:
sympy-bot: :x:

Hi, I am the [SymPy bot](https://github.com/sympy/sympy-bot) (v125). I'm here to make sure this pull request has a release notes entry. Please read the [guide on how to write release notes](https://github.com/sympy/sympy/wiki/Writing-Release-Notes). <details><summary>Click here to see the pull request description that was parsed.</summary>

    Deprecated source function as in #14908 
    Added decorator to source function with necessary flags and added test for deprecated behaviour as mentioned in https://github.com/sympy/sympy/wiki/Deprecating-policy.

</details><p>

There was an issue with the release notes.

The `<!-- BEGIN RELEASE NOTES -->` block was not found

Note: This comment will be updated with the latest check if you edit the pull request. You need to reload the page to see it.


yatna: @asmeurer Done the changes


Patch:
diff --git a/sympy/solvers/solveset.py b/sympy/solvers/solveset.py
index c0a243b3d9..5ac6781a0f 100644
--- a/sympy/solvers/solveset.py
+++ b/sympy/solvers/solveset.py
@@ -246,15 +246,10 @@ def _invert_real(f, g_ys, symbol):
                 s, b = integer_log(rhs, base)
                 if b:
                     return _invert_real(expo, FiniteSet(s), symbol)
-                else:
-                    return _invert_real(expo, S.EmptySet, symbol)
-            elif base.is_zero:
-                one = Eq(rhs, 1)
-                if one == S.true:
-                    # special case: 0**x - 1
-                    return _invert_real(expo, FiniteSet(0), symbol)
-                elif one == S.false:
-                    return _invert_real(expo, S.EmptySet, symbol)
+            elif rhs is S.One:
+                # special case: 0**x - 1
+                return (expo, FiniteSet(0))
+            return (expo, S.EmptySet)
 
 
     if isinstance(f, TrigonometricFunction):
@@ -1128,8 +1123,8 @@ def _solve_exponential(lhs, rhs, symbol, domain):
             Ne(a_base, 0),
             Ne(b_base, 0))
 
-    L, R = map(lambda i: expand_log(log(i), force=True), (a, -b))
-    solutions = _solveset(L - R, symbol, domain)
+    log_type_equation = expand_log(log(a), force=True) - expand_log(log(-b), force=True)
+    solutions = _solveset(log_type_equation, symbol, domain)
 
     return ConditionSet(symbol, conditions, solutions)
 
diff --git a/sympy/stats/joint_rv.py b/sympy/stats/joint_rv.py
index 8d31e7a028..b6884cee44 100644
--- a/sympy/stats/joint_rv.py
+++ b/sympy/stats/joint_rv.py
@@ -23,7 +23,6 @@
     SingleContinuousDistribution, SingleContinuousPSpace)
 from sympy.stats.drv import (DiscreteDistribution,
     SingleDiscreteDistribution, SingleDiscretePSpace)
-from sympy.core.compatibility import string_types
 from sympy.matrices import ImmutableMatrix
 from sympy.core.containers import Tuple
 from sympy.utilities.misc import filldedent
@@ -35,14 +34,11 @@ class JointPSpace(ProductPSpace):
     each component and a distribution.
     """
     def __new__(cls, sym, dist):
+        sym = sympify(sym)
         if isinstance(dist, SingleContinuousDistribution):
             return SingleContinuousPSpace(sym, dist)
         if isinstance(dist, SingleDiscreteDistribution):
             return SingleDiscretePSpace(sym, dist)
-        if isinstance(sym, string_types):
-            sym = Symbol(sym)
-        if not isinstance(sym, Symbol):
-            raise TypeError("s should have been string or Symbol")
         return Basic.__new__(cls, sym, dist)
 
     @property
diff --git a/sympy/stats/joint_rv_types.py b/sympy/stats/joint_rv_types.py
index 490a4cc729..d1e1b7fd18 100644
--- a/sympy/stats/joint_rv_types.py
+++ b/sympy/stats/joint_rv_types.py
@@ -13,6 +13,7 @@
 # ]
 
 def multivariate_rv(cls, sym, *args):
+    sym = sympify(sym)
     args = list(map(sympify, args))
     dist = cls(*args)
     args = dist.args
diff --git a/sympy/utilities/source.py b/sympy/utilities/source.py
index e3934acb62..54aaca948c 100644
--- a/sympy/utilities/source.py
+++ b/sympy/utilities/source.py
@@ -3,10 +3,11 @@
 """
 
 from __future__ import print_function, division
+from sympy.core.decorators import deprecated
 
 import inspect
 
-
+@deprecated(useinstead="?? in IPython/Jupyter or inspect.getsource", issue=14905, deprecated_since_version="1.3")
 def source(object):
     """
     Prints the source code of a given object.


Test patch:
diff --git a/sympy/solvers/tests/test_solveset.py b/sympy/solvers/tests/test_solveset.py
index 3785645add..2b37104a79 100644
--- a/sympy/solvers/tests/test_solveset.py
+++ b/sympy/solvers/tests/test_solveset.py
@@ -962,9 +962,6 @@ def test_conditionset():
     assert solveset(Eq(sin(Abs(x)), x), x, domain=S.Reals
         ) == ConditionSet(x, Eq(-x + sin(Abs(x)), 0), S.Reals)
 
-    assert solveset(y**x-z, x, S.Reals) == \
-        ConditionSet(x, Eq(y**x - z, 0), S.Reals)
-
 
 @XFAIL
 def test_conditionset_equality():
@@ -1960,9 +1957,7 @@ def test_is_logarithmic():
 
 
 def test_solve_logarithm():
-    y = Symbol('y')
     assert _solve_logarithm(log(x**y) - y*log(x), 0, x, S.Reals) == S.Reals
-    y = Symbol('y', positive=True)
     assert _solve_logarithm(log(x)*log(y), 0, x, S.Reals) == FiniteSet(1)
 
 # end of logarithmic tests
diff --git a/sympy/stats/tests/test_joint_rv.py b/sympy/stats/tests/test_joint_rv.py
index c2216dc732..0af7b30b4f 100644
--- a/sympy/stats/tests/test_joint_rv.py
+++ b/sympy/stats/tests/test_joint_rv.py
@@ -18,8 +18,8 @@ def test_Normal():
     assert density(m)(x, y) == density(p)(x, y)
     assert marginal_distribution(n, 0, 1)(1, 2) == 1/(2*pi)
     assert integrate(density(m)(x, y), (x, -oo, oo), (y, -oo, oo)).evalf() == 1
-    N = Normal('N', [1, 2], [[x, 0], [0, y]])
-    assert density(N)(0, 0) == exp(-2/y - 1/(2*x))/(2*pi*sqrt(x*y))
+    N1 = Normal('N1', [1, 2], [[x, 0], [0, y]])
+    assert density(N1)(0, 0) == exp(-2/y - 1/(2*x))/(2*pi*sqrt(x*y))
 
     raises (ValueError, lambda: Normal('M', [1, 2], [[1, 1], [1, -1]]))
 
diff --git a/sympy/utilities/tests/test_source.py b/sympy/utilities/tests/test_source.py
index 468185bc57..cb91f9388b 100644
--- a/sympy/utilities/tests/test_source.py
+++ b/sympy/utilities/tests/test_source.py
@@ -1,5 +1,11 @@
-from sympy.utilities.source import get_mod_func, get_class
+from sympy.utilities.source import get_mod_func, get_class, source
+from sympy.utilities.pytest import raises
+from sympy import point
+from sympy.utilities.exceptions import SymPyDeprecationWarning
 
+def test_source():
+    with raises(SymPyDeprecationWarning):
+        source(point)
 
 def test_get_mod_func():
     assert get_mod_func(