Repository: astropy/astropy

Issue:
`overwrite=True` ignored in FITS writing for Path filename
### Description

Something is wrong in the FITS table writer when providing the input filename as a `Path` object and overwriting an existing file. Even though the function call clearly has `overwrite=True` the code fails to overwrite. When the filename is instead a `str` then the expected behavior is seen. I also don't see this behavior in `io.ascii`.

### Expected behavior

Existing file is overwritten.

### How to Reproduce


```python
In [11]: %astro
astropy=6.0.dev673+gd57101dbc9

In [12]: t = Table({"a": [1,2], "b": [3,4]})

In [13]: from pathlib import Path

In [14]: t.write(Path("junk.fits"), format="fits", overwrite=True)

In [15]: t.write(Path("junk.fits"), format="fits", overwrite=True)
---------------------------------------------------------------------------
OSError                                   Traceback (most recent call last)
Cell In[15], line 1
----> 1 t.write(Path("junk.fits"), format="fits", overwrite=True)

File ~/git/astropy/astropy/table/connect.py:130, in TableWrite.__call__(self, serialize_method, *args, **kwargs)
    128 instance = self._instance
    129 with serialize_method_as(instance, serialize_method):
--> 130     self.registry.write(instance, *args, **kwargs)

File ~/git/astropy/astropy/io/registry/core.py:382, in UnifiedOutputRegistry.write(self, data, format, *args, **kwargs)
    377     format = self._get_valid_format(
    378         "write", data.__class__, path, fileobj, args, kwargs
    379     )
    381 writer = self.get_writer(format, data.__class__)
--> 382 return writer(data, *args, **kwargs)

File ~/git/astropy/astropy/io/fits/connect.py:448, in write_table_fits(input, output, overwrite, append)
    446     fits_append(output, table_hdu.data, table_hdu.header, verify=False)
    447 else:
--> 448     table_hdu.writeto(output)

File ~/git/astropy/astropy/io/fits/hdu/base.py:1599, in ExtensionHDU.writeto(self, name, output_verify, overwrite, checksum)
   1596 from .image import PrimaryHDU
   1598 hdulist = HDUList([PrimaryHDU(), self])
-> 1599 hdulist.writeto(name, output_verify, overwrite=overwrite, checksum=checksum)

File ~/git/astropy/astropy/io/fits/hdu/hdulist.py:1010, in HDUList.writeto(self, fileobj, output_verify, overwrite, checksum)
   1006 mode = FILE_MODES[fileobj_mode(fileobj)] if isfile(fileobj) else "ostream"
   1008 # This can accept an open file object that's open to write only, or in
   1009 # append/update modes but only if the file doesn't exist.
-> 1010 fileobj = _File(fileobj, mode=mode, overwrite=overwrite)
   1011 hdulist = self.fromfile(fileobj)
   1012 try:

File ~/git/astropy/astropy/io/fits/file.py:217, in _File.__init__(self, fileobj, mode, memmap, overwrite, cache, use_fsspec, fsspec_kwargs)
    215     self._open_fileobj(fileobj, mode, overwrite)
    216 elif isinstance(fileobj, (str, bytes)):
--> 217     self._open_filename(fileobj, mode, overwrite)
    218 else:
    219     self._open_filelike(fileobj, mode, overwrite)

File ~/git/astropy/astropy/io/fits/file.py:615, in _File._open_filename(self, filename, mode, overwrite)
    613 """Open a FITS file from a filename string."""
    614 if mode == "ostream":
--> 615     self._overwrite_existing(overwrite, None, True)
    617 if os.path.exists(self.name):
    618     with open(self.name, "rb") as f:

File ~/git/astropy/astropy/io/fits/file.py:498, in _File._overwrite_existing(self, overwrite, fileobj, closed)
    496         os.remove(self.name)
    497 else:
--> 498     raise OSError(NOT_OVERWRITING_MSG.format(self.name))

OSError: File junk.fits already exists. If you mean to replace it then use the argument "overwrite=True".
.
```


### Versions

macOS-10.16-x86_64-i386-64bit
Python 3.10.10 (main, Mar 21 2023, 13:41:39) [Clang 14.0.6 ]
astropy 6.0.dev673+gd57101dbc9
Numpy 1.24.2
pyerfa 2.0.0.3
Scipy 1.10.1
Matplotlib 3.7.1


Discussion:

Patch:
diff --git a/astropy/io/fits/connect.py b/astropy/io/fits/connect.py
index 8d9db62f6b..ae315c9d06 100644
--- a/astropy/io/fits/connect.py
+++ b/astropy/io/fits/connect.py
@@ -435,7 +435,7 @@ def write_table_fits(input, output, overwrite=False, append=False):
     ----------
     input : Table
         The table to write out.
-    output : str
+    output : str or os.PathLike[str]
         The filename to write the table to.
     overwrite : bool
         Whether to overwrite any existing file without warning.
@@ -448,7 +448,7 @@ def write_table_fits(input, output, overwrite=False, append=False):
     table_hdu = table_to_hdu(input, character_as_bytes=True)
 
     # Check if output file already exists
-    if isinstance(output, str) and os.path.exists(output):
+    if os.path.exists(output):
         if overwrite:
             os.remove(output)
         elif not append:
diff --git a/docs/changes/io.fits/17552.bugfix.rst b/docs/changes/io.fits/17552.bugfix.rst
new file mode 100644
index 0000000000..9e9e91e269
--- /dev/null
+++ b/docs/changes/io.fits/17552.bugfix.rst
@@ -0,0 +1,1 @@
+Fixed ``Table.write(..., format="fits", overwrite=True)`` when filename is provided as ``pathlib.Path``.


Test patch:
diff --git a/astropy/io/fits/tests/test_connect.py b/astropy/io/fits/tests/test_connect.py
index b172877c26..05322fe837 100644
--- a/astropy/io/fits/tests/test_connect.py
+++ b/astropy/io/fits/tests/test_connect.py
@@ -1,5 +1,7 @@
+import contextlib
 import gc
 import warnings
+from pathlib import Path
 
 import numpy as np
 import pytest
@@ -64,6 +66,14 @@ class TestSingleTable:
             dtype=[("a", int), ("b", "U1"), ("c", float)],
         )
 
+    def test_overwrite_with_path(self, tmp_path):
+        filename = "temp.fits"
+        t1 = Table(self.data)
+        with contextlib.chdir(tmp_path):
+            t1.write(filename, format="fits")
+            t1.write(Path(filename), format="fits", overwrite=True)
+        t1.write(Path(tmp_path / filename), format="fits", overwrite=True)
+
     def test_simple(self, tmp_path):
         filename = tmp_path / "test_simple.fts"
         t1 = Table(self.data)