Step 07 tool use
So the commit changed `is_fits` in `astropy/io/fits/connect.py` from:
```python
def is_fits(origin, filepath, fileobj, *args, **kwargs):
if fileobj is not None:
pos = fileobj.tell()
sig = fileobj.read(30)
fileobj.seek(pos)
return sig == FITS_SIGNATURE
elif filepath is not None:
if filepath.lower().endswith(
(".fits", ".fits.gz", ".fit", ".fit.gz", ".fts", ".fts.gz")
):
return True
else:
return False
return isinstance(args[0], (HDUList, TableHDU, BinTableHDU, GroupsHDU))
```
to:
```python
def is_fits(origin, filepath, fileobj, *args, **kwargs):
if fileobj is not None:
pos = fileobj.tell()
sig = fileobj.read(30)
fileobj.seek(pos)
return sig == FITS_SIGNATURE
elif filepath is not None:
if filepath.lower().endswith(
(".fits", ".fits.gz", ".fit", ".fit.gz", ".fts", ".fts.gz")
):
return True
return isinstance(args[0], (HDUList, TableHDU, BinTableHDU, GroupsHDU))
```
The original code had `else: return False` when the filepath doesn't match a FITS extension. The refactored code removed that `else: return False` branch, so now it falls through to `return isinstance(args[0], ...)`. But when `filepath` is a string that doesn't match FITS extensions and `args` is empty, this causes the IndexError.
The fix should be to check if `args` is non-empty before accessing `args[0]`, or simply add back the `else: return False` but using the SIM103-compatible style.
Wait, the SIM103 style would be something like:
```python
return isinstance(args[0], (HDUList, TableHDU, BinTableHDU, GroupsHDU))
```
But the issue is that `args` could be empty. The proper fix should be:
```python
def is_fits(origin, filepath, fileobj, *args, **kwargs):
if fileobj is not None:
pos = fileobj.tell()
sig = fileobj.read(30)
fileobj.seek(pos)
return sig == FITS_SIGNATURE
elif filepath is not None:
if filepath.lower().endswith(
(".fits", ".fits.gz", ".fit", ".fit.gz", ".fts", ".fts.gz")
):
return True
return args and isinstance(args[0], (HDUList, TableHDU, BinTableHDU, GroupsHDU))
```
Or more explicitly:
```python
if args:
return isinstance(args[0], (HDUList, TableHDU, BinTableHDU, GroupsHDU))
return False
```
Wait, let me think about the logic more carefully:
- If `fileobj is not None`: check FITS signature
- Else if `filepath is not None`: check if extension matches FITS extensions
- Else (both None): check if args[0] is an HDU object
The problem is that when `filepath` is not None but doesn't match FITS extensions, it falls through to the `args[0]` check. The original code had an explicit `else: return False`.
The simplest fix that preserves the SIM103 style is:
```python
def is_fits(origin, filepath, fileobj, *args, **kwargs):
if fileobj is not None:
pos = fileobj.tell()
sig = fileobj.read(30)
fileobj.seek(pos)
return sig == FITS_SIGNATURE
elif filepath is not None:
return filepath.lower().endswith(
(".fits", ".fits.gz", ".fit", ".fit.gz", ".fts", ".fts.gz")
)
return isinstance(args[0], (HDUList, TableHDU, BinTableHDU, GroupsHDU))
```
This way:
- If `filepath` is not None, return the result of the extension check (True/False) - no fallthrough.
- If `filepath` is None and `fileobj` is None, then check `args[0]`.
But wait, there's still the case where both `filepath` and `fileobj` are None and `args` is empty. That would still cause an IndexError. However, looking at the original code, this case was never handled either - it would also crash. But the reported issue specifically comes from the path where `filepath` is a non-FITS string and args is empty.
Let me just fix both cases:
edit_file{ path: "astropy/io/fits/connect.py", old_string: " if fileobj is not None:\n pos = fileobj.tell()\n sig = fileobj.read(30)\n fileobj.seek(pos)\n return sig == FITS_SIGNATURE\n elif …", new_string: " if fileobj is not None:\n pos = fileobj.tell()\n sig = fileobj.read(30)\n fileobj.seek(pos)\n return sig == FITS_SIGNATURE\n elif …" }
tool result · edit_file
File astropy/io/fits/connect.py edited successfully.