There are things that have read attributes that *won't* work here either.  It looks like `is_fits` is also making this assumption.  You might instead want to look at some of the utility functions in `astropy.io.fits.util` such as `isfile`, `isreadable`, and `fileobj_is_binary`.  Some of them may seem trivial, but their behavior is modified when running under Python 3 which has some more complicated assumptions when it comes to file I/O.

Instead you might check if the input is already an `HDUList` or `_TableBaseHDU` and as a last result call `read_fits_table` recursively like:

```
if isinstance(input, HDUList):
    ...
elif isinstance(input, (TableHDU, BinTableHDU, GroupsHDU)):
    ...
else:
    return read_table_fits(fits_open(input), hdu=hdu)
```

`fits_open` already implements all the specific machinery for what types of file objects it can actually read from and should hopefully raise an `IOError` if it turns out the input was no good.  There are just lots of weird cases, especially when you move into Python 3 (which was *supposed* to make this simpler, but it hasn't really...)