lamindb 0.69.7__py3-none-any.whl → 0.69.9__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 (46) hide show
  1. lamindb/__init__.py +1 -1
  2. lamindb/_annotate.py +46 -42
  3. lamindb/_artifact.py +66 -70
  4. lamindb/_can_validate.py +29 -25
  5. lamindb/_collection.py +30 -34
  6. lamindb/_feature.py +10 -8
  7. lamindb/_feature_set.py +17 -15
  8. lamindb/_filter.py +2 -2
  9. lamindb/_finish.py +14 -8
  10. lamindb/_from_values.py +13 -9
  11. lamindb/_is_versioned.py +2 -2
  12. lamindb/_parents.py +16 -11
  13. lamindb/_query_manager.py +8 -4
  14. lamindb/_query_set.py +15 -15
  15. lamindb/_registry.py +36 -34
  16. lamindb/_run.py +3 -5
  17. lamindb/_save.py +13 -11
  18. lamindb/_transform.py +9 -11
  19. lamindb/_ulabel.py +11 -9
  20. lamindb/_view.py +3 -2
  21. lamindb/core/_data.py +21 -17
  22. lamindb/core/_feature_manager.py +18 -13
  23. lamindb/core/_label_manager.py +13 -9
  24. lamindb/core/_mapped_collection.py +16 -12
  25. lamindb/core/_run_context.py +21 -17
  26. lamindb/core/_settings.py +19 -16
  27. lamindb/core/_sync_git.py +4 -5
  28. lamindb/core/_track_environment.py +6 -1
  29. lamindb/core/_transform_settings.py +3 -3
  30. lamindb/core/_view_tree.py +2 -1
  31. lamindb/core/datasets/_core.py +3 -2
  32. lamindb/core/datasets/_fake.py +2 -2
  33. lamindb/core/storage/_anndata_sizes.py +2 -0
  34. lamindb/core/storage/_backed_access.py +17 -12
  35. lamindb/core/storage/_zarr.py +7 -3
  36. lamindb/core/storage/file.py +13 -6
  37. lamindb/core/storage/object.py +7 -3
  38. lamindb/core/types.py +0 -2
  39. lamindb/core/versioning.py +12 -8
  40. lamindb/integrations/_vitessce.py +2 -0
  41. lamindb/setup/core/__init__.py +3 -14
  42. {lamindb-0.69.7.dist-info → lamindb-0.69.9.dist-info}/METADATA +5 -5
  43. lamindb-0.69.9.dist-info/RECORD +54 -0
  44. lamindb-0.69.7.dist-info/RECORD +0 -54
  45. {lamindb-0.69.7.dist-info → lamindb-0.69.9.dist-info}/LICENSE +0 -0
  46. {lamindb-0.69.7.dist-info → lamindb-0.69.9.dist-info}/WHEEL +0 -0
lamindb/_parents.py CHANGED
@@ -1,5 +1,7 @@
1
+ from __future__ import annotations
2
+
1
3
  import builtins
2
- from typing import List, Optional, Set, Union
4
+ from typing import TYPE_CHECKING
3
5
 
4
6
  import lamindb_setup as ln_setup
5
7
  from lamin_utils import logger
@@ -8,7 +10,10 @@ from lnschema_core.models import HasParents, format_field_value
8
10
 
9
11
  from lamindb._utils import attach_func_to_class_method
10
12
 
11
- from ._registry import StrField, get_default_str_field
13
+ from ._registry import get_default_str_field
14
+
15
+ if TYPE_CHECKING:
16
+ from lnschema_core.types import StrField
12
17
 
13
18
  LAMIN_GREEN_LIGHTER = "#10b981"
14
19
  LAMIN_GREEN_DARKER = "#065f46"
@@ -47,7 +52,7 @@ def _view(u):
47
52
 
48
53
  def view_parents(
49
54
  self,
50
- field: Optional[StrField] = None,
55
+ field: StrField | None = None,
51
56
  with_children: bool = False,
52
57
  distance: int = 5,
53
58
  ):
@@ -61,7 +66,7 @@ def view_parents(
61
66
  )
62
67
 
63
68
 
64
- def view_lineage(data: Union[Artifact, Collection], with_children: bool = True) -> None:
69
+ def view_lineage(data: Artifact | Collection, with_children: bool = True) -> None:
65
70
  """Graph of data flow.
66
71
 
67
72
  Notes:
@@ -81,7 +86,7 @@ def view_lineage(data: Union[Artifact, Collection], with_children: bool = True)
81
86
  data_label = _record_label(data)
82
87
 
83
88
  def add_node(
84
- record: Union[Run, Artifact, Collection],
89
+ record: Run | Artifact | Collection,
85
90
  node_id: str,
86
91
  node_label: str,
87
92
  u: graphviz.Digraph,
@@ -256,7 +261,7 @@ def _df_edges_from_parents(
256
261
  return df_edges
257
262
 
258
263
 
259
- def _record_label(record: Registry, field: Optional[str] = None):
264
+ def _record_label(record: Registry, field: str | None = None):
260
265
  if isinstance(record, Artifact):
261
266
  if record.description is None:
262
267
  name = record.key
@@ -310,7 +315,7 @@ def _add_emoji(record: Registry, label: str):
310
315
  return f"{emoji} {label}"
311
316
 
312
317
 
313
- def _get_all_parent_runs(data: Union[Artifact, Collection]) -> List:
318
+ def _get_all_parent_runs(data: Artifact | Collection) -> list:
314
319
  """Get all input file/collection runs recursively."""
315
320
  name = data._meta.model_name
316
321
  run_inputs_outputs = []
@@ -346,10 +351,10 @@ def _get_all_parent_runs(data: Union[Artifact, Collection]) -> List:
346
351
  return run_inputs_outputs
347
352
 
348
353
 
349
- def _get_all_child_runs(data: Union[Artifact, Collection]) -> List:
354
+ def _get_all_child_runs(data: Artifact | Collection) -> list:
350
355
  """Get all output file/collection runs recursively."""
351
356
  name = data._meta.model_name
352
- all_runs: Set[Run] = set()
357
+ all_runs: set[Run] = set()
353
358
  run_inputs_outputs = []
354
359
 
355
360
  if data.run is not None:
@@ -367,7 +372,7 @@ def _get_all_child_runs(data: Union[Artifact, Collection]) -> List:
367
372
  )
368
373
  while runs.difference(all_runs):
369
374
  all_runs.update(runs)
370
- child_runs: Set[Run] = set()
375
+ child_runs: set[Run] = set()
371
376
  for r in runs:
372
377
  inputs_run = (
373
378
  r.__getattribute__(f"input_{name}s")
@@ -409,7 +414,7 @@ def _get_all_child_runs(data: Union[Artifact, Collection]) -> List:
409
414
  return run_inputs_outputs
410
415
 
411
416
 
412
- def _df_edges_from_runs(df_values: List):
417
+ def _df_edges_from_runs(df_values: list):
413
418
  import pandas as pd
414
419
 
415
420
  df = pd.DataFrame(df_values, columns=["source_record", "target_record"])
lamindb/_query_manager.py CHANGED
@@ -1,13 +1,17 @@
1
- from typing import NamedTuple, Optional
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING, NamedTuple
2
4
 
3
5
  from django.db import models
4
6
  from lamin_utils import logger
5
7
  from lamindb_setup.core._docs import doc_args
6
8
  from lnschema_core.models import Registry
7
- from lnschema_core.types import StrField
8
9
 
9
10
  from .core._feature_manager import get_feature_set_by_slot
10
11
 
12
+ if TYPE_CHECKING:
13
+ from lnschema_core.types import StrField
14
+
11
15
 
12
16
  class QueryManager(models.Manager):
13
17
  """Manage queries through fields.
@@ -41,7 +45,7 @@ class QueryManager(models.Manager):
41
45
  logger.warning(WARNING_RUN_TRANSFORM)
42
46
  _track_run_input(self.instance)
43
47
 
44
- def list(self, field: Optional[str] = None):
48
+ def list(self, field: str | None = None):
45
49
  """Populate a list with the results.
46
50
 
47
51
  Examples:
@@ -83,7 +87,7 @@ class QueryManager(models.Manager):
83
87
  return _search(cls=self.all(), string=string, **kwargs)
84
88
 
85
89
  @doc_args(Registry.lookup.__doc__)
86
- def lookup(self, field: Optional[StrField] = None, **kwargs) -> NamedTuple:
90
+ def lookup(self, field: StrField | None = None, **kwargs) -> NamedTuple:
87
91
  """{}."""
88
92
  from ._registry import _lookup
89
93
 
lamindb/_query_set.py CHANGED
@@ -1,5 +1,7 @@
1
+ from __future__ import annotations
2
+
1
3
  from collections import UserList
2
- from typing import Dict, Iterable, List, NamedTuple, Optional, Union
4
+ from typing import TYPE_CHECKING, Iterable, NamedTuple
3
5
 
4
6
  import pandas as pd
5
7
  from django.db import models
@@ -15,7 +17,9 @@ from lnschema_core.models import (
15
17
  Run,
16
18
  Transform,
17
19
  )
18
- from lnschema_core.types import ListLike, StrField
20
+
21
+ if TYPE_CHECKING:
22
+ from lnschema_core.types import ListLike, StrField
19
23
 
20
24
 
21
25
  class NoResultFound(Exception):
@@ -32,7 +36,7 @@ class MultipleResultsFound(Exception):
32
36
  # return (series + timedelta).dt.strftime("%Y-%m-%d %H:%M:%S %Z")
33
37
 
34
38
 
35
- def get_keys_from_df(data: List, registry: Registry) -> List[str]:
39
+ def get_keys_from_df(data: list, registry: Registry) -> list[str]:
36
40
  if len(data) > 0:
37
41
  if isinstance(data[0], dict):
38
42
  keys = list(data[0].keys())
@@ -94,7 +98,7 @@ class QuerySet(models.QuerySet, CanValidate, IsTree):
94
98
  """
95
99
 
96
100
  @doc_args(Registry.df.__doc__)
97
- def df(self, include: Optional[Union[str, List[str]]] = None) -> pd.DataFrame:
101
+ def df(self, include: str | list[str] | None = None) -> pd.DataFrame:
98
102
  """{}."""
99
103
  data = self.values()
100
104
  keys = get_keys_from_df(data, self.model)
@@ -173,7 +177,7 @@ class QuerySet(models.QuerySet, CanValidate, IsTree):
173
177
  else:
174
178
  self._delete_base_class(*args, **kwargs)
175
179
 
176
- def list(self, field: Optional[str] = None) -> List[Registry]:
180
+ def list(self, field: str | None = None) -> list[Registry]:
177
181
  """Populate a list with the results.
178
182
 
179
183
  Examples:
@@ -185,7 +189,7 @@ class QuerySet(models.QuerySet, CanValidate, IsTree):
185
189
  else:
186
190
  return list(self.values_list(field, flat=True))
187
191
 
188
- def first(self) -> Optional[Registry]:
192
+ def first(self) -> Registry | None:
189
193
  """If non-empty, the first result in the query set, otherwise ``None``.
190
194
 
191
195
  Examples:
@@ -203,7 +207,7 @@ class QuerySet(models.QuerySet, CanValidate, IsTree):
203
207
  """
204
208
  return one_helper(self)
205
209
 
206
- def one_or_none(self) -> Optional[Registry]:
210
+ def one_or_none(self) -> Registry | None:
207
211
  """At most one result. Returns it if there is one, otherwise returns ``None``.
208
212
 
209
213
  Examples:
@@ -232,25 +236,21 @@ class QuerySet(models.QuerySet, CanValidate, IsTree):
232
236
  return _search(cls=self, string=string, **kwargs)
233
237
 
234
238
  @doc_args(Registry.lookup.__doc__)
235
- def lookup(self, field: Optional[StrField] = None, **kwargs) -> NamedTuple:
239
+ def lookup(self, field: StrField | None = None, **kwargs) -> NamedTuple:
236
240
  """{}."""
237
241
  from ._registry import _lookup
238
242
 
239
243
  return _lookup(cls=self, field=field, **kwargs)
240
244
 
241
245
  @doc_args(CanValidate.validate.__doc__)
242
- def validate(
243
- self, values: ListLike, field: Optional[Union[str, StrField]] = None, **kwargs
244
- ):
246
+ def validate(self, values: ListLike, field: str | StrField | None = None, **kwargs):
245
247
  """{}."""
246
248
  from ._can_validate import _validate
247
249
 
248
250
  return _validate(cls=self, values=values, field=field, **kwargs)
249
251
 
250
252
  @doc_args(CanValidate.inspect.__doc__)
251
- def inspect(
252
- self, values: ListLike, field: Optional[Union[str, StrField]] = None, **kwargs
253
- ):
253
+ def inspect(self, values: ListLike, field: str | StrField | None = None, **kwargs):
254
254
  """{}."""
255
255
  from ._can_validate import _inspect
256
256
 
@@ -258,7 +258,7 @@ class QuerySet(models.QuerySet, CanValidate, IsTree):
258
258
 
259
259
  @doc_args(CanValidate.standardize.__doc__)
260
260
  def standardize(
261
- self, values: Iterable, field: Optional[Union[str, StrField]] = None, **kwargs
261
+ self, values: Iterable, field: str | StrField | None = None, **kwargs
262
262
  ):
263
263
  """{}."""
264
264
  from ._can_validate import _standardize
lamindb/_registry.py CHANGED
@@ -1,5 +1,7 @@
1
+ from __future__ import annotations
2
+
1
3
  import builtins
2
- from typing import Iterable, List, NamedTuple, Optional, Union
4
+ from typing import TYPE_CHECKING, Iterable, List, NamedTuple
3
5
  from uuid import UUID
4
6
 
5
7
  import dj_database_url
@@ -17,13 +19,15 @@ from lamindb_setup.core._docs import doc_args
17
19
  from lamindb_setup.core._hub_core import connect_instance
18
20
  from lamindb_setup.core._settings_storage import StorageSettings
19
21
  from lnschema_core import Registry
20
- from lnschema_core.types import ListLike, StrField
21
22
 
22
23
  from lamindb._utils import attach_func_to_class_method
23
24
  from lamindb.core._settings import settings
24
25
 
25
26
  from ._from_values import get_or_create_records
26
27
 
28
+ if TYPE_CHECKING:
29
+ from lnschema_core.types import ListLike, StrField
30
+
27
31
  IPYTHON = getattr(builtins, "__IPYTHON__", False)
28
32
 
29
33
 
@@ -53,7 +57,7 @@ def validate_required_fields(orm: Registry, kwargs):
53
57
  raise TypeError(f"{missing_fields} are required.")
54
58
 
55
59
 
56
- def suggest_objects_with_same_name(orm: Registry, kwargs) -> Optional[str]:
60
+ def suggest_objects_with_same_name(orm: Registry, kwargs) -> str | None:
57
61
  if kwargs.get("name") is None:
58
62
  return None
59
63
  else:
@@ -125,8 +129,8 @@ def __init__(orm: Registry, *args, **kwargs):
125
129
  @classmethod # type:ignore
126
130
  @doc_args(Registry.from_values.__doc__)
127
131
  def from_values(
128
- cls, values: ListLike, field: Optional[StrField] = None, **kwargs
129
- ) -> List["Registry"]:
132
+ cls, values: ListLike, field: StrField | None = None, **kwargs
133
+ ) -> list[Registry]:
130
134
  """{}."""
131
135
  from_public = True if cls.__module__.startswith("lnschema_bionty.") else False
132
136
  field_str = get_default_str_field(cls, field=field)
@@ -150,21 +154,21 @@ def _search(
150
154
  cls,
151
155
  string: str,
152
156
  *,
153
- field: Optional[Union[StrField, List[StrField]]] = None,
154
- limit: Optional[int] = 10,
157
+ field: StrField | list[StrField] | None = None,
158
+ limit: int | None = 10,
155
159
  return_queryset: bool = False,
156
160
  case_sensitive: bool = False,
157
- synonyms_field: Optional[StrField] = "synonyms",
158
- using_key: Optional[str] = None,
159
- ) -> Union["pd.DataFrame", "QuerySet"]:
161
+ synonyms_field: StrField | None = "synonyms",
162
+ using_key: str | None = None,
163
+ ) -> pd.DataFrame | QuerySet:
160
164
  queryset = _queryset(cls, using_key=using_key)
161
165
  orm = queryset.model
162
166
 
163
167
  def _search_single_field(
164
168
  string: str,
165
- field: Optional[StrField],
166
- synonyms_field: Optional[StrField] = "synonyms",
167
- ) -> "pd.DataFrame":
169
+ field: StrField | None,
170
+ synonyms_field: StrField | None = "synonyms",
171
+ ) -> pd.DataFrame:
168
172
  field = get_default_str_field(orm=orm, field=field)
169
173
 
170
174
  try:
@@ -233,12 +237,12 @@ def search(
233
237
  cls,
234
238
  string: str,
235
239
  *,
236
- field: Optional[StrField] = None,
237
- limit: Optional[int] = 20,
240
+ field: StrField | None = None,
241
+ limit: int | None = 20,
238
242
  return_queryset: bool = False,
239
243
  case_sensitive: bool = False,
240
- synonyms_field: Optional[StrField] = "synonyms",
241
- ) -> Union["pd.DataFrame", "QuerySet"]:
244
+ synonyms_field: StrField | None = "synonyms",
245
+ ) -> pd.DataFrame | QuerySet:
242
246
  """{}."""
243
247
  return _search(
244
248
  cls=cls,
@@ -253,9 +257,9 @@ def search(
253
257
 
254
258
  def _lookup(
255
259
  cls,
256
- field: Optional[StrField] = None,
257
- return_field: Optional[StrField] = None,
258
- using_key: Optional[str] = None,
260
+ field: StrField | None = None,
261
+ return_field: StrField | None = None,
262
+ using_key: str | None = None,
259
263
  ) -> NamedTuple:
260
264
  """{}."""
261
265
  queryset = _queryset(cls, using_key=using_key)
@@ -279,17 +283,17 @@ def _lookup(
279
283
  @doc_args(Registry.lookup.__doc__)
280
284
  def lookup(
281
285
  cls,
282
- field: Optional[StrField] = None,
283
- return_field: Optional[StrField] = None,
286
+ field: StrField | None = None,
287
+ return_field: StrField | None = None,
284
288
  ) -> NamedTuple:
285
289
  """{}."""
286
290
  return _lookup(cls=cls, field=field, return_field=return_field)
287
291
 
288
292
 
289
293
  def get_default_str_field(
290
- orm: Union[Registry, QuerySet, Manager],
294
+ orm: Registry | QuerySet | Manager,
291
295
  *,
292
- field: Optional[Union[str, StrField]] = None,
296
+ field: str | StrField | None = None,
293
297
  ) -> str:
294
298
  """Get the 1st char or text field from the orm."""
295
299
  if isinstance(orm, (QuerySet, Manager)):
@@ -332,7 +336,7 @@ def get_default_str_field(
332
336
  return field
333
337
 
334
338
 
335
- def _queryset(cls: Union[Registry, QuerySet, Manager], using_key: str) -> QuerySet:
339
+ def _queryset(cls: Registry | QuerySet | Manager, using_key: str) -> QuerySet:
336
340
  queryset = (
337
341
  cls.all() if isinstance(cls, QuerySet) else cls.objects.using(using_key).all()
338
342
  )
@@ -354,7 +358,7 @@ def add_db_connection(db: str, using: str):
354
358
  def using(
355
359
  cls,
356
360
  instance: str,
357
- ) -> "QuerySet":
361
+ ) -> QuerySet:
358
362
  """{}."""
359
363
  from lamindb_setup._connect_instance import (
360
364
  load_instance_settings,
@@ -388,9 +392,9 @@ REGISTRY_UNIQUE_FIELD = {
388
392
 
389
393
 
390
394
  def update_fk_to_default_db(
391
- records: Union[Registry, List[Registry], QuerySet],
395
+ records: Registry | list[Registry] | QuerySet,
392
396
  fk: str,
393
- using_key: Optional[str],
397
+ using_key: str | None,
394
398
  ):
395
399
  record = records[0] if isinstance(records, (List, QuerySet)) else records
396
400
  if hasattr(record, f"{fk}_id") and getattr(record, f"{fk}_id") is not None:
@@ -424,20 +428,18 @@ FKBULK = [
424
428
  ]
425
429
 
426
430
 
427
- def transfer_fk_to_default_db_bulk(
428
- records: Union[List, QuerySet], using_key: Optional[str]
429
- ):
431
+ def transfer_fk_to_default_db_bulk(records: list | QuerySet, using_key: str | None):
430
432
  for fk in FKBULK:
431
433
  update_fk_to_default_db(records, fk, using_key)
432
434
 
433
435
 
434
436
  def transfer_to_default_db(
435
437
  record: Registry,
436
- using_key: Optional[str],
438
+ using_key: str | None,
437
439
  save: bool = False,
438
440
  mute: bool = False,
439
441
  transfer_fk: bool = True,
440
- ) -> Optional[Registry]:
442
+ ) -> Registry | None:
441
443
  db = record._state.db
442
444
  if db is not None and db != "default" and using_key is None:
443
445
  registry = record.__class__
@@ -495,7 +497,7 @@ def save(self, *args, **kwargs) -> None:
495
497
  using_key = kwargs["using"]
496
498
  db = self._state.db
497
499
  pk_on_db = self.pk
498
- artifacts: List = []
500
+ artifacts: list = []
499
501
  if self.__class__.__name__ == "Collection" and self.id is not None:
500
502
  # when creating a new collection without being able to access artifacts
501
503
  artifacts = self.artifacts.list()
lamindb/_run.py CHANGED
@@ -1,4 +1,4 @@
1
- from typing import Optional
1
+ from __future__ import annotations
2
2
 
3
3
  from lnschema_core.models import Run, Transform
4
4
 
@@ -13,10 +13,8 @@ def __init__(run: Run, *args, **kwargs):
13
13
  transform: Transform = None
14
14
  if "transform" in kwargs or len(args) == 1:
15
15
  transform = kwargs.pop("transform") if len(args) == 0 else args[0]
16
- reference: Optional[str] = (
17
- kwargs.pop("reference") if "reference" in kwargs else None
18
- )
19
- reference_type: Optional[str] = (
16
+ reference: str | None = kwargs.pop("reference") if "reference" in kwargs else None
17
+ reference_type: str | None = (
20
18
  kwargs.pop("reference_type") if "reference_type" in kwargs else None
21
19
  )
22
20
  if transform is None:
lamindb/_save.py CHANGED
@@ -1,10 +1,12 @@
1
+ from __future__ import annotations
2
+
1
3
  import os
2
4
  import shutil
3
5
  import traceback
4
6
  from collections import defaultdict
5
7
  from datetime import datetime
6
8
  from functools import partial
7
- from typing import Iterable, List, Optional, Tuple, Union, overload
9
+ from typing import Iterable, overload
8
10
 
9
11
  import lamindb_setup
10
12
  from django.db import transaction
@@ -30,7 +32,7 @@ except ImportError:
30
32
 
31
33
 
32
34
  def save(
33
- records: Iterable[Registry], ignore_conflicts: Optional[bool] = False, **kwargs
35
+ records: Iterable[Registry], ignore_conflicts: bool | None = False, **kwargs
34
36
  ) -> None:
35
37
  """Bulk save to registries & storage.
36
38
 
@@ -123,7 +125,7 @@ def save(
123
125
  return None
124
126
 
125
127
 
126
- def bulk_create(records: Iterable[Registry], ignore_conflicts: Optional[bool] = False):
128
+ def bulk_create(records: Iterable[Registry], ignore_conflicts: bool | None = False):
127
129
  records_by_orm = defaultdict(list)
128
130
  for record in records:
129
131
  records_by_orm[record.__class__].append(record)
@@ -134,9 +136,9 @@ def bulk_create(records: Iterable[Registry], ignore_conflicts: Optional[bool] =
134
136
  # This is also used within Artifact.save()
135
137
  def check_and_attempt_upload(
136
138
  artifact: Artifact,
137
- using_key: Optional[str] = None,
138
- access_token: Optional[str] = None,
139
- ) -> Optional[Exception]:
139
+ using_key: str | None = None,
140
+ access_token: str | None = None,
141
+ ) -> Exception | None:
140
142
  # if Artifact object is either newly instantiated or replace() was called on
141
143
  # a local env it will have a _local_filepath and needs to be uploaded
142
144
  if hasattr(artifact, "_local_filepath"):
@@ -199,8 +201,8 @@ def copy_or_move_to_cache(artifact: Artifact, storage_path: UPath):
199
201
 
200
202
  # This is also used within Artifact.save()
201
203
  def check_and_attempt_clearing(
202
- artifact: Artifact, using_key: Optional[str] = None
203
- ) -> Optional[Exception]:
204
+ artifact: Artifact, using_key: str | None = None
205
+ ) -> Exception | None:
204
206
  # this is a clean-up operation after replace() was called
205
207
  # this will only evaluate to True if replace() was called
206
208
  if hasattr(artifact, "_clear_storagekey"):
@@ -220,13 +222,13 @@ def check_and_attempt_clearing(
220
222
 
221
223
 
222
224
  def store_artifacts(
223
- artifacts: Iterable[Artifact], using_key: Optional[str] = None
225
+ artifacts: Iterable[Artifact], using_key: str | None = None
224
226
  ) -> None:
225
227
  """Upload artifacts in a list of database-committed artifacts to storage.
226
228
 
227
229
  If any upload fails, subsequent artifacts are cleaned up from the DB.
228
230
  """
229
- exception: Optional[Exception] = None
231
+ exception: Exception | None = None
230
232
  # because uploads might fail, we need to maintain a new list
231
233
  # of the succeeded uploads
232
234
  stored_artifacts = []
@@ -274,7 +276,7 @@ def prepare_error_message(records, stored_artifacts, exception) -> str:
274
276
 
275
277
 
276
278
  def upload_artifact(
277
- artifact, using_key: Optional[str] = None, access_token: Optional[str] = None
279
+ artifact, using_key: str | None = None, access_token: str | None = None
278
280
  ) -> UPath:
279
281
  """Store and add file and its linked entries."""
280
282
  # can't currently use filepath_from_artifact here because it resolves to ._local_filepath
lamindb/_transform.py CHANGED
@@ -1,4 +1,4 @@
1
- from typing import Optional
1
+ from __future__ import annotations
2
2
 
3
3
  from lnschema_core.models import Artifact, Run, Transform
4
4
  from lnschema_core.types import TransformType
@@ -11,24 +11,22 @@ def __init__(transform: Transform, *args, **kwargs):
11
11
  if len(args) == len(transform._meta.concrete_fields):
12
12
  super(Transform, transform).__init__(*args, **kwargs)
13
13
  return None
14
- name: Optional[str] = kwargs.pop("name") if "name" in kwargs else None
15
- key: Optional[str] = kwargs.pop("key") if "key" in kwargs else None
16
- is_new_version_of: Optional[Transform] = (
14
+ name: str | None = kwargs.pop("name") if "name" in kwargs else None
15
+ key: str | None = kwargs.pop("key") if "key" in kwargs else None
16
+ is_new_version_of: Transform | None = (
17
17
  kwargs.pop("is_new_version_of") if "is_new_version_of" in kwargs else None
18
18
  )
19
19
  (kwargs.pop("initial_version_id") if "initial_version_id" in kwargs else None)
20
- version: Optional[str] = kwargs.pop("version") if "version" in kwargs else None
21
- type: Optional[TransformType] = (
20
+ version: str | None = kwargs.pop("version") if "version" in kwargs else None
21
+ type: TransformType | None = (
22
22
  kwargs.pop("type") if "type" in kwargs else TransformType.pipeline
23
23
  )
24
- reference: Optional[str] = (
25
- kwargs.pop("reference") if "reference" in kwargs else None
26
- )
27
- reference_type: Optional[str] = (
24
+ reference: str | None = kwargs.pop("reference") if "reference" in kwargs else None
25
+ reference_type: str | None = (
28
26
  kwargs.pop("reference_type") if "reference_type" in kwargs else None
29
27
  )
30
28
  # below is internal use that we'll hopefully be able to eliminate
31
- uid: Optional[str] = kwargs.pop("uid") if "uid" in kwargs else None
29
+ uid: str | None = kwargs.pop("uid") if "uid" in kwargs else None
32
30
  if not len(kwargs) == 0:
33
31
  raise ValueError(
34
32
  "Only name, key, version, type, is_new_version_of, reference, "
lamindb/_ulabel.py CHANGED
@@ -1,14 +1,18 @@
1
- from typing import List, Optional
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING
2
4
 
3
5
  import lamindb_setup as ln_setup
4
6
  from lamindb_setup.core._docs import doc_args
5
7
  from lnschema_core import ULabel
6
- from lnschema_core.types import ListLike
7
8
 
8
9
  from lamindb._utils import attach_func_to_class_method
9
10
 
10
11
  from ._from_values import get_or_create_records
11
12
 
13
+ if TYPE_CHECKING:
14
+ from lnschema_core.types import ListLike
15
+
12
16
 
13
17
  def __init__(self, *args, **kwargs):
14
18
  if len(args) == len(self._meta.concrete_fields):
@@ -17,14 +21,12 @@ def __init__(self, *args, **kwargs):
17
21
  # now we proceed with the user-facing constructor
18
22
  if len(args) > 0:
19
23
  raise ValueError("Only one non-keyword arg allowed")
20
- name: Optional[str] = kwargs.pop("name") if "name" in kwargs else None
21
- description: Optional[str] = (
24
+ name: str | None = kwargs.pop("name") if "name" in kwargs else None
25
+ description: str | None = (
22
26
  kwargs.pop("description") if "description" in kwargs else None
23
27
  )
24
- reference: Optional[str] = (
25
- kwargs.pop("reference") if "reference" in kwargs else None
26
- )
27
- reference_type: Optional[str] = (
28
+ reference: str | None = kwargs.pop("reference") if "reference" in kwargs else None
29
+ reference_type: str | None = (
28
30
  kwargs.pop("reference_type") if "reference_type" in kwargs else None
29
31
  )
30
32
  if len(kwargs) > 0:
@@ -41,7 +43,7 @@ def __init__(self, *args, **kwargs):
41
43
 
42
44
  @classmethod # type:ignore
43
45
  @doc_args(ULabel.from_values.__doc__)
44
- def from_values(cls, values: ListLike, **kwargs) -> List["ULabel"]:
46
+ def from_values(cls, values: ListLike, **kwargs) -> list[ULabel]:
45
47
  """{}."""
46
48
  records = get_or_create_records(
47
49
  iterable=values,
lamindb/_view.py CHANGED
@@ -1,6 +1,7 @@
1
+ from __future__ import annotations
2
+
1
3
  import importlib
2
4
  import inspect
3
- from typing import List, Optional
4
5
 
5
6
  from IPython.display import display
6
7
  from lamin_utils import colors, logger
@@ -10,7 +11,7 @@ from lnschema_core import Registry
10
11
 
11
12
 
12
13
  def view(
13
- n: int = 7, schema: Optional[str] = None, registries: Optional[List[str]] = None
14
+ n: int = 7, schema: str | None = None, registries: list[str] | None = None
14
15
  ) -> None:
15
16
  """View latest metadata state.
16
17