Skip to content
This repository was archived by the owner on Sep 9, 2026. It is now read-only.

Commit 2ec599b

Browse files
committed
chore: first commit
1 parent 81a13d1 commit 2ec599b

8 files changed

Lines changed: 149 additions & 58 deletions

File tree

‎docarray/array/chunk.py‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from typing import Iterable, TYPE_CHECKING
1+
from typing import TYPE_CHECKING
22

33
from .document import DocumentArray
44

@@ -11,7 +11,7 @@ class ChunkArray(DocumentArray):
1111
:class:`ChunkArray` inherits from :class:`DocumentArray`.
1212
It's a subset of Documents.
1313
14-
:param doc_views: Set of sub-documents (i.e chunks) of `reference_doc`
14+
:param docs: Set of sub-documents (i.e chunks) of `reference_doc`
1515
:param reference_doc: Reference :class:`Document` for the sub-documents
1616
"""
1717

‎docarray/array/match.py‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@ class MatchArray(DocumentArray):
1111
:class:`MatchArray` inherits from :class:`DocumentArray`.
1212
It's a subset of Documents that represents the matches
1313
14-
:param doc_views: Set of matches of the `reference_doc`
14+
:param docs: Set of matches of the `reference_doc`
1515
:param reference_doc: Reference :class:`Document` for the sub-documents
1616
"""
1717

18-
def __init__(self, doc_views, reference_doc: 'Document'):
18+
def __init__(self, docs, reference_doc: 'Document'):
1919
self._ref_doc = reference_doc
20-
super().__init__(doc_views)
20+
super().__init__(docs)
2121

2222
def append(self, document: 'Document'):
2323
"""Add a matched document to the current Document.

‎docarray/document/__init__.py‎

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from typing import TYPE_CHECKING, Optional
22

3-
from .data import DocumentData
3+
from .data import DocumentData, default_values
44
from .mixins import AllMixins
55

66
if TYPE_CHECKING:
@@ -17,12 +17,51 @@ def __init__(self, obj: Optional['Document'] = None, copy: bool = False, **kwarg
1717
self.copy_from(obj)
1818
else:
1919
self._data = obj._data
20+
elif isinstance(obj, dict):
21+
kwargs.update(obj)
2022
if kwargs:
2123
# check if there are mutually exclusive content fields
2224
if len(self._all_doc_content_keys.intersection(kwargs.keys())) > 1:
2325
raise ValueError(
2426
f'Document content fields are mutually exclusive, please provide only one of {self._all_doc_content_keys}'
2527
)
26-
self._data = DocumentData(**kwargs)
28+
self._data = DocumentData(self, **kwargs)
2729
if obj is None and not kwargs:
28-
self._data = DocumentData()
30+
self._data = DocumentData(self)
31+
32+
if self._data is None:
33+
raise ValueError(f'Failed to initialize Document from obj={obj}, kwargs={kwargs}')
34+
35+
def _set_default_value_if_none(self, key):
36+
if getattr(self._data, key) is None:
37+
v = default_values.get(key, None)
38+
if v is not None:
39+
if v == 'DocumentArray':
40+
from .. import DocumentArray
41+
setattr(self._data, key, DocumentArray())
42+
elif v == 'ChunkArray':
43+
from ..array.chunk import ChunkArray
44+
setattr(self._data, key, ChunkArray(None, reference_doc=self))
45+
elif v == 'MatchArray':
46+
from ..array.match import MatchArray
47+
setattr(self._data, key, MatchArray(None, reference_doc=self))
48+
else:
49+
setattr(self._data, key, v() if callable(v) else v)
50+
51+
def __setattr__(self, key, value):
52+
if value is not None:
53+
if key == 'text' or key == 'blob' or key == 'buffer':
54+
# enable mutual exclusivity for content field
55+
if value != default_values.get(key):
56+
self.text = None
57+
self.blob = None
58+
self.buffer = None
59+
elif key == 'chunks':
60+
from ..array.chunk import ChunkArray
61+
if not isinstance(value, ChunkArray):
62+
value = ChunkArray(None, reference_doc=self)
63+
elif key == 'matches':
64+
from ..array.match import MatchArray
65+
if not isinstance(value, MatchArray):
66+
value = MatchArray(None, reference_doc=self)
67+
super().__setattr__(key, value)

‎docarray/document/data.py‎

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
if TYPE_CHECKING:
66
from .score import NamedScore
7-
from .. import DocumentArray
7+
from .. import DocumentArray, Document
88
from ..typing import ArrayType, StructValueType
99
from datetime import datetime
1010

@@ -23,14 +23,15 @@
2323
modality='',
2424
evaluations=list,
2525
scores=dict,
26-
chunks='DocumentArray',
27-
matches='DocumentArray',
26+
chunks='ChunkArray',
27+
matches='MatchArray',
2828
timestamps=dict,
2929
)
3030

3131

3232
@dataclass(unsafe_hash=True)
3333
class DocumentData:
34+
_reference_doc: 'Document' = field(hash=False, compare=False)
3435
id: str = field(default_factory=lambda: uuid.uuid1().hex)
3536
granularity: Optional[int] = None
3637
adjacency: Optional[int] = None
@@ -63,10 +64,14 @@ def __setattr__(self, key, value):
6364
# enable mutual exclusivity for content field
6465
if value != default_values.get(key):
6566
self._clear_content()
66-
elif key == 'chunks' or key == 'matches':
67-
# force setter to DocumentArray
68-
from .. import DocumentArray
69-
value = DocumentArray(value)
67+
elif key == 'chunks':
68+
from ..array.chunk import ChunkArray
69+
if not isinstance(value, ChunkArray):
70+
value = ChunkArray(value, reference_doc=self._reference_doc)
71+
elif key == 'matches':
72+
from ..array.match import MatchArray
73+
if not isinstance(value, MatchArray):
74+
value = MatchArray(value, reference_doc=self._reference_doc)
7075
super().__setattr__(key, value)
7176

7277
@property
@@ -80,21 +85,25 @@ def non_empty_fields(self) -> Tuple[str]:
8085
r = []
8186
for f in fields(self):
8287
f_name = f.name
83-
v = getattr(self, f_name)
84-
if v is not None:
85-
if f.name not in default_values:
86-
r.append(f_name)
87-
elif v != default_values[f_name]:
88-
r.append(f_name)
88+
if not f_name.startswith('_'):
89+
v = getattr(self, f_name)
90+
if v is not None:
91+
if f.name not in default_values:
92+
r.append(f_name)
93+
elif v != default_values[f_name]:
94+
r.append(f_name)
8995
return tuple(r)
9096

9197
def _set_default_value_if_none(self, key):
9298
if getattr(self, key) is None:
9399
v = default_values.get(key, None)
94100
if v is not None:
95101
if v == 'DocumentArray':
96-
from ... import DocumentArray
97-
102+
from .. import DocumentArray
98103
setattr(self, key, DocumentArray())
99-
else:
100-
setattr(self, key, v() if callable(v) else v)
104+
elif v == 'ChunkArray':
105+
from ..array.chunk import ChunkArray
106+
setattr(self, key, ChunkArray(None, reference_doc=self._reference_doc))
107+
elif v == 'MatchArray':
108+
from ..array.match import MatchArray
109+
setattr(self, key, MatchArray(None, reference_doc=self._reference_doc))

‎docarray/document/mixins/base.py‎

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -72,12 +72,6 @@ def nbytes(self) -> int:
7272
def __hash__(self):
7373
return hash(self._data)
7474

75-
def __copy__(self):
76-
return type(self)(self)
77-
78-
def __deepcopy__(self, memodict={}):
79-
return type(self)(self, copy=True)
80-
8175
def __repr__(self):
8276
content = str(self._data.non_empty_fields)
8377
content += f' at {id(self)}'

‎docarray/document/mixins/property.py‎

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33

44
if TYPE_CHECKING:
55
from ..score import NamedScore
6-
from ... import DocumentArray
6+
from ...array.match import MatchArray
7+
from ...array.chunk import ChunkArray
78
from ...typing import ArrayType, StructValueType
89
from datetime import datetime
910

@@ -22,7 +23,7 @@ def non_empty_fields(self) -> Tuple[str]:
2223

2324
@property
2425
def id(self) -> str:
25-
self._data._set_default_value_if_none('id')
26+
self._set_default_value_if_none('id')
2627
return self._data.id
2728

2829
@id.setter
@@ -31,7 +32,7 @@ def id(self, value: str):
3132

3233
@property
3334
def granularity(self) -> Optional[int]:
34-
self._data._set_default_value_if_none('granularity')
35+
self._set_default_value_if_none('granularity')
3536
return self._data.granularity
3637

3738
@granularity.setter
@@ -40,7 +41,7 @@ def granularity(self, value: Optional[int]):
4041

4142
@property
4243
def adjacency(self) -> Optional[int]:
43-
self._data._set_default_value_if_none('adjacency')
44+
self._set_default_value_if_none('adjacency')
4445
return self._data.adjacency
4546

4647
@adjacency.setter
@@ -49,7 +50,7 @@ def adjacency(self, value: Optional[int]):
4950

5051
@property
5152
def parent_id(self) -> Optional[str]:
52-
self._data._set_default_value_if_none('parent_id')
53+
self._set_default_value_if_none('parent_id')
5354
return self._data.parent_id
5455

5556
@parent_id.setter
@@ -58,7 +59,7 @@ def parent_id(self, value: Optional[str]):
5859

5960
@property
6061
def buffer(self) -> Optional[bytes]:
61-
self._data._set_default_value_if_none('buffer')
62+
self._set_default_value_if_none('buffer')
6263
return self._data.buffer
6364

6465
@buffer.setter
@@ -67,7 +68,7 @@ def buffer(self, value: Optional[bytes]):
6768

6869
@property
6970
def blob(self) -> Optional['ArrayType']:
70-
self._data._set_default_value_if_none('blob')
71+
self._set_default_value_if_none('blob')
7172
return self._data.blob
7273

7374
@blob.setter
@@ -76,7 +77,7 @@ def blob(self, value: Optional['ArrayType']):
7677

7778
@property
7879
def text(self) -> Optional[str]:
79-
self._data._set_default_value_if_none('text')
80+
self._set_default_value_if_none('text')
8081
return self._data.text
8182

8283
@text.setter
@@ -85,7 +86,7 @@ def text(self, value: Optional[str]):
8586

8687
@property
8788
def weight(self) -> Optional[float]:
88-
self._data._set_default_value_if_none('weight')
89+
self._set_default_value_if_none('weight')
8990
return self._data.weight
9091

9192
@weight.setter
@@ -94,7 +95,7 @@ def weight(self, value: Optional[float]):
9495

9596
@property
9697
def uri(self) -> Optional[str]:
97-
self._data._set_default_value_if_none('uri')
98+
self._set_default_value_if_none('uri')
9899
return self._data.uri
99100

100101
@uri.setter
@@ -103,7 +104,7 @@ def uri(self, value: Optional[str]):
103104

104105
@property
105106
def mime_type(self) -> Optional[str]:
106-
self._data._set_default_value_if_none('mime_type')
107+
self._set_default_value_if_none('mime_type')
107108
return self._data.mime_type
108109

109110
@mime_type.setter
@@ -112,7 +113,7 @@ def mime_type(self, value: Optional[str]):
112113

113114
@property
114115
def tags(self) -> Optional[Dict[str, 'StructValueType']]:
115-
self._data._set_default_value_if_none('tags')
116+
self._set_default_value_if_none('tags')
116117
return self._data.tags
117118

118119
@tags.setter
@@ -121,7 +122,7 @@ def tags(self, value: Optional[Dict[str, 'StructValueType']]):
121122

122123
@property
123124
def offset(self) -> Optional[float]:
124-
self._data._set_default_value_if_none('offset')
125+
self._set_default_value_if_none('offset')
125126
return self._data.offset
126127

127128
@offset.setter
@@ -130,7 +131,7 @@ def offset(self, value: Optional[float]):
130131

131132
@property
132133
def location(self) -> Optional[List[float]]:
133-
self._data._set_default_value_if_none('location')
134+
self._set_default_value_if_none('location')
134135
return self._data.location
135136

136137
@location.setter
@@ -139,7 +140,7 @@ def location(self, value: Optional[List[float]]):
139140

140141
@property
141142
def embedding(self) -> Optional['ArrayType']:
142-
self._data._set_default_value_if_none('embedding')
143+
self._set_default_value_if_none('embedding')
143144
return self._data.embedding
144145

145146
@embedding.setter
@@ -148,7 +149,7 @@ def embedding(self, value: Optional['ArrayType']):
148149

149150
@property
150151
def modality(self) -> Optional[str]:
151-
self._data._set_default_value_if_none('modality')
152+
self._set_default_value_if_none('modality')
152153
return self._data.modality
153154

154155
@modality.setter
@@ -157,7 +158,7 @@ def modality(self, value: Optional[str]):
157158

158159
@property
159160
def evaluations(self) -> Optional[Dict[str, 'NamedScore']]:
160-
self._data._set_default_value_if_none('evaluations')
161+
self._set_default_value_if_none('evaluations')
161162
return self._data.evaluations
162163

163164
@evaluations.setter
@@ -166,25 +167,25 @@ def evaluations(self, value: Optional[Dict[str, 'NamedScore']]):
166167

167168
@property
168169
def scores(self) -> Optional[Dict[str, 'NamedScore']]:
169-
self._data._set_default_value_if_none('scores')
170+
self._set_default_value_if_none('scores')
170171
return self._data.scores
171172

172173
@scores.setter
173174
def scores(self, value: Optional[Dict[str, 'NamedScore']]):
174175
self._data.scores = value
175176

176177
@property
177-
def chunks(self) -> Optional['DocumentArray']:
178-
self._data._set_default_value_if_none('chunks')
178+
def chunks(self) -> Optional['ChunkArray']:
179+
self._set_default_value_if_none('chunks')
179180
return self._data.chunks
180181

181182
@chunks.setter
182183
def chunks(self, value: Optional['DocumentArray']):
183184
self._data.chunks = value
184185

185186
@property
186-
def matches(self) -> Optional['DocumentArray']:
187-
self._data._set_default_value_if_none('matches')
187+
def matches(self) -> Optional['MatchArray']:
188+
self._set_default_value_if_none('matches')
188189
return self._data.matches
189190

190191
@matches.setter
@@ -193,7 +194,7 @@ def matches(self, value: Optional['DocumentArray']):
193194

194195
@property
195196
def timestamps(self) -> Optional[Dict[str, 'datetime']]:
196-
self._data._set_default_value_if_none('timestamps')
197+
self._set_default_value_if_none('timestamps')
197198
return self._data.timestamps
198199

199200
@timestamps.setter

0 commit comments

Comments
 (0)