Repository: astropy/astropy (Python)

Issue:
PR #17263 created a possible regression with using a pandas Series to initialize an Angle.
### Description

For 6.1.4 and previous this would work:
```
from astropy.coordinates import Angle
from astropy import units
import pandas as pd


df = pd.DataFrame({"angle": ["10 0 0", "12 0 0"]})

angle = Angle(df["angle"], unit=units.hourangle)
```
But with 6.1.5 (presumably due to #17263) this now raises `TypeError: The value must be a valid Python or Numpy numeric type.`

### Expected behavior

We should get an angle that looks like `<Angle [10., 12.] hourangle>`

### How to Reproduce

Conda forge pandas, python 3.11, astropy 6.1.5 (this works with 6.1.4 and previous):

```python
from astropy.coordinates import Angle
from astropy import units
import pandas as pd


df = pd.DataFrame({"angle": ["10 0 0", "12 0 0"]})

angle = Angle(df["angle"], unit=units.hourangle)
```


### Versions

```python
import astropy
try:
    astropy.system_info()
except AttributeError:
    import platform; print(platform.platform())
    import sys; print("Python", sys.version)
    import astropy; print("astropy", astropy.__version__)
    import numpy; print("Numpy", numpy.__version__)
    import erfa; print("pyerfa", erfa.__version__)
    try:
        import scipy
        print("Scipy", scipy.__version__)
    except ImportError:
        print("Scipy not installed")
    try:
        import matplotlib
        print("Matplotlib", matplotlib.__version__)
    except ImportError:
        print("Matplotlib not installed")
```
```
Linux-3.10.0-1160.119.1.el7.x86_64-x86_64-with-glibc2.17
Python 3.11.10 | packaged by conda-forge | (main, Oct 16 2024, 01:27:36) [GCC 13.3.0]
astropy 6.1.5
Numpy 2.1.3
pyerfa 2.0.1.4
Scipy not installed
Matplotlib not installed
```



Discussion:
Workaround locally is just to wrap the call with `np.asarray()` but I thought that was supposed to happen with the new code and for some reason astropy isn't doing it properly.
Ah it seems that when you pass in the numpy array you get the magic call to:
```
                if angle.dtype.kind in "SUVO":
                    angle = [cls(x, unit, copy=COPY_IF_NEEDED) for x in angle]
```
But not when it is converted.  Does this need to be added after `angle = np.asarray(angle)`?
Thanks a lot for reporting this regression.
The logic in `Angle.__new__` is brittle, but I think I have a fix at https://github.com/astropy/astropy/pull/17358



Patch:
diff --git a/astropy/coordinates/angles/core.py b/astropy/coordinates/angles/core.py
index 10e40e76af58..b91543a405db 100644
--- a/astropy/coordinates/angles/core.py
+++ b/astropy/coordinates/angles/core.py
@@ -184,7 +184,9 @@ def __new__(cls, angle, unit=None, dtype=np.inexact, copy=True, **kwargs):
                 if angle.dtype.kind in "SUVO":
                     angle = [cls(x, unit, copy=COPY_IF_NEEDED) for x in angle]
 
-            elif hasattr(angle, "__array__"):
+            elif hasattr(angle, "__array__") and (
+                not hasattr(angle, "dtype") or angle.dtype.kind not in "SUVO"
+            ):
                 angle = np.asarray(angle)
 
             elif isiterable(angle):
diff --git a/docs/changes/coordinates/17358.bugfix.rst b/docs/changes/coordinates/17358.bugfix.rst
new file mode 100644
index 000000000000..6d6076372b0b
--- /dev/null
+++ b/docs/changes/coordinates/17358.bugfix.rst
@@ -0,0 +1,1 @@
+Fixed instantiating ``Angle`` from a ``pandas`` ``Series`` object.


Test patch:
diff --git a/astropy/coordinates/tests/test_arrays.py b/astropy/coordinates/tests/test_arrays.py
index 102b0a4f4129..bbb0570c54fa 100644
--- a/astropy/coordinates/tests/test_arrays.py
+++ b/astropy/coordinates/tests/test_arrays.py
@@ -67,6 +67,17 @@ def test_angle_from_pyarrow():
     npt.assert_array_equal(angle.value, input_data)
 
 
+def test_angle_from_pandas():
+    # see https://github.com/astropy/astropy/issues/17357
+    pd = pytest.importorskip("pandas")
+
+    input_data = ["10 0 0", "12 0 0"]
+    df = pd.DataFrame({"angle": input_data})
+    angle = Angle(df["angle"], unit=u.hourangle)
+    expected = Angle(input_data, u.hourangle)
+    npt.assert_array_equal(angle.value, expected.value)
+
+
 def test_dms():
     a1 = Angle([0, 45.5, -45.5], unit=u.degree)
     d, m, s = a1.dms