lamindb 0.69.7__py3-none-any.whl → 0.69.8__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 (44) hide show
  1. lamindb/__init__.py +1 -1
  2. lamindb/_annotate.py +46 -42
  3. lamindb/_artifact.py +63 -64
  4. lamindb/_can_validate.py +29 -25
  5. lamindb/_collection.py +28 -32
  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 +17 -12
  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 +10 -6
  37. lamindb/core/storage/object.py +7 -3
  38. lamindb/core/versioning.py +12 -8
  39. lamindb/integrations/_vitessce.py +2 -0
  40. {lamindb-0.69.7.dist-info → lamindb-0.69.8.dist-info}/METADATA +4 -4
  41. lamindb-0.69.8.dist-info/RECORD +54 -0
  42. lamindb-0.69.7.dist-info/RECORD +0 -54
  43. {lamindb-0.69.7.dist-info → lamindb-0.69.8.dist-info}/LICENSE +0 -0
  44. {lamindb-0.69.7.dist-info → lamindb-0.69.8.dist-info}/WHEEL +0 -0
lamindb/_can_validate.py CHANGED
@@ -1,28 +1,32 @@
1
- from typing import Dict, Iterable, List, Literal, Optional, Set, Union
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING, Iterable, Literal
2
4
 
3
5
  import lamindb_setup as ln_setup
4
6
  import numpy as np
5
7
  import pandas as pd
6
8
  from django.core.exceptions import FieldDoesNotExist
7
- from django.db.models import QuerySet
8
9
  from lamin_utils import colors, logger
9
- from lamin_utils._inspect import InspectResult
10
10
  from lamindb_setup.core._docs import doc_args
11
11
  from lnschema_core import CanValidate, Registry
12
- from lnschema_core.types import ListLike, StrField
13
12
 
14
13
  from lamindb._utils import attach_func_to_class_method
15
14
 
16
15
  from ._from_values import _has_organism_field, _print_values
17
16
  from ._registry import _queryset, get_default_str_field
18
17
 
18
+ if TYPE_CHECKING:
19
+ from django.db.models import QuerySet
20
+ from lamin_utils._inspect import InspectResult
21
+ from lnschema_core.types import ListLike, StrField
22
+
19
23
 
20
24
  @classmethod # type: ignore
21
25
  @doc_args(CanValidate.inspect.__doc__)
22
26
  def inspect(
23
27
  cls,
24
28
  values: ListLike,
25
- field: Optional[Union[str, StrField]] = None,
29
+ field: str | StrField | None = None,
26
30
  *,
27
31
  mute: bool = False,
28
32
  **kwargs,
@@ -42,7 +46,7 @@ def inspect(
42
46
  def validate(
43
47
  cls,
44
48
  values: ListLike,
45
- field: Optional[Union[str, StrField]] = None,
49
+ field: str | StrField | None = None,
46
50
  *,
47
51
  mute: bool = False,
48
52
  **kwargs,
@@ -54,12 +58,12 @@ def validate(
54
58
  def _inspect(
55
59
  cls,
56
60
  values: ListLike,
57
- field: Optional[Union[str, StrField]] = None,
61
+ field: str | StrField | None = None,
58
62
  *,
59
63
  mute: bool = False,
60
- using_key: Optional[str] = None,
64
+ using_key: str | None = None,
61
65
  **kwargs,
62
- ) -> Union["pd.DataFrame", Dict[str, List[str]]]:
66
+ ) -> pd.DataFrame | dict[str, list[str]]:
63
67
  """{}."""
64
68
  from lamin_utils._inspect import inspect
65
69
 
@@ -138,10 +142,10 @@ def _inspect(
138
142
  def _validate(
139
143
  cls,
140
144
  values: ListLike,
141
- field: Optional[Union[str, StrField]] = None,
145
+ field: str | StrField | None = None,
142
146
  *,
143
147
  mute: bool = False,
144
- using_key: Optional[str] = None,
148
+ using_key: str | None = None,
145
149
  **kwargs,
146
150
  ) -> np.ndarray:
147
151
  """{}."""
@@ -182,7 +186,7 @@ def _validate(
182
186
  def standardize(
183
187
  cls,
184
188
  values: Iterable,
185
- field: Optional[Union[str, StrField]] = None,
189
+ field: str | StrField | None = None,
186
190
  *,
187
191
  return_field: str = None,
188
192
  return_mapper: bool = False,
@@ -192,7 +196,7 @@ def standardize(
192
196
  keep: Literal["first", "last", False] = "first",
193
197
  synonyms_field: str = "synonyms",
194
198
  **kwargs,
195
- ) -> Union[List[str], Dict[str, str]]:
199
+ ) -> list[str] | dict[str, str]:
196
200
  """{}."""
197
201
  return _standardize(
198
202
  cls=cls,
@@ -226,9 +230,9 @@ def set_abbr(self, value: str):
226
230
 
227
231
  def add_synonym(
228
232
  self,
229
- synonym: Union[str, ListLike],
233
+ synonym: str | ListLike,
230
234
  force: bool = False,
231
- save: Optional[bool] = None,
235
+ save: bool | None = None,
232
236
  ):
233
237
  _check_synonyms_field_exist(self)
234
238
  _add_or_remove_synonyms(
@@ -236,7 +240,7 @@ def add_synonym(
236
240
  )
237
241
 
238
242
 
239
- def remove_synonym(self, synonym: Union[str, ListLike]):
243
+ def remove_synonym(self, synonym: str | ListLike):
240
244
  _check_synonyms_field_exist(self)
241
245
  _add_or_remove_synonyms(synonym=synonym, record=self, action="remove")
242
246
 
@@ -244,7 +248,7 @@ def remove_synonym(self, synonym: Union[str, ListLike]):
244
248
  def _standardize(
245
249
  cls,
246
250
  values: Iterable,
247
- field: Optional[Union[str, StrField]] = None,
251
+ field: str | StrField | None = None,
248
252
  *,
249
253
  return_field: str = None,
250
254
  return_mapper: bool = False,
@@ -253,9 +257,9 @@ def _standardize(
253
257
  public_aware: bool = True,
254
258
  keep: Literal["first", "last", False] = "first",
255
259
  synonyms_field: str = "synonyms",
256
- using_key: Optional[str] = None,
260
+ using_key: str | None = None,
257
261
  **kwargs,
258
- ) -> Union[List[str], Dict[str, str]]:
262
+ ) -> list[str] | dict[str, str]:
259
263
  """{}."""
260
264
  from lamin_utils._standardize import standardize as map_synonyms
261
265
 
@@ -302,7 +306,7 @@ def _standardize(
302
306
  **_kwargs,
303
307
  )
304
308
 
305
- def _return(result: List, mapper: Dict):
309
+ def _return(result: list, mapper: dict):
306
310
  if return_mapper:
307
311
  return mapper
308
312
  else:
@@ -350,15 +354,15 @@ def _standardize(
350
354
 
351
355
 
352
356
  def _add_or_remove_synonyms(
353
- synonym: Union[str, Iterable],
357
+ synonym: str | Iterable,
354
358
  record: Registry,
355
359
  action: Literal["add", "remove"],
356
360
  force: bool = False,
357
- save: Optional[bool] = None,
361
+ save: bool | None = None,
358
362
  ):
359
363
  """Add or remove synonyms."""
360
364
 
361
- def check_synonyms_in_all_records(synonyms: Set[str], record: Registry):
365
+ def check_synonyms_in_all_records(synonyms: set[str], record: Registry):
362
366
  """Errors if input synonym is associated with other records in the DB."""
363
367
  import pandas as pd
364
368
  from IPython.display import display
@@ -437,8 +441,8 @@ def _check_synonyms_field_exist(record: Registry):
437
441
 
438
442
  def _filter_query_based_on_organism(
439
443
  queryset: QuerySet,
440
- organism: Optional[Union[str, Registry]] = None,
441
- values_list_field: Optional[str] = None,
444
+ organism: str | Registry | None = None,
445
+ values_list_field: str | None = None,
442
446
  ):
443
447
  """Filter a queryset based on organism."""
444
448
  import pandas as pd
lamindb/_collection.py CHANGED
@@ -1,14 +1,11 @@
1
+ from __future__ import annotations
2
+
1
3
  from collections import defaultdict
2
4
  from typing import (
3
5
  TYPE_CHECKING,
4
6
  Any,
5
- Dict,
6
7
  Iterable,
7
- List,
8
8
  Literal,
9
- Optional,
10
- Tuple,
11
- Union,
12
9
  )
13
10
 
14
11
  import anndata as ad
@@ -24,12 +21,10 @@ from lnschema_core.types import DataLike, VisibilityChoice
24
21
  from lamindb._utils import attach_func_to_class_method
25
22
  from lamindb.core._data import _track_run_input
26
23
  from lamindb.core._mapped_collection import MappedCollection
27
- from lamindb.core.storage import UPath
28
24
  from lamindb.core.versioning import get_uid_from_old_version, init_uid
29
25
 
30
26
  from . import Artifact, Run
31
27
  from ._artifact import data_is_anndata
32
- from ._query_set import QuerySet
33
28
  from ._registry import init_self_from_db
34
29
  from .core._data import (
35
30
  add_transform_to_kwargs,
@@ -39,10 +34,13 @@ from .core._data import (
39
34
  )
40
35
 
41
36
  if TYPE_CHECKING:
37
+ from lamindb.core.storage import UPath
42
38
  from lamindb.core.storage._backed_access import AnnDataAccessor, BackedAccessor
43
39
 
40
+ from ._query_set import QuerySet
41
+
44
42
 
45
- def _check_accessor_collection(data: Any, accessor: Optional[str] = None):
43
+ def _check_accessor_collection(data: Any, accessor: str | None = None):
46
44
  if accessor is None and isinstance(data, (AnnData, pd.DataFrame)):
47
45
  if isinstance(data, pd.DataFrame):
48
46
  logger.warning("data is a DataFrame, please use .from_df()")
@@ -64,31 +62,29 @@ def __init__(
64
62
  # now we proceed with the user-facing constructor
65
63
  if len(args) > 1:
66
64
  raise ValueError("Only one non-keyword arg allowed: data")
67
- data: Union[Artifact, Iterable[Artifact]] = (
65
+ data: Artifact | Iterable[Artifact] = (
68
66
  kwargs.pop("data") if len(args) == 0 else args[0]
69
67
  )
70
- meta: Optional[str] = kwargs.pop("meta") if "meta" in kwargs else None
71
- name: Optional[str] = kwargs.pop("name") if "name" in kwargs else None
72
- description: Optional[str] = (
68
+ meta: str | None = kwargs.pop("meta") if "meta" in kwargs else None
69
+ name: str | None = kwargs.pop("name") if "name" in kwargs else None
70
+ description: str | None = (
73
71
  kwargs.pop("description") if "description" in kwargs else None
74
72
  )
75
- reference: Optional[str] = (
76
- kwargs.pop("reference") if "reference" in kwargs else None
77
- )
78
- reference_type: Optional[str] = (
73
+ reference: str | None = kwargs.pop("reference") if "reference" in kwargs else None
74
+ reference_type: str | None = (
79
75
  kwargs.pop("reference_type") if "reference_type" in kwargs else None
80
76
  )
81
- run: Optional[Run] = kwargs.pop("run") if "run" in kwargs else None
82
- is_new_version_of: Optional[Collection] = (
77
+ run: Run | None = kwargs.pop("run") if "run" in kwargs else None
78
+ is_new_version_of: Collection | None = (
83
79
  kwargs.pop("is_new_version_of") if "is_new_version_of" in kwargs else None
84
80
  )
85
- version: Optional[str] = kwargs.pop("version") if "version" in kwargs else None
86
- visibility: Optional[int] = (
81
+ version: str | None = kwargs.pop("version") if "version" in kwargs else None
82
+ visibility: int | None = (
87
83
  kwargs.pop("visibility")
88
84
  if "visibility" in kwargs
89
85
  else VisibilityChoice.default.value
90
86
  )
91
- feature_sets: Dict[str, FeatureSet] = (
87
+ feature_sets: dict[str, FeatureSet] = (
92
88
  kwargs.pop("feature_sets") if "feature_sets" in kwargs else {}
93
89
  )
94
90
  accessor = kwargs.pop("accessor") if "accessor" in kwargs else None
@@ -166,7 +162,7 @@ def __init__(
166
162
 
167
163
 
168
164
  # internal function, not exposed to user
169
- def from_artifacts(artifacts: Iterable[Artifact]) -> Tuple[str, Dict[str, str]]:
165
+ def from_artifacts(artifacts: Iterable[Artifact]) -> tuple[str, dict[str, str]]:
170
166
  # assert all artifacts are already saved
171
167
  logger.debug("check not saved")
172
168
  saved = not any(artifact._state.adding for artifact in artifacts)
@@ -228,16 +224,16 @@ def from_artifacts(artifacts: Iterable[Artifact]) -> Tuple[str, Dict[str, str]]:
228
224
  # docstring handled through attach_func_to_class_method
229
225
  def mapped(
230
226
  self,
231
- label_keys: Optional[Union[str, List[str]]] = None,
232
- join: Optional[Literal["inner", "outer"]] = "inner",
233
- encode_labels: Union[bool, List[str]] = True,
234
- unknown_label: Optional[Union[str, Dict[str, str]]] = None,
227
+ label_keys: str | list[str] | None = None,
228
+ join: Literal["inner", "outer"] | None = "inner",
229
+ encode_labels: bool | list[str] = True,
230
+ unknown_label: str | dict[str, str] | None = None,
235
231
  cache_categories: bool = True,
236
232
  parallel: bool = False,
237
- dtype: Optional[str] = None,
233
+ dtype: str | None = None,
238
234
  stream: bool = False,
239
- is_run_input: Optional[bool] = None,
240
- ) -> "MappedCollection":
235
+ is_run_input: bool | None = None,
236
+ ) -> MappedCollection:
241
237
  path_list = []
242
238
  for artifact in self.artifacts.all():
243
239
  if artifact.suffix not in {".h5ad", ".zrad", ".zarr"}:
@@ -263,7 +259,7 @@ def mapped(
263
259
 
264
260
 
265
261
  # docstring handled through attach_func_to_class_method
266
- def stage(self, is_run_input: Optional[bool] = None) -> List[UPath]:
262
+ def stage(self, is_run_input: bool | None = None) -> list[UPath]:
267
263
  _track_run_input(self, is_run_input)
268
264
  path_list = []
269
265
  for artifact in self.artifacts.all():
@@ -275,7 +271,7 @@ def stage(self, is_run_input: Optional[bool] = None) -> List[UPath]:
275
271
  def load(
276
272
  self,
277
273
  join: Literal["inner", "outer"] = "outer",
278
- is_run_input: Optional[bool] = None,
274
+ is_run_input: bool | None = None,
279
275
  **kwargs,
280
276
  ) -> DataLike:
281
277
  # cannot call _track_run_input here, see comment further down
@@ -301,7 +297,7 @@ def load(
301
297
 
302
298
 
303
299
  # docstring handled through attach_func_to_class_method
304
- def delete(self, permanent: Optional[bool] = None) -> None:
300
+ def delete(self, permanent: bool | None = None) -> None:
305
301
  # change visibility to trash
306
302
  trash_visibility = VisibilityChoice.trash.value
307
303
  if self.visibility > trash_visibility and permanent is not True:
lamindb/_feature.py CHANGED
@@ -1,10 +1,11 @@
1
- from typing import Dict, List, Optional, Union
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING, List
2
4
 
3
5
  import lamindb_setup as ln_setup
4
6
  import pandas as pd
5
7
  from lamindb_setup.core._docs import doc_args
6
8
  from lnschema_core.models import Feature, Registry
7
- from lnschema_core.types import FieldAttr
8
9
  from pandas.api.types import CategoricalDtype, is_string_dtype
9
10
 
10
11
  from lamindb._utils import attach_func_to_class_method
@@ -12,6 +13,9 @@ from lamindb.core._settings import settings
12
13
 
13
14
  from ._query_set import RecordsList
14
15
 
16
+ if TYPE_CHECKING:
17
+ from lnschema_core.types import FieldAttr
18
+
15
19
  FEATURE_TYPES = {
16
20
  "int": "number",
17
21
  "float": "number",
@@ -41,7 +45,7 @@ def __init__(self, *args, **kwargs):
41
45
  type: Optional[Union[type, str]] = ( # noqa
42
46
  kwargs.pop("type") if "type" in kwargs else None
43
47
  )
44
- registries: Optional[List[Registry]] = (
48
+ registries: list[Registry] | None = (
45
49
  kwargs.pop("registries") if "registries" in kwargs else None
46
50
  )
47
51
  # cast type
@@ -55,7 +59,7 @@ def __init__(self, *args, **kwargs):
55
59
  raise ValueError("type has to be one of 'number', 'category', 'bool'!")
56
60
  kwargs["type"] = type_str
57
61
  # cast registries
58
- registries_str: Optional[str] = None
62
+ registries_str: str | None = None
59
63
  if registries is not None:
60
64
  if isinstance(registries, str):
61
65
  # TODO: add more validation
@@ -73,7 +77,7 @@ def __init__(self, *args, **kwargs):
73
77
  super(Feature, self).__init__(*args, **kwargs)
74
78
 
75
79
 
76
- def categoricals_from_df(df: "pd.DataFrame") -> Dict:
80
+ def categoricals_from_df(df: pd.DataFrame) -> dict:
77
81
  """Returns categorical columns."""
78
82
  string_cols = [col for col in df.columns if is_string_dtype(df[col])]
79
83
  categoricals = {
@@ -90,9 +94,7 @@ def categoricals_from_df(df: "pd.DataFrame") -> Dict:
90
94
 
91
95
  @classmethod # type:ignore
92
96
  @doc_args(Feature.from_df.__doc__)
93
- def from_df(
94
- cls, df: "pd.DataFrame", field: Optional[FieldAttr] = None
95
- ) -> "RecordsList":
97
+ def from_df(cls, df: pd.DataFrame, field: FieldAttr | None = None) -> RecordsList:
96
98
  """{}."""
97
99
  field = Feature.name if field is None else field
98
100
  categoricals = categoricals_from_df(df)
lamindb/_feature_set.py CHANGED
@@ -1,4 +1,6 @@
1
- from typing import TYPE_CHECKING, Dict, Iterable, List, Optional, Type, Union
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING, Iterable
2
4
 
3
5
  import lamindb_setup as ln_setup
4
6
  import numpy as np
@@ -22,7 +24,7 @@ NUMBER_TYPE = "number"
22
24
 
23
25
 
24
26
  def dict_related_model_to_related_name(orm):
25
- d: Dict = {
27
+ d: dict = {
26
28
  i.related_model.__get_name_with_schema__(): i.related_name
27
29
  for i in orm._meta.related_objects
28
30
  if i.related_name is not None
@@ -39,7 +41,7 @@ def dict_related_model_to_related_name(orm):
39
41
 
40
42
 
41
43
  def dict_schema_name_to_model_name(orm):
42
- d: Dict = {
44
+ d: dict = {
43
45
  i.related_model.__get_name_with_schema__(): i.related_model
44
46
  for i in orm._meta.related_objects
45
47
  if i.related_name is not None
@@ -72,7 +74,7 @@ def get_related_name(features_type: Registry):
72
74
  return candidates[0]
73
75
 
74
76
 
75
- def validate_features(features: List[Registry]) -> Registry:
77
+ def validate_features(features: list[Registry]) -> Registry:
76
78
  """Validate and return feature type."""
77
79
  try:
78
80
  if len(features) == 0:
@@ -104,8 +106,8 @@ def __init__(self, *args, **kwargs):
104
106
  if len(args) > 1:
105
107
  raise ValueError("Only one non-keyword arg allowed: features")
106
108
  features: Iterable[Registry] = kwargs.pop("features") if len(args) == 0 else args[0]
107
- type: Optional[Union[type, str]] = kwargs.pop("type") if "type" in kwargs else None
108
- name: Optional[str] = kwargs.pop("name") if "name" in kwargs else None
109
+ type: str | None = kwargs.pop("type") if "type" in kwargs else None
110
+ name: str | None = kwargs.pop("name") if "name" in kwargs else None
109
111
  if len(kwargs) > 0:
110
112
  raise ValueError("Only features, type, name are valid keyword arguments")
111
113
  # now code
@@ -142,9 +144,9 @@ def save(self, *args, **kwargs) -> None:
142
144
  getattr(self, related_name).set(records)
143
145
 
144
146
 
145
- def get_type_str(type: Optional[Union[Type, str]]) -> Optional[str]:
147
+ def get_type_str(type: str | None) -> str | None:
146
148
  if type is not None:
147
- type_str = type.__name__ if not isinstance(type, str) else type
149
+ type_str = type.__name__ if not isinstance(type, str) else type # type: ignore
148
150
  else:
149
151
  type_str = None
150
152
  if type == "int" or type == "float":
@@ -158,10 +160,10 @@ def from_values(
158
160
  cls,
159
161
  values: ListLike,
160
162
  field: FieldAttr = Feature.name,
161
- type: Optional[Union[Type, str]] = None,
162
- name: Optional[str] = None,
163
+ type: str | None = None,
164
+ name: str | None = None,
163
165
  **kwargs,
164
- ) -> Optional["FeatureSet"]:
166
+ ) -> FeatureSet | None:
165
167
  """{}."""
166
168
  if not isinstance(field, FieldAttr):
167
169
  raise TypeError(
@@ -192,11 +194,11 @@ def from_values(
192
194
  @doc_args(FeatureSet.from_df.__doc__)
193
195
  def from_df(
194
196
  cls,
195
- df: "pd.DataFrame",
197
+ df: pd.DataFrame,
196
198
  field: FieldAttr = Feature.name,
197
- name: Optional[str] = None,
199
+ name: str | None = None,
198
200
  **kwargs,
199
- ) -> Optional["FeatureSet"]:
201
+ ) -> FeatureSet | None:
200
202
  """{}."""
201
203
  registry = field.field.model
202
204
  validated = registry.validate(df.columns, field=field, **kwargs)
@@ -225,7 +227,7 @@ def from_df(
225
227
 
226
228
  @property # type: ignore
227
229
  @doc_args(FeatureSet.members.__doc__)
228
- def members(self) -> "QuerySet":
230
+ def members(self) -> QuerySet:
229
231
  """{}."""
230
232
  if self._state.adding:
231
233
  # this should return a queryset and not a list...
lamindb/_filter.py CHANGED
@@ -1,4 +1,4 @@
1
- from typing import Type
1
+ from __future__ import annotations
2
2
 
3
3
  from lnschema_core import Artifact, Collection, Registry
4
4
  from lnschema_core.types import VisibilityChoice
@@ -7,7 +7,7 @@ from lamindb import settings
7
7
  from lamindb._query_set import QuerySet
8
8
 
9
9
 
10
- def filter(Registry: Type[Registry], **expressions) -> QuerySet:
10
+ def filter(Registry: type[Registry], **expressions) -> QuerySet:
11
11
  """See :meth:`~lamindb.core.Registry.filter`."""
12
12
  _using_key = None
13
13
  if "_using_key" in expressions:
lamindb/_finish.py CHANGED
@@ -1,18 +1,24 @@
1
+ from __future__ import annotations
2
+
1
3
  import os
2
4
  import shutil
3
5
  import subprocess
4
6
  from datetime import datetime, timezone
5
- from pathlib import Path
6
- from typing import Optional
7
+ from typing import TYPE_CHECKING
7
8
 
8
9
  import lamindb_setup as ln_setup
9
10
  from lamin_utils import logger
10
- from lnschema_core import Run, Transform
11
11
  from lnschema_core.types import TransformType
12
12
 
13
- from ._query_set import QuerySet
14
13
  from .core._run_context import is_run_from_ipython, run_context
15
14
 
15
+ if TYPE_CHECKING:
16
+ from pathlib import Path
17
+
18
+ from lnschema_core import Run, Transform
19
+
20
+ from ._query_set import QuerySet
21
+
16
22
 
17
23
  class CallFinishInLastCell(SystemExit):
18
24
  pass
@@ -34,13 +40,13 @@ def finish(i_saved_the_notebook: bool = False):
34
40
 
35
41
  if not i_saved_the_notebook and not ln_setup._TESTING:
36
42
  logger.error(
37
- "Please save the notebook, pass `i_saved_the_notebook=True`, and re-run this cell."
43
+ "Please pass `i_saved_the_notebook=True` to `ln.finish()`, save the notebook, and re-run this cell."
38
44
  )
39
45
  return None
40
46
  notebook_content = read_notebook(run_context.path) # type: ignore
41
47
  if not check_last_cell(notebook_content, "i_saved_the_notebook"):
42
48
  raise CallFinishInLastCell(
43
- "Can only finish() from the last code cell of the notebook."
49
+ "Can only run `ln.finish(i_saved_the_notebook=True)` from the last code cell of the notebook."
44
50
  )
45
51
  save_run_context_core(
46
52
  run=run_context.run,
@@ -61,11 +67,11 @@ def save_run_context_core(
61
67
  run: Run,
62
68
  transform: Transform,
63
69
  filepath: Path,
64
- transform_family: Optional[QuerySet] = None,
70
+ transform_family: QuerySet | None = None,
65
71
  is_consecutive: bool = True,
66
72
  finished_at: bool = False,
67
73
  notebook_content=None, # nbproject.Notebook
68
- ) -> Optional[str]:
74
+ ) -> str | None:
69
75
  import lamindb as ln
70
76
 
71
77
  ln.settings.verbosity = "success"
lamindb/_from_values.py CHANGED
@@ -1,13 +1,17 @@
1
- from typing import Any, Dict, Iterable, List, Tuple, Union
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING, Any, Iterable
2
4
 
3
5
  import pandas as pd
4
6
  from django.core.exceptions import FieldDoesNotExist
5
7
  from lamin_utils import colors, logger
6
8
  from lnschema_core.models import Feature, Registry, ULabel
7
- from lnschema_core.types import ListLike, StrField
8
9
 
9
10
  from .core._settings import settings
10
11
 
12
+ if TYPE_CHECKING:
13
+ from lnschema_core.types import ListLike, StrField
14
+
11
15
 
12
16
  # The base function for `from_values`
13
17
  def get_or_create_records(
@@ -16,7 +20,7 @@ def get_or_create_records(
16
20
  *,
17
21
  from_public: bool = False,
18
22
  **kwargs,
19
- ) -> List[Registry]:
23
+ ) -> list[Registry]:
20
24
  """Get or create records from iterables."""
21
25
  upon_create_search_names = settings.upon_create_search_names
22
26
  settings.upon_create_search_names = False
@@ -74,12 +78,12 @@ def get_or_create_records(
74
78
  def get_existing_records(
75
79
  iterable_idx: pd.Index,
76
80
  field: StrField,
77
- kwargs: Dict = None,
81
+ kwargs: dict = None,
78
82
  ):
79
83
  if kwargs is None:
80
84
  kwargs = {}
81
85
  model = field.field.model
82
- condition: Dict = {} if len(kwargs) == 0 else kwargs.copy()
86
+ condition: dict = {} if len(kwargs) == 0 else kwargs.copy()
83
87
  # existing records matching is agnostic to the bionty source
84
88
  if "public_source" in condition:
85
89
  condition.pop("public_source")
@@ -167,7 +171,7 @@ def create_records_from_public(
167
171
  **kwargs,
168
172
  ):
169
173
  model = field.field.model
170
- records: List = []
174
+ records: list = []
171
175
  # populate additional fields from bionty
172
176
  from lnschema_bionty._bionty import get_public_source_record
173
177
 
@@ -247,7 +251,7 @@ def index_iterable(iterable: Iterable) -> pd.Index:
247
251
  return idx[(idx != "") & (~idx.isnull())]
248
252
 
249
253
 
250
- def _print_values(names: List, n: int = 20) -> str:
254
+ def _print_values(names: list, n: int = 20) -> str:
251
255
  print_values = ", ".join([f"'{name}'" for name in names[:n]])
252
256
  if len(names) > n:
253
257
  print_values += ", ..."
@@ -292,8 +296,8 @@ def _filter_bionty_df_columns(model: Registry, public_ontology: Any) -> pd.DataF
292
296
 
293
297
 
294
298
  def _bulk_create_dicts_from_df(
295
- keys: Union[set, List], column_name: str, df: pd.DataFrame
296
- ) -> Tuple[Dict, str]:
299
+ keys: set | list, column_name: str, df: pd.DataFrame
300
+ ) -> tuple[dict, str]:
297
301
  """Get fields from a DataFrame for many rows."""
298
302
  multi_msg = ""
299
303
  if df.index.name != column_name:
lamindb/_is_versioned.py CHANGED
@@ -1,4 +1,4 @@
1
- from typing import Optional
1
+ from __future__ import annotations
2
2
 
3
3
  import lamindb_setup as ln_setup
4
4
  from lamin_utils import logger
@@ -12,7 +12,7 @@ from .core.versioning import get_new_path_from_uid, get_uid_from_old_version
12
12
 
13
13
  # docstring handled through attach_func_to_class_method
14
14
  def add_to_version_family(
15
- self, is_new_version_of: IsVersioned, version: Optional[str] = None
15
+ self, is_new_version_of: IsVersioned, version: str | None = None
16
16
  ):
17
17
  old_uid = self.uid
18
18
  new_uid, version = get_uid_from_old_version(is_new_version_of, version)