Skip to content

Commit bcb60ca

Browse files
fix: better error message when docvec is unusable (#1675)
Signed-off-by: Johannes Messner <[email protected]>
1 parent b6eaa94 commit bcb60ca

File tree

5 files changed

+43
-1
lines changed

5 files changed

+43
-1
lines changed

docarray/array/any_array.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
from docarray.base_doc import BaseDoc
2323
from docarray.display.document_array_summary import DocArraySummary
24+
from docarray.exceptions.exceptions import UnusableObjectError
2425
from docarray.typing.abstract_type import AbstractType
2526
from docarray.utils._internal._typing import change_cls_name
2627

@@ -32,6 +33,13 @@
3233
T_doc = TypeVar('T_doc', bound=BaseDoc)
3334
IndexIterType = Union[slice, Iterable[int], Iterable[bool], None]
3435

36+
UNUSABLE_ERROR_MSG = (
37+
'This {cls} instance is in an unusable state. \n'
38+
'The most common cause of this is converting a DocVec to a DocList. '
39+
'After you call `doc_vec.to_doc_list()`, `doc_vec` cannot be used anymore. '
40+
'Instead, you should do `doc_list = doc_vec.to_doc_list()` and only use `doc_list`.'
41+
)
42+
3543

3644
class AnyDocArray(Sequence[T_doc], Generic[T_doc], AbstractType):
3745
doc_type: Type[BaseDoc]
@@ -64,9 +72,17 @@ class _DocArrayTyped(cls): # type: ignore
6472

6573
def _property_generator(val: str):
6674
def _getter(self):
75+
if getattr(self, '_is_unusable', False):
76+
raise UnusableObjectError(
77+
UNUSABLE_ERROR_MSG.format(cls=cls.__name__)
78+
)
6779
return self._get_data_column(val)
6880

6981
def _setter(self, value):
82+
if getattr(self, '_is_unusable', False):
83+
raise UnusableObjectError(
84+
UNUSABLE_ERROR_MSG.format(cls=cls.__name__)
85+
)
7086
self._set_data_column(val, value)
7187

7288
# need docstring for the property

docarray/array/doc_vec/doc_vec.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@ def __init__(
170170
f'docs = DocVec[MyDoc](docs) instead of DocVec(docs)'
171171
)
172172
self.tensor_type = tensor_type
173+
self._is_unusable = False
173174

174175
tensor_columns: Dict[str, Optional[AbstractTensor]] = dict()
175176
doc_columns: Dict[str, Optional['DocVec']] = dict()
@@ -769,7 +770,14 @@ def to_doc_list(self: T) -> DocList[T_doc]:
769770

770771
del self._storage
771772

772-
return DocList.__class_getitem__(self.doc_type).construct(docs)
773+
doc_type = self.doc_type
774+
775+
# Setting _is_unusable will raise an Exception if someone interacts with this instance from hereon out.
776+
# I don't like relying on this state, but we can't override the getattr/setattr directly:
777+
# https://stackoverflow.com/questions/10376604/overriding-special-methods-on-an-instance
778+
self._is_unusable = True
779+
780+
return DocList.__class_getitem__(doc_type).construct(docs)
773781

774782
def traverse_flat(
775783
self,

docarray/exceptions/__init__.py

Whitespace-only changes.

docarray/exceptions/exceptions.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
class UnusableObjectError(NotImplementedError):
2+
...

tests/units/array/stack/test_array_stacked.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from docarray import BaseDoc, DocList
99
from docarray.array import DocVec
1010
from docarray.documents import ImageDoc
11+
from docarray.exceptions.exceptions import UnusableObjectError
1112
from docarray.typing import AnyEmbedding, AnyTensor, NdArray, TorchTensor
1213

1314

@@ -657,3 +658,18 @@ class ImageDoc(BaseDoc):
657658
)
658659

659660
assert da != da2
661+
662+
663+
def teste_unusable_state_raises_exception():
664+
from docarray import DocVec
665+
from docarray.documents import ImageDoc
666+
667+
docs = DocVec[ImageDoc]([ImageDoc(url='http://url.com/foo.png') for _ in range(10)])
668+
669+
docs.to_doc_list()
670+
671+
with pytest.raises(UnusableObjectError):
672+
docs.url
673+
674+
with pytest.raises(UnusableObjectError):
675+
docs.url = 'hi'

0 commit comments

Comments
 (0)