Repository: sympy/sympy

Issue:
Functions don't respond to name
Symbols have a 'name' attribute, but functions don't:

```
>>> import sympy as sy
>>> x = sy.Symbol('x')
>>> x.name
'x'
>>> f = sy.Function('f')
>>> f.name
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: type object 'f' has no attribute 'name'
>>> f = sy.sin
>>> f.name
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: type object 'sin' has no attribute 'name'
```

From reading the source code of the printing system, I discovered that I can get the name of a function using `f.__name__`, but this is rather unexpected from a user point of view, and it would be helpful if either this could be documented, or if functions would respond to `.name` instead.

Discussion:

Patch:
diff --git a/sympy/core/function.py b/sympy/core/function.py
index dbb44e2d5e..f871643f67 100644
--- a/sympy/core/function.py
+++ b/sympy/core/function.py
@@ -843,6 +843,7 @@ def __new__(mcl, name, bases=(AppliedUndef,), __dict__=None, **kwargs):
         __dict__.update({'_extra_kwargs': kwargs})
         __dict__['__module__'] = None # For pickling
         ret = super(UndefinedFunction, mcl).__new__(mcl, name, bases, __dict__)
+        ret.name = name
         return ret
 
     def __instancecheck__(cls, instance):


Test patch:
diff --git a/sympy/core/tests/test_function.py b/sympy/core/tests/test_function.py
index b43bb4eae6..130e19b146 100644
--- a/sympy/core/tests/test_function.py
+++ b/sympy/core/tests/test_function.py
@@ -1220,3 +1220,7 @@ def test_Subs_Derivative():
     ans = 3*x**2*exp(1/x)*exp(x**3) - exp(1/x)*exp(x**3)/x**2
     assert all(subs(i).doit().expand() == ans for i in eqs)
     assert all(subs(i.doit()).doit().expand() == ans for i in eqs)
+
+def test_issue_15360():
+    f = Function('f')
+    assert f.name == 'f'