datachain 0.14.2__py3-none-any.whl → 0.39.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (137) hide show
  1. datachain/__init__.py +20 -0
  2. datachain/asyn.py +11 -12
  3. datachain/cache.py +7 -7
  4. datachain/catalog/__init__.py +2 -2
  5. datachain/catalog/catalog.py +621 -507
  6. datachain/catalog/dependency.py +164 -0
  7. datachain/catalog/loader.py +28 -18
  8. datachain/checkpoint.py +43 -0
  9. datachain/cli/__init__.py +24 -33
  10. datachain/cli/commands/__init__.py +1 -8
  11. datachain/cli/commands/datasets.py +83 -52
  12. datachain/cli/commands/ls.py +17 -17
  13. datachain/cli/commands/show.py +4 -4
  14. datachain/cli/parser/__init__.py +8 -74
  15. datachain/cli/parser/job.py +95 -3
  16. datachain/cli/parser/studio.py +11 -4
  17. datachain/cli/parser/utils.py +1 -2
  18. datachain/cli/utils.py +2 -15
  19. datachain/client/azure.py +4 -4
  20. datachain/client/fsspec.py +45 -28
  21. datachain/client/gcs.py +6 -6
  22. datachain/client/hf.py +29 -2
  23. datachain/client/http.py +157 -0
  24. datachain/client/local.py +15 -11
  25. datachain/client/s3.py +17 -9
  26. datachain/config.py +4 -8
  27. datachain/data_storage/db_engine.py +12 -6
  28. datachain/data_storage/job.py +5 -1
  29. datachain/data_storage/metastore.py +1252 -186
  30. datachain/data_storage/schema.py +58 -45
  31. datachain/data_storage/serializer.py +105 -15
  32. datachain/data_storage/sqlite.py +286 -127
  33. datachain/data_storage/warehouse.py +250 -113
  34. datachain/dataset.py +353 -148
  35. datachain/delta.py +391 -0
  36. datachain/diff/__init__.py +27 -29
  37. datachain/error.py +60 -0
  38. datachain/func/__init__.py +2 -1
  39. datachain/func/aggregate.py +66 -42
  40. datachain/func/array.py +242 -38
  41. datachain/func/base.py +7 -4
  42. datachain/func/conditional.py +110 -60
  43. datachain/func/func.py +96 -45
  44. datachain/func/numeric.py +55 -38
  45. datachain/func/path.py +32 -20
  46. datachain/func/random.py +2 -2
  47. datachain/func/string.py +67 -37
  48. datachain/func/window.py +7 -8
  49. datachain/hash_utils.py +123 -0
  50. datachain/job.py +11 -7
  51. datachain/json.py +138 -0
  52. datachain/lib/arrow.py +58 -22
  53. datachain/lib/audio.py +245 -0
  54. datachain/lib/clip.py +14 -13
  55. datachain/lib/convert/flatten.py +5 -3
  56. datachain/lib/convert/python_to_sql.py +6 -10
  57. datachain/lib/convert/sql_to_python.py +8 -0
  58. datachain/lib/convert/values_to_tuples.py +156 -51
  59. datachain/lib/data_model.py +42 -20
  60. datachain/lib/dataset_info.py +36 -8
  61. datachain/lib/dc/__init__.py +8 -2
  62. datachain/lib/dc/csv.py +25 -28
  63. datachain/lib/dc/database.py +398 -0
  64. datachain/lib/dc/datachain.py +1289 -425
  65. datachain/lib/dc/datasets.py +320 -38
  66. datachain/lib/dc/hf.py +38 -24
  67. datachain/lib/dc/json.py +29 -32
  68. datachain/lib/dc/listings.py +112 -8
  69. datachain/lib/dc/pandas.py +16 -12
  70. datachain/lib/dc/parquet.py +35 -23
  71. datachain/lib/dc/records.py +31 -23
  72. datachain/lib/dc/storage.py +154 -64
  73. datachain/lib/dc/storage_pattern.py +251 -0
  74. datachain/lib/dc/utils.py +24 -16
  75. datachain/lib/dc/values.py +8 -9
  76. datachain/lib/file.py +622 -89
  77. datachain/lib/hf.py +69 -39
  78. datachain/lib/image.py +14 -14
  79. datachain/lib/listing.py +14 -11
  80. datachain/lib/listing_info.py +1 -2
  81. datachain/lib/meta_formats.py +3 -4
  82. datachain/lib/model_store.py +39 -7
  83. datachain/lib/namespaces.py +125 -0
  84. datachain/lib/projects.py +130 -0
  85. datachain/lib/pytorch.py +32 -21
  86. datachain/lib/settings.py +192 -56
  87. datachain/lib/signal_schema.py +427 -104
  88. datachain/lib/tar.py +1 -2
  89. datachain/lib/text.py +8 -7
  90. datachain/lib/udf.py +164 -76
  91. datachain/lib/udf_signature.py +60 -35
  92. datachain/lib/utils.py +118 -4
  93. datachain/lib/video.py +17 -9
  94. datachain/lib/webdataset.py +61 -56
  95. datachain/lib/webdataset_laion.py +15 -16
  96. datachain/listing.py +22 -10
  97. datachain/model/bbox.py +3 -1
  98. datachain/model/ultralytics/bbox.py +16 -12
  99. datachain/model/ultralytics/pose.py +16 -12
  100. datachain/model/ultralytics/segment.py +16 -12
  101. datachain/namespace.py +84 -0
  102. datachain/node.py +6 -6
  103. datachain/nodes_thread_pool.py +0 -1
  104. datachain/plugins.py +24 -0
  105. datachain/project.py +78 -0
  106. datachain/query/batch.py +40 -41
  107. datachain/query/dataset.py +604 -322
  108. datachain/query/dispatch.py +261 -154
  109. datachain/query/metrics.py +4 -6
  110. datachain/query/params.py +2 -3
  111. datachain/query/queue.py +3 -12
  112. datachain/query/schema.py +11 -6
  113. datachain/query/session.py +200 -33
  114. datachain/query/udf.py +34 -2
  115. datachain/remote/studio.py +171 -69
  116. datachain/script_meta.py +12 -12
  117. datachain/semver.py +68 -0
  118. datachain/sql/__init__.py +2 -0
  119. datachain/sql/functions/array.py +33 -1
  120. datachain/sql/postgresql_dialect.py +9 -0
  121. datachain/sql/postgresql_types.py +21 -0
  122. datachain/sql/sqlite/__init__.py +5 -1
  123. datachain/sql/sqlite/base.py +102 -29
  124. datachain/sql/sqlite/types.py +8 -13
  125. datachain/sql/types.py +70 -15
  126. datachain/studio.py +223 -46
  127. datachain/toolkit/split.py +31 -10
  128. datachain/utils.py +101 -59
  129. {datachain-0.14.2.dist-info → datachain-0.39.0.dist-info}/METADATA +77 -22
  130. datachain-0.39.0.dist-info/RECORD +173 -0
  131. {datachain-0.14.2.dist-info → datachain-0.39.0.dist-info}/WHEEL +1 -1
  132. datachain/cli/commands/query.py +0 -53
  133. datachain/query/utils.py +0 -42
  134. datachain-0.14.2.dist-info/RECORD +0 -158
  135. {datachain-0.14.2.dist-info → datachain-0.39.0.dist-info}/entry_points.txt +0 -0
  136. {datachain-0.14.2.dist-info → datachain-0.39.0.dist-info}/licenses/LICENSE +0 -0
  137. {datachain-0.14.2.dist-info → datachain-0.39.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,130 @@
1
+ from datachain.error import ProjectCreateNotAllowedError, ProjectDeleteNotAllowedError
2
+ from datachain.project import Project
3
+ from datachain.query import Session
4
+
5
+
6
+ def create(
7
+ namespace: str,
8
+ name: str,
9
+ descr: str | None = None,
10
+ session: Session | None = None,
11
+ ) -> Project:
12
+ """
13
+ Creates a new project under a specified namespace.
14
+
15
+ Projects help organize datasets. A default project is always available,
16
+ but users can create additional ones (only in Studio, not via CLI).
17
+
18
+
19
+ Parameters:
20
+ name: Name of the new project.
21
+ namespace: Namespace to create the project in. Created if it doesn't exist.
22
+ descr: Optional description of the project.
23
+ session: Optional session to use for the operation.
24
+
25
+ Example:
26
+ ```py
27
+ import datachain as dc
28
+ project = dc.create_project("dev", "my-project", "My personal project")
29
+ ```
30
+ """
31
+ session = Session.get(session)
32
+
33
+ from datachain.lib.dc.utils import is_studio
34
+
35
+ if not is_studio():
36
+ raise ProjectCreateNotAllowedError("Creating project is not allowed")
37
+
38
+ Project.validate_name(name)
39
+
40
+ return session.catalog.metastore.create_project(namespace, name, descr)
41
+
42
+
43
+ def get(name: str, namespace: str, session: Session | None) -> Project:
44
+ """
45
+ Gets a project by name in some namespace.
46
+ If the project is not found, a `ProjectNotFoundError` is raised.
47
+
48
+ Parameters:
49
+ name : The name of the project.
50
+ namespace : The name of the namespace.
51
+ session : Session to use for getting project.
52
+
53
+ Example:
54
+ ```py
55
+ import datachain as dc
56
+ from datachain.lib.projects import get as get_project
57
+ project = get_project("my-project", "local")
58
+ ```
59
+ """
60
+ return Session.get(session).catalog.metastore.get_project(name, namespace)
61
+
62
+
63
+ def ls(namespace: str | None = None, session: Session | None = None) -> list[Project]:
64
+ """
65
+ Gets a list of projects in a specific namespace or from all namespaces.
66
+
67
+ Parameters:
68
+ namespace : An optional namespace name.
69
+ session : Session to use for getting project.
70
+
71
+ Example:
72
+ ```py
73
+ import datachain as dc
74
+ from datachain.lib.projects import ls as ls_projects
75
+ local_namespace_projects = ls_projects("local")
76
+ all_projects = ls_projects()
77
+ ```
78
+ """
79
+ session = Session.get(session)
80
+ namespace_id = None
81
+ if namespace:
82
+ namespace_id = session.catalog.metastore.get_namespace(namespace).id
83
+
84
+ return session.catalog.metastore.list_projects(namespace_id)
85
+
86
+
87
+ def delete(name: str, namespace: str, session: Session | None = None) -> None:
88
+ """
89
+ Removes a project by name within a namespace.
90
+
91
+ Raises:
92
+ ProjectNotFoundError: If the project does not exist.
93
+ ProjectDeleteNotAllowedError: If the project is non-empty,
94
+ is the default project, or is a listing project,
95
+ as these cannot be removed.
96
+
97
+ Parameters:
98
+ name : The name of the project.
99
+ namespace : The name of the namespace.
100
+ session : Session to use for getting project.
101
+
102
+ Example:
103
+ ```py
104
+ import datachain as dc
105
+ dc.delete_project("my-project", "local")
106
+ ```
107
+ """
108
+ session = Session.get(session)
109
+ metastore = session.catalog.metastore
110
+
111
+ project = metastore.get_project(name, namespace)
112
+
113
+ if metastore.is_listing_project(name, namespace):
114
+ raise ProjectDeleteNotAllowedError(
115
+ f"Project {metastore.listing_project_name} cannot be removed"
116
+ )
117
+
118
+ if metastore.is_default_project(name, namespace):
119
+ raise ProjectDeleteNotAllowedError(
120
+ f"Project {metastore.default_project_name} cannot be removed"
121
+ )
122
+
123
+ num_datasets = metastore.count_datasets(project.id)
124
+ if num_datasets > 0:
125
+ raise ProjectDeleteNotAllowedError(
126
+ f"Project cannot be removed. It contains {num_datasets} dataset(s). "
127
+ "Please remove the dataset(s) first."
128
+ )
129
+
130
+ metastore.remove_project(project.id)
datachain/lib/pytorch.py CHANGED
@@ -1,9 +1,9 @@
1
1
  import logging
2
2
  import os
3
3
  import weakref
4
- from collections.abc import Generator, Iterable, Iterator
4
+ from collections.abc import Callable, Generator, Iterable, Iterator
5
5
  from contextlib import closing
6
- from typing import TYPE_CHECKING, Any, Callable, Optional
6
+ from typing import TYPE_CHECKING, Any
7
7
 
8
8
  from PIL import Image
9
9
  from torch import float32
@@ -43,13 +43,13 @@ class PytorchDataset(IterableDataset):
43
43
  def __init__(
44
44
  self,
45
45
  name: str,
46
- version: Optional[int] = None,
47
- catalog: Optional["Catalog"] = None,
48
- transform: Optional["Transform"] = None,
49
- tokenizer: Optional[Callable] = None,
50
- tokenizer_kwargs: Optional[dict[str, Any]] = None,
46
+ version: str | None = None,
47
+ catalog: Catalog | None = None,
48
+ transform: "Transform | None" = None,
49
+ tokenizer: Callable | None = None,
50
+ tokenizer_kwargs: dict[str, Any] | None = None,
51
51
  num_samples: int = 0,
52
- dc_settings: Optional[Settings] = None,
52
+ dc_settings: Settings | None = None,
53
53
  remove_prefetched: bool = False,
54
54
  ):
55
55
  """
@@ -60,7 +60,7 @@ class PytorchDataset(IterableDataset):
60
60
 
61
61
  Args:
62
62
  name (str): Name of DataChain dataset to stream.
63
- version (int): Version of DataChain dataset to stream.
63
+ version (str): Version of DataChain dataset to stream.
64
64
  catalog (Catalog): DataChain catalog to which dataset belongs.
65
65
  transform (Transform): Torchvision transforms to apply to the dataset.
66
66
  tokenizer (Callable): Tokenizer to use to tokenize text values.
@@ -74,6 +74,7 @@ class PytorchDataset(IterableDataset):
74
74
  self.tokenizer = tokenizer
75
75
  self.tokenizer_kwargs = tokenizer_kwargs or {}
76
76
  self.num_samples = num_samples
77
+ owns_catalog = catalog is None
77
78
  if catalog is None:
78
79
  catalog = get_catalog()
79
80
  self._init_catalog(catalog)
@@ -84,7 +85,7 @@ class PytorchDataset(IterableDataset):
84
85
  self.prefetch = prefetch
85
86
 
86
87
  self._cache = catalog.cache
87
- self._prefetch_cache: Optional[Cache] = None
88
+ self._prefetch_cache: Cache | None = None
88
89
  self._remove_prefetched = remove_prefetched
89
90
  if prefetch and not self.cache:
90
91
  tmp_dir = catalog.cache.tmp_dir
@@ -93,6 +94,10 @@ class PytorchDataset(IterableDataset):
93
94
  self._cache = self._prefetch_cache
94
95
  weakref.finalize(self, self._prefetch_cache.destroy)
95
96
 
97
+ # Close the catalog if we created it - we only needed it for clone params
98
+ if owns_catalog:
99
+ catalog.close()
100
+
96
101
  def close(self) -> None:
97
102
  if self._prefetch_cache:
98
103
  self._prefetch_cache.destroy()
@@ -104,7 +109,7 @@ class PytorchDataset(IterableDataset):
104
109
  self._ms_params = catalog.metastore.clone_params()
105
110
  self._wh_params = catalog.warehouse.clone_params()
106
111
  self._catalog_params = catalog.get_init_params()
107
- self.catalog: Optional[Catalog] = None
112
+ self.catalog: Catalog | None = None
108
113
 
109
114
  def _get_catalog(self) -> "Catalog":
110
115
  ms_cls, ms_args, ms_kwargs = self._ms_params
@@ -121,16 +126,22 @@ class PytorchDataset(IterableDataset):
121
126
  total_workers: int,
122
127
  ) -> Generator[tuple[Any, ...], None, None]:
123
128
  catalog = self._get_catalog()
124
- session = Session("PyTorch", catalog=catalog)
125
- ds = read_dataset(
126
- name=self.name, version=self.version, session=session
127
- ).settings(cache=self.cache, prefetch=self.prefetch)
128
- ds = ds.remove_file_signals()
129
-
130
- if self.num_samples > 0:
131
- ds = ds.sample(self.num_samples)
132
- ds = ds.chunk(total_rank, total_workers)
133
- yield from ds.collect()
129
+ try:
130
+ session = Session("PyTorch", catalog=catalog)
131
+ ds = read_dataset(
132
+ name=self.name, version=self.version, session=session
133
+ ).settings(cache=self.cache, prefetch=self.prefetch)
134
+
135
+ # remove file signals from dataset
136
+ schema = ds.signals_schema.clone_without_file_signals()
137
+ ds = ds.select(*schema.values.keys())
138
+
139
+ if self.num_samples > 0:
140
+ ds = ds.sample(self.num_samples)
141
+ ds = ds.chunk(total_rank, total_workers)
142
+ yield from ds.to_iter()
143
+ finally:
144
+ catalog.close()
134
145
 
135
146
  def _iter_with_prefetch(self) -> Generator[tuple[Any], None, None]:
136
147
  from datachain.lib.udf import _prefetch_inputs
datachain/lib/settings.py CHANGED
@@ -1,78 +1,214 @@
1
+ from typing import Any
2
+
1
3
  from datachain.lib.utils import DataChainParamsError
2
4
 
5
+ DEFAULT_CACHE = False
6
+ DEFAULT_PREFETCH = 2
7
+ DEFAULT_BATCH_SIZE = 2_000
8
+
3
9
 
4
10
  class SettingsError(DataChainParamsError):
5
- def __init__(self, msg):
11
+ def __init__(self, msg: str) -> None:
6
12
  super().__init__(f"Dataset settings error: {msg}")
7
13
 
8
14
 
9
15
  class Settings:
10
- def __init__(
16
+ """Settings for datachain."""
17
+
18
+ _cache: bool | None
19
+ _prefetch: int | None
20
+ _parallel: bool | int | None
21
+ _workers: int | None
22
+ _namespace: str | None
23
+ _project: str | None
24
+ _min_task_size: int | None
25
+ _batch_size: int | None
26
+
27
+ def __init__( # noqa: C901, PLR0912
11
28
  self,
12
- cache=None,
13
- parallel=None,
14
- workers=None,
15
- min_task_size=None,
16
- prefetch=None,
17
- ):
18
- self._cache = cache
19
- self.parallel = parallel
20
- self._workers = workers
21
- self.min_task_size = min_task_size
22
- self.prefetch = prefetch
23
-
24
- if not isinstance(cache, bool) and cache is not None:
25
- raise SettingsError(
26
- "'cache' argument must be bool"
27
- f" while {cache.__class__.__name__} was given"
28
- )
29
-
30
- if not isinstance(parallel, int) and parallel is not None:
31
- raise SettingsError(
32
- "'parallel' argument must be int or None"
33
- f" while {parallel.__class__.__name__} was given"
34
- )
35
-
36
- if (
37
- not isinstance(workers, bool)
38
- and not isinstance(workers, int)
39
- and workers is not None
40
- ):
41
- raise SettingsError(
42
- "'workers' argument must be int or bool"
43
- f" while {workers.__class__.__name__} was given"
44
- )
45
-
46
- if min_task_size is not None and not isinstance(min_task_size, int):
47
- raise SettingsError(
48
- "'min_task_size' argument must be int or None"
49
- f", {min_task_size.__class__.__name__} was given"
50
- )
29
+ cache: bool | None = None,
30
+ prefetch: bool | int | None = None,
31
+ parallel: bool | int | None = None,
32
+ workers: int | None = None,
33
+ namespace: str | None = None,
34
+ project: str | None = None,
35
+ min_task_size: int | None = None,
36
+ batch_size: int | None = None,
37
+ ) -> None:
38
+ if cache is None:
39
+ self._cache = None
40
+ else:
41
+ if not isinstance(cache, bool):
42
+ raise SettingsError(
43
+ "'cache' argument must be bool"
44
+ f" while {cache.__class__.__name__} was given"
45
+ )
46
+ self._cache = cache
47
+
48
+ if prefetch is None or prefetch is True:
49
+ self._prefetch = None
50
+ elif prefetch is False:
51
+ self._prefetch = 0 # disable prefetch (False == 0)
52
+ else:
53
+ if not isinstance(prefetch, int):
54
+ raise SettingsError(
55
+ "'prefetch' argument must be int or bool"
56
+ f" while {prefetch.__class__.__name__} was given"
57
+ )
58
+ if prefetch < 0:
59
+ raise SettingsError(
60
+ "'prefetch' argument must be non-negative integer"
61
+ f", {prefetch} was given"
62
+ )
63
+ self._prefetch = prefetch
64
+
65
+ if parallel is None or parallel is False:
66
+ self._parallel = None
67
+ elif parallel is True:
68
+ self._parallel = True
69
+ else:
70
+ if not isinstance(parallel, int):
71
+ raise SettingsError(
72
+ "'parallel' argument must be int or bool"
73
+ f" while {parallel.__class__.__name__} was given"
74
+ )
75
+ if parallel <= 0:
76
+ raise SettingsError(
77
+ "'parallel' argument must be positive integer"
78
+ f", {parallel} was given"
79
+ )
80
+ self._parallel = parallel
81
+
82
+ if workers is None:
83
+ self._workers = None
84
+ else:
85
+ if not isinstance(workers, int) or isinstance(workers, bool):
86
+ raise SettingsError(
87
+ "'workers' argument must be int"
88
+ f" while {workers.__class__.__name__} was given"
89
+ )
90
+ if workers <= 0:
91
+ raise SettingsError(
92
+ f"'workers' argument must be positive integer, {workers} was given"
93
+ )
94
+ self._workers = workers
95
+
96
+ if namespace is None:
97
+ self._namespace = None
98
+ else:
99
+ if not isinstance(namespace, str):
100
+ raise SettingsError(
101
+ "'namespace' argument must be str"
102
+ f", {namespace.__class__.__name__} was given"
103
+ )
104
+ self._namespace = namespace
105
+
106
+ if project is None:
107
+ self._project = None
108
+ else:
109
+ if not isinstance(project, str):
110
+ raise SettingsError(
111
+ "'project' argument must be str"
112
+ f", {project.__class__.__name__} was given"
113
+ )
114
+ self._project = project
115
+
116
+ if min_task_size is None:
117
+ self._min_task_size = None
118
+ else:
119
+ if not isinstance(min_task_size, int) or isinstance(min_task_size, bool):
120
+ raise SettingsError(
121
+ "'min_task_size' argument must be int"
122
+ f", {min_task_size.__class__.__name__} was given"
123
+ )
124
+ if min_task_size <= 0:
125
+ raise SettingsError(
126
+ "'min_task_size' argument must be positive integer"
127
+ f", {min_task_size} was given"
128
+ )
129
+ self._min_task_size = min_task_size
130
+
131
+ if batch_size is None:
132
+ self._batch_size = None
133
+ else:
134
+ if not isinstance(batch_size, int) or isinstance(batch_size, bool):
135
+ raise SettingsError(
136
+ "'batch_size' argument must be int"
137
+ f", {batch_size.__class__.__name__} was given"
138
+ )
139
+ if batch_size <= 0:
140
+ raise SettingsError(
141
+ "'batch_size' argument must be positive integer"
142
+ f", {batch_size} was given"
143
+ )
144
+ self._batch_size = batch_size
145
+
146
+ @property
147
+ def cache(self) -> bool:
148
+ return self._cache if self._cache is not None else DEFAULT_CACHE
149
+
150
+ @property
151
+ def prefetch(self) -> int | None:
152
+ return self._prefetch if self._prefetch is not None else DEFAULT_PREFETCH
153
+
154
+ @property
155
+ def parallel(self) -> bool | int | None:
156
+ return self._parallel if self._parallel is not None else None
157
+
158
+ @property
159
+ def workers(self) -> int | None:
160
+ return self._workers if self._workers is not None else None
161
+
162
+ @property
163
+ def namespace(self) -> str | None:
164
+ return self._namespace if self._namespace is not None else None
165
+
166
+ @property
167
+ def project(self) -> str | None:
168
+ return self._project if self._project is not None else None
51
169
 
52
170
  @property
53
- def cache(self):
54
- return self._cache if self._cache is not None else False
171
+ def min_task_size(self) -> int | None:
172
+ return self._min_task_size if self._min_task_size is not None else None
55
173
 
56
174
  @property
57
- def workers(self):
58
- return self._workers if self._workers is not None else False
175
+ def batch_size(self) -> int:
176
+ return self._batch_size if self._batch_size is not None else DEFAULT_BATCH_SIZE
59
177
 
60
- def to_dict(self):
61
- res = {}
178
+ def to_dict(self) -> dict[str, Any]:
179
+ res: dict[str, Any] = {}
62
180
  if self._cache is not None:
63
181
  res["cache"] = self.cache
64
- if self.parallel is not None:
182
+ if self._prefetch is not None:
183
+ res["prefetch"] = self.prefetch
184
+ if self._parallel is not None:
65
185
  res["parallel"] = self.parallel
66
186
  if self._workers is not None:
67
187
  res["workers"] = self.workers
68
- if self.min_task_size is not None:
188
+ if self._min_task_size is not None:
69
189
  res["min_task_size"] = self.min_task_size
190
+ if self._namespace is not None:
191
+ res["namespace"] = self.namespace
192
+ if self._project is not None:
193
+ res["project"] = self.project
194
+ if self._batch_size is not None:
195
+ res["batch_size"] = self.batch_size
70
196
  return res
71
197
 
72
- def add(self, settings: "Settings"):
73
- self._cache = settings._cache or self._cache
74
- self.parallel = settings.parallel or self.parallel
75
- self._workers = settings._workers or self._workers
76
- self.min_task_size = settings.min_task_size or self.min_task_size
77
- if settings.prefetch is not None:
78
- self.prefetch = settings.prefetch
198
+ def add(self, settings: "Settings") -> None:
199
+ if settings._cache is not None:
200
+ self._cache = settings._cache
201
+ if settings._prefetch is not None:
202
+ self._prefetch = settings._prefetch
203
+ if settings._parallel is not None:
204
+ self._parallel = settings._parallel
205
+ if settings._workers is not None:
206
+ self._workers = settings._workers
207
+ if settings._namespace is not None:
208
+ self._namespace = settings._namespace
209
+ if settings._project is not None:
210
+ self._project = settings._project
211
+ if settings._min_task_size is not None:
212
+ self._min_task_size = settings._min_task_size
213
+ if settings._batch_size is not None:
214
+ self._batch_size = settings._batch_size