Covtype dataset raises error when fetching

### Describe the bug

When fetching the Covtype dataset
```python
from sklearn.datasets import fetch_covtype
fetch_covtype()
```

I am getting an

```python
error: Error -3 while decompressing data: invalid block type
```

Renaming the folder `$HOME/scikit_learn_data` and fetching the dataset again solves the problem, so the problem must be related to an old cached version of the folder.

### Steps/Code to Reproduce

```python
from sklearn.datasets import fetch_covtype

fetch_covtype()
```

### Expected Results

Dataset should be fetched without errors

### Actual Results

```python-traceback
UnboundLocalError                         Traceback (most recent call last)
File ~/scikit-learn/sklearn/datasets/_covtype.py:172, in fetch_covtype(data_home, download_if_missing, random_state, shuffle, return_X_y, as_frame)
    [171](file:///home/arturoamor/scikit-learn/sklearn/datasets/_covtype.py?line=170)[ try:
--> ]()[172](file:///home/arturoamor/scikit-learn/sklearn/datasets/_covtype.py?line=171)[     X, y
    ]()[173](file:///home/arturoamor/scikit-learn/sklearn/datasets/_covtype.py?line=172)[ except NameError:

UnboundLocalError: local variable 'X' referenced before assignment

During handling of the above exception, another exception occurred:

error                                     Traceback (most recent call last)
/home/arturoamor/scikit-learn/doc/developers/test_datasets.py in <module>
      ]()[94](file:///home/arturoamor/scikit-learn/doc/developers/test_datasets.py?line=93)[ from sklearn.datasets import fetch_covtype
----> ]()[96](file:///home/arturoamor/scikit-learn/doc/developers/test_datasets.py?line=95)[ fetch_covtype()

File ~/scikit-learn/sklearn/datasets/_covtype.py:174, in fetch_covtype(data_home, download_if_missing, random_state, shuffle, return_X_y, as_frame)
    ]()[172](file:///home/arturoamor/scikit-learn/sklearn/datasets/_covtype.py?line=171)[     X, y
    ]()[173](file:///home/arturoamor/scikit-learn/sklearn/datasets/_covtype.py?line=172)[ except NameError:
--> ]()[174](file:///home/arturoamor/scikit-learn/sklearn/datasets/_covtype.py?line=173)[     X = joblib.load(samples_path)
    ]()[175](file:///home/arturoamor/scikit-learn/sklearn/datasets/_covtype.py?line=174)[     y = joblib.load(targets_path)
    ]()[177](file:///home/arturoamor/scikit-learn/sklearn/datasets/_covtype.py?line=176)[ if shuffle:

File ~/miniforge3/envs/dev-scikit-learn/lib/python3.9/site-packages/joblib/numpy_pickle.py:587, in load(filename, mmap_mode)
    ]()[581](file:///home/arturoamor/miniforge3/envs/dev-scikit-learn/lib/python3.9/site-packages/joblib/numpy_pickle.py?line=580)[             if isinstance(fobj, str):
    ]()[582](file:///home/arturoamor/miniforge3/envs/dev-scikit-learn/lib/python3.9/site-packages/joblib/numpy_pickle.py?line=581)[                 # if the returned file object is a string, this means we
    ]()[583](file:///home/arturoamor/miniforge3/envs/dev-scikit-learn/lib/python3.9/site-packages/joblib/numpy_pickle.py?line=582)[                 # try to load a pickle file generated with an version of
    ]()[584](file:///home/arturoamor/miniforge3/envs/dev-scikit-learn/lib/python3.9/site-packages/joblib/numpy_pickle.py?line=583)[                 # Joblib so we load it with joblib compatibility function.
    ]()[585](file:///home/arturoamor/miniforge3/envs/dev-scikit-learn/lib/python3.9/site-packages/joblib/numpy_pickle.py?line=584)[                 return load_compatibility(fobj)
--> ]()[587](file:///home/arturoamor/miniforge3/envs/dev-scikit-learn/lib/python3.9/site-packages/joblib/numpy_pickle.py?line=586)[             obj = _unpickle(fobj, filename, mmap_mode)
    ]()[588](file:///home/arturoamor/miniforge3/envs/dev-scikit-learn/lib/python3.9/site-packages/joblib/numpy_pickle.py?line=587)[ return obj

File ~/miniforge3/envs/dev-scikit-learn/lib/python3.9/site-packages/joblib/numpy_pickle.py:506, in _unpickle(fobj, filename, mmap_mode)
    ]()[504](file:///home/arturoamor/miniforge3/envs/dev-scikit-learn/lib/python3.9/site-packages/joblib/numpy_pickle.py?line=503)[ obj = None
    ]()[505](file:///home/arturoamor/miniforge3/envs/dev-scikit-learn/lib/python3.9/site-packages/joblib/numpy_pickle.py?line=504)[ try:
--> ]()[506](file:///home/arturoamor/miniforge3/envs/dev-scikit-learn/lib/python3.9/site-packages/joblib/numpy_pickle.py?line=505)[     obj = unpickler.load()
    ]()[507](file:///home/arturoamor/miniforge3/envs/dev-scikit-learn/lib/python3.9/site-packages/joblib/numpy_pickle.py?line=506)[     if unpickler.compat_mode:
    ]()[508](file:///home/arturoamor/miniforge3/envs/dev-scikit-learn/lib/python3.9/site-packages/joblib/numpy_pickle.py?line=507)[         warnings.warn("The file '%s' has been generated with a "
    ]()[509](file:///home/arturoamor/miniforge3/envs/dev-scikit-learn/lib/python3.9/site-packages/joblib/numpy_pickle.py?line=508)[                       "joblib version less than 0.10. "
    ]()[510](file:///home/arturoamor/miniforge3/envs/dev-scikit-learn/lib/python3.9/site-packages/joblib/numpy_pickle.py?line=509)[                       "Please regenerate this pickle file."
    ]()[511](file:///home/arturoamor/miniforge3/envs/dev-scikit-learn/lib/python3.9/site-packages/joblib/numpy_pickle.py?line=510)[                       % filename,
    ]()[512](file:///home/arturoamor/miniforge3/envs/dev-scikit-learn/lib/python3.9/site-packages/joblib/numpy_pickle.py?line=511)[                       DeprecationWarning, stacklevel=3)

File ~/miniforge3/envs/dev-scikit-learn/lib/python3.9/pickle.py:1208, in _Unpickler.load(self)
   ]()[1206](file:///home/arturoamor/miniforge3/envs/dev-scikit-learn/lib/python3.9/pickle.py?line=1205)[ try:
   ]()[1207](file:///home/arturoamor/miniforge3/envs/dev-scikit-learn/lib/python3.9/pickle.py?line=1206)[     while True:
-> ]()[1208](file:///home/arturoamor/miniforge3/envs/dev-scikit-learn/lib/python3.9/pickle.py?line=1207)[         key = read(1)
   ]()[1209](file:///home/arturoamor/miniforge3/envs/dev-scikit-learn/lib/python3.9/pickle.py?line=1208)[         if not key:
   ]()[1210](file:///home/arturoamor/miniforge3/envs/dev-scikit-learn/lib/python3.9/pickle.py?line=1209)[             raise EOFError

File ~/miniforge3/envs/dev-scikit-learn/lib/python3.9/pickle.py:298, in _Unframer.read(self, n)
    ]()[296](file:///home/arturoamor/miniforge3/envs/dev-scikit-learn/lib/python3.9/pickle.py?line=295)[     return data
    ]()[297](file:///home/arturoamor/miniforge3/envs/dev-scikit-learn/lib/python3.9/pickle.py?line=296)[ else:
--> ]()[298](file:///home/arturoamor/miniforge3/envs/dev-scikit-learn/lib/python3.9/pickle.py?line=297)[     return self.file_read(n)

File ~/miniforge3/envs/dev-scikit-learn/lib/python3.9/site-packages/joblib/compressor.py:464, in BinaryZlibFile.readinto(self, b)
    ]()[459](file:///home/arturoamor/miniforge3/envs/dev-scikit-learn/lib/python3.9/site-packages/joblib/compressor.py?line=458)[ """Read up to len(b) bytes into b.
    ]()[460](file:///home/arturoamor/miniforge3/envs/dev-scikit-learn/lib/python3.9/site-packages/joblib/compressor.py?line=459)[ 
    ]()[461](file:///home/arturoamor/miniforge3/envs/dev-scikit-learn/lib/python3.9/site-packages/joblib/compressor.py?line=460)[ Returns the number of bytes read (0 for EOF).
    ]()[462](file:///home/arturoamor/miniforge3/envs/dev-scikit-learn/lib/python3.9/site-packages/joblib/compressor.py?line=461)[ """
    ]()[463](file:///home/arturoamor/miniforge3/envs/dev-scikit-learn/lib/python3.9/site-packages/joblib/compressor.py?line=462)[ with self._lock:
--> ]()[464](file:///home/arturoamor/miniforge3/envs/dev-scikit-learn/lib/python3.9/site-packages/joblib/compressor.py?line=463)[     return io.BufferedIOBase.readinto(self, b)

File ~/miniforge3/envs/dev-scikit-learn/lib/python3.9/site-packages/joblib/compressor.py:456, in BinaryZlibFile.read(self, size)
    ]()[454](file:///home/arturoamor/miniforge3/envs/dev-scikit-learn/lib/python3.9/site-packages/joblib/compressor.py?line=453)[     return self._read_all()
    ]()[455](file:///home/arturoamor/miniforge3/envs/dev-scikit-learn/lib/python3.9/site-packages/joblib/compressor.py?line=454)[ else:
--> ]()[456](file:///home/arturoamor/miniforge3/envs/dev-scikit-learn/lib/python3.9/site-packages/joblib/compressor.py?line=455)[     return self._read_block(size)

File ~/miniforge3/envs/dev-scikit-learn/lib/python3.9/site-packages/joblib/compressor.py:429, in BinaryZlibFile._read_block(self, n_bytes, return_data)
    ]()[426](file:///home/arturoamor/miniforge3/envs/dev-scikit-learn/lib/python3.9/site-packages/joblib/compressor.py?line=425)[ self._buffer_offset = 0
    ]()[428](file:///home/arturoamor/miniforge3/envs/dev-scikit-learn/lib/python3.9/site-packages/joblib/compressor.py?line=427)[ blocks = []
--> ]()[429](file:///home/arturoamor/miniforge3/envs/dev-scikit-learn/lib/python3.9/site-packages/joblib/compressor.py?line=428)[ while n_bytes > 0 and self._fill_buffer():
    ]()[430](file:///home/arturoamor/miniforge3/envs/dev-scikit-learn/lib/python3.9/site-packages/joblib/compressor.py?line=429)[     if n_bytes < len(self._buffer):
    ]()[431](file:///home/arturoamor/miniforge3/envs/dev-scikit-learn/lib/python3.9/site-packages/joblib/compressor.py?line=430)[         data = self._buffer[:n_bytes]

File ~/miniforge3/envs/dev-scikit-learn/lib/python3.9/site-packages/joblib/compressor.py:393, in BinaryZlibFile._fill_buffer(self)
    ]()[391](file:///home/arturoamor/miniforge3/envs/dev-scikit-learn/lib/python3.9/site-packages/joblib/compressor.py?line=390)[         return False
    ]()[392](file:///home/arturoamor/miniforge3/envs/dev-scikit-learn/lib/python3.9/site-packages/joblib/compressor.py?line=391)[     else:
--> ]()[393](file:///home/arturoamor/miniforge3/envs/dev-scikit-learn/lib/python3.9/site-packages/joblib/compressor.py?line=392)[         self._buffer = self._decompressor.decompress(rawblock)
    ]()[394](file:///home/arturoamor/miniforge3/envs/dev-scikit-learn/lib/python3.9/site-packages/joblib/compressor.py?line=393)[     self._buffer_offset = 0
    ]()[395](file:///home/arturoamor/miniforge3/envs/dev-scikit-learn/lib/python3.9/site-packages/joblib/compressor.py?line=394)[ return True

error: Error -3 while decompressing data: invalid block type]()
```

