gemd 2.3.2__tar.gz → 3.0.0__tar.gz
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.
- {gemd-2.3.2 → gemd-3.0.0}/PKG-INFO +2 -4
- gemd-3.0.0/gemd/__version__.py +1 -0
- {gemd-2.3.2 → gemd-3.0.0}/gemd/builders/impl.py +13 -14
- {gemd-2.3.2 → gemd-3.0.0}/gemd/demo/strehlow_and_cook.py +1 -1
- {gemd-2.3.2 → gemd-3.0.0}/gemd/entity/attribute/base_attribute.py +10 -10
- {gemd-2.3.2 → gemd-3.0.0}/gemd/entity/attribute/condition.py +1 -3
- {gemd-2.3.2 → gemd-3.0.0}/gemd/entity/attribute/parameter.py +1 -3
- {gemd-2.3.2 → gemd-3.0.0}/gemd/entity/attribute/property.py +1 -3
- {gemd-2.3.2 → gemd-3.0.0}/gemd/entity/attribute/property_and_conditions.py +4 -4
- {gemd-2.3.2 → gemd-3.0.0}/gemd/entity/base_entity.py +8 -9
- {gemd-2.3.2 → gemd-3.0.0}/gemd/entity/bounds/base_bounds.py +4 -4
- {gemd-2.3.2 → gemd-3.0.0}/gemd/entity/bounds/categorical_bounds.py +9 -8
- {gemd-2.3.2 → gemd-3.0.0}/gemd/entity/bounds/composition_bounds.py +6 -5
- {gemd-2.3.2 → gemd-3.0.0}/gemd/entity/bounds/integer_bounds.py +4 -4
- {gemd-2.3.2 → gemd-3.0.0}/gemd/entity/bounds/molecular_structure_bounds.py +4 -6
- {gemd-2.3.2 → gemd-3.0.0}/gemd/entity/bounds/real_bounds.py +4 -4
- {gemd-2.3.2 → gemd-3.0.0}/gemd/entity/case_insensitive_dict.py +33 -11
- {gemd-2.3.2 → gemd-3.0.0}/gemd/entity/dict_serializable.py +11 -12
- {gemd-2.3.2 → gemd-3.0.0}/gemd/entity/has_dependencies.py +2 -2
- {gemd-2.3.2 → gemd-3.0.0}/gemd/entity/object/base_object.py +4 -4
- {gemd-2.3.2 → gemd-3.0.0}/gemd/entity/object/has_conditions.py +5 -5
- {gemd-2.3.2 → gemd-3.0.0}/gemd/entity/object/has_material.py +3 -4
- {gemd-2.3.2 → gemd-3.0.0}/gemd/entity/object/has_parameters.py +5 -5
- {gemd-2.3.2 → gemd-3.0.0}/gemd/entity/object/has_process.py +3 -4
- {gemd-2.3.2 → gemd-3.0.0}/gemd/entity/object/has_properties.py +5 -5
- {gemd-2.3.2 → gemd-3.0.0}/gemd/entity/object/has_quantities.py +1 -1
- {gemd-2.3.2 → gemd-3.0.0}/gemd/entity/object/has_source.py +1 -1
- {gemd-2.3.2 → gemd-3.0.0}/gemd/entity/object/has_spec.py +6 -7
- {gemd-2.3.2 → gemd-3.0.0}/gemd/entity/object/has_template.py +5 -6
- {gemd-2.3.2 → gemd-3.0.0}/gemd/entity/object/has_template_check_generator.py +3 -2
- {gemd-2.3.2 → gemd-3.0.0}/gemd/entity/object/ingredient_run.py +14 -13
- {gemd-2.3.2 → gemd-3.0.0}/gemd/entity/object/ingredient_spec.py +10 -10
- {gemd-2.3.2 → gemd-3.0.0}/gemd/entity/object/material_run.py +11 -10
- {gemd-2.3.2 → gemd-3.0.0}/gemd/entity/object/material_spec.py +11 -13
- {gemd-2.3.2 → gemd-3.0.0}/gemd/entity/object/measurement_run.py +10 -10
- {gemd-2.3.2 → gemd-3.0.0}/gemd/entity/object/measurement_spec.py +6 -6
- {gemd-2.3.2 → gemd-3.0.0}/gemd/entity/object/process_run.py +10 -9
- {gemd-2.3.2 → gemd-3.0.0}/gemd/entity/object/process_spec.py +10 -9
- {gemd-2.3.2 → gemd-3.0.0}/gemd/entity/setters.py +5 -4
- {gemd-2.3.2 → gemd-3.0.0}/gemd/entity/template/base_template.py +5 -5
- {gemd-2.3.2 → gemd-3.0.0}/gemd/entity/template/has_condition_templates.py +8 -7
- {gemd-2.3.2 → gemd-3.0.0}/gemd/entity/template/has_parameter_templates.py +8 -7
- {gemd-2.3.2 → gemd-3.0.0}/gemd/entity/template/has_property_templates.py +9 -8
- {gemd-2.3.2 → gemd-3.0.0}/gemd/entity/util.py +2 -2
- {gemd-2.3.2 → gemd-3.0.0}/gemd/entity/valid_list.py +4 -3
- {gemd-2.3.2 → gemd-3.0.0}/gemd/entity/value/discrete_categorical.py +3 -3
- {gemd-2.3.2 → gemd-3.0.0}/gemd/enumeration/base_enumeration.py +4 -5
- {gemd-2.3.2 → gemd-3.0.0}/gemd/json/gemd_json.py +5 -5
- {gemd-2.3.2 → gemd-3.0.0}/gemd/units/__init__.py +2 -0
- {gemd-2.3.2 → gemd-3.0.0}/gemd/units/impl.py +28 -47
- {gemd-2.3.2 → gemd-3.0.0}/gemd/util/impl.py +19 -29
- {gemd-2.3.2 → gemd-3.0.0}/gemd.egg-info/PKG-INFO +2 -4
- gemd-3.0.0/gemd.egg-info/requires.txt +2 -0
- {gemd-2.3.2 → gemd-3.0.0}/pyproject.toml +8 -15
- gemd-2.3.2/gemd/__version__.py +0 -1
- gemd-2.3.2/gemd.egg-info/requires.txt +0 -5
- {gemd-2.3.2 → gemd-3.0.0}/LICENSE +0 -0
- {gemd-2.3.2 → gemd-3.0.0}/README.md +0 -0
- {gemd-2.3.2 → gemd-3.0.0}/gemd/__init__.py +0 -0
- {gemd-2.3.2 → gemd-3.0.0}/gemd/builders/__init__.py +0 -0
- {gemd-2.3.2 → gemd-3.0.0}/gemd/demo/__init__.py +0 -0
- {gemd-2.3.2 → gemd-3.0.0}/gemd/demo/cake.py +0 -0
- {gemd-2.3.2 → gemd-3.0.0}/gemd/demo/material_run_example.py +0 -0
- {gemd-2.3.2 → gemd-3.0.0}/gemd/demo/measurement_example.py +0 -0
- {gemd-2.3.2 → gemd-3.0.0}/gemd/demo/strehlow_and_cook.pif +0 -0
- {gemd-2.3.2 → gemd-3.0.0}/gemd/demo/strehlow_and_cook_small.pif +0 -0
- {gemd-2.3.2 → gemd-3.0.0}/gemd/demo/table_example.py +0 -0
- {gemd-2.3.2 → gemd-3.0.0}/gemd/demo/toothpick.jpg +0 -0
- {gemd-2.3.2 → gemd-3.0.0}/gemd/entity/__init__.py +0 -0
- {gemd-2.3.2 → gemd-3.0.0}/gemd/entity/attribute/__init__.py +0 -0
- {gemd-2.3.2 → gemd-3.0.0}/gemd/entity/bounds/__init__.py +0 -0
- {gemd-2.3.2 → gemd-3.0.0}/gemd/entity/bounds_validation.py +0 -0
- {gemd-2.3.2 → gemd-3.0.0}/gemd/entity/file_link.py +0 -0
- {gemd-2.3.2 → gemd-3.0.0}/gemd/entity/link_by_uid.py +0 -0
- {gemd-2.3.2 → gemd-3.0.0}/gemd/entity/object/__init__.py +0 -0
- {gemd-2.3.2 → gemd-3.0.0}/gemd/entity/source/__init__.py +0 -0
- {gemd-2.3.2 → gemd-3.0.0}/gemd/entity/source/performed_source.py +0 -0
- {gemd-2.3.2 → gemd-3.0.0}/gemd/entity/template/__init__.py +0 -0
- {gemd-2.3.2 → gemd-3.0.0}/gemd/entity/template/attribute_template.py +0 -0
- {gemd-2.3.2 → gemd-3.0.0}/gemd/entity/template/condition_template.py +0 -0
- {gemd-2.3.2 → gemd-3.0.0}/gemd/entity/template/material_template.py +0 -0
- {gemd-2.3.2 → gemd-3.0.0}/gemd/entity/template/measurement_template.py +0 -0
- {gemd-2.3.2 → gemd-3.0.0}/gemd/entity/template/parameter_template.py +0 -0
- {gemd-2.3.2 → gemd-3.0.0}/gemd/entity/template/process_template.py +0 -0
- {gemd-2.3.2 → gemd-3.0.0}/gemd/entity/template/property_template.py +0 -0
- {gemd-2.3.2 → gemd-3.0.0}/gemd/entity/value/__init__.py +0 -0
- {gemd-2.3.2 → gemd-3.0.0}/gemd/entity/value/base_value.py +0 -0
- {gemd-2.3.2 → gemd-3.0.0}/gemd/entity/value/categorical_value.py +0 -0
- {gemd-2.3.2 → gemd-3.0.0}/gemd/entity/value/composition_value.py +0 -0
- {gemd-2.3.2 → gemd-3.0.0}/gemd/entity/value/continuous_value.py +0 -0
- {gemd-2.3.2 → gemd-3.0.0}/gemd/entity/value/empirical_formula.py +0 -0
- {gemd-2.3.2 → gemd-3.0.0}/gemd/entity/value/inchi_value.py +0 -0
- {gemd-2.3.2 → gemd-3.0.0}/gemd/entity/value/integer_value.py +0 -0
- {gemd-2.3.2 → gemd-3.0.0}/gemd/entity/value/molecular_value.py +0 -0
- {gemd-2.3.2 → gemd-3.0.0}/gemd/entity/value/nominal_categorical.py +0 -0
- {gemd-2.3.2 → gemd-3.0.0}/gemd/entity/value/nominal_composition.py +0 -0
- {gemd-2.3.2 → gemd-3.0.0}/gemd/entity/value/nominal_integer.py +0 -0
- {gemd-2.3.2 → gemd-3.0.0}/gemd/entity/value/nominal_real.py +0 -0
- {gemd-2.3.2 → gemd-3.0.0}/gemd/entity/value/normal_real.py +0 -0
- {gemd-2.3.2 → gemd-3.0.0}/gemd/entity/value/smiles_value.py +0 -0
- {gemd-2.3.2 → gemd-3.0.0}/gemd/entity/value/uniform_integer.py +0 -0
- {gemd-2.3.2 → gemd-3.0.0}/gemd/entity/value/uniform_real.py +0 -0
- {gemd-2.3.2 → gemd-3.0.0}/gemd/enumeration/__init__.py +0 -0
- {gemd-2.3.2 → gemd-3.0.0}/gemd/enumeration/origin.py +0 -0
- {gemd-2.3.2 → gemd-3.0.0}/gemd/enumeration/sample_type.py +0 -0
- {gemd-2.3.2 → gemd-3.0.0}/gemd/json/__init__.py +0 -0
- {gemd-2.3.2 → gemd-3.0.0}/gemd/json/gemd_encoder.py +0 -0
- {gemd-2.3.2 → gemd-3.0.0}/gemd/units/citrine_en.txt +0 -0
- {gemd-2.3.2 → gemd-3.0.0}/gemd/units/constants_en.txt +0 -0
- {gemd-2.3.2 → gemd-3.0.0}/gemd/util/__init__.py +0 -0
- {gemd-2.3.2 → gemd-3.0.0}/gemd.egg-info/SOURCES.txt +0 -0
- {gemd-2.3.2 → gemd-3.0.0}/gemd.egg-info/dependency_links.txt +0 -0
- {gemd-2.3.2 → gemd-3.0.0}/gemd.egg-info/top_level.txt +0 -0
- {gemd-2.3.2 → gemd-3.0.0}/setup.cfg +0 -0
- {gemd-2.3.2 → gemd-3.0.0}/tests/test_examples.py +0 -0
|
@@ -1,21 +1,19 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: gemd
|
|
3
|
-
Version:
|
|
3
|
+
Version: 3.0.0
|
|
4
4
|
Summary: Python binding for Citrine's GEMD data model
|
|
5
5
|
Author: Citrine Informatics
|
|
6
6
|
Project-URL: Homepage, http://github.com/CitrineInformatics/gemd-python
|
|
7
7
|
Classifier: Programming Language :: Python :: 3
|
|
8
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
9
8
|
Classifier: Programming Language :: Python :: 3.10
|
|
10
9
|
Classifier: Programming Language :: Python :: 3.11
|
|
11
10
|
Classifier: Programming Language :: Python :: 3.12
|
|
12
11
|
Classifier: Programming Language :: Python :: 3.13
|
|
13
|
-
Requires-Python: >=3.
|
|
12
|
+
Requires-Python: >=3.10
|
|
14
13
|
Description-Content-Type: text/markdown
|
|
15
14
|
License-File: LICENSE
|
|
16
15
|
Requires-Dist: pint<0.25,>=0.24.4
|
|
17
16
|
Requires-Dist: deprecation<3,>=2.1.0
|
|
18
|
-
Requires-Dist: typing_extensions<5,>=4.8; python_version < "3.10"
|
|
19
17
|
Dynamic: license-file
|
|
20
18
|
|
|
21
19
|
# GEMD-python
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "3.0.0"
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
# Tools to help build GEMD objects
|
|
2
|
-
from typing import List, Union
|
|
3
2
|
|
|
4
3
|
from gemd.entity.attribute import Condition, Parameter, Property, PropertyAndConditions
|
|
5
4
|
from gemd.entity.attribute.base_attribute import BaseAttribute
|
|
@@ -104,10 +103,10 @@ def add_edge(
|
|
|
104
103
|
output_material: MaterialRun,
|
|
105
104
|
*,
|
|
106
105
|
name: str = None,
|
|
107
|
-
mass_fraction:
|
|
108
|
-
number_fraction:
|
|
109
|
-
volume_fraction:
|
|
110
|
-
absolute_quantity:
|
|
106
|
+
mass_fraction: float | ContinuousValue = None,
|
|
107
|
+
number_fraction: float | ContinuousValue = None,
|
|
108
|
+
volume_fraction: float | ContinuousValue = None,
|
|
109
|
+
absolute_quantity: int | float | ContinuousValue = None,
|
|
111
110
|
absolute_units: str = None,
|
|
112
111
|
) -> IngredientRun:
|
|
113
112
|
"""Connect two material-process spec-run quadruples with ingredients.
|
|
@@ -209,7 +208,7 @@ def add_measurement(
|
|
|
209
208
|
*,
|
|
210
209
|
name: str = None,
|
|
211
210
|
template: MeasurementTemplate = None,
|
|
212
|
-
attributes:
|
|
211
|
+
attributes: list[BaseAttribute] = None,
|
|
213
212
|
) -> MeasurementRun:
|
|
214
213
|
"""Add a measurement run-spec set to a :class:`~gemd.entity.object.material_run.MaterialRun`.
|
|
215
214
|
|
|
@@ -264,10 +263,10 @@ def add_measurement(
|
|
|
264
263
|
|
|
265
264
|
|
|
266
265
|
def add_attribute(
|
|
267
|
-
target:
|
|
268
|
-
template:
|
|
269
|
-
value:
|
|
270
|
-
) ->
|
|
266
|
+
target: HasProperties | HasConditions | HasParameters,
|
|
267
|
+
template: PropertyTemplate | ConditionTemplate | ParameterTemplate,
|
|
268
|
+
value: BaseValue | str | float | int,
|
|
269
|
+
) -> Property | Condition | Parameter:
|
|
271
270
|
"""Generate an attribute, and then add it attribute to a GEMD object.
|
|
272
271
|
|
|
273
272
|
Parameters
|
|
@@ -314,9 +313,9 @@ def add_attribute(
|
|
|
314
313
|
|
|
315
314
|
|
|
316
315
|
def make_attribute(
|
|
317
|
-
template:
|
|
318
|
-
value:
|
|
319
|
-
) ->
|
|
316
|
+
template: PropertyTemplate | ConditionTemplate | ParameterTemplate,
|
|
317
|
+
value: BaseValue | str | float | int,
|
|
318
|
+
) -> Property | Condition | Parameter:
|
|
320
319
|
"""Generate an Attribute and the contained Value.
|
|
321
320
|
|
|
322
321
|
Parameters
|
|
@@ -350,7 +349,7 @@ def make_attribute(
|
|
|
350
349
|
return attribute
|
|
351
350
|
|
|
352
351
|
|
|
353
|
-
def make_value(value:
|
|
352
|
+
def make_value(value: str | float | int, bounds: BaseBounds) -> BaseValue:
|
|
354
353
|
"""Generate a Value object based upon a number or string and a particular bounds.
|
|
355
354
|
|
|
356
355
|
Parameters
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from abc import abstractmethod
|
|
2
|
-
from
|
|
2
|
+
from collections.abc import Iterable
|
|
3
3
|
|
|
4
4
|
from gemd.entity.bounds_validation import WarningLevel, get_validation_level
|
|
5
5
|
from gemd.entity.dict_serializable import DictSerializable, logger
|
|
@@ -37,11 +37,11 @@ class BaseAttribute(DictSerializable):
|
|
|
37
37
|
self,
|
|
38
38
|
name: str,
|
|
39
39
|
*,
|
|
40
|
-
template:
|
|
41
|
-
origin:
|
|
40
|
+
template: AttributeTemplate | LinkByUID | None = None,
|
|
41
|
+
origin: Origin | str = Origin.UNKNOWN,
|
|
42
42
|
value: BaseValue = None,
|
|
43
43
|
notes: str = None,
|
|
44
|
-
file_links:
|
|
44
|
+
file_links: Iterable[FileLink] | FileLink | None = None,
|
|
45
45
|
):
|
|
46
46
|
self.name = name
|
|
47
47
|
self.notes = notes
|
|
@@ -85,12 +85,12 @@ class BaseAttribute(DictSerializable):
|
|
|
85
85
|
raise TypeError(f"value must be a BaseValue: {value}")
|
|
86
86
|
|
|
87
87
|
@property
|
|
88
|
-
def template(self) ->
|
|
88
|
+
def template(self) -> AttributeTemplate | LinkByUID | None:
|
|
89
89
|
"""Get the template."""
|
|
90
90
|
return self._template
|
|
91
91
|
|
|
92
92
|
@template.setter
|
|
93
|
-
def template(self, template:
|
|
93
|
+
def template(self, template: AttributeTemplate | LinkByUID | None):
|
|
94
94
|
"""Set the template."""
|
|
95
95
|
if template is None:
|
|
96
96
|
self._template = None
|
|
@@ -103,7 +103,7 @@ class BaseAttribute(DictSerializable):
|
|
|
103
103
|
|
|
104
104
|
@staticmethod
|
|
105
105
|
@abstractmethod
|
|
106
|
-
def _template_type() ->
|
|
106
|
+
def _template_type() -> type:
|
|
107
107
|
"""Get the expected type of template for this object (property of child)."""
|
|
108
108
|
|
|
109
109
|
@property
|
|
@@ -112,18 +112,18 @@ class BaseAttribute(DictSerializable):
|
|
|
112
112
|
return self._origin
|
|
113
113
|
|
|
114
114
|
@origin.setter
|
|
115
|
-
def origin(self, origin:
|
|
115
|
+
def origin(self, origin: Origin | str):
|
|
116
116
|
"""Set the origin."""
|
|
117
117
|
if origin is None:
|
|
118
118
|
raise ValueError("origin must be specified (but may be `unknown`)")
|
|
119
119
|
self._origin = Origin.from_str(origin, exception=True)
|
|
120
120
|
|
|
121
121
|
@property
|
|
122
|
-
def file_links(self) ->
|
|
122
|
+
def file_links(self) -> list[FileLink]:
|
|
123
123
|
"""Get the file links."""
|
|
124
124
|
return self._file_links
|
|
125
125
|
|
|
126
126
|
@file_links.setter
|
|
127
|
-
def file_links(self, file_links:
|
|
127
|
+
def file_links(self, file_links: Iterable[FileLink] | FileLink | None):
|
|
128
128
|
"""Set the file links."""
|
|
129
129
|
self._file_links = validate_list(file_links, FileLink)
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
from typing import Type
|
|
2
|
-
|
|
3
1
|
from gemd.entity.attribute.base_attribute import BaseAttribute
|
|
4
2
|
from gemd.entity.template import ConditionTemplate
|
|
5
3
|
|
|
@@ -32,5 +30,5 @@ class Condition(BaseAttribute, typ="condition"):
|
|
|
32
30
|
"""
|
|
33
31
|
|
|
34
32
|
@staticmethod
|
|
35
|
-
def _template_type() ->
|
|
33
|
+
def _template_type() -> type:
|
|
36
34
|
return ConditionTemplate
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
from typing import Type
|
|
2
|
-
|
|
3
1
|
from gemd.entity.attribute.base_attribute import BaseAttribute
|
|
4
2
|
from gemd.entity.template import ParameterTemplate
|
|
5
3
|
|
|
@@ -33,5 +31,5 @@ class Parameter(BaseAttribute, typ="parameter"):
|
|
|
33
31
|
"""
|
|
34
32
|
|
|
35
33
|
@staticmethod
|
|
36
|
-
def _template_type() ->
|
|
34
|
+
def _template_type() -> type:
|
|
37
35
|
return ParameterTemplate
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
from typing import Type
|
|
2
|
-
|
|
3
1
|
from gemd.entity.attribute.base_attribute import BaseAttribute
|
|
4
2
|
from gemd.entity.template import PropertyTemplate
|
|
5
3
|
|
|
@@ -32,5 +30,5 @@ class Property(BaseAttribute, typ="property"):
|
|
|
32
30
|
"""
|
|
33
31
|
|
|
34
32
|
@staticmethod
|
|
35
|
-
def _template_type() ->
|
|
33
|
+
def _template_type() -> type:
|
|
36
34
|
return PropertyTemplate
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from
|
|
1
|
+
from collections.abc import Iterable
|
|
2
2
|
|
|
3
3
|
from gemd.entity.attribute.condition import Condition
|
|
4
4
|
from gemd.entity.attribute.property import Property
|
|
@@ -26,7 +26,7 @@ class PropertyAndConditions(DictSerializable, typ="property_and_conditions"):
|
|
|
26
26
|
"""
|
|
27
27
|
|
|
28
28
|
def __init__(
|
|
29
|
-
self, property: Property = None, conditions:
|
|
29
|
+
self, property: Property = None, conditions: Iterable[Condition] | Condition = None
|
|
30
30
|
):
|
|
31
31
|
self._property = None
|
|
32
32
|
self.property = property
|
|
@@ -34,7 +34,7 @@ class PropertyAndConditions(DictSerializable, typ="property_and_conditions"):
|
|
|
34
34
|
self.conditions = conditions
|
|
35
35
|
|
|
36
36
|
@property
|
|
37
|
-
def conditions(self) ->
|
|
37
|
+
def conditions(self) -> list[Condition]:
|
|
38
38
|
"""Get conditions."""
|
|
39
39
|
return self._conditions
|
|
40
40
|
|
|
@@ -49,7 +49,7 @@ class PropertyAndConditions(DictSerializable, typ="property_and_conditions"):
|
|
|
49
49
|
return self.property.name
|
|
50
50
|
|
|
51
51
|
@property
|
|
52
|
-
def template(self) ->
|
|
52
|
+
def template(self) -> PropertyTemplate | LinkByUID | None:
|
|
53
53
|
"""Get template of attribute (use template of property)."""
|
|
54
54
|
return self.property.template
|
|
55
55
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"""Base class for all entities."""
|
|
2
2
|
|
|
3
|
-
from
|
|
3
|
+
from collections.abc import Iterable, MutableMapping
|
|
4
|
+
from typing import TypeVar
|
|
4
5
|
|
|
5
6
|
from gemd.entity.case_insensitive_dict import CaseInsensitiveDict
|
|
6
7
|
from gemd.entity.dict_serializable import DictSerializable
|
|
@@ -28,7 +29,7 @@ class BaseEntity(DictSerializable):
|
|
|
28
29
|
self.uids = uids
|
|
29
30
|
|
|
30
31
|
@property
|
|
31
|
-
def tags(self) ->
|
|
32
|
+
def tags(self) -> list[str]:
|
|
32
33
|
"""A collection of structured labels.
|
|
33
34
|
|
|
34
35
|
`Tags <https://citrineinformatics.github.io/gemd-documentation/specification/tags/>`_
|
|
@@ -43,7 +44,7 @@ class BaseEntity(DictSerializable):
|
|
|
43
44
|
self._tags = validate_list(tags, str)
|
|
44
45
|
|
|
45
46
|
@property
|
|
46
|
-
def uids(self) ->
|
|
47
|
+
def uids(self) -> dict[str, str]:
|
|
47
48
|
"""A collection of unique IDs.
|
|
48
49
|
|
|
49
50
|
Requirements for and the value of unique IDs are discussed
|
|
@@ -76,9 +77,7 @@ class BaseEntity(DictSerializable):
|
|
|
76
77
|
"""
|
|
77
78
|
self.uids[scope] = uid
|
|
78
79
|
|
|
79
|
-
def to_link(
|
|
80
|
-
self, scope: Optional[str] = None, *, allow_fallback: bool = False
|
|
81
|
-
) -> LinkByUIDType:
|
|
80
|
+
def to_link(self, scope: str | None = None, *, allow_fallback: bool = False) -> LinkByUIDType:
|
|
82
81
|
"""Generate a ~gemd.entity.link_by_uid.LinkByUID for this object.
|
|
83
82
|
|
|
84
83
|
Parameters
|
|
@@ -107,7 +106,7 @@ class BaseEntity(DictSerializable):
|
|
|
107
106
|
|
|
108
107
|
return LinkByUID(scope=scope, id=uid)
|
|
109
108
|
|
|
110
|
-
def all_dependencies(self) ->
|
|
109
|
+
def all_dependencies(self) -> set[BaseEntityType | LinkByUIDType]:
|
|
111
110
|
"""Return a set of all immediate dependencies (no recursion)."""
|
|
112
111
|
result = set()
|
|
113
112
|
queue = [type(self)]
|
|
@@ -121,8 +120,8 @@ class BaseEntity(DictSerializable):
|
|
|
121
120
|
|
|
122
121
|
@staticmethod
|
|
123
122
|
def _cached_equals(
|
|
124
|
-
this: "BaseEntity", that: "BaseEntity", *, cache:
|
|
125
|
-
) ->
|
|
123
|
+
this: "BaseEntity", that: "BaseEntity", *, cache: dict[frozenset, bool | None] = None
|
|
124
|
+
) -> bool | None:
|
|
126
125
|
"""Compute and stash whether two Base Entities are equal in a recursive sense.
|
|
127
126
|
|
|
128
127
|
The cache uses ternary logic to communicate state. True or False indicate a completed
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""Base class for all bounds."""
|
|
2
2
|
|
|
3
3
|
from abc import abstractmethod
|
|
4
|
-
from typing import TypeVar
|
|
4
|
+
from typing import TypeVar
|
|
5
5
|
|
|
6
6
|
from gemd.entity.dict_serializable import DictSerializable
|
|
7
7
|
|
|
@@ -14,7 +14,7 @@ class BaseBounds(DictSerializable):
|
|
|
14
14
|
"""Base class for bounds, including RealBounds and CategoricalBounds."""
|
|
15
15
|
|
|
16
16
|
@abstractmethod
|
|
17
|
-
def contains(self, bounds:
|
|
17
|
+
def contains(self, bounds: BaseBoundsType | BaseValueType):
|
|
18
18
|
"""Check if another bounds is contained within this bounds.
|
|
19
19
|
|
|
20
20
|
Parameters
|
|
@@ -41,7 +41,7 @@ class BaseBounds(DictSerializable):
|
|
|
41
41
|
raise TypeError(f"{bounds} is not a Bounds object")
|
|
42
42
|
|
|
43
43
|
@abstractmethod
|
|
44
|
-
def union(self, *others:
|
|
44
|
+
def union(self, *others: BaseBoundsType | BaseValueType) -> BaseBoundsType:
|
|
45
45
|
"""Return the union of this bounds and other bounds.
|
|
46
46
|
|
|
47
47
|
The others list must also be the same class (e.g., categorical, real...).
|
|
@@ -61,7 +61,7 @@ class BaseBounds(DictSerializable):
|
|
|
61
61
|
"""
|
|
62
62
|
|
|
63
63
|
@abstractmethod
|
|
64
|
-
def update(self, *others:
|
|
64
|
+
def update(self, *others: BaseBoundsType | BaseValueType):
|
|
65
65
|
"""Update this bounds to include other bounds.
|
|
66
66
|
|
|
67
67
|
The others list must also be the same class (e.g., categorical, real...).
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
from
|
|
1
|
+
from collections.abc import Iterable
|
|
2
|
+
from typing import Any, TypeVar
|
|
2
3
|
|
|
3
4
|
from gemd.entity.bounds.base_bounds import BaseBounds
|
|
4
5
|
from gemd.entity.util import array_like
|
|
@@ -19,17 +20,17 @@ class CategoricalBounds(BaseBounds, typ="categorical_bounds"):
|
|
|
19
20
|
|
|
20
21
|
"""
|
|
21
22
|
|
|
22
|
-
def __init__(self, categories:
|
|
23
|
+
def __init__(self, categories: Iterable[str] | None = None):
|
|
23
24
|
self._categories = None
|
|
24
25
|
self.categories = categories
|
|
25
26
|
|
|
26
27
|
@property
|
|
27
|
-
def categories(self) ->
|
|
28
|
+
def categories(self) -> set[str]:
|
|
28
29
|
"""The collection of allowed categories."""
|
|
29
30
|
return self._categories
|
|
30
31
|
|
|
31
32
|
@categories.setter
|
|
32
|
-
def categories(self, categories:
|
|
33
|
+
def categories(self, categories: Iterable[str] | None):
|
|
33
34
|
if categories is None:
|
|
34
35
|
self._categories = set()
|
|
35
36
|
elif isinstance(categories, array_like()):
|
|
@@ -42,7 +43,7 @@ class CategoricalBounds(BaseBounds, typ="categorical_bounds"):
|
|
|
42
43
|
if not all(isinstance(x, str) for x in self.categories):
|
|
43
44
|
raise ValueError("All the categories must be strings")
|
|
44
45
|
|
|
45
|
-
def contains(self, bounds:
|
|
46
|
+
def contains(self, bounds: BaseBounds | BaseValueType) -> bool:
|
|
46
47
|
"""Check if another bounds object or value object is contained by this bounds.
|
|
47
48
|
|
|
48
49
|
The other object must also be Categorical and its allowed categories must be a
|
|
@@ -74,7 +75,7 @@ class CategoricalBounds(BaseBounds, typ="categorical_bounds"):
|
|
|
74
75
|
return bounds.categories.issubset(self.categories)
|
|
75
76
|
|
|
76
77
|
def union(
|
|
77
|
-
self, *others:
|
|
78
|
+
self, *others: CategoricalBoundsType | CategoricalValueType
|
|
78
79
|
) -> CategoricalBoundsType:
|
|
79
80
|
"""Return the union of this bounds and other bounds.
|
|
80
81
|
|
|
@@ -111,7 +112,7 @@ class CategoricalBounds(BaseBounds, typ="categorical_bounds"):
|
|
|
111
112
|
result.update(bounds.categories)
|
|
112
113
|
return CategoricalBounds(result)
|
|
113
114
|
|
|
114
|
-
def update(self, *others:
|
|
115
|
+
def update(self, *others: CategoricalBoundsType | CategoricalValueType):
|
|
115
116
|
"""Update this bounds to include other bounds.
|
|
116
117
|
|
|
117
118
|
The others list must also be Categorical Bounds or Values.
|
|
@@ -126,7 +127,7 @@ class CategoricalBounds(BaseBounds, typ="categorical_bounds"):
|
|
|
126
127
|
"""
|
|
127
128
|
self.categories = self.union(*others).categories
|
|
128
129
|
|
|
129
|
-
def as_dict(self) ->
|
|
130
|
+
def as_dict(self) -> dict[str, Any]:
|
|
130
131
|
"""Convert bounds to a dictionary.
|
|
131
132
|
|
|
132
133
|
Returns
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"""Bounds a composition to have a specified set of components."""
|
|
2
2
|
|
|
3
|
-
from
|
|
3
|
+
from collections.abc import Iterable
|
|
4
|
+
from typing import TypeVar
|
|
4
5
|
|
|
5
6
|
from gemd.entity.bounds.base_bounds import BaseBounds
|
|
6
7
|
from gemd.entity.util import array_like
|
|
@@ -26,7 +27,7 @@ class CompositionBounds(BaseBounds, typ="composition_bounds"):
|
|
|
26
27
|
self.components = components
|
|
27
28
|
|
|
28
29
|
@property
|
|
29
|
-
def components(self) ->
|
|
30
|
+
def components(self) -> set[str]:
|
|
30
31
|
"""Get the collection of the components that are allowed in the composition."""
|
|
31
32
|
return self._components
|
|
32
33
|
|
|
@@ -45,7 +46,7 @@ class CompositionBounds(BaseBounds, typ="composition_bounds"):
|
|
|
45
46
|
if not all(isinstance(x, str) for x in self.components):
|
|
46
47
|
raise ValueError("All the components must be strings")
|
|
47
48
|
|
|
48
|
-
def contains(self, bounds:
|
|
49
|
+
def contains(self, bounds: BaseBounds | BaseValueType) -> bool:
|
|
49
50
|
"""Check if another bounds or value object is contained by this bounds.
|
|
50
51
|
|
|
51
52
|
The other object must also be a Composition and its components must be a subset of
|
|
@@ -76,7 +77,7 @@ class CompositionBounds(BaseBounds, typ="composition_bounds"):
|
|
|
76
77
|
return bounds.components.issubset(self.components)
|
|
77
78
|
|
|
78
79
|
def union(
|
|
79
|
-
self, *others:
|
|
80
|
+
self, *others: CompositionBoundsType | CompositionValueType
|
|
80
81
|
) -> CompositionBoundsType:
|
|
81
82
|
"""Return the union of this bounds and other bounds.
|
|
82
83
|
|
|
@@ -113,7 +114,7 @@ class CompositionBounds(BaseBounds, typ="composition_bounds"):
|
|
|
113
114
|
result.update(bounds.components)
|
|
114
115
|
return CompositionBounds(result)
|
|
115
116
|
|
|
116
|
-
def update(self, *others:
|
|
117
|
+
def update(self, *others: CompositionBoundsType | CompositionValueType):
|
|
117
118
|
"""Update this bounds to include other bounds.
|
|
118
119
|
|
|
119
120
|
The others list must also be Composition Bounds or Values.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""Bounds an integer to be between two values."""
|
|
2
2
|
|
|
3
3
|
from math import isfinite
|
|
4
|
-
from typing import TypeVar
|
|
4
|
+
from typing import TypeVar
|
|
5
5
|
|
|
6
6
|
from gemd.entity.bounds.base_bounds import BaseBounds
|
|
7
7
|
|
|
@@ -64,7 +64,7 @@ class IntegerBounds(BaseBounds, typ="integer_bounds"):
|
|
|
64
64
|
)
|
|
65
65
|
self._upper_bound = int(value)
|
|
66
66
|
|
|
67
|
-
def contains(self, bounds:
|
|
67
|
+
def contains(self, bounds: BaseBounds | BaseValueType) -> bool:
|
|
68
68
|
"""Check if another bounds or value object is a subset of this range.
|
|
69
69
|
|
|
70
70
|
The other object must also be an Integer and its lower and upper bound must *both*
|
|
@@ -94,7 +94,7 @@ class IntegerBounds(BaseBounds, typ="integer_bounds"):
|
|
|
94
94
|
|
|
95
95
|
return bounds.lower_bound >= self.lower_bound and bounds.upper_bound <= self.upper_bound
|
|
96
96
|
|
|
97
|
-
def union(self, *others:
|
|
97
|
+
def union(self, *others: IntegerBoundsType | IntegerValueType) -> IntegerBoundsType:
|
|
98
98
|
"""Return the union of this bounds and other bounds.
|
|
99
99
|
|
|
100
100
|
The others list must also be Integer Bounds or Values.
|
|
@@ -132,7 +132,7 @@ class IntegerBounds(BaseBounds, typ="integer_bounds"):
|
|
|
132
132
|
upper = bounds.upper_bound
|
|
133
133
|
return IntegerBounds(lower_bound=lower, upper_bound=upper)
|
|
134
134
|
|
|
135
|
-
def update(self, *others:
|
|
135
|
+
def update(self, *others: IntegerBoundsType | IntegerValueType):
|
|
136
136
|
"""Update this bounds to include other bounds.
|
|
137
137
|
|
|
138
138
|
The others list must also be Integer Bounds or Values.
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
In the future, this may include substructural restrictions.
|
|
4
4
|
"""
|
|
5
5
|
|
|
6
|
-
from typing import TypeVar
|
|
6
|
+
from typing import TypeVar
|
|
7
7
|
|
|
8
8
|
from gemd.entity.bounds.base_bounds import BaseBounds
|
|
9
9
|
|
|
@@ -16,7 +16,7 @@ MolecularValueType = TypeVar("MolecularValueType", bound="MolecularValue") # no
|
|
|
16
16
|
class MolecularStructureBounds(BaseBounds, typ="molecular_structure_bounds"):
|
|
17
17
|
"""Molecular bounds, with no component or substructural restrictions (yet)."""
|
|
18
18
|
|
|
19
|
-
def contains(self, bounds:
|
|
19
|
+
def contains(self, bounds: BaseBounds | BaseValueType) -> bool:
|
|
20
20
|
"""Check if another bounds or value object is contained by this bounds.
|
|
21
21
|
|
|
22
22
|
The other object must also be or type Molecular. There are no other
|
|
@@ -46,9 +46,7 @@ class MolecularStructureBounds(BaseBounds, typ="molecular_structure_bounds"):
|
|
|
46
46
|
|
|
47
47
|
return True
|
|
48
48
|
|
|
49
|
-
def union(
|
|
50
|
-
self, *others: Union[MolecularBoundsType, MolecularValueType]
|
|
51
|
-
) -> MolecularBoundsType:
|
|
49
|
+
def union(self, *others: MolecularBoundsType | MolecularValueType) -> MolecularBoundsType:
|
|
52
50
|
"""Return the union of this bounds and other bounds.
|
|
53
51
|
|
|
54
52
|
The others list must also be Molecular Structure Bounds or Values.
|
|
@@ -79,7 +77,7 @@ class MolecularStructureBounds(BaseBounds, typ="molecular_structure_bounds"):
|
|
|
79
77
|
)
|
|
80
78
|
return MolecularStructureBounds()
|
|
81
79
|
|
|
82
|
-
def update(self, *others:
|
|
80
|
+
def update(self, *others: MolecularBoundsType | MolecularValueType):
|
|
83
81
|
"""Update this bounds to include other bounds.
|
|
84
82
|
|
|
85
83
|
The others list must also be Molecular Structure Bounds or Values.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""Bound a real number to be between two values."""
|
|
2
2
|
|
|
3
3
|
from math import isfinite
|
|
4
|
-
from typing import TypeVar
|
|
4
|
+
from typing import TypeVar
|
|
5
5
|
|
|
6
6
|
import gemd.units as units
|
|
7
7
|
from gemd.entity.bounds.base_bounds import BaseBounds
|
|
@@ -85,7 +85,7 @@ class RealBounds(BaseBounds, typ="real_bounds"):
|
|
|
85
85
|
)
|
|
86
86
|
self._default_units = units.parse_units(default_units, return_unit=False)
|
|
87
87
|
|
|
88
|
-
def contains(self, bounds:
|
|
88
|
+
def contains(self, bounds: BaseBounds | BaseValueType) -> bool:
|
|
89
89
|
"""Check if another bounds or value object is a subset of this range.
|
|
90
90
|
|
|
91
91
|
The other object must also be Real and its lower and upper bound must *both*
|
|
@@ -121,7 +121,7 @@ class RealBounds(BaseBounds, typ="real_bounds"):
|
|
|
121
121
|
|
|
122
122
|
return bounds.lower_bound >= lower and bounds.upper_bound <= upper
|
|
123
123
|
|
|
124
|
-
def union(self, *others:
|
|
124
|
+
def union(self, *others: RealBoundsType | ContinuousValueType) -> RealBoundsType:
|
|
125
125
|
"""Return the union of this bounds and other bounds.
|
|
126
126
|
|
|
127
127
|
The others list must also be Real Bounds or Values.
|
|
@@ -163,7 +163,7 @@ class RealBounds(BaseBounds, typ="real_bounds"):
|
|
|
163
163
|
upper = bnd_hi
|
|
164
164
|
return RealBounds(lower_bound=lower, upper_bound=upper, default_units=unit_)
|
|
165
165
|
|
|
166
|
-
def update(self, *others:
|
|
166
|
+
def update(self, *others: RealBoundsType | ContinuousValueType):
|
|
167
167
|
"""Update this bounds to include other bounds.
|
|
168
168
|
|
|
169
169
|
The others list must also be Real Bounds or Values.
|
|
@@ -1,11 +1,15 @@
|
|
|
1
|
-
from
|
|
1
|
+
from collections.abc import Mapping, Sequence
|
|
2
|
+
from typing import Any, TypeVar, overload
|
|
2
3
|
|
|
3
4
|
__all__ = ["CaseInsensitiveDict"]
|
|
4
5
|
|
|
5
|
-
|
|
6
|
+
_VT = TypeVar("_VT")
|
|
7
|
+
_T = TypeVar("_T")
|
|
6
8
|
|
|
9
|
+
_RaiseKeyError: Any = object() # singleton for no-default behavior
|
|
7
10
|
|
|
8
|
-
|
|
11
|
+
|
|
12
|
+
class CaseInsensitiveDict(dict[str, _VT]):
|
|
9
13
|
"""A dictionary in which the keys are case-insensitive.
|
|
10
14
|
|
|
11
15
|
It is initialized the same way as a typical dict, but the values can be accessed without
|
|
@@ -29,10 +33,19 @@ class CaseInsensitiveDict(dict):
|
|
|
29
33
|
for key in self:
|
|
30
34
|
self._register_key(key)
|
|
31
35
|
|
|
32
|
-
def __getitem__(self, key: str) ->
|
|
36
|
+
def __getitem__(self, key: str) -> _VT:
|
|
33
37
|
return super().__getitem__(self.lowercase_dict[key.lower()])
|
|
34
38
|
|
|
35
|
-
|
|
39
|
+
@overload
|
|
40
|
+
def get(self, key: str, default: None = None, /) -> _VT | None: ...
|
|
41
|
+
|
|
42
|
+
@overload
|
|
43
|
+
def get(self, key: str, default: _VT, /) -> _VT: ...
|
|
44
|
+
|
|
45
|
+
@overload
|
|
46
|
+
def get(self, key: str, default: _T, /) -> _VT | _T: ...
|
|
47
|
+
|
|
48
|
+
def get(self, key: str, default: Any = None, /) -> Any:
|
|
36
49
|
"""Get the value for a given case-insensitive key.
|
|
37
50
|
|
|
38
51
|
Parameters
|
|
@@ -55,7 +68,7 @@ class CaseInsensitiveDict(dict):
|
|
|
55
68
|
else:
|
|
56
69
|
return default
|
|
57
70
|
|
|
58
|
-
def __setitem__(self, key: str, value:
|
|
71
|
+
def __setitem__(self, key: str, value: _VT) -> None:
|
|
59
72
|
self._register_key(key)
|
|
60
73
|
super().__setitem__(key, value)
|
|
61
74
|
|
|
@@ -72,7 +85,16 @@ class CaseInsensitiveDict(dict):
|
|
|
72
85
|
super().clear()
|
|
73
86
|
self.lowercase_dict.clear()
|
|
74
87
|
|
|
75
|
-
|
|
88
|
+
@overload
|
|
89
|
+
def pop(self, key: str, /) -> _VT: ...
|
|
90
|
+
|
|
91
|
+
@overload
|
|
92
|
+
def pop(self, key: str, default: _VT, /) -> _VT: ...
|
|
93
|
+
|
|
94
|
+
@overload
|
|
95
|
+
def pop(self, key: str, default: _T, /) -> _VT | _T: ...
|
|
96
|
+
|
|
97
|
+
def pop(self, key: str, default: Any = _RaiseKeyError, /) -> Any:
|
|
76
98
|
"""Remove and return the value for a given key from the dictionary.
|
|
77
99
|
|
|
78
100
|
If key is in the dictionary, remove it and return its value, else return default.
|
|
@@ -103,7 +125,7 @@ class CaseInsensitiveDict(dict):
|
|
|
103
125
|
del self.lowercase_dict[key.lower()]
|
|
104
126
|
return val
|
|
105
127
|
|
|
106
|
-
def popitem(self) ->
|
|
128
|
+
def popitem(self) -> tuple[str, _VT]:
|
|
107
129
|
"""Remove and return a (key, value) pair from the dictionary.
|
|
108
130
|
|
|
109
131
|
popitem() is useful to destructively iterate over a dictionary, as often used
|
|
@@ -115,7 +137,7 @@ class CaseInsensitiveDict(dict):
|
|
|
115
137
|
|
|
116
138
|
Returns
|
|
117
139
|
-------
|
|
118
|
-
|
|
140
|
+
tuple[str, Any]
|
|
119
141
|
The key-value pair
|
|
120
142
|
|
|
121
143
|
"""
|
|
@@ -123,7 +145,7 @@ class CaseInsensitiveDict(dict):
|
|
|
123
145
|
del self.lowercase_dict[result[0].lower()]
|
|
124
146
|
return result
|
|
125
147
|
|
|
126
|
-
def copy(self) -> "CaseInsensitiveDict":
|
|
148
|
+
def copy(self) -> "CaseInsensitiveDict[_VT]":
|
|
127
149
|
"""Return a shallow copy of the dictionary.
|
|
128
150
|
|
|
129
151
|
Returns
|
|
@@ -134,7 +156,7 @@ class CaseInsensitiveDict(dict):
|
|
|
134
156
|
"""
|
|
135
157
|
return CaseInsensitiveDict(super().copy())
|
|
136
158
|
|
|
137
|
-
def update(self, mapping:
|
|
159
|
+
def update(self, mapping: Mapping[str, Any] | None = None, **kwargs) -> None:
|
|
138
160
|
"""Update the dictionary with the key/value pairs from other, overwriting existing keys.
|
|
139
161
|
|
|
140
162
|
update() accepts either another dictionary object or an iterable of
|