Repository: explodinggradients/ragas
Issue: Error importing module
Root cause: External Dependency Breakage

[ v ] I have checked the [documentation](https://docs.ragas.io/) and related resources and couldn't resolve my bug.

**Describe the bug**
Error `module 'pyarrow' has no attribute 'PyExtensionType'` directly appeared after installing and importing ragas

Ragas version: 0.3.1
Python version: 3.11

**Code to Reproduce**
In notebook:

!pip install ragas
from ragas import evaluate

**Error trace**
```
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
Cell In[7], line 12
      1 # from ragas.metrics import (
      2 #     ContextRelevance,
      3 #     ResponseGroundedness, 
   (...)
     10 #     EvaluationDataset
     11 # )
---> 12 from ragas import evaluate
     13 # from ragas.llms import LangchainLLMWrapper
     14 # import ragas

File [/opt/conda/lib/python3.11/site-packages/ragas/__init__.py:2](https://lt7bqomdzjry51g.studio.us-west-2.sagemaker.aws/opt/conda/lib/python3.11/site-packages/ragas/__init__.py#line=1)
      1 from ragas.cache import CacheInterface, DiskCacheBackend, cacher
----> 2 from ragas.dataset_schema import EvaluationDataset, MultiTurnSample, SingleTurnSample
      3 from ragas.evaluation import evaluate
      4 from ragas.run_config import RunConfig

File [/opt/conda/lib/python3.11/site-packages/ragas/dataset_schema.py:13](https://lt7bqomdzjry51g.studio.us-west-2.sagemaker.aws/opt/conda/lib/python3.11/site-packages/ragas/dataset_schema.py#line=12)
     11 import numpy as np
     12 import requests
---> 13 from datasets import Dataset as HFDataset
     14 from pydantic import BaseModel, field_validator
     16 from ragas._version import __version__

File [/opt/conda/lib/python3.11/site-packages/datasets/__init__.py:37](https://lt7bqomdzjry51g.studio.us-west-2.sagemaker.aws/opt/conda/lib/python3.11/site-packages/datasets/__init__.py#line=36)
     34 del pyarrow
     35 del version
---> 37 from .arrow_dataset import Dataset, concatenate_datasets
     38 from .arrow_reader import ReadInstruction
     39 from .builder import ArrowBasedBuilder, BeamBasedBuilder, BuilderConfig, DatasetBuilder, GeneratorBasedBuilder

File [/opt/conda/lib/python3.11/site-packages/datasets/arrow_dataset.py:61](https://lt7bqomdzjry51g.studio.us-west-2.sagemaker.aws/opt/conda/lib/python3.11/site-packages/datasets/arrow_dataset.py#line=60)
     59 from . import config
     60 from .arrow_reader import ArrowReader
---> 61 from .arrow_writer import ArrowWriter, OptimizedTypedSequence
     62 from .features import Audio, ClassLabel, Features, Image, Sequence, Value
     63 from .features.features import FeatureType, _ArrayXD, decode_nested_example, pandas_types_mapper, require_decoding

File [/opt/conda/lib/python3.11/site-packages/datasets/arrow_writer.py:26](https://lt7bqomdzjry51g.studio.us-west-2.sagemaker.aws/opt/conda/lib/python3.11/site-packages/datasets/arrow_writer.py#line=25)
     23 import pyarrow as pa
     25 from . import config
---> 26 from .features import Features, Image, Value
     27 from .features.features import (
     28     FeatureType,
     29     _ArrayXDExtensionType,
   (...)
     34     numpy_to_pyarrow_listarray,
     35 )
     36 from .info import DatasetInfo

File [/opt/conda/lib/python3.11/site-packages/datasets/features/__init__.py:18](https://lt7bqomdzjry51g.studio.us-west-2.sagemaker.aws/opt/conda/lib/python3.11/site-packages/datasets/features/__init__.py#line=17)
      3 __all__ = [
      4     "Audio",
      5     "Array2D",
   (...)
     15     "TranslationVariableLanguages",
     16 ]
     17 from .audio import Audio
---> 18 from .features import Array2D, Array3D, Array4D, Array5D, ClassLabel, Features, Sequence, Value
     19 from .image import Image
     20 from .translation import Translation, TranslationVariableLanguages

File [/opt/conda/lib/python3.11/site-packages/datasets/features/features.py:513](https://lt7bqomdzjry51g.studio.us-west-2.sagemaker.aws/opt/conda/lib/python3.11/site-packages/datasets/features/features.py#line=512)
    509     # Automatically constructed
    510     _type: str = field(default="Array5D", init=False, repr=False)
--> 513 class _ArrayXDExtensionType(pa.PyExtensionType):
    514     ndims: Optional[int] = None
    516     def __init__(self, shape: tuple, dtype: str):

AttributeError: module 'pyarrow' has no attribute 'PyExtensionType'
```

**Expected behavior**
Module imported successfully


**Additional context**
Add any other context about the problem here.

<!-- PS: bugs suck but is also part of the process. We sincerely apologies for breaking your flow because of it, but don't worry, we got your back ❤️. We will get this fixed as fast as we can and thanks for helping us out by reporting it 🙏. -->


I had a look and believe I found the issue:

The issue is that PyArrow version 21.0.0 doesn’t have PyExtensionType. This was changed in newer versions of PyArrow. The
PyExtensionType class was renamed to ExtensionType in PyArrow 13.0.0 and later versions.

This seems to come from a core dependency of ragas - the datasets library, not directly from ragas itself:

Making the following changes to the following lib files should temporarily resolve the issue.

I will submit a PR to the dataets library in the meantime.

env_name/lib/python3.10/site-packages/datasets/features/features.py:

```
> 521            self.shape = tuple(shape)
       522            self.value_type = dtype
       523            self.storage_dtype = self._generate_dtype(self.value_type)
       524 -          pa.PyExtensionType.__init__(self, self.storage_dtype)
       524 +          pa.ExtensionType.__init__(self, self.storage_dtype)
       525
       526        def __reduce__(self):
       527            return self.__class__, (
```

Updated venv_name/lib/python3.10/site-packages/datasets/features/features.py:
```      
 510        _type: str = field(default=“Array5D”, init=False, repr=False)
       511
       512
       513 -  class _ArrayXDExtensionType(pa.PyExtensionType):
       513 +  class _ArrayXDExtensionType(pa.ExtensionType):
       514        ndims: Optional[int] = None
       515
       516        def __init__(self, shape: tuple, dtype: str):
```

Ok, so I checked the datastes library and the latest version of datasets already addresses this issue.

In my case the issue was that the datasets library was at version 2.2.1 for some reason. This is strange since my venv had only recently been created and ragas requires datasets withot a version specification. 

The following may therefore be a more sustainable way to solve the issue:

` pip install --upgrade "datasets>=2.20.0" `


Ok, I did some more digging, specifically about why pip had decided to to resolve datasets to version 2.2.1 and here are my findings:

The dependency that caused datasets to resolve to version 2.2.1 is PyArrow 21.0.0.

Here's what happened:

1. PyArrow 21.0.0 was installed (the pip output shows it collected pyarrow>=15.0.0 and used cached pyarrow-21.0.0)
2. Newer versions of datasets (3.0+ to <4.x) have an incompatibility with PyArrow 21.0.0 because:
    - PyArrow 21.0.0 removed the PyExtensionType attribute
    - Datasets 3.0+ still use this deprecated attribute
    - This causes an AttributeError when trying to import datasets

3. Pip's dependency resolver detected this incompatibility during installation and had to backtrack through many versions (you can see it trying versions from datasets 4.0.0 all the way down to 2.2.1)
4. **Pip appears to have gotten confused and though** that Datasets 2.2.1 was the last version that could work with PyArrow 21.0.0 without the PyExtensionType issue

--> this is actually an incorrect conclusion which is caused by a something else:

**WHY DIDN'T IT USE datasets 4.0.0?**
Looking at the pip output, it didn't immediately reject datasets 4.0.0. Here's what actually happened:

The Real Story:

1. Pip initially collected datasets-4.0.0 metadata successfully
2. It then collected pyarrow>=15.0.0 requirement from datasets 4.0.0, and selected pyarrow-21.0.0
3. Then pip says "INFO: pip is looking at multiple versions of datasets to determine which version is compatible with other requirements"

The key is that pip didn't reject datasets 4.0.0 due to a runtime error. Instead, it rejected it due to a dependency conflict with another package.

This is likely due to the following: 
Collecting pyarrow-hotfix (from datasets->-r requirements.txt (line 14))

This is where the issue is likely coming from:

When pip tried datasets versions 2.20.0 through 3.x, they required pyarrow-hotfix - a package that was created specifically to
work around the PyArrow 21.0.0 breaking changes. But something in the dependency tree (likely one of the other packages) had a conflict with pyarrow-hotfix.

The actual reason:

Datasets 4.0.0 doesn't require pyarrow-hotfix (it assumes PyArrow will be compatible)
Datasets 3.x and 2.20+ do require pyarrow-hotfix
Datasets 2.2.1 predates the need for pyarrow-hotfix

So pip kept backtracking until it found datasets 2.2.1, which:
1. Doesn't require pyarrow-hotfix (avoiding the conflict)
2. Has loose enough PyArrow requirements to accept 21.0.0
3. But will fail at runtime due to the PyExtensionType issue

Pip's dependency resolver only checks declared dependencies, not runtime compatibility! That's why it "successfully" installed datasets 2.2.1 with PyArro 21.0.0, even though they're incompatible at runtime.


Submitted a PR. Please test carefully. 

https://github.com/explodinggradients/ragas/pull/2201


Throws another error when updating datasets to 4.0.x 

Error: 
```
ImportError: cannot import name 'xopen' from 'datasets.utils.file_utils' (/Users/vaibhav/Developer/TM/retrieval/.venv/lib/python3.13/site-packages/datasets/utils/file_utils.py)
```

For reference:

```
uv pip install git+https://github.com/explodinggradients/ragas
    Updated https://github.com/explodinggradients/ragas (1e7dcb84f5b15078f1baf526fd05834b394f37d8)
Resolved 85 packages in 4.65s
      Built ragas @ git+https://github.com/explodinggradients/ragas@1e7dcb84f5b15078f1baf526fd05834b394f37d8
Prepared 1 package in 430ms
Uninstalled 1 package in 2ms
Installed 6 packages in 12ms
 + appdirs==1.4.4
 + datasets==4.0.0
 + dill==0.3.8
 - fsspec==2025.3.2
 + fsspec==2025.3.0
 + multiprocess==0.70.16
 + ragas==0.3.3.dev24+g1e7dcb84f (from git+https://github.com/explodinggradients/ragas@1e7dcb84f5b15078f1baf526fd05834b394f37d8)
```