diff --git a/docarray/array/any_array.py b/docarray/array/any_array.py index 612fba7f42e..c896d4e782e 100644 --- a/docarray/array/any_array.py +++ b/docarray/array/any_array.py @@ -21,6 +21,7 @@ from docarray.base_doc import BaseDoc from docarray.display.document_array_summary import DocArraySummary +from docarray.exceptions.exceptions import UnusableObjectError from docarray.typing.abstract_type import AbstractType from docarray.utils._internal._typing import change_cls_name @@ -32,6 +33,13 @@ T_doc = TypeVar('T_doc', bound=BaseDoc) IndexIterType = Union[slice, Iterable[int], Iterable[bool], None] +UNUSABLE_ERROR_MSG = ( + 'This {cls} instance is in an unusable state. \n' + 'The most common cause of this is converting a DocVec to a DocList. ' + 'After you call `doc_vec.to_doc_list()`, `doc_vec` cannot be used anymore. ' + 'Instead, you should do `doc_list = doc_vec.to_doc_list()` and only use `doc_list`.' +) + class AnyDocArray(Sequence[T_doc], Generic[T_doc], AbstractType): doc_type: Type[BaseDoc] @@ -64,9 +72,17 @@ class _DocArrayTyped(cls): # type: ignore def _property_generator(val: str): def _getter(self): + if getattr(self, '_is_unusable', False): + raise UnusableObjectError( + UNUSABLE_ERROR_MSG.format(cls=cls.__name__) + ) return self._get_data_column(val) def _setter(self, value): + if getattr(self, '_is_unusable', False): + raise UnusableObjectError( + UNUSABLE_ERROR_MSG.format(cls=cls.__name__) + ) self._set_data_column(val, value) # need docstring for the property diff --git a/docarray/array/doc_vec/doc_vec.py b/docarray/array/doc_vec/doc_vec.py index e1ba944fd10..3025c52a09b 100644 --- a/docarray/array/doc_vec/doc_vec.py +++ b/docarray/array/doc_vec/doc_vec.py @@ -170,6 +170,7 @@ def __init__( f'docs = DocVec[MyDoc](docs) instead of DocVec(docs)' ) self.tensor_type = tensor_type + self._is_unusable = False tensor_columns: Dict[str, Optional[AbstractTensor]] = dict() doc_columns: Dict[str, Optional['DocVec']] = dict() @@ -769,7 +770,14 @@ def to_doc_list(self: T) -> DocList[T_doc]: del self._storage - return DocList.__class_getitem__(self.doc_type).construct(docs) + doc_type = self.doc_type + + # Setting _is_unusable will raise an Exception if someone interacts with this instance from hereon out. + # I don't like relying on this state, but we can't override the getattr/setattr directly: + # https://stackoverflow.com/questions/10376604/overriding-special-methods-on-an-instance + self._is_unusable = True + + return DocList.__class_getitem__(doc_type).construct(docs) def traverse_flat( self, diff --git a/docarray/exceptions/__init__.py b/docarray/exceptions/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/docarray/exceptions/exceptions.py b/docarray/exceptions/exceptions.py new file mode 100644 index 00000000000..ef659901b36 --- /dev/null +++ b/docarray/exceptions/exceptions.py @@ -0,0 +1,2 @@ +class UnusableObjectError(NotImplementedError): + ... diff --git a/tests/units/array/stack/test_array_stacked.py b/tests/units/array/stack/test_array_stacked.py index 35509338068..e199a706b63 100644 --- a/tests/units/array/stack/test_array_stacked.py +++ b/tests/units/array/stack/test_array_stacked.py @@ -8,6 +8,7 @@ from docarray import BaseDoc, DocList from docarray.array import DocVec from docarray.documents import ImageDoc +from docarray.exceptions.exceptions import UnusableObjectError from docarray.typing import AnyEmbedding, AnyTensor, NdArray, TorchTensor @@ -657,3 +658,18 @@ class ImageDoc(BaseDoc): ) assert da != da2 + + +def teste_unusable_state_raises_exception(): + from docarray import DocVec + from docarray.documents import ImageDoc + + docs = DocVec[ImageDoc]([ImageDoc(url='http://url.com/foo.png') for _ in range(10)]) + + docs.to_doc_list() + + with pytest.raises(UnusableObjectError): + docs.url + + with pytest.raises(UnusableObjectError): + docs.url = 'hi' pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy