GitHub issue #3596: Loss of cast `Image` feature on certain dataset method
State: closed | Created: 2022-01-18T20:44:01Z

## Describe the bug

When an a column is cast to an `Image` feature, the cast type appears to be lost during certain operations. I first noticed this when using the `push_to_hub` method on a dataset that contained urls pointing to images which had been cast to an `image`. This also happens when using select on a dataset which has had a column cast to an `Image`.

I suspect this might be related to https://github.com/huggingface/datasets/pull/3556 but I don't believe that pull request fixes this issue.  

## Steps to reproduce the bug

An example of casting a url to an image followed by using the `select` method:

```python
from datasets import Dataset
from datasets import features
url = "https://cf.ltkcdn.net/cats/images/std-lg/246866-1200x816-grey-white-kitten.webp"
data_dict = {"url": [url]*2}
dataset = Dataset.from_dict(data_dict)
dataset =  dataset.cast_column('url',features.Image())
sample = dataset.select([1])
```

[example notebook](https://gist.github.com/davanstrien/06e53f4383c28ae77ce1b30d0eaf0d70#file-potential_casting_bug-ipynb)

## Expected results
The cast value is maintained when further methods are applied to the dataset. 

## Actual results
```python
---------------------------------------------------------------------------

ValueError                                Traceback (most recent call last)

<ipython-input-12-47f393bc2d0d> in <module>()
----> 1 sample = dataset.select([1])

4 frames

/usr/local/lib/python3.7/dist-packages/datasets/arrow_dataset.py in wrapper(*args, **kwargs)
    487         }
    488         # apply actual function
--> 489         out: Union["Dataset", "DatasetDict"] = func(self, *args, **kwargs)
    490         datasets: List["Dataset"] = list(out.values()) if isinstance(out, dict) else [out]
    491         # re-apply format to the output

/usr/local/lib/python3.7/dist-packages/datasets/fingerprint.py in wrapper(*args, **kwargs)
    409             # Call actual function
    410 
--> 411             out = func(self, *args, **kwargs)
    412 
    413             # Update fingerprint of in-place transforms + update in-place history of transforms

/usr/local/lib/python3.7/dist-packages/datasets/arrow_dataset.py in select(self, indices, keep_in_memory, indices_cache_file_name, writer_batch_size, new_fingerprint)
   2772             )
   2773         else:
-> 2774             return self._new_dataset_with_indices(indices_buffer=buf_writer.getvalue(), fingerprint=new_fingerprint)
   2775 
   2776     @transmit_format

/usr/local/lib/python3.7/dist-packages/datasets/arrow_dataset.py in _new_dataset_with_indices(self, indices_cache_file_name, indices_buffer, fingerprint)
   2688             split=self.split,
   2689             indices_table=indices_table,
-> 2690             fingerprint=fingerprint,
   2691         )
   2692 

/usr/local/lib/python3.7/dist-packages/datasets/arrow_dataset.py in __init__(self, arrow_table, info, split, indices_table, fingerprint)
    664         if self.info.features.type != inferred_features.type:
    665             raise ValueError(
--> 666                 f"External features info don't match the dataset:\nGot\n{self.info.features}\nwith type\n{self.info.features.type}\n\nbut expected something like\n{inferred_features}\nwith type\n{inferred_features.type}"
    667             )
    668 

ValueError: External features info don't match the dataset:
Got
{'url': Image(id=None)}
with type
struct<url: extension<arrow.py_extension_type<ImageExtensionType>>>

but expected something like
{'url': Value(dtype='string', id=None)}
with type
struct<url: string>
```

## Environment info
<!-- You can run the command `datasets-cli env` and copy-and-paste its output below. -->
- `datasets` version: 1.17.1.dev0
- Platform: Linux-5.4.144+-x86_64-with-Ubuntu-18.04-bionic
- Python version: 3.7.12
- PyArrow version: 3.0.0