### Versions

```shell
System:
    python: 3.9.9 | packaged by conda-forge | (main, Dec 20 2021, 02:40:17)  [GCC 9.4.0]
executable: /home/arturoamor/miniforge3/envs/dev-scikit-learn/bin/python
   machine: Linux-5.14.0-1031-oem-x86_64-with-glibc2.31

Python dependencies:
      sklearn: 1.1.dev0
          pip: 21.3.1
   setuptools: 60.5.0
        numpy: 1.22.1
        scipy: 1.7.3
       Cython: 0.29.26
       pandas: 1.3.5
   matplotlib: 3.5.1
       joblib: 1.1.0
threadpoolctl: 3.0.0

Built with OpenMP: True

threadpoolctl info:
       user_api: blas
   internal_api: openblas
         prefix: libopenblas
       filepath: /home/arturoamor/miniforge3/envs/dev-scikit-learn/lib/python3.9/site-packages/numpy.libs/libopenblas64_p-r0-2f7c42d4.3.18.so
        version: 0.3.18
threading_layer: pthreads
   architecture: SkylakeX
    num_threads: 8

       user_api: blas
   internal_api: openblas
         prefix: libopenblas
       filepath: /home/arturoamor/miniforge3/envs/dev-scikit-learn/lib/python3.9/site-packages/scipy.libs/libopenblasp-r0-8b9e111f.3.17.so
        version: 0.3.17
threading_layer: pthreads
   architecture: SkylakeX
    num_threads: 8

       user_api: openmp
   internal_api: openmp
         prefix: libgomp
       filepath: /home/arturoamor/miniforge3/envs/dev-scikit-learn/lib/libgomp.so.1.0.0
        version: None
    num_threads: 8
```

COMMENT:
By looking at the source code of `fetch_covtype`, it appears that this code is not concurrent safe: it does not use the typical "download and save to a temporary file" followed by "atomic rename to the final filepath".

This can explain that we can get corrupted covtype data, for instance by running the test with pytest-xdist.

Something similar was implemented in #21833 to make `fetch_openml` concurrent-safe.

Labels: Bug, module:datasets