liminal-orm 2.0.0__py3-none-any.whl → 2.0.2__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.
@@ -1,96 +1,9 @@
1
- from typing import Any, ClassVar
1
+ import warnings
2
2
 
3
- from pydantic import BaseModel, ConfigDict, field_validator
3
+ from liminal.orm.name_template_parts import * # noqa: F403
4
4
 
5
- from liminal.enums.name_template_part_type import NameTemplatePartType
6
-
7
-
8
- class NameTemplatePart(BaseModel):
9
- """Base class for all name template parts. These are put together in a list (where order matters) to form a name template.
10
-
11
- Parameters
12
- ----------
13
- component_type : NameTemplatePartType
14
- The type of the component. One of the values in the NameTemplatePartType enum.
15
-
16
- """
17
-
18
- component_type: ClassVar[NameTemplatePartType]
19
-
20
- _type_map: ClassVar[dict[NameTemplatePartType, type["NameTemplatePart"]]] = {}
21
-
22
- model_config = ConfigDict(arbitrary_types_allowed=True)
23
-
24
- def __init_subclass__(cls, **kwargs: Any) -> None:
25
- super().__init_subclass__(**kwargs)
26
- cls._type_map[cls.component_type] = cls
27
-
28
- @classmethod
29
- def resolve_type(cls, type: NameTemplatePartType) -> type["NameTemplatePart"]:
30
- if type not in cls._type_map:
31
- raise ValueError(f"Invalid name template part type: {type}")
32
- return cls._type_map[type]
33
-
34
-
35
- class SeparatorPart(NameTemplatePart):
36
- component_type: ClassVar[NameTemplatePartType] = NameTemplatePartType.SEPARATOR
37
- value: str
38
-
39
- @field_validator("value")
40
- def validate_value(cls, v: str) -> str:
41
- if not v:
42
- raise ValueError("value cannot be empty")
43
- return v
44
-
45
-
46
- class TextPart(NameTemplatePart):
47
- component_type: ClassVar[NameTemplatePartType] = NameTemplatePartType.TEXT
48
- value: str
49
-
50
- @field_validator("value")
51
- def validate_value(cls, v: str) -> str:
52
- if not v:
53
- raise ValueError("value cannot be empty")
54
- return v
55
-
56
-
57
- class CreationYearPart(NameTemplatePart):
58
- component_type: ClassVar[NameTemplatePartType] = NameTemplatePartType.CREATION_YEAR
59
-
60
-
61
- class CreationDatePart(NameTemplatePart):
62
- component_type: ClassVar[NameTemplatePartType] = NameTemplatePartType.CREATION_DATE
63
-
64
-
65
- class FieldPart(NameTemplatePart):
66
- component_type: ClassVar[NameTemplatePartType] = NameTemplatePartType.FIELD
67
- wh_field_name: str
68
-
69
-
70
- class ParentLotNumberPart(NameTemplatePart):
71
- component_type: ClassVar[NameTemplatePartType] = (
72
- NameTemplatePartType.CHILD_ENTITY_LOT_NUMBER
73
- )
74
- wh_field_name: str
75
-
76
-
77
- class RegistryIdentifierNumberPart(NameTemplatePart):
78
- component_type: ClassVar[NameTemplatePartType] = (
79
- NameTemplatePartType.REGISTRY_IDENTIFIER_NUMBER
80
- )
81
-
82
-
83
- class ProjectPart(NameTemplatePart):
84
- component_type: ClassVar[NameTemplatePartType] = NameTemplatePartType.PROJECT
85
-
86
-
87
- NameTemplateParts = (
88
- SeparatorPart
89
- | TextPart
90
- | CreationYearPart
91
- | CreationDatePart
92
- | FieldPart
93
- | RegistryIdentifierNumberPart
94
- | ProjectPart
95
- | ParentLotNumberPart
5
+ warnings.warn(
6
+ "Importing from 'liminal.base.name_template_parts' is deprecated. Please import from 'liminal.orm.name_template_parts' instead.",
7
+ DeprecationWarning,
8
+ stacklevel=2,
96
9
  )
@@ -4,7 +4,7 @@ from typing import Any
4
4
 
5
5
  from pydantic import BaseModel, ConfigDict
6
6
 
7
- from liminal.base.name_template_parts import NameTemplateParts
7
+ from liminal.orm.name_template_parts import NameTemplateParts
8
8
 
9
9
 
10
10
  class BaseNameTemplate(BaseModel):
@@ -135,7 +135,7 @@ def generate_all_entity_schema_files(
135
135
  if name_template != NameTemplate():
136
136
  import_strings.append("from liminal.orm.name_template import NameTemplate")
137
137
  parts_imports = [
138
- f"from liminal.base.name_template_parts import {', '.join(set([part.__class__.__name__ for part in name_template.parts]))}"
138
+ f"from liminal.orm.name_template_parts import {', '.join(set([part.__class__.__name__ for part in name_template.parts]))}"
139
139
  ]
140
140
  import_strings.extend(parts_imports)
141
141
  for col_name, col in columns.items():
@@ -5,9 +5,6 @@ from typing import Any
5
5
  import requests
6
6
  from pydantic import BaseModel
7
7
 
8
- from liminal.base.name_template_parts import (
9
- NameTemplatePart,
10
- )
11
8
  from liminal.base.properties.base_field_properties import BaseFieldProperties
12
9
  from liminal.base.properties.base_name_template import BaseNameTemplate
13
10
  from liminal.base.properties.base_schema_properties import BaseSchemaProperties
@@ -24,6 +21,9 @@ from liminal.mappers import (
24
21
  convert_entity_type_to_api_entity_type,
25
22
  convert_field_type_to_api_field_type,
26
23
  )
24
+ from liminal.orm.name_template_parts import (
25
+ NameTemplatePart,
26
+ )
27
27
  from liminal.orm.schema_properties import MixtureSchemaConfig
28
28
 
29
29
 
@@ -1,14 +1,5 @@
1
1
  # flake8: noqa: F401
2
2
  from liminal.base.base_operation import BaseOperation
3
- from liminal.base.name_template_parts import (
4
- CreationDatePart,
5
- CreationYearPart,
6
- FieldPart,
7
- ProjectPart,
8
- RegistryIdentifierNumberPart,
9
- SeparatorPart,
10
- TextPart,
11
- )
12
3
  from liminal.base.properties.base_field_properties import BaseFieldProperties
13
4
  from liminal.base.properties.base_name_template import BaseNameTemplate
14
5
  from liminal.base.properties.base_schema_properties import BaseSchemaProperties
@@ -42,3 +33,12 @@ from liminal.enums import (
42
33
  BenchlingNamingStrategy,
43
34
  BenchlingSequenceType,
44
35
  )
36
+ from liminal.orm.name_template_parts import (
37
+ CreationDatePart,
38
+ CreationYearPart,
39
+ FieldPart,
40
+ ProjectPart,
41
+ RegistryIdentifierNumberPart,
42
+ SeparatorPart,
43
+ TextPart,
44
+ )
liminal/orm/base_model.py CHANGED
@@ -12,11 +12,11 @@ from sqlalchemy.orm import Query, RelationshipProperty, Session, relationship
12
12
  from sqlalchemy.orm.decl_api import declared_attr
13
13
 
14
14
  from liminal.base.base_validation_filters import BaseValidatorFilters
15
- from liminal.base.name_template_parts import FieldPart
16
15
  from liminal.enums import BenchlingNamingStrategy
17
16
  from liminal.orm.base import Base
18
17
  from liminal.orm.base_tables.user import User
19
18
  from liminal.orm.name_template import NameTemplate
19
+ from liminal.orm.name_template_parts import FieldPart
20
20
  from liminal.orm.schema_properties import SchemaProperties
21
21
  from liminal.validation import BenchlingValidatorReport
22
22
 
@@ -4,8 +4,8 @@ from typing import Any
4
4
 
5
5
  from pydantic import ConfigDict, field_validator
6
6
 
7
- from liminal.base.name_template_parts import NameTemplateParts, SeparatorPart
8
7
  from liminal.base.properties.base_name_template import BaseNameTemplate
8
+ from liminal.orm.name_template_parts import NameTemplateParts, SeparatorPart
9
9
 
10
10
 
11
11
  class NameTemplate(BaseNameTemplate):
@@ -19,7 +19,7 @@ class NameTemplate(BaseNameTemplate):
19
19
  The list of name template parts that make up the name template (order matters). Defaults to no parts, an empty list.
20
20
  order_name_parts_by_sequence : bool = False
21
21
  Whether to order the name parts by sequence. This can only be set to True for sequence enity types. If one or many part link fields are included in the name template,
22
- list parts in the order they appear on the sequence map, sorted by start position and then end position.Defaults to False.
22
+ list parts in the order they appear on the sequence map, sorted by start position and then end position. Defaults to False.
23
23
  """
24
24
 
25
25
  parts: list[NameTemplateParts] = []
@@ -0,0 +1,96 @@
1
+ from typing import Any, ClassVar
2
+
3
+ from pydantic import BaseModel, ConfigDict, field_validator
4
+
5
+ from liminal.enums.name_template_part_type import NameTemplatePartType
6
+
7
+
8
+ class NameTemplatePart(BaseModel):
9
+ """Base class for all name template parts. These are put together in a list (where order matters) to form a name template.
10
+
11
+ Parameters
12
+ ----------
13
+ component_type : NameTemplatePartType
14
+ The type of the component. One of the values in the NameTemplatePartType enum.
15
+
16
+ """
17
+
18
+ component_type: ClassVar[NameTemplatePartType]
19
+
20
+ _type_map: ClassVar[dict[NameTemplatePartType, type["NameTemplatePart"]]] = {}
21
+
22
+ model_config = ConfigDict(arbitrary_types_allowed=True)
23
+
24
+ def __init_subclass__(cls, **kwargs: Any) -> None:
25
+ super().__init_subclass__(**kwargs)
26
+ cls._type_map[cls.component_type] = cls
27
+
28
+ @classmethod
29
+ def resolve_type(cls, type: NameTemplatePartType) -> type["NameTemplatePart"]:
30
+ if type not in cls._type_map:
31
+ raise ValueError(f"Invalid name template part type: {type}")
32
+ return cls._type_map[type]
33
+
34
+
35
+ class SeparatorPart(NameTemplatePart):
36
+ component_type: ClassVar[NameTemplatePartType] = NameTemplatePartType.SEPARATOR
37
+ value: str
38
+
39
+ @field_validator("value")
40
+ def validate_value(cls, v: str) -> str:
41
+ if not v:
42
+ raise ValueError("value cannot be empty")
43
+ return v
44
+
45
+
46
+ class TextPart(NameTemplatePart):
47
+ component_type: ClassVar[NameTemplatePartType] = NameTemplatePartType.TEXT
48
+ value: str
49
+
50
+ @field_validator("value")
51
+ def validate_value(cls, v: str) -> str:
52
+ if not v:
53
+ raise ValueError("value cannot be empty")
54
+ return v
55
+
56
+
57
+ class CreationYearPart(NameTemplatePart):
58
+ component_type: ClassVar[NameTemplatePartType] = NameTemplatePartType.CREATION_YEAR
59
+
60
+
61
+ class CreationDatePart(NameTemplatePart):
62
+ component_type: ClassVar[NameTemplatePartType] = NameTemplatePartType.CREATION_DATE
63
+
64
+
65
+ class FieldPart(NameTemplatePart):
66
+ component_type: ClassVar[NameTemplatePartType] = NameTemplatePartType.FIELD
67
+ wh_field_name: str
68
+
69
+
70
+ class ParentLotNumberPart(NameTemplatePart):
71
+ component_type: ClassVar[NameTemplatePartType] = (
72
+ NameTemplatePartType.CHILD_ENTITY_LOT_NUMBER
73
+ )
74
+ wh_field_name: str
75
+
76
+
77
+ class RegistryIdentifierNumberPart(NameTemplatePart):
78
+ component_type: ClassVar[NameTemplatePartType] = (
79
+ NameTemplatePartType.REGISTRY_IDENTIFIER_NUMBER
80
+ )
81
+
82
+
83
+ class ProjectPart(NameTemplatePart):
84
+ component_type: ClassVar[NameTemplatePartType] = NameTemplatePartType.PROJECT
85
+
86
+
87
+ NameTemplateParts = (
88
+ SeparatorPart
89
+ | TextPart
90
+ | CreationYearPart
91
+ | CreationDatePart
92
+ | FieldPart
93
+ | RegistryIdentifierNumberPart
94
+ | ProjectPart
95
+ | ParentLotNumberPart
96
+ )
@@ -1,7 +1,6 @@
1
1
  import copy
2
2
  from unittest.mock import Mock, patch
3
3
 
4
- from liminal.base.name_template_parts import TextPart
5
4
  from liminal.base.properties.base_field_properties import BaseFieldProperties
6
5
  from liminal.entity_schemas.compare import compare_entity_schemas
7
6
  from liminal.entity_schemas.operations import (
@@ -18,6 +17,7 @@ from liminal.entity_schemas.operations import (
18
17
  )
19
18
  from liminal.enums import BenchlingFieldType
20
19
  from liminal.orm.name_template import NameTemplate
20
+ from liminal.orm.name_template_parts import TextPart
21
21
 
22
22
 
23
23
  class TestCompareEntitySchemas:
@@ -1,7 +1,7 @@
1
1
  import inspect
2
2
  from datetime import datetime
3
- from functools import wraps
4
- from typing import TYPE_CHECKING, Callable
3
+ from functools import partial, wraps
4
+ from typing import TYPE_CHECKING, Any, Callable
5
5
 
6
6
  from pydantic import BaseModel, ConfigDict
7
7
 
@@ -67,6 +67,7 @@ class BenchlingValidatorReport(BaseModel):
67
67
  entity: type["BenchlingBaseModel"],
68
68
  validator_name: str,
69
69
  message: str | None = None,
70
+ **kwargs: Any,
70
71
  ) -> "BenchlingValidatorReport":
71
72
  """Creates a BenchlingValidatorReport with the given parameters.
72
73
 
@@ -96,59 +97,68 @@ class BenchlingValidatorReport(BaseModel):
96
97
  creator_email=entity.creator.email if entity.creator else None,
97
98
  updated_date=entity.modified_at,
98
99
  message=message,
100
+ **kwargs,
99
101
  )
100
102
 
101
103
 
102
- def liminal_validator(
103
- validator_level: ValidationSeverity = ValidationSeverity.LOW,
104
- validator_name: str | None = None,
104
+ def _liminal_decorator(
105
+ func: Callable[[type["BenchlingBaseModel"]], BenchlingValidatorReport | None],
106
+ validator_level: ValidationSeverity,
107
+ validator_name: str | None,
105
108
  ) -> Callable:
106
- """A decorator that validates a function that takes a Benchling entity as an argument and returns None.
107
-
108
- Parameters:
109
- validator_level: ValidationSeverity
110
- The level of the validator.
111
- validator_name: str | None
112
- The name of the validator. Defaults to the pascalized name of the function.
113
- """
114
-
115
- def decorator(func: Callable[[type["BenchlingBaseModel"]], None]) -> Callable:
116
- """Decorator that validates a function that takes a Benchling entity as an argument and returns None."""
117
- sig = inspect.signature(func)
118
- params = list(sig.parameters.values())
119
- if not params or params[0].name != "self" or len(params) > 1:
120
- raise TypeError(
121
- "Validator must defined in a schema class, where the only argument to this validator must be 'self'."
122
- )
109
+ """Core decorator logic for liminal_validator."""
110
+ sig = inspect.signature(func)
111
+ params = list(sig.parameters.values())
112
+ if not params or params[0].name != "self" or len(params) > 1:
113
+ raise TypeError(
114
+ "Validator must be defined in a schema class, where the only argument to this validator must be 'self'."
115
+ )
123
116
 
124
- if sig.return_annotation is not None:
125
- raise TypeError("The return type must be None.")
126
-
127
- nonlocal validator_name
128
- if validator_name is None:
129
- validator_name = pascalize(func.__name__)
130
-
131
- @wraps(func)
132
- def wrapper(self: type["BenchlingBaseModel"]) -> BenchlingValidatorReport:
133
- """Wrapper that runs the validator function and returns a BenchlingValidatorReport."""
134
- try:
135
- func(self)
136
- except Exception as e:
137
- return BenchlingValidatorReport.create_validation_report(
138
- valid=False,
139
- level=validator_level,
140
- entity=self,
141
- validator_name=validator_name,
142
- message=str(e),
143
- )
117
+ if validator_name is None:
118
+ validator_name = pascalize(func.__name__)
119
+
120
+ @wraps(func)
121
+ def wrapper(self: type["BenchlingBaseModel"]) -> BenchlingValidatorReport:
122
+ """Wrapper that runs the validator function and returns a BenchlingValidatorReport."""
123
+ try:
124
+ ret_val = func(self)
125
+ if type(ret_val) is BenchlingValidatorReport:
126
+ return ret_val
127
+ except Exception as e:
144
128
  return BenchlingValidatorReport.create_validation_report(
145
- valid=True,
129
+ valid=False,
146
130
  level=validator_level,
147
131
  entity=self,
148
132
  validator_name=validator_name,
133
+ message=str(e),
149
134
  )
135
+ return BenchlingValidatorReport.create_validation_report(
136
+ valid=True,
137
+ level=validator_level,
138
+ entity=self,
139
+ validator_name=validator_name,
140
+ )
141
+
142
+ setattr(wrapper, "_is_liminal_validator", True)
143
+ return wrapper
150
144
 
151
- setattr(wrapper, "_is_liminal_validator", True)
152
- return wrapper
153
145
 
154
- return decorator
146
+ def liminal_validator(
147
+ validator_level: ValidationSeverity = ValidationSeverity.LOW,
148
+ validator_name: str | None = None,
149
+ ) -> Callable:
150
+ """A decorator for a function that validates a Benchling entity, defined on a schema class.
151
+ Wraps around any exceptions raised by the validator function, and returns a BenchlingValidatorReport.
152
+
153
+ Parameters
154
+ ----------
155
+ validator_level: ValidationSeverity
156
+ The severity level of the validation report. Defaults to ValidationSeverity.LOW.
157
+ validator_name: str | None =
158
+ The name of the validator. Defaults to the PascalCase version of the function name.
159
+ """
160
+ return partial(
161
+ _liminal_decorator,
162
+ validator_level=validator_level,
163
+ validator_name=validator_name,
164
+ )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: liminal-orm
3
- Version: 2.0.0
3
+ Version: 2.0.2
4
4
  Summary: An ORM and toolkit that builds on top of Benchling's platform to keep your schemas and downstream code dependencies in sync.
5
5
  Home-page: https://github.com/dynotx/liminal-orm
6
6
  Author: DynoTx Open Source
@@ -88,7 +88,7 @@ With your schemas defined in code, you can now take advantage of the additional
88
88
  class Pizza(BaseModel, CustomEntityMixin):
89
89
  ...
90
90
 
91
- @liminal_validator(ValidationSeverity.MED)
91
+ @liminal_validator
92
92
  def cook_time_and_temp_validator(self) -> None:
93
93
  if self.cook_time is not None and self.cook_temp is None:
94
94
  raise ValueError("Cook temp is required if cook time is set")
@@ -3,9 +3,9 @@ liminal/base/base_dropdown.py,sha256=Unk4l_5Y8rj_eSWYqzFi2BAFSQToQDWW2qdXwiCHTg8
3
3
  liminal/base/base_operation.py,sha256=RjGRaCTNQ5oVI4PAQ5D3svymw_HAcGvzBXWWrMRo29k,3128
4
4
  liminal/base/base_validation_filters.py,sha256=kHG3G5gXkuNHQosMTrxRc57OTmczcaoSx0DmkrScIr4,1043
5
5
  liminal/base/compare_operation.py,sha256=hkpv4ewHhxy4dlTPKgJuzBjsAqO6Km7OrrKB44pRA_o,352
6
- liminal/base/name_template_parts.py,sha256=KCGXAcCuOqCjlgYn-mw1K7fwDI92D20l-FnlpEVrbM8,2771
6
+ liminal/base/name_template_parts.py,sha256=dJeyrhhhZHDwKXe_p7AtgDlbZlzsnYQ8FoM8FXVF7q0,271
7
7
  liminal/base/properties/base_field_properties.py,sha256=NvuQjYZ5U_2363P2c8FXmmLfOtdzUqTuZTjDDfXnO-E,4922
8
- liminal/base/properties/base_name_template.py,sha256=EHytur3jcPSRx-it_2elYSjdgx7OOr206qyf2bFcweg,3151
8
+ liminal/base/properties/base_name_template.py,sha256=AOtaW4QEDRC-mjZOZk6jgc_mopUMsHS2Fj6VVsO07WY,3150
9
9
  liminal/base/properties/base_schema_properties.py,sha256=pVeIVHea-3Wt0fde9CsOvluwVmYMbsMhGeSncRL2Ats,5351
10
10
  liminal/base/str_enum.py,sha256=jF3d-Lo8zsHUe6GsctX2L-TSj92Y3qCYDrTD-saeJoc,210
11
11
  liminal/cli/cli.py,sha256=JxWHLO9KMeMaOnOYwzdH0w71l0477ScFOkWNtTlc97Y,9045
@@ -23,9 +23,9 @@ liminal/dropdowns/utils.py,sha256=1-H7bTszCUeqeRBpiYXjRjreDzhn1Fd1MFwIsrEI-o4,41
23
23
  liminal/entity_schemas/api.py,sha256=Emn_Y95cAG9Wis6tpchw6QBVKQh4If86LOdgKk0Ndjw,3575
24
24
  liminal/entity_schemas/compare.py,sha256=CIYglq1F-g9jGc1eRRD4LnNErrH2n__pPIJc4EB1hkM,16570
25
25
  liminal/entity_schemas/entity_schema_models.py,sha256=YDpz1XkNc9e51zah8Z6qCk30gAuXP6xLEYv1Lb3ECpA,6838
26
- liminal/entity_schemas/generate_files.py,sha256=ujzofsGlr76z5YadOar0_6ufkjBYZjz0aawBUupIvnU,8878
26
+ liminal/entity_schemas/generate_files.py,sha256=oYx0t76oRa36gWwVl1W5jHryh-POIyZPDMbGNjT5bfY,8877
27
27
  liminal/entity_schemas/operations.py,sha256=rs9EXmHDgnUad2SSfZ3tnDPFA6L-2wvllAGqBwBurMs,24020
28
- liminal/entity_schemas/tag_schema_models.py,sha256=BGvfQwjfIcRl3yHmYUM6sQpkbFTUMaeT6ix62fjKp2A,22017
28
+ liminal/entity_schemas/tag_schema_models.py,sha256=h6Zf_zXYG_gTh2eQh_lEGZKUAmvzdnnArlmAhIeX1bM,22016
29
29
  liminal/entity_schemas/utils.py,sha256=iZ1_M2r8zKOCFj9QSMdrv-_4XznDn_znAOfoP4Mh1jA,4943
30
30
  liminal/enums/__init__.py,sha256=Ue_3QtElW-JMSWtu4vGsAOFQbYnzHHZUdkWpdkzkKA4,453
31
31
  liminal/enums/benchling_api_field_type.py,sha256=0QamSWEMnxZtedZXlh6zNhSRogS9ZqvWskdHHN19xJo,633
@@ -35,20 +35,21 @@ liminal/enums/benchling_folder_item_type.py,sha256=Jb-YxCvB8O86_qTsfwtLQOkKGjTWG
35
35
  liminal/enums/benchling_naming_strategy.py,sha256=wG3AfnPOui5Qfc0Fihszm5uKWjuc7gdpI8jptNB5A-w,1201
36
36
  liminal/enums/benchling_sequence_type.py,sha256=TBI4C5c1XKE4ZXqsz1ApDUzy2wR-04u-M3VO_zLikjM,202
37
37
  liminal/enums/name_template_part_type.py,sha256=Kv0phZIO_dPN3tLHM0lT2tjUd3zBGqpJQGahEpGjNcU,365
38
- liminal/external/__init__.py,sha256=rYg51-fI6FO7H2iZkbIPUzWpSW8MTBKfiTNwLZt3yvY,1265
38
+ liminal/external/__init__.py,sha256=nMpyzpBXpYhTvN3R3HQEiYb24_U2AYjz_20seAUUK9s,1264
39
39
  liminal/mappers.py,sha256=O9gc95b7JvfaR8xVrn0X1d0Tcs6Iwh-yhBHXhWSX8i0,9616
40
40
  liminal/migrate/components.py,sha256=2HuFp5KDNhofROMRI-BioUoA4CCjhQ_v_F0QmGJzUBU,3480
41
41
  liminal/migrate/revision.py,sha256=KppU0u-d0JsfPsXsmncxy9Q_XBJyf-o4e16wNZAJODM,7774
42
42
  liminal/migrate/revisions_timeline.py,sha256=G9VwxPrLhLqKOrIXyxrXyHpujc-72m7omsZjI5-0D0M,14520
43
43
  liminal/migrate/utils.py,sha256=HdSr3N2WN_1S-PLRGVWSMYl-4gIcP-Ph2wPycGi2cGg,3404
44
44
  liminal/orm/base.py,sha256=fFSpiNRYgK5UG7lbXdQGV8KgO8pwjMqt0pycM3rWJ2o,615
45
- liminal/orm/base_model.py,sha256=RYVQ2kFaxMDGYWL2Lv63KMUZljSyIkdkjoSHoHLU8UU,13892
45
+ liminal/orm/base_model.py,sha256=Nf4gSEwvORRdnY5ODW79ddJWxnshLLvrPo8xcimHH6c,13891
46
46
  liminal/orm/base_tables/registry_entity.py,sha256=4ET1cepTGjZ3AMFI5q-iMYxMObzXwuUDBD0jNNqCipE,2126
47
47
  liminal/orm/base_tables/schema.py,sha256=7_btCVSUJxjVdGcKVRKL8sKcNw7-_gazTpfEh1jru3o,921
48
48
  liminal/orm/base_tables/user.py,sha256=elRAHj7HgO3iVLK_pNCIwf_9Rl_9k6vkBgaYazoJSQc,818
49
49
  liminal/orm/column.py,sha256=e4JWn97s_4EVJ1LOO5l6iucHQUd39Vl0stqMEj0uet8,5114
50
50
  liminal/orm/mixins.py,sha256=yEeUDF1qEBLP523q8bZra4KtNVK0gwZN9mXJSNe3GEE,4802
51
- liminal/orm/name_template.py,sha256=qsppCDPCVBhVZs3Uz-x4QdJbElH6VPlwfRD1BX_pAwE,1739
51
+ liminal/orm/name_template.py,sha256=ftXZOiRR6gGGvGaZkFVDXKOboIHFWauhQENRguBGWMI,1739
52
+ liminal/orm/name_template_parts.py,sha256=KCGXAcCuOqCjlgYn-mw1K7fwDI92D20l-FnlpEVrbM8,2771
52
53
  liminal/orm/relationship.py,sha256=Zl4bMHbtDSPx1psGHYnojGGJpA8B8hwcPJdgjB1lmW0,2490
53
54
  liminal/orm/schema_properties.py,sha256=yv6MOsE_16OWJnGDh2K8wI_054PJwafYmHgY_Awr3XA,3420
54
55
  liminal/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -56,12 +57,12 @@ liminal/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
56
57
  liminal/tests/conftest.py,sha256=B463eOfe1uCHDJsUNvG-6tY8Qx8FJMByGDOtuyM87lA,17669
57
58
  liminal/tests/from benchling_sdk.py,sha256=CjRUHFB3iaa4rUPLGOqDiBq5EPKldm-Fd8aQQr92zF4,147
58
59
  liminal/tests/test_dropdown_compare.py,sha256=yHB0ovQlBLRu8-qYkqIPd8VtYEOmOft_93FQM86g_z8,8198
59
- liminal/tests/test_entity_schema_compare.py,sha256=JfvrdRfnm77dchHL5mwTLXfrKYW47wANacFJlS5Iw80,18953
60
+ liminal/tests/test_entity_schema_compare.py,sha256=-26Bu5eYIuHRswB5kYjGDo5Wed5LUWjm1e6IRI1Q-lE,18952
60
61
  liminal/utils.py,sha256=radRtRsZmCiNblMvxOX1DH0rcO5TR09kFlp6OONIPBU,2951
61
- liminal/validation/__init__.py,sha256=HOjBHCwxvQao6SN_Q5B-JbabG7Z6ff44JIDKLeK96l8,5458
62
+ liminal/validation/__init__.py,sha256=aMxO1vcZ_1Ay1Br0BCEEc09xge8-g5TL1sJ0KHbtRM8,5684
62
63
  liminal/validation/validation_severity.py,sha256=ib03PTZCQHcbBDc01v4gJF53YtA-ANY6QSFnhTV-FbU,259
63
- liminal_orm-2.0.0.dist-info/LICENSE.md,sha256=oVA877F_D1AV44dpjsv4f-4k690uNGApX1EtzOo3T8U,11353
64
- liminal_orm-2.0.0.dist-info/METADATA,sha256=_ioXetNNEIXfaO4Zmgis49Y86FfiUyGbmpCqy5SJI3E,11056
65
- liminal_orm-2.0.0.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
66
- liminal_orm-2.0.0.dist-info/entry_points.txt,sha256=atIrU63rrzH81dWC2sjUbFLlc5FWMmYRdMxXEWexIZA,47
67
- liminal_orm-2.0.0.dist-info/RECORD,,
64
+ liminal_orm-2.0.2.dist-info/LICENSE.md,sha256=oVA877F_D1AV44dpjsv4f-4k690uNGApX1EtzOo3T8U,11353
65
+ liminal_orm-2.0.2.dist-info/METADATA,sha256=xOqcfpE7GSkUtmzLq_aNi8xGC74QEmKgK1Ki50przG4,11032
66
+ liminal_orm-2.0.2.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
67
+ liminal_orm-2.0.2.dist-info/entry_points.txt,sha256=atIrU63rrzH81dWC2sjUbFLlc5FWMmYRdMxXEWexIZA,47
68
+ liminal_orm-2.0.2.dist-info/RECORD,,