diff --git a/docs/source/_static/favicon.png b/docs/source/_static/favicon.png
new file mode 100644
index 00000000..62a362ea
Binary files /dev/null and b/docs/source/_static/favicon.png differ
diff --git a/docs/source/_static/logo.png b/docs/source/_static/logo.png
new file mode 100644
index 00000000..9481d88e
Binary files /dev/null and b/docs/source/_static/logo.png differ
diff --git a/docs/source/conf.py b/docs/source/conf.py
index a6c8a9f9..94b60730 100644
--- a/docs/source/conf.py
+++ b/docs/source/conf.py
@@ -10,9 +10,10 @@
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
+import gemd
import os
import sys
-sys.path.insert(0, os.path.abspath('../../gemd'))
+sys.path.insert(0, os.path.abspath('../..'))
# -- Project information -----------------------------------------------------
@@ -21,8 +22,10 @@
copyright = '2020, Citrine Informatics'
author = 'Citrine Informatics'
-# The full version, including alpha/beta/rc tags
-release = '0.0.0'
+# The short X.Y version.
+version = gemd.__version__
+# The full version, including alpha/beta/rc tags.
+release = gemd.__version__
# -- General configuration ---------------------------------------------------
@@ -43,8 +46,9 @@
# See: https://github.com/sphinx-contrib/apidoc
apidoc_module_dir = '../../gemd'
apidoc_output_dir = 'reference'
-apidoc_excluded_paths = ['tests']
+apidoc_excluded_paths = ['tests', '*impl*']
apidoc_separate_modules = True
+apidoc_toc_file = False
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
@@ -76,6 +80,9 @@
# autodoc_mock_imports allows Sphinx to ignore any external modules listed in the array
autodoc_mock_imports = []
+html_favicon = '_static/favicon.png'
+html_logo = '_static/logo.png'
html_theme_options = {
- "sticky_navigation": False
-}
\ No newline at end of file
+ 'sticky_navigation': False,
+ 'logo_only': True
+}
diff --git a/docs/source/depth/index.rst b/docs/source/depth/index.rst
deleted file mode 100644
index 11e06753..00000000
--- a/docs/source/depth/index.rst
+++ /dev/null
@@ -1,9 +0,0 @@
-======================
-In depth documentation
-======================
-
-.. toctree::
- :maxdepth: 2
-
- unit_parsing
- serialization
\ No newline at end of file
diff --git a/docs/source/depth/unit_parsing.rst b/docs/source/depth/unit_parsing.rst
index 7abd1bdb..d7430b3c 100644
--- a/docs/source/depth/unit_parsing.rst
+++ b/docs/source/depth/unit_parsing.rst
@@ -7,8 +7,13 @@ By default, Pint supports a larger set of units than the Citrine Platform.
Therefore, we include a custom unit definition file in gemd-python: `citrine_en.txt`_.
This file contains the most commonly used units and will grow over time.
+In support of common patterns in materials science, we permit including scaling factors in a unit of measure.
+For example, industrial researchers may have recorded historical data as ``g / 2.5 cm``.
+While this could be converted a simple SI expression, that would prevent researchers from representing the data
+as originally reported, thus creating a potential source of error during the input process.
+
Requests for support of additional units can be made by opening an issue in the `gemd-python repository`_ on github.
-.. _Pint: https://pint.readthedocs.io/en/0.9/
+.. _Pint: https://pint.readthedocs.io/en/0.20/
.. _citrine_en.txt: https://github.com/CitrineInformatics/gemd-python/blob/main/gemd/units/citrine_en.txt
.. _GEMD-python repository: https://github.com/CitrineInformatics/gemd-python
diff --git a/docs/source/index.rst b/docs/source/index.rst
index fdc129a9..a49d07df 100644
--- a/docs/source/index.rst
+++ b/docs/source/index.rst
@@ -6,11 +6,28 @@
Welcome to the GEMD-Python Documentation!
===================================================
-``gemd`` is the Python implementation of the Citrine data model, the full documentation of which
-can be found `here `_.
+This site documents the Python implementation of the Graphical Expression of Materials Data (GEMD) model.
+GEMD is an open source data format developed by `Citrine Informatics `_ for representing
+data in materials in a `FAIR `_ and transformable manner.
+Documentation of the underlying data model can be found `here `_.
To learn about the details of specific classes, please see the module index.
+Installation
+------------
+
+The latest release can be installed via `pip`:
+
+.. code:: bash
+
+ pip install gemd
+
+or a specific version can be installed, for example:
+
+.. code:: bash
+
+ pip install gemd==1.17.1
+
Table of Contents
-----------------
@@ -18,11 +35,17 @@ Table of Contents
:maxdepth: 2
:numbered: 4
- depth/index
+ depth/unit_parsing
+ depth/serialization
-Indices and tables
+Indices
------------------
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`
+
+.. toctree::
+ :maxdepth: 1
+
+ reference/gemd
diff --git a/docs/source/modules.rst b/docs/source/modules.rst
deleted file mode 100644
index f96a8607..00000000
--- a/docs/source/modules.rst
+++ /dev/null
@@ -1,4 +0,0 @@
-.. toctree::
- :maxdepth: 4
-
- setup
diff --git a/docs/source/setup.rst b/docs/source/setup.rst
deleted file mode 100644
index 552eb49d..00000000
--- a/docs/source/setup.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-setup module
-============
-
-.. automodule:: setup
- :members:
- :undoc-members:
- :show-inheritance:
diff --git a/gemd/__init__.py b/gemd/__init__.py
index c1ab8ccf..b8ae0b5a 100644
--- a/gemd/__init__.py
+++ b/gemd/__init__.py
@@ -1,5 +1,5 @@
"""Data concepts library."""
-# flake8: noqa
+from .__version__ import __version__ # noqa: F401
from .entity import Condition, Parameter, Property, PropertyAndConditions, \
CategoricalBounds, CompositionBounds, IntegerBounds, \
MolecularStructureBounds, RealBounds, \
@@ -12,7 +12,7 @@
UniformInteger, DiscreteCategorical, NominalCategorical, \
EmpiricalFormula, NominalComposition, InChI, Smiles, \
LinkByUID, \
- FileLink
+ FileLink # noqa: F401
__all__ = ["Condition", "Parameter", "Property", "PropertyAndConditions",
"CategoricalBounds", "CompositionBounds", "IntegerBounds",
diff --git a/gemd/__version__.py b/gemd/__version__.py
new file mode 100644
index 00000000..4a7bff54
--- /dev/null
+++ b/gemd/__version__.py
@@ -0,0 +1 @@
+__version__ = "1.18.1"
diff --git a/gemd/builders/__init__.py b/gemd/builders/__init__.py
index 2b6884c9..9b21387f 100644
--- a/gemd/builders/__init__.py
+++ b/gemd/builders/__init__.py
@@ -1,2 +1,6 @@
# flake8: noqa
from .impl import make_node, add_edge, add_measurement, add_attribute, make_attribute, make_value
+
+__all__ = [
+ "make_node", "add_edge", "add_measurement", "add_attribute", "make_attribute", "make_value"
+]
diff --git a/gemd/builders/impl.py b/gemd/builders/impl.py
index 430f76b7..395755d9 100644
--- a/gemd/builders/impl.py
+++ b/gemd/builders/impl.py
@@ -18,6 +18,10 @@
from typing import Union, List
+__all__ = [
+ "make_node", "add_edge", "add_measurement", "add_attribute", "make_attribute", "make_value"
+]
+
def make_node(name: str,
*,
@@ -30,19 +34,22 @@ def make_node(name: str,
Parameters
----------
name: str
- Name of the MaterialRun and MaterialSpec.
+ Name of the :class:`~gemd.entity.object.material_run.MaterialRun`
+ and :class:`~gemd.entity.object.material_spec.MaterialSpec`.
process_name: str
- Name of the ProcessRun and ProcessSpec. Defaults to
- `process_template.name` if `process_template` is defined, else `name`.
- process_template: ProcessTemplate
- ProcessTemplate for the quadruple.
- material_template: MaterialTemplate
- MaterialTemplate for the quadruple.
+ Name of the :class:`~gemd.entity.object.process_run.ProcessRun`
+ and :class:`~gemd.entity.object.process_spec.ProcessSpec`. Defaults to
+ :attr:`process_template.name` if `process_template` is defined, else `name`.
+ process_template: ~gemd.entity.template.process_template.ProcessTemplate
+ :class:`~gemd.entity.template.process_template.ProcessTemplate` for the quadruple.
+ material_template: ~gemd.entity.template.material_template.MaterialTemplate
+ :class:`~gemd.entity.template.material_template.MaterialTemplate` for the quadruple.
Returns
--------
- MaterialRun
- A MaterialRun with linked processes, specs and templates
+ ~gemd.entity.object.material_run.MaterialRun
+ A :class:`~gemd.entity.object.material_run.MaterialRun` with linked processes,
+ specs and templates
"""
if process_name is None:
@@ -90,28 +97,45 @@ def add_edge(input_material: MaterialRun,
Parameters
----------
- input_material: MaterialRun
- The `material` for the returned IngredientRun
- output_material: MaterialRun
- The `process` for the returned IngredientRun will be
- `output_material.process`
+ input_material: ~gemd.entity.object.material_run.MaterialRun
+ The :attr:`~gemd.entity.object.ingredient_run.IngredientRun.material`
+ for the returned
+ :class:`~gemd.entity.object.ingredient_run.IngredientRun`
+ output_material: ~gemd.entity.object.material_run.MaterialRun
+ The :attr:`~gemd.entity.object.ingredient_run.IngredientRun.process`
+ for the returned
+ :class:`~gemd.entity.object.ingredient_run.IngredientRun`
+ will be `output_material.process`
name: str
The ingredient name. Defaults to `input_material.name`.
- mass_fraction: float or ContinuousValue
- The mass fraction of the Ingredient Run. 0 <= x <= 1
- number_fraction: float or ContinuousValue
- The number fraction of the Ingredient Run. 0 <= x <= 1
- volume_fraction: float or ContinuousValue
- The volume fraction of the Ingredient Run. 0 <= x <= 1
- absolute_quantity: float or ContinuousValue
- The absolute quantity. 0 <= x
+ mass_fraction: float or ~gemd.entity.value.continuous_value.ContinuousValue
+ The :attr:`~gemd.entity.object.ingredient_run.IngredientRun.mass_fraction`
+ of the returned
+ :class:`~gemd.entity.object.ingredient_run.IngredientRun`.`
+ 0 <= x <= 1
+ number_fraction: float or ~gemd.entity.value.continuous_value.ContinuousValue
+ The :attr:`~gemd.entity.object.ingredient_run.IngredientRun.number_fraction`
+ of the returned
+ :class:`~gemd.entity.object.ingredient_run.IngredientRun`.
+ 0 <= x <= 1
+ volume_fraction: float or ~gemd.entity.value.continuous_value.ContinuousValue
+ The :attr:`~gemd.entity.object.ingredient_run.IngredientRun.volume_fraction`
+ of the returned
+ :class:`~gemd.entity.object.ingredient_run.IngredientRun`.
+ 0 <= x <= 1
+ absolute_quantity: float or ~gemd.entity.value.continuous_value.ContinuousValue
+ The :attr:`~gemd.entity.object.ingredient_run.IngredientRun.absolute_quantity`
+ of the returned
+ :class:`~gemd.entity.object.ingredient_run.IngredientRun`.
+ 0 <= x
absolute_units: str
The absolute units. Required if absolute_quantity is provided as a float
Returns
--------
- IngredientRun
- A IngredientRun with linked processes, specs and materials
+ ~gemd.entity.object.ingredient_run.IngredientRun
+ A :class:`~gemd.entity.object.ingredient_run.IngredientRun`
+ with linked processes, specs and materials
"""
output_spec = output_material.spec
@@ -171,24 +195,33 @@ def add_measurement(material: MaterialRun,
attributes: List[BaseAttribute] = None,
) -> MeasurementRun:
"""
- Add a measurement run-spec set to a MaterialRun.
+ Add a measurement run-spec set to a :class:`~gemd.entity.object.material_run.MaterialRun`.
Parameters
----------
- material: MaterialRun
- The `material` for the returned MeasurementRun
+ material: ~gemd.entity.object.material_run.MaterialRun
+ The :attr:`~gemd.entity.object.measurement_run.MeasurementRun.material`
+ for the returned
+ :class:`~gemd.entity.object.measurement_run.MeasurementRun`
name: str
- The name of the measurement. Defaults to
- `template.name` if `template` is defined.
- template: MeasurementTemplate
- The MeasurementTemplate.
+ The :attr:`~gemd.entity.object.measurement_run.MeasurementRun.name`
+ of the measurement. Defaults to `template.name` if `template` is defined.
+ template: ~gemd.entity.template.measurement_template.MeasurementTemplate
+ The :attr:`~gemd.entity.object.measurement_run.MeasurementRun.template`
+ for the returned
+ :class:`~gemd.entity.object.measurement_run.MeasurementRun`
attributes: List[BaseAttribute]
- Attributes you want associated with this MeasurementRun.
+ Attributes you want associated with this
+ :class:`~gemd.entity.object.measurement_run.MeasurementRun`. These can be
+ :class:`Conditions `,
+ :class:`Parameters `,
+ and/or :class:`Properties `.
Returns
--------
- MeasurementRun
- A MeasurementRun with linked material, spec and template
+ ~gemd.entity.object.measurement_run.MeasurementRun
+ A :class:`~gemd.entity.object.measurement_run.MeasurementRun`
+ with linked material, spec and template
"""
if name is None:
@@ -226,10 +259,10 @@ def add_attribute(target: Union[HasProperties, HasConditions, HasParameters],
target: BaseObject
The object to attach the attribute to
template: AttributeTemplate
- The AttributeTemplate for the attribute.
- value: Union[BaseValue, str, float, int]
- The value for the attribute. Accepts any GEMD Value type, or will
- attempt to generate an appropriate Value given a str, float or int.
+ The :attr:`~BaseAttribute.template` for the attribute.
+ value: BaseValue, str, float, or int
+ The :attr:`~BaseAttribute.value` for the attribute. Accepts any GEMD Value type, or will
+ attempt to generate an appropriate :class:`BaseValue` subclass given a str, float or int.
Returns
--------
@@ -272,9 +305,9 @@ def make_attribute(template: Union[PropertyTemplate, ConditionTemplate, Paramete
Parameters
----------
template: AttributeTemplate
- The AttributeTemplate for the attribute.
- value: Union[BaseValue, str, float, int]
- The value for the attribute. Accepts any GEMD Value type, or will
+ The :attr:`~BaseAttribute.template` for the attribute.
+ value: BaseValue, str, float, or int
+ The :attr:`~BaseAttribute.value` for the attribute. Accepts any GEMD Value type, or will
attempt to generate an appropriate Value given a str, float or int.
Returns
@@ -307,7 +340,7 @@ def make_value(value: Union[str, float, int],
Parameters
----------
- value: Union[str, float, int]
+ value: str, float, or int
The primitive type to wrap in a Value
bounds: BaseBounds
The bounds type to determine which value type we want to coerce the value into
diff --git a/gemd/demo/cake.py b/gemd/demo/cake.py
index 055e3ecc..fb266340 100644
--- a/gemd/demo/cake.py
+++ b/gemd/demo/cake.py
@@ -25,6 +25,10 @@
from gemd.util.impl import recursive_foreach
+__all__ = [
+ "change_scope", "get_demo_scope", "get_template_scope", "import_toothpick_picture",
+ "make_cake_templates", "make_cake_spec", "make_cake"
+]
# For now, module constant, though likely this should get promoted to a package level
DEMO_SCOPE = 'citrine-demo'
diff --git a/gemd/demo/strehlow_and_cook.py b/gemd/demo/strehlow_and_cook.py
index 389b9ab9..bc6f768a 100644
--- a/gemd/demo/strehlow_and_cook.py
+++ b/gemd/demo/strehlow_and_cook.py
@@ -37,6 +37,11 @@
FULL_TABLE = "strehlow_and_cook.pif"
SMALL_TABLE = "strehlow_and_cook_small.pif"
+__all__ = [
+ "import_table", "minimal_subset", "make_templates", "make_strehlow_objects",
+ "make_strehlow_table", "make_display_table"
+]
+
def import_table(filename=SMALL_TABLE):
"""Return the deserialized JSON table."""
@@ -398,6 +403,7 @@ def make_display_table(structured):
(CSV of scalar values) based upon some standard assumptions about how it should be displayed.
:param structured: A structured table, such as generated by make_strehlow_table
+
:return
"""
table = [[]]
diff --git a/gemd/entity/attribute/base_attribute.py b/gemd/entity/attribute/base_attribute.py
index 3f103907..c38aa026 100644
--- a/gemd/entity/attribute/base_attribute.py
+++ b/gemd/entity/attribute/base_attribute.py
@@ -1,7 +1,7 @@
from gemd.entity.dict_serializable import DictSerializable, logger
from gemd.entity.template.attribute_template import AttributeTemplate
from gemd.entity.value.base_value import BaseValue
-from gemd.enumeration import Origin
+from gemd.enumeration.origin import Origin
from gemd.entity.setters import validate_list
from gemd.entity.file_link import FileLink
from gemd.entity.link_by_uid import LinkByUID
@@ -21,16 +21,15 @@ class BaseAttribute(DictSerializable):
Required name of the attribute. Each attribute within an object must have a unique name.
notes: str
Optional free-form notes about the attribute.
- value: :py:class:`BaseValue `
+ value: BaseValue
The value of the attribute.
- template: :class:`AttributeTemplate \
- `
+ template: AttributeTemplate
Attribute template that defines the allowed bounds of this attribute. If a template
and value are both present then the value must be within the template bounds.
- origin: str
+ origin: str or ~gemd.enumeration.origin.Origin
The origin of the attribute. Must be one of "measured", "predicted", "summary",
"specified", "computed", or "unknown." Default is "unknown."
- file_links: List[FileLink]
+ file_links: List[~gemd.entity.file_link.FileLink]
Links to files associated with the attribute.
"""
@@ -69,11 +68,12 @@ def _check(template: AttributeTemplate, value: BaseValue):
@property
def value(self) -> BaseValue:
- """Get value."""
+ """Get the value."""
return self._value
@value.setter
def value(self, value: BaseValue):
+ """Set the value."""
if value is None:
self._value = None
elif isinstance(value, BaseValue):
@@ -85,11 +85,12 @@ def value(self, value: BaseValue):
@property
def template(self) -> Optional[Union[AttributeTemplate, LinkByUID]]:
- """Get template."""
+ """Get the template."""
return self._template
@template.setter
def template(self, template: Optional[Union[AttributeTemplate, LinkByUID]]):
+ """Set the template."""
if template is None:
self._template = None
elif isinstance(template, (self._template_type(), LinkByUID)):
@@ -107,20 +108,22 @@ def _template_type() -> Type:
@property
def origin(self) -> Origin:
- """Get origin."""
+ """Get the origin."""
return self._origin
@origin.setter
def origin(self, origin: Union[Origin, str]):
+ """Set the origin."""
if origin is None:
raise ValueError("origin must be specified (but may be `unknown`)")
self._origin = Origin.from_str(origin, exception=True)
@property
def file_links(self) -> List[FileLink]:
- """Get file links."""
+ """Get the file links."""
return self._file_links
@file_links.setter
def file_links(self, file_links: Optional[Union[Iterable[FileLink], FileLink]]):
+ """Set the file links."""
self._file_links = validate_list(file_links, FileLink)
diff --git a/gemd/entity/attribute/condition.py b/gemd/entity/attribute/condition.py
index 90315d1b..aff09882 100644
--- a/gemd/entity/attribute/condition.py
+++ b/gemd/entity/attribute/condition.py
@@ -3,6 +3,8 @@
from typing import Type
+__all__ = ["Condition"]
+
class Condition(BaseAttribute, typ="condition"):
"""
@@ -17,16 +19,15 @@ class Condition(BaseAttribute, typ="condition"):
Required name of the attribute. Each attribute within an object must have a unique name.
notes: str
Optional free-form notes about the attribute.
- value: :class:`BaseValue `
+ value: ~gemd.entity.value.base_value.BaseValue
The value of the attribute.
- template: :class:`AttributeTemplate \
- `
+ template: ~gemd.entity.template.attribute_template.AttributeTemplate
Attribute template that defines the allowed bounds of this attribute. If a template
and value are both present then the value must be within the template bounds.
origin: str
The origin of the attribute. Must be one of "measured", "predicted", "summary",
"specified", "computed", or "unknown." Default is "unknown."
- file_links: List[:class:`FileLink `]
+ file_links: List[~gemd.entity.file_link.FileLink]
Links to files associated with the attribute.
"""
diff --git a/gemd/entity/attribute/parameter.py b/gemd/entity/attribute/parameter.py
index 5d8615e3..d8bf136c 100644
--- a/gemd/entity/attribute/parameter.py
+++ b/gemd/entity/attribute/parameter.py
@@ -3,6 +3,8 @@
from typing import Type
+__all__ = ["Parameter"]
+
class Parameter(BaseAttribute, typ="parameter"):
"""
@@ -18,16 +20,15 @@ class Parameter(BaseAttribute, typ="parameter"):
Required name of the attribute. Each attribute within an object must have a unique name.
notes: str
Optional free-form notes about the attribute.
- value: :class:`BaseValue `
+ value: ~gemd.entity.value.base_value.BaseValue
The value of the attribute.
- template: :class:`AttributeTemplate \
- `
+ template: ~gemd.entity.template.attribute_template.AttributeTemplate
Attribute template that defines the allowed bounds of this attribute. If a template
and value are both present then the value must be within the template bounds.
origin: str
The origin of the attribute. Must be one of "measured", "predicted", "summary",
"specified", "computed", or "unknown." Default is "unknown."
- file_links: List[:class:`FileLink `]
+ file_links: List[~gemd.entity.file_link.FileLink]
Links to files associated with the attribute.
"""
diff --git a/gemd/entity/attribute/property.py b/gemd/entity/attribute/property.py
index 6528fc92..bdc0277c 100644
--- a/gemd/entity/attribute/property.py
+++ b/gemd/entity/attribute/property.py
@@ -3,6 +3,8 @@
from typing import Type
+__all__ = ["Property"]
+
class Property(BaseAttribute, typ="property"):
"""
@@ -17,16 +19,15 @@ class Property(BaseAttribute, typ="property"):
Required name of the attribute. Each attribute within an object must have a unique name.
notes: str
Optional free-form notes about the attribute.
- value: :class:`BaseValue `
+ value: ~gemd.entity.value.base_value.BaseValue
The value of the attribute.
- template: :class:`AttributeTemplate \
- `
+ template: ~gemd.entity.template.attribute_template.AttributeTemplate
Attribute template that defines the allowed bounds of this attribute. If a template
and value are both present then the value must be within the template bounds.
origin: str
The origin of the attribute. Must be one of "measured", "predicted", "summary",
"specified", "computed", or "unknown." Default is "unknown."
- file_links: List[:class:`FileLink `]
+ file_links: List[~gemd.entity.file_link.FileLink]
Links to files associated with the attribute.
"""
diff --git a/gemd/entity/attribute/property_and_conditions.py b/gemd/entity/attribute/property_and_conditions.py
index 192d5af9..040f77da 100644
--- a/gemd/entity/attribute/property_and_conditions.py
+++ b/gemd/entity/attribute/property_and_conditions.py
@@ -8,6 +8,8 @@
from typing import Optional, Union, Iterable, List
+__all__ = ["PropertyAndConditions"]
+
class PropertyAndConditions(DictSerializable, typ="property_and_conditions"):
"""
@@ -17,9 +19,9 @@ class PropertyAndConditions(DictSerializable, typ="property_and_conditions"):
Parameters
----------
- property: :class:`Property `
+ property: ~gemd.entity.attribute.property.Property
A property attribute
- conditions: List[:class:`Condition `]
+ conditions: List[~gemd.entity.attribute.condition.Condition]
An optional list of conditions associated with this property.
"""
diff --git a/gemd/entity/base_entity.py b/gemd/entity/base_entity.py
index c1d72289..06d169e8 100644
--- a/gemd/entity/base_entity.py
+++ b/gemd/entity/base_entity.py
@@ -1,30 +1,20 @@
"""Base class for all entities."""
-from typing import Optional, Union, Iterable, List, Set, FrozenSet, Mapping, Dict
+from typing import TypeVar, Optional, Union, Iterable, List, Set, FrozenSet, MutableMapping, Dict
from gemd.entity.dict_serializable import DictSerializable
from gemd.entity.has_dependencies import HasDependencies
from gemd.entity.case_insensitive_dict import CaseInsensitiveDict
from gemd.entity.setters import validate_list
+__all__ = ["BaseEntity"]
+BaseEntityType = TypeVar("BaseEntityType", bound="BaseEntity")
+LinkByUIDType = TypeVar("LinkByUIDType", bound="LinkByUID") # noqa: F821
-class BaseEntity(DictSerializable):
- """
- Base class for any entity, which includes objects and templates.
-
- Parameters
- ----------
- uids: Map[str, str]
- A collection of
- `unique IDs `_.
- tags: List[str]
- `Tags `_
- are hierarchical strings that store information about an entity. They can be used
- for filtering and discoverability.
- """
+class BaseEntity(DictSerializable):
+ """Base class for any entity, which includes objects and templates."""
- def __init__(self, uids: Mapping[str, str], tags: Iterable[str]):
+ def __init__(self, uids: MutableMapping[str, str], tags: Iterable[str]):
self._tags = None
self.tags = tags
@@ -33,23 +23,37 @@ def __init__(self, uids: Mapping[str, str], tags: Iterable[str]):
@property
def tags(self) -> List[str]:
- """Get the tags."""
+ """A collection of structured labels.
+
+ `Tags `_
+ are hierarchical strings that store information about an entity. They can be used
+ for filtering and discoverability.
+ """
return self._tags
@tags.setter
def tags(self, tags: Iterable[str]):
+ """Set the tags."""
self._tags = validate_list(tags, str)
@property
- def uids(self) -> Mapping[str, str]:
- """Get the uids."""
+ def uids(self) -> Dict[str, str]:
+ """
+ A collection of unique IDs.
+
+ Requirements for and the value of unique IDs are discussed
+ `here `_.
+
+ """
return self._uids
@uids.setter
- def uids(self, uids: Mapping[str, str]):
+ def uids(self, uids: MutableMapping[str, str]):
+ """Set the uids."""
if uids is None:
self._uids = CaseInsensitiveDict()
- elif isinstance(uids, Mapping):
+ elif isinstance(uids, MutableMapping):
self._uids = CaseInsensitiveDict(**uids)
else:
self._uids = CaseInsensitiveDict(**{uids[0]: uids[1]})
@@ -71,9 +75,10 @@ def add_uid(self, scope: str, uid: str):
def to_link(self,
scope: Optional[str] = None,
*,
- allow_fallback: bool = False) -> 'LinkByUID': # noqa: F821
+ allow_fallback: bool = False
+ ) -> LinkByUIDType:
"""
- Generate a LinkByUID for this object.
+ Generate a ~gemd.entity.link_by_uid.LinkByUID for this object.
Parameters
----------
@@ -84,7 +89,7 @@ def to_link(self,
Returns
-------
- LinkByUID
+ ~gemd.entity.link_by_uid.LinkByUID
"""
from gemd.entity.link_by_uid import LinkByUID
@@ -100,7 +105,7 @@ def to_link(self,
return LinkByUID(scope=scope, id=uid)
- def all_dependencies(self) -> Set[Union["BaseEntity", "LinkByUID"]]: # noqa: F821
+ def all_dependencies(self) -> Set[Union[BaseEntityType, LinkByUIDType]]:
"""Return a set of all immediate dependencies (no recursion)."""
result = set()
queue = [type(self)]
@@ -113,10 +118,11 @@ def all_dependencies(self) -> Set[Union["BaseEntity", "LinkByUID"]]: # noqa: F8
return result
@staticmethod
- def _cached_equals(this: 'BaseEntity',
- that: 'BaseEntity',
+ def _cached_equals(this: "BaseEntity",
+ that: "BaseEntity",
*,
- cache: Dict[FrozenSet, Optional[bool]] = None) -> Optional[bool]:
+ cache: Dict[FrozenSet, Optional[bool]] = None
+ ) -> Optional[bool]:
"""
Compute and stash whether two Base Entities are equal in a recursive sense.
diff --git a/gemd/entity/bounds/base_bounds.py b/gemd/entity/bounds/base_bounds.py
index fb6b4236..93281264 100644
--- a/gemd/entity/bounds/base_bounds.py
+++ b/gemd/entity/bounds/base_bounds.py
@@ -1,28 +1,33 @@
"""Base class for all bounds."""
from abc import abstractmethod
-from typing import Union
+from typing import TypeVar, Union
from gemd.entity.dict_serializable import DictSerializable
+__all__ = ["BaseBounds"]
+BaseBoundsType = TypeVar("BaseBoundsType", bound="BaseBounds")
+BaseValueType = TypeVar("BaseValueType", bound="BaseValue") # noqa: F821
+
class BaseBounds(DictSerializable):
"""Base class for bounds, including RealBounds and CategoricalBounds."""
@abstractmethod
- def contains(self, bounds: Union["BaseBounds", "BaseValue"]): # noqa: F821
+ def contains(self, bounds: Union[BaseBoundsType, BaseValueType]):
"""
Check if another bounds is contained within this bounds.
Parameters
----------
- bounds: Union[BaseBounds, BaseValue]
+ bounds: BaseBounds or BaseValue
Other bounds object to check. If it's a Value object, check against
- the smallest compatible bounds, as returned by the
+ the smallest compatible bounds, as returned by the Value's
+ :func:`~gemd.entity.base_bounds.BaseBounds._to_bounds` method.
Returns
-------
bool
- True if any value that validates true for bounds also validates true for this
+ True if all values valid for `bounds` are also valid for this object
"""
from gemd.entity.value.base_value import BaseValue
@@ -36,7 +41,7 @@ def contains(self, bounds: Union["BaseBounds", "BaseValue"]): # noqa: F821
raise TypeError('{} is not a Bounds object'.format(bounds))
@abstractmethod
- def union(self, *others: Union["BaseBounds", "BaseValue"]) -> "BaseBounds": # noqa: F821
+ def union(self, *others: Union[BaseBoundsType, BaseValueType]) -> BaseBoundsType:
"""
Return the union of this bounds and other bounds.
@@ -44,8 +49,10 @@ def union(self, *others: Union["BaseBounds", "BaseValue"]) -> "BaseBounds": # n
Parameters
----------
- others: Union[BaseBounds, BaseValue]
- Other bounds or value objects to include.
+ others: BaseBounds or BaseValue
+ Other bounds or value objects to include. If they're Value objects,
+ increase by the smallest compatible bounds, as returned by the value's
+ :func:`~gemd.entity.base_bounds.BaseBounds._to_bounds` method.
Returns
-------
@@ -53,10 +60,9 @@ def union(self, *others: Union["BaseBounds", "BaseValue"]) -> "BaseBounds": # n
The union of this bounds and the passed bounds
"""
- pass # pragma: no cover
@abstractmethod
- def update(self, *others: Union["BaseBounds", "BaseValue"]): # noqa: F821
+ def update(self, *others: Union[BaseBoundsType, BaseValueType]):
"""
Update this bounds to include other bounds.
@@ -64,8 +70,9 @@ def update(self, *others: Union["BaseBounds", "BaseValue"]): # noqa: F821
Parameters
----------
- others: Union[BaseBounds, BaseValue]
- Other bounds or value objects to include.
+ others: BaseBounds or BaseValue
+ Other bounds or value objects to include. If they're Value objects,
+ increase by the smallest compatible bounds, as returned by the value's
+ :func:`~gemd.entity.base_bounds.BaseBounds._to_bounds` method.
"""
- pass # pragma: no cover
diff --git a/gemd/entity/bounds/categorical_bounds.py b/gemd/entity/bounds/categorical_bounds.py
index bad59205..20be8acf 100644
--- a/gemd/entity/bounds/categorical_bounds.py
+++ b/gemd/entity/bounds/categorical_bounds.py
@@ -1,8 +1,12 @@
-"""A restricted set of categories."""
+from typing import TypeVar, Any, Union, Set, Optional, Iterable, Dict
+
from gemd.entity.bounds.base_bounds import BaseBounds
from gemd.entity.util import array_like
-from typing import Union, Set, Optional, Iterable
+__all__ = ["CategoricalBounds"]
+CategoricalBoundsType = TypeVar("CategoricalBoundsType", bound="CategoricalBounds")
+BaseValueType = TypeVar("BaseValueType", bound="BaseValue") # noqa: F821
+CategoricalValueType = TypeVar("CategoricalValueType", bound="CategoricalValue") # noqa: F821
class CategoricalBounds(BaseBounds, typ="categorical_bounds"):
@@ -22,7 +26,7 @@ def __init__(self, categories: Optional[Iterable[str]] = None):
@property
def categories(self) -> Set[str]:
- """Get the set of categories."""
+ """The collection of allowed categories."""
return self._categories
@categories.setter
@@ -39,17 +43,20 @@ def categories(self, categories: Optional[Iterable[str]]):
if not all(isinstance(x, str) for x in self.categories):
raise ValueError("All the categories must be strings")
- def contains(self, bounds: Union[BaseBounds, "BaseValue"]) -> bool: # noqa: F821
+ def contains(self, bounds: Union[BaseBounds, BaseValueType]) -> bool:
"""
- Check if another bounds object or value objects is contained by this bounds.
+ Check if another bounds object or value object is contained by this bounds.
The other object must also be Categorical and its allowed categories must be a
subset of this bounds's allowed categories.
Parameters
----------
- bounds: Union[BaseBounds, BaseValue]
- Other bounds or value object to check.
+ bounds: BaseBounds or BaseValue
+ Other bounds or value object to check. If it's a Value object, check against
+ the smallest compatible bounds, as returned by the Value's
+ :func:`~gemd.entity.base_bounds.BaseBounds._to_bounds` method.
+
Returns
-------
@@ -69,8 +76,8 @@ def contains(self, bounds: Union[BaseBounds, "BaseValue"]) -> bool: # noqa: F82
return bounds.categories.issubset(self.categories)
def union(self,
- *others: Union["CategoricalBounds", "CategoricalValue"] # noqa: F821
- ) -> "CategoricalBounds": # noqa: F821
+ *others: Union[CategoricalBoundsType, CategoricalValueType]
+ ) -> CategoricalBoundsType:
"""
Return the union of this bounds and other bounds.
@@ -78,8 +85,10 @@ def union(self,
Parameters
----------
- others: Union[CategoricalBounds, CategoricalValue]
- Other bounds or value objects to include.
+ others: CategoricalBounds or ~gemd.value.categorical_value.CategoricalValue
+ Other bounds or value objects to include. If they're Value objects,
+ increase by the smallest compatible bounds, as returned by the value's
+ :func:`~gemd.entity.base_bounds.BaseBounds._to_bounds` method.
Returns
-------
@@ -102,7 +111,7 @@ def union(self,
result.update(bounds.categories)
return CategoricalBounds(result)
- def update(self, *others: Union["CategoricalBounds", "CategoricalValue"]): # noqa: F821
+ def update(self, *others: Union[CategoricalBoundsType, CategoricalValueType]):
"""
Update this bounds to include other bounds.
@@ -110,13 +119,15 @@ def update(self, *others: Union["CategoricalBounds", "CategoricalValue"]): # no
Parameters
----------
- others: Union[CategoricalBounds, CategoricalValue]
- Other bounds or value objects to include.
+ others: CategoricalBounds or ~gemd.entity.value.categorical_value.CategoricalValue
+ Other bounds or value objects to include. If they're Value objects,
+ increase by the smallest compatible bounds, as returned by the value's
+ :func:`~gemd.entity.base_bounds.BaseBounds._to_bounds` method.
"""
self.categories = self.union(*others).categories
- def as_dict(self):
+ def as_dict(self) -> Dict[str, Any]:
"""
Convert bounds to a dictionary.
diff --git a/gemd/entity/bounds/composition_bounds.py b/gemd/entity/bounds/composition_bounds.py
index db399d5c..3b2ff8fd 100644
--- a/gemd/entity/bounds/composition_bounds.py
+++ b/gemd/entity/bounds/composition_bounds.py
@@ -2,7 +2,12 @@
from gemd.entity.bounds.base_bounds import BaseBounds
from gemd.entity.util import array_like
-from typing import Union
+from typing import TypeVar, Union, Set, Iterable
+
+__all__ = ["CompositionBounds"]
+CompositionBoundsType = TypeVar("CompositionBoundsType", bound="CompositionBounds")
+BaseValueType = TypeVar("BaseValueType", bound="BaseValue") # noqa: F821
+CompositionValueType = TypeVar("CompositionValueType", bound="CompositionValue") # noqa: F821
class CompositionBounds(BaseBounds, typ="composition_bounds"):
@@ -21,12 +26,13 @@ def __init__(self, components=None):
self.components = components
@property
- def components(self):
- """Get the allowed components."""
+ def components(self) -> Set[str]:
+ """Get the collection of the components that are allowed in the composition."""
return self._components
@components.setter
- def components(self, value):
+ def components(self, value: Iterable[str]):
+ """Set collection of the components that are allowed in the composition."""
if value is None:
self._components = set()
elif isinstance(value, array_like()):
@@ -39,7 +45,7 @@ def components(self, value):
if not all(isinstance(x, str) for x in self.components):
raise ValueError("All the components must be strings")
- def contains(self, bounds: Union[BaseBounds, "BaseValue"]) -> bool: # noqa: F821
+ def contains(self, bounds: Union[BaseBounds, BaseValueType]) -> bool:
"""
Check if another bounds or value object is contained by this bounds.
@@ -48,8 +54,10 @@ def contains(self, bounds: Union[BaseBounds, "BaseValue"]) -> bool: # noqa: F82
Parameters
----------
- bounds: Union[BaseBounds, BaseValue]
- Other object to check.
+ bounds: BaseBounds or BaseValue
+ Other object to check. If it's a Value object, check against
+ the smallest compatible bounds, as returned by the Value's
+ :func:`~gemd.entity.base_bounds.BaseBounds._to_bounds` method.
Returns
-------
@@ -69,8 +77,8 @@ def contains(self, bounds: Union[BaseBounds, "BaseValue"]) -> bool: # noqa: F82
return bounds.components.issubset(self.components)
def union(self,
- *others: Union["CompositionBounds", "CompositionValue"] # noqa: F821
- ) -> "CompositionBounds": # noqa: F821
+ *others: Union[CompositionBoundsType, CompositionValueType]
+ ) -> CompositionBoundsType:
"""
Return the union of this bounds and other bounds.
@@ -78,12 +86,14 @@ def union(self,
Parameters
----------
- others: Union[CompositionBounds, CompositionValue]
- Other bounds or value objects to include.
+ others: CompositionBounds or ~gemd.entity.value.compositional_value.CompositionValue
+ Other bounds or value objects to include. If they're Value objects,
+ increase by the smallest compatible bounds, as returned by the value's
+ :func:`~gemd.entity.base_bounds.BaseBounds._to_bounds` method.
Returns
-------
- CategoricalBounds
+ CompositionBounds
The union of this bounds and the passed bounds
"""
@@ -102,16 +112,18 @@ def union(self,
result.update(bounds.components)
return CompositionBounds(result)
- def update(self, *others: Union["CompositionBounds", "CompositionValue"]): # noqa: F821
+ def update(self, *others: Union[CompositionBoundsType, CompositionValueType]):
"""
Update this bounds to include other bounds.
- The others list must also be Categorical Bounds or Values.
+ The others list must also be Composition Bounds or Values.
Parameters
----------
- others: Union[CategoricalBounds, CategoricalValue]
- Other bounds or value objects to include.
+ others: CompositionBounds or ~gemd.entity.value.compositional_value.CompositionValue
+ Other bounds or value objects to include. If they're Value objects,
+ increase by the smallest compatible bounds, as returned by the value's
+ :func:`~gemd.entity.base_bounds.BaseBounds._to_bounds` method.
"""
self.components = self.union(*others).components
diff --git a/gemd/entity/bounds/integer_bounds.py b/gemd/entity/bounds/integer_bounds.py
index 212fffda..bd27b991 100644
--- a/gemd/entity/bounds/integer_bounds.py
+++ b/gemd/entity/bounds/integer_bounds.py
@@ -1,14 +1,26 @@
"""Bounds an integer to be between two values."""
from math import isfinite
-from typing import Union
+from typing import TypeVar, Union
from gemd.entity.bounds.base_bounds import BaseBounds
__all__ = ["IntegerBounds"]
+IntegerBoundsType = TypeVar("IntegerBoundsType", bound="IntegerBounds")
+BaseValueType = TypeVar("BaseValueType", bound="BaseValue") # noqa: F821
+IntegerValueType = TypeVar("IntegerValueType", bound="IntegerValue") # noqa: F821
class IntegerBounds(BaseBounds, typ="integer_bounds"):
- """Bounded subset of the integers, parameterized by a lower and upper bound."""
+ """
+ Bounded subset of the integers, parameterized by a lower and upper bound.
+
+ Parameters
+ ----------
+ lower_bound: int
+ The lower endpoint (inclusive) of the permitted range.
+ upper_bound: int
+ The upper endpoint (inclusive) of the permitted range.
+ """
def __init__(self, lower_bound: int, upper_bound: int):
self._lower_bound = None
@@ -47,7 +59,7 @@ def upper_bound(self, value: int):
f"greater than or equal to lower bound ({self.lower_bound})")
self._upper_bound = int(value)
- def contains(self, bounds: Union[BaseBounds, "BaseValue"]) -> bool: # noqa: F821
+ def contains(self, bounds: Union[BaseBounds, BaseValueType]) -> bool:
"""
Check if another bounds or value object is a subset of this range.
@@ -56,8 +68,10 @@ def contains(self, bounds: Union[BaseBounds, "BaseValue"]) -> bool: # noqa: F82
Parameters
----------
- bounds: Union[BaseBounds, BaseValue]
- Other bounds or value object to check.
+ bounds: BaseBounds or BaseValue
+ Other bounds or value object to check. If it's a Value object, check against
+ the smallest compatible bounds, as returned by the Value's
+ :func:`~gemd.entity.base_bounds.BaseBounds._to_bounds` method.
Returns
-------
@@ -77,8 +91,8 @@ def contains(self, bounds: Union[BaseBounds, "BaseValue"]) -> bool: # noqa: F82
return bounds.lower_bound >= self.lower_bound and bounds.upper_bound <= self.upper_bound
def union(self,
- *others: Union["IntegerBounds", "IntegerValue"] # noqa: F821
- ) -> "IntegerBounds": # noqa: F821
+ *others: Union[IntegerBoundsType, IntegerValueType]
+ ) -> IntegerBoundsType:
"""
Return the union of this bounds and other bounds.
@@ -86,8 +100,10 @@ def union(self,
Parameters
----------
- others: Union[IntegerBounds, IntegerValue]
- Other bounds or value objects to include.
+ others: IntegerBounds or ~gemd.entity.value.integer_value.IntegerValue
+ Other bounds or value objects to include. If they're Value objects,
+ increase by the smallest compatible bounds, as returned by the value's
+ :func:`~gemd.entity.base_bounds.BaseBounds._to_bounds` method.
Returns
-------
@@ -113,16 +129,18 @@ def union(self,
upper = bounds.upper_bound
return IntegerBounds(lower_bound=lower, upper_bound=upper)
- def update(self, *others: Union["IntegerBounds", "IntegerValue"]): # noqa: F821
+ def update(self, *others: Union[IntegerBoundsType, IntegerValueType]):
"""
Update this bounds to include other bounds.
- The others list must also be Categorical Bounds or Values.
+ The others list must also be Integer Bounds or Values.
Parameters
----------
- others: Union[IntegerBounds, IntegerValue]
- Other bounds or value objects to include.
+ others: IntegerBounds or ~gemd.entity.value.integer_value.IntegerValue
+ Other bounds or value objects to include. If they're Value objects,
+ increase by the smallest compatible bounds, as returned by the value's
+ :func:`~gemd.entity.base_bounds.BaseBounds._to_bounds` method.
"""
result = self.union(*others)
diff --git a/gemd/entity/bounds/molecular_structure_bounds.py b/gemd/entity/bounds/molecular_structure_bounds.py
index de08b369..4586531e 100644
--- a/gemd/entity/bounds/molecular_structure_bounds.py
+++ b/gemd/entity/bounds/molecular_structure_bounds.py
@@ -5,13 +5,18 @@
"""
from gemd.entity.bounds.base_bounds import BaseBounds
-from typing import Union
+from typing import TypeVar, Union
+
+__all__ = ["MolecularStructureBounds"]
+MolecularBoundsType = TypeVar("MolecularBoundsType", bound="MolecularStructureBounds")
+BaseValueType = TypeVar("BaseValueType", bound="BaseValue") # noqa: F821
+MolecularValueType = TypeVar("MolecularValueType", bound="MolecularValue") # noqa: F821
class MolecularStructureBounds(BaseBounds, typ="molecular_structure_bounds"):
"""Molecular bounds, with no component or substructural restrictions (yet)."""
- def contains(self, bounds: Union[BaseBounds, "BaseValue"]) -> bool: # noqa: F821
+ def contains(self, bounds: Union[BaseBounds, BaseValueType]) -> bool:
"""
Check if another bounds or value object is contained by this bounds.
@@ -20,8 +25,10 @@ def contains(self, bounds: Union[BaseBounds, "BaseValue"]) -> bool: # noqa: F82
Parameters
----------
- bounds: Union[BaseBounds, BaseValue]
- Other bounds or value object to check.
+ bounds: BaseBounds or BaseValue
+ Other bounds or value object to check. If it's a Value object, check against
+ the smallest compatible bounds, as returned by the Value's
+ :func:`~gemd.entity.base_bounds.BaseBounds._to_bounds` method.
Returns
-------
@@ -41,8 +48,8 @@ def contains(self, bounds: Union[BaseBounds, "BaseValue"]) -> bool: # noqa: F82
return True
def union(self,
- *others: Union["MolecularStructureBounds", "MolecularValue"] # noqa: F821
- ) -> "MolecularStructureBounds": # noqa: F821
+ *others: Union[MolecularBoundsType, MolecularValueType]
+ ) -> MolecularBoundsType:
"""
Return the union of this bounds and other bounds.
@@ -50,13 +57,15 @@ def union(self,
Parameters
----------
- others: Union[MolecularStructureBounds, MolecularValue]
+ others: MolecularStructureBounds or ~gemd.entity.value.molecular_value.MolecularValue
Other bounds or value objects to include.
Returns
-------
- CategoricalBounds
- The union of this bounds and the passed bounds
+ MolecularStructureBounds
+ The union of this bounds and the passed bounds. If they're Value objects,
+ increase by the smallest compatible bounds, as returned by the value's
+ :func:`~gemd.entity.base_bounds.BaseBounds._to_bounds` method.
"""
from gemd.entity.value.molecular_value import MolecularValue
@@ -69,7 +78,7 @@ def union(self,
f"expected molecular structure, found {misses}")
return MolecularStructureBounds()
- def update(self, *others: Union["MolecularStructureBounds", "MolecularValue"]): # noqa: F821
+ def update(self, *others: Union[MolecularBoundsType, MolecularValueType]):
"""
Update this bounds to include other bounds.
@@ -77,8 +86,10 @@ def update(self, *others: Union["MolecularStructureBounds", "MolecularValue"]):
Parameters
----------
- others: Union[MolecularStructureBounds, MolecularValue]
- Other bounds or value objects to include.
+ others: MolecularStructureBounds or ~gemd.entity.value.molecular_value.MolecularValue
+ Other bounds or value objects to include. If they're Value objects,
+ increase by the smallest compatible bounds, as returned by the value's
+ :func:`~gemd.entity.base_bounds.BaseBounds._to_bounds` method.
"""
pass # This is a no-op for Molecular structure
diff --git a/gemd/entity/bounds/real_bounds.py b/gemd/entity/bounds/real_bounds.py
index 786888e8..041d0159 100644
--- a/gemd/entity/bounds/real_bounds.py
+++ b/gemd/entity/bounds/real_bounds.py
@@ -1,13 +1,27 @@
"""Bound a real number to be between two values."""
from math import isfinite
-from typing import Union
+from typing import TypeVar, Union
from gemd.entity.bounds.base_bounds import BaseBounds
import gemd.units as units
+__all__ = ["RealBounds"]
+RealBoundsType = TypeVar("RealBoundsType", bound="RealBounds")
+BaseValueType = TypeVar("BaseValueType", bound="BaseValue") # noqa: F821
+ContinuousValueType = TypeVar("ContinuousValueType", bound="ContinuousValue") # noqa: F821
+
class RealBounds(BaseBounds, typ="real_bounds"):
- """Bounded subset of the real numbers, parameterized by a lower and upper bound."""
+ """
+ Bounded subset of the real numbers, parameterized by a lower and upper bound.
+
+ Parameters
+ ----------
+ lower_bound: float
+ The lower endpoint (inclusive) of the permitted range.
+ upper_bound: float
+ The upper endpoint (inclusive) of the permitted range.
+ """
def __init__(self, lower_bound: float, upper_bound: float, default_units: str):
self._default_units = None
@@ -66,7 +80,7 @@ def default_units(self, default_units: str):
"Use an empty string for a dimensionless quantity.")
self._default_units = units.parse_units(default_units, return_unit=False)
- def contains(self, bounds: Union[BaseBounds, "BaseValue"]) -> bool: # noqa: F821
+ def contains(self, bounds: Union[BaseBounds, BaseValueType]) -> bool:
"""
Check if another bounds or value object is a subset of this range.
@@ -77,8 +91,10 @@ def contains(self, bounds: Union[BaseBounds, "BaseValue"]) -> bool: # noqa: F82
Parameters
----------
- bounds: Union[BaseBounds, BaseValue]
- Other bounds or value object to check.
+ bounds: BaseBounds or BaseValue
+ Other bounds or value object to check. If it's a Value object, check against
+ the smallest compatible bounds, as returned by the Value's
+ :func:`~gemd.entity.base_bounds.BaseBounds._to_bounds` method.
Returns
-------
@@ -101,7 +117,9 @@ def contains(self, bounds: Union[BaseBounds, "BaseValue"]) -> bool: # noqa: F82
return bounds.lower_bound >= lower and bounds.upper_bound <= upper
- def union(self, *others: Union["RealBounds", "ContinuousValue"]) -> "RealBounds": # noqa: F821
+ def union(self,
+ *others: Union[RealBoundsType, ContinuousValueType]
+ ) -> RealBoundsType:
"""
Return the union of this bounds and other bounds.
@@ -109,8 +127,10 @@ def union(self, *others: Union["RealBounds", "ContinuousValue"]) -> "RealBounds"
Parameters
----------
- others: Union[RealBounds, ContinuousValue]
- Other bounds or value objects to include.
+ others: RealBounds or ContinuousValue
+ Other bounds or value objects to include. If they're Value objects,
+ increase by the smallest compatible bounds, as returned by the value's
+ :func:`~gemd.entity.base_bounds.BaseBounds._to_bounds` method.
Returns
-------
@@ -140,7 +160,7 @@ def union(self, *others: Union["RealBounds", "ContinuousValue"]) -> "RealBounds"
upper = bnd_hi
return RealBounds(lower_bound=lower, upper_bound=upper, default_units=unit_)
- def update(self, *others: Union["RealBounds", "ContinuousValue"]): # noqa: F821
+ def update(self, *others: Union[RealBoundsType, ContinuousValueType]):
"""
Update this bounds to include other bounds.
@@ -148,8 +168,10 @@ def update(self, *others: Union["RealBounds", "ContinuousValue"]): # noqa: F821
Parameters
----------
- others: Union[RealBounds, ContinuousValue]
- Other bounds or value objects to include.
+ others: RealBounds or ContinuousValue
+ Other bounds or value objects to include. If they're Value objects,
+ increase by the smallest compatible bounds, as returned by the value's
+ :func:`~gemd.entity.base_bounds.BaseBounds._to_bounds` method.
"""
result = self.union(*others)
diff --git a/gemd/entity/bounds_validation.py b/gemd/entity/bounds_validation.py
index 328254f1..3b8c039b 100644
--- a/gemd/entity/bounds_validation.py
+++ b/gemd/entity/bounds_validation.py
@@ -1,6 +1,8 @@
from enum import IntEnum
from contextlib import contextmanager
+__all__ = ["WarningLevel", "get_validation_level", "set_validation_level", "validation_level"]
+
class WarningLevel(IntEnum):
"""
diff --git a/gemd/entity/case_insensitive_dict.py b/gemd/entity/case_insensitive_dict.py
index ad9bba29..6aac2b3d 100644
--- a/gemd/entity/case_insensitive_dict.py
+++ b/gemd/entity/case_insensitive_dict.py
@@ -1,5 +1,7 @@
from typing import Tuple, Sequence, Any, Mapping, Optional
+__all__ = ["CaseInsensitiveDict"]
+
_RaiseKeyError = object() # singleton for no-default behavior
diff --git a/gemd/entity/dict_serializable.py b/gemd/entity/dict_serializable.py
index 02ff6290..664af86b 100644
--- a/gemd/entity/dict_serializable.py
+++ b/gemd/entity/dict_serializable.py
@@ -6,6 +6,8 @@
import functools
from typing import TypeVar, Union, Iterable, List, Mapping, Dict, Set, Any
+__all__ = ["DictSerializable"]
+
# There are some weird (probably resolvable) errors during object cloning if this is an
# instance variable of DictSerializable.
logger = getLogger(__name__)
@@ -123,7 +125,7 @@ def dump(self) -> Dict[str, Any]:
return json.loads(encoder.raw_dumps(self))
@staticmethod
- def build(d: Mapping[str, Any]) -> "DictSerializable":
+ def build(d: Mapping[str, Any]) -> DictSerializableType:
"""
Build an object from a JSON dictionary.
diff --git a/gemd/entity/file_link.py b/gemd/entity/file_link.py
index f22ada95..24e971af 100644
--- a/gemd/entity/file_link.py
+++ b/gemd/entity/file_link.py
@@ -1,6 +1,8 @@
"""Represents a link to an external file."""
from gemd.entity.dict_serializable import DictSerializable
+__all__ = ["FileLink"]
+
class FileLink(DictSerializable, typ="file_link"):
"""
diff --git a/gemd/entity/has_dependencies.py b/gemd/entity/has_dependencies.py
index 87b6f4e0..ce57b0ee 100644
--- a/gemd/entity/has_dependencies.py
+++ b/gemd/entity/has_dependencies.py
@@ -1,11 +1,15 @@
"""For entities that have dependencies."""
from abc import ABC, abstractmethod
-from typing import Union, Set
+from typing import TypeVar, Union, Set
+
+__all__ = ["HasDependencies"]
+BaseEntityType = TypeVar("BaseEntityType", bound="BaseEntity") # noqa: F821
+LinkByUIDType = TypeVar("LinkByUIDType", bound="LinkByUID") # noqa: F821
class HasDependencies(ABC):
"""Mix-in trait for objects that reference other objects."""
@abstractmethod
- def _local_dependencies(self) -> Set[Union["BaseEntity", "LinkByUID"]]: # noqa: F821
+ def _local_dependencies(self) -> Set[Union[BaseEntityType, LinkByUIDType]]:
"""All dependencies (objects) that this class introduces."""
diff --git a/gemd/entity/link_by_uid.py b/gemd/entity/link_by_uid.py
index bec0b045..27302685 100644
--- a/gemd/entity/link_by_uid.py
+++ b/gemd/entity/link_by_uid.py
@@ -1,9 +1,13 @@
"""A unique id that stands in for a data object."""
+from typing import TypeVar
import uuid
from warnings import warn
from gemd.entity.dict_serializable import DictSerializable
+__all__ = ["LinkByUID"]
+BaseEntityType = TypeVar("BaseEntityType", bound="BaseEntity") # noqa: F821
+
class LinkByUID(DictSerializable, typ="link_by_uid"):
"""
@@ -27,7 +31,7 @@ def __repr__(self):
return str({"scope": self.scope, "id": self.id})
@classmethod
- def from_entity(cls, entity, name=None, *, scope=None):
+ def from_entity(cls, entity: BaseEntityType, name=None, *, scope=None):
"""
Create LinkByUID from in-memory object.
diff --git a/gemd/entity/object/base_object.py b/gemd/entity/object/base_object.py
index 4020e12e..6078e83c 100644
--- a/gemd/entity/object/base_object.py
+++ b/gemd/entity/object/base_object.py
@@ -6,6 +6,8 @@
from typing import Optional, Union, Iterable, List, Mapping
+__all__ = ["BaseObject"]
+
class BaseObject(BaseEntity):
"""
@@ -27,7 +29,7 @@ class BaseObject(BaseEntity):
for filtering and discoverability.
notes: str, optional
Long-form notes about the object.
- file_links: List[:class:`FileLink `], optional
+ file_links: List[~gemd.entity.file_link.FileLink], optional
Links to associated files, with resource paths into the files API.
"""
@@ -61,16 +63,17 @@ def _attribute_has_setter(cls, name: str) -> bool:
@property
def name(self) -> str:
- """Get name."""
+ """Name of the object."""
return self._name
@name.setter
def name(self, name: str):
+ """Set the name."""
self._name = validate_str(name)
@property
def file_links(self) -> List[FileLink]:
- """Get file links."""
+ """Links to associated files, with resource paths into the files API."""
return self._file_links
@file_links.setter
diff --git a/gemd/entity/object/has_conditions.py b/gemd/entity/object/has_conditions.py
index e0287407..8be1bb14 100644
--- a/gemd/entity/object/has_conditions.py
+++ b/gemd/entity/object/has_conditions.py
@@ -1,5 +1,7 @@
"""For entities that have conditions."""
+from gemd.entity.base_entity import BaseEntity
from gemd.entity.has_dependencies import HasDependencies
+from gemd.entity.link_by_uid import LinkByUID
from gemd.entity.object.has_template_check_generator import HasTemplateCheckGenerator
from gemd.entity.template.has_condition_templates import HasConditionTemplates
from gemd.entity.attribute.condition import Condition
@@ -8,16 +10,11 @@
from typing import Union, Iterable, List, Set
from abc import ABC
+__all__ = ["HasConditions"]
-class HasConditions(HasTemplateCheckGenerator, HasDependencies, ABC):
- """Mixin-trait for entities that include conditions.
-
- Parameters
- ----------
- conditions: List[:class:`Condition `]
- A list of conditions associated with this entity.
- """
+class HasConditions(HasTemplateCheckGenerator, HasDependencies, ABC):
+ """Mixin-trait for entities that include conditions."""
def __init__(self, conditions: Union[Condition, Iterable[Condition]]):
self._conditions = None
@@ -25,7 +22,7 @@ def __init__(self, conditions: Union[Condition, Iterable[Condition]]):
@property
def conditions(self) -> List[Condition]:
- """Get a list of the conditions."""
+ """A list of conditions associated with this entity."""
return self._conditions
@conditions.setter
@@ -34,6 +31,6 @@ def conditions(self, conditions: Union[Condition, Iterable[Condition]]):
checker = self._generate_template_check(HasConditionTemplates.validate_condition)
self._conditions = validate_list(conditions, Condition, trigger=checker)
- def _local_dependencies(self) -> Set[Union["BaseEntity", "LinkByUID"]]: # noqa: F821
+ def _local_dependencies(self) -> Set[Union[BaseEntity, LinkByUID]]:
"""Return a set of all immediate dependencies (no recursion)."""
return {cond.template for cond in self.conditions if cond.template is not None}
diff --git a/gemd/entity/object/has_material.py b/gemd/entity/object/has_material.py
index 7a9d5f5b..dd8c326a 100644
--- a/gemd/entity/object/has_material.py
+++ b/gemd/entity/object/has_material.py
@@ -1,11 +1,14 @@
"""For entities that have specs."""
+from gemd.entity.base_entity import BaseEntity
from gemd.entity.has_dependencies import HasDependencies
-from gemd.entity.object.base_object import BaseObject
from gemd.entity.link_by_uid import LinkByUID
+from gemd.entity.object.base_object import BaseObject
from abc import ABC, abstractmethod
from typing import Union, Set
+__all__ = ["HasMaterial"]
+
class HasMaterial(HasDependencies, ABC):
"""Mix-in trait for objects that can be assigned materials."""
@@ -20,6 +23,6 @@ def material(self) -> Union[BaseObject, LinkByUID]:
def material(self, spec: Union[BaseObject, LinkByUID]):
"""Set the material."""
- def _local_dependencies(self) -> Set[Union["BaseEntity", "LinkByUID"]]: # noqa: F821
+ def _local_dependencies(self) -> Set[Union[BaseEntity, LinkByUID]]:
"""Return a set of all immediate dependencies (no recursion)."""
return {self.material} if self.material is not None else set()
diff --git a/gemd/entity/object/has_parameters.py b/gemd/entity/object/has_parameters.py
index 28a18e67..3343c470 100644
--- a/gemd/entity/object/has_parameters.py
+++ b/gemd/entity/object/has_parameters.py
@@ -1,5 +1,7 @@
"""For entities that have parameters."""
+from gemd.entity.base_entity import BaseEntity
from gemd.entity.has_dependencies import HasDependencies
+from gemd.entity.link_by_uid import LinkByUID
from gemd.entity.object.has_template_check_generator import HasTemplateCheckGenerator
from gemd.entity.template.has_parameter_templates import HasParameterTemplates
from gemd.entity.attribute.parameter import Parameter
@@ -8,16 +10,11 @@
from typing import Union, Iterable, List, Set
from abc import ABC
+__all__ = ["HasParameters"]
-class HasParameters(HasTemplateCheckGenerator, HasDependencies, ABC):
- """Mixin-trait for entities that include parameters.
-
- Parameters
- ----------
- parameters: List[:class:`Parameter `]
- A list of parameters associated with this entity.
- """
+class HasParameters(HasTemplateCheckGenerator, HasDependencies, ABC):
+ """Mixin-trait for entities that include parameters."""
def __init__(self, parameters: Union[Parameter, Iterable[Parameter]]):
self._parameters = None
@@ -25,7 +22,7 @@ def __init__(self, parameters: Union[Parameter, Iterable[Parameter]]):
@property
def parameters(self) -> List[Parameter]:
- """Get the list of parameters."""
+ """A list of parameters associated with this entity."""
return self._parameters
@parameters.setter
@@ -34,6 +31,6 @@ def parameters(self, parameters: Union[Parameter, Iterable[Parameter]]):
checker = self._generate_template_check(HasParameterTemplates.validate_parameter)
self._parameters = validate_list(parameters, Parameter, trigger=checker)
- def _local_dependencies(self) -> Set[Union["BaseEntity", "LinkByUID"]]: # noqa: F821
+ def _local_dependencies(self) -> Set[Union[BaseEntity, LinkByUID]]:
"""Return a set of all immediate dependencies (no recursion)."""
return {param.template for param in self.parameters if param.template is not None}
diff --git a/gemd/entity/object/has_process.py b/gemd/entity/object/has_process.py
index d26b05d8..9f686e68 100644
--- a/gemd/entity/object/has_process.py
+++ b/gemd/entity/object/has_process.py
@@ -1,11 +1,14 @@
"""For entities that have specs."""
+from gemd.entity.base_entity import BaseEntity
from gemd.entity.has_dependencies import HasDependencies
-from gemd.entity.object.base_object import BaseObject
from gemd.entity.link_by_uid import LinkByUID
+from gemd.entity.object.base_object import BaseObject
from abc import abstractmethod
from typing import Union, Set
+__all__ = ["HasProcess"]
+
class HasProcess(HasDependencies):
"""Mix-in trait for objects that can be assigned materials."""
@@ -20,6 +23,6 @@ def process(self) -> Union[BaseObject, LinkByUID]:
def process(self, process: Union[BaseObject, LinkByUID]):
"""Set the process."""
- def _local_dependencies(self) -> Set[Union["BaseEntity", "LinkByUID"]]: # noqa: F821
+ def _local_dependencies(self) -> Set[Union[BaseEntity, LinkByUID]]:
"""Return a set of all immediate dependencies (no recursion)."""
return {self.process} if self.process is not None else set()
diff --git a/gemd/entity/object/has_properties.py b/gemd/entity/object/has_properties.py
index d247db9e..28341af0 100644
--- a/gemd/entity/object/has_properties.py
+++ b/gemd/entity/object/has_properties.py
@@ -1,5 +1,7 @@
"""For entities that have properties."""
+from gemd.entity.base_entity import BaseEntity
from gemd.entity.has_dependencies import HasDependencies
+from gemd.entity.link_by_uid import LinkByUID
from gemd.entity.object.has_template_check_generator import HasTemplateCheckGenerator
from gemd.entity.template.has_property_templates import HasPropertyTemplates
from gemd.entity.attribute.property import Property
@@ -8,16 +10,11 @@
from typing import Union, Iterable, List, Set
from abc import ABC
+__all__ = ["HasProperties"]
-class HasProperties(HasTemplateCheckGenerator, HasDependencies, ABC):
- """Mixin-trait for entities that include properties.
-
- Parameters
- ----------
- properties: List[:class:`Property `]
- A list of properties associated with this entity
- """
+class HasProperties(HasTemplateCheckGenerator, HasDependencies, ABC):
+ """Mixin-trait for entities that include properties."""
def __init__(self, properties: Union[Property, Iterable[Property]]):
self._properties = None
@@ -25,7 +22,7 @@ def __init__(self, properties: Union[Property, Iterable[Property]]):
@property
def properties(self) -> List[Property]:
- """Get a list of the properties."""
+ """A list of properties associated with this entity."""
return self._properties
@properties.setter
@@ -34,6 +31,6 @@ def properties(self, properties: Union[Property, Iterable[Property]]):
checker = self._generate_template_check(HasPropertyTemplates.validate_property)
self._properties = validate_list(properties, Property, trigger=checker)
- def _local_dependencies(self) -> Set[Union["BaseEntity", "LinkByUID"]]: # noqa: F821
+ def _local_dependencies(self) -> Set[Union[BaseEntity, LinkByUID]]:
"""Return a set of all immediate dependencies (no recursion)."""
return {prop.template for prop in self.properties if prop.template is not None}
diff --git a/gemd/entity/object/has_quantities.py b/gemd/entity/object/has_quantities.py
index bc7ea8ff..5c366eb3 100644
--- a/gemd/entity/object/has_quantities.py
+++ b/gemd/entity/object/has_quantities.py
@@ -7,26 +7,11 @@
from gemd.entity.bounds_validation import get_validation_level, WarningLevel
from gemd.entity.dict_serializable import logger
+__all__ = ["HasQuantities"]
+
class HasQuantities(object):
- """Mixin-trait that includes the mass, volume, number fraction, and absolute quantity.
-
- Parameters
- ----------
- mass_fraction: :class:`ContinuousValue \
- `, optional
- The mass fraction of the quantity.
- volume_fraction: :class:`ContinuousValue \
- `, optional
- The volume fraction of the quantity.
- number_fraction: :class:`ContinuousValue \
- `, optional
- The number fraction of the quantity.
- absolute_quantity: :class:`ContinuousValue \
- `, optional
- The absolute quantity of the quantity.
-
- """
+ """Mixin-trait that includes the mass, volume, number fraction, and absolute quantity."""
def __init__(self, *,
mass_fraction: ContinuousValue = None,
@@ -60,7 +45,7 @@ def _check(value: BaseValue):
@property
def mass_fraction(self) -> ContinuousValue:
- """Get mass fraction."""
+ """The mass fraction of the material."""
return self._mass_fraction
@mass_fraction.setter
@@ -75,7 +60,7 @@ def mass_fraction(self, mass_fraction: ContinuousValue):
@property
def volume_fraction(self) -> ContinuousValue:
- """Get volume fraction."""
+ """The volume fraction of the material."""
return self._volume_fraction
@volume_fraction.setter
@@ -90,7 +75,7 @@ def volume_fraction(self, volume_fraction: ContinuousValue):
@property
def number_fraction(self) -> ContinuousValue:
- """Get number fraction."""
+ """The number fraction (commonly called mole fraction) of the material."""
return self._number_fraction
@number_fraction.setter
@@ -105,7 +90,7 @@ def number_fraction(self, number_fraction: ContinuousValue):
@property
def absolute_quantity(self) -> ContinuousValue:
- """Get absolute quantity."""
+ """The absolute quantity of the material."""
return self._absolute_quantity
@absolute_quantity.setter
diff --git a/gemd/entity/object/has_source.py b/gemd/entity/object/has_source.py
index a4b04bb1..f14dcc5c 100644
--- a/gemd/entity/object/has_source.py
+++ b/gemd/entity/object/has_source.py
@@ -1,17 +1,11 @@
"""For entities that have parameters."""
from gemd.entity.source.performed_source import PerformedSource
+__all__ = ["HasSource"]
-class HasSource(object):
- """Mixin-trait for entities that include sources (data provenance).
-
- Parameters
- ----------
- source: :class:`PerformedSource\
- `, optional
- Information about the person who performed the run and when.
- """
+class HasSource(object):
+ """Mixin-trait for entities that include sources (data provenance)."""
def __init__(self, source: PerformedSource):
self._source = None
@@ -19,7 +13,7 @@ def __init__(self, source: PerformedSource):
@property
def source(self) -> PerformedSource:
- """Get the list of parameters."""
+ """Information about the person who performed the run and when."""
return self._source
@source.setter
diff --git a/gemd/entity/object/has_spec.py b/gemd/entity/object/has_spec.py
index d91ca213..7772cde3 100644
--- a/gemd/entity/object/has_spec.py
+++ b/gemd/entity/object/has_spec.py
@@ -1,22 +1,18 @@
"""For entities that have specs."""
+from gemd.entity.base_entity import BaseEntity
from gemd.entity.has_dependencies import HasDependencies
+from gemd.entity.link_by_uid import LinkByUID
from gemd.entity.object.has_template import HasTemplate
from gemd.entity.template.base_template import BaseTemplate
-from gemd.entity.link_by_uid import LinkByUID
from abc import abstractmethod
from typing import Optional, Union, Set, Type
+__all__ = ["HasSpec"]
-class HasSpec(HasDependencies):
- """Mix-in trait for objects that can be assigned specs.
- Parameters
- ----------
- spec: :class:`Has_Template `
- A spec, which expresses the anticipated or aspirational behavior of this object.
-
- """
+class HasSpec(HasDependencies):
+ """Mix-in trait for objects that can be assigned specs."""
def __init__(self, spec: Union[HasTemplate, LinkByUID] = None):
self._spec = None
@@ -24,7 +20,7 @@ def __init__(self, spec: Union[HasTemplate, LinkByUID] = None):
@property
def spec(self) -> Union[HasTemplate, LinkByUID]:
- """Get the spec."""
+ """A spec, which expresses the anticipated or aspirational behavior of this object."""
return self._spec
@spec.setter
@@ -51,6 +47,6 @@ def template(self) -> Optional[Union[BaseTemplate, LinkByUID]]:
else:
return None
- def _local_dependencies(self) -> Set[Union["BaseEntity", "LinkByUID"]]: # noqa: F821
+ def _local_dependencies(self) -> Set[Union[BaseEntity, LinkByUID]]:
"""Return a set of all immediate dependencies (no recursion)."""
return {self.spec} if self.spec is not None else set()
diff --git a/gemd/entity/object/has_template.py b/gemd/entity/object/has_template.py
index c968f9fa..c38662e1 100644
--- a/gemd/entity/object/has_template.py
+++ b/gemd/entity/object/has_template.py
@@ -1,21 +1,17 @@
"""For entities that have templates."""
+from gemd.entity.base_entity import BaseEntity
from gemd.entity.has_dependencies import HasDependencies
-from gemd.entity.template.base_template import BaseTemplate
from gemd.entity.link_by_uid import LinkByUID
+from gemd.entity.template.base_template import BaseTemplate
from abc import abstractmethod
from typing import Optional, Union, Set, Type
+__all__ = ["HasTemplate"]
-class HasTemplate(HasDependencies):
- """Mix-in trait for objects that can be assigned templates.
- Parameters
- ----------
- template: :class:`BaseTemplate `
- A template that defines the allowed values.
-
- """
+class HasTemplate(HasDependencies):
+ """Mix-in trait for objects that can be assigned templates."""
def __init__(self, template: Optional[Union[BaseTemplate, LinkByUID]] = None):
self._template = None
@@ -28,7 +24,7 @@ def _template_type() -> Type:
@property
def template(self) -> Optional[Union[BaseTemplate, LinkByUID]]:
- """Get the template."""
+ """A template that defines the allowed values."""
return self._template
@template.setter
@@ -42,6 +38,6 @@ def template(self, template: Optional[Union[BaseTemplate, LinkByUID]]):
raise TypeError(f"Template must be a {self._template_type()} or LinkByUID, "
f"not {type(template)}")
- def _local_dependencies(self) -> Set[Union["BaseEntity", "LinkByUID"]]: # noqa: F821
+ def _local_dependencies(self) -> Set[Union[BaseEntity, LinkByUID]]:
"""Return a set of all immediate dependencies (no recursion)."""
return {self.template} if self.template is not None else set()
diff --git a/gemd/entity/object/has_template_check_generator.py b/gemd/entity/object/has_template_check_generator.py
index 6fa49dee..23b936ba 100644
--- a/gemd/entity/object/has_template_check_generator.py
+++ b/gemd/entity/object/has_template_check_generator.py
@@ -8,6 +8,8 @@
from inspect import getmodule, getmembers, isclass, signature
from typing import Union, Callable, TypeVar
+__all__ = ["HasTemplateCheckGenerator"]
+
T = TypeVar('T')
@@ -30,9 +32,9 @@ def _generate_template_check(self,
with `self` (provided that object template is defined, attribute templates are defined,
etc.).
The returned function is intended to work as a `trigger` for a
- :py:class `~gemd.entity.valid_list.ValidList`.
+ :class:`~gemd.entity.valid_list.ValidList`.
The behavior following this check -- ignore, warn or raise exception -- is controlled
- by the :py:class `~gemd.entity.bounds_validation.WarningLevel` as returned by the
+ by the :class:`~gemd.entity.bounds_validation.WarningLevel` as returned by the
:py:func `~gemd.entity.bounds_validation.get_validation_level`.
Parameters
diff --git a/gemd/entity/object/ingredient_run.py b/gemd/entity/object/ingredient_run.py
index ad53ffc9..4be4a690 100644
--- a/gemd/entity/object/ingredient_run.py
+++ b/gemd/entity/object/ingredient_run.py
@@ -14,6 +14,8 @@
from typing import Optional, Union, Iterable, List, Mapping, Type, Any
+__all__ = ["IngredientRun"]
+
class IngredientRun(BaseObject,
HasQuantities, HasSpec, HasMaterial, HasProcess,
@@ -35,25 +37,21 @@ class IngredientRun(BaseObject,
for filtering and discoverability.
notes: str, optional
Long-form notes about the ingredient run.
- material: :class:`MaterialRun `
+ material: ~gemd.entity.object.material_run.MaterialRun
Material that this ingredient is.
- process: :class:`ProcessRun `
+ process: ~gemd.entity.object.process_run.ProcessRun
Process that this ingredient is used in.
- mass_fraction: :py:class:`ContinuousValue \
- `, optional
+ mass_fraction: ~gemd.entity.value.continuous_value.ContinuousValue, optional
The mass fraction of the ingredient in the process.
- volume_fraction: :py:class:`ContinuousValue \
- `, optional
+ volume_fraction: ~gemd.entity.value.continuous_value.ContinuousValue, optional
The volume fraction of the ingredient in the process.
- number_fraction: :py:class:`ContinuousValue \
- `, optional
+ number_fraction: ~gemd.entity.value.continuous_value.ContinuousValue, optional
The number fraction of the ingredient in the process.
- absolute_quantity: :py:class:`ContinuousValue \
- `, optional
+ absolute_quantity: ~gemd.entity.value.continuous_value.ContinuousValue, optional
The absolute quantity of the ingredient in the process.
- spec: IngredientSpec
+ spec: ~gemd.entity.object.ingredient_spec.IngredientSpec
The specification of which this ingredient is a realization.
- file_links: List[:class:`FileLink `], optional
+ file_links: List[~gemd.entity.file_link.FileLink], optional
Links to associated files, with resource paths into the files API.
"""
diff --git a/gemd/entity/object/ingredient_spec.py b/gemd/entity/object/ingredient_spec.py
index 614b6370..7a2f8d41 100644
--- a/gemd/entity/object/ingredient_spec.py
+++ b/gemd/entity/object/ingredient_spec.py
@@ -12,6 +12,8 @@
from typing import Optional, Union, Iterable, List, Mapping, Type
+__all__ = ["IngredientSpec"]
+
class IngredientSpec(BaseObject,
HasQuantities, HasTemplate, HasMaterial, HasProcess,
@@ -35,25 +37,21 @@ class IngredientSpec(BaseObject,
for filtering and discoverability.
notes: str, optional
Long-form notes about the ingredient spec.
- material: :class:`MaterialSpec `
+ material: ~gemd.entity.object.material_spec.MaterialSpec
Material that this ingredient is.
- process: :class:`ProcessSpec `
+ process: ~gemd.entity.object.process_spec.ProcessSpec
Process that this ingredient is used in.
- mass_fraction: :py:class:`ContinuousValue \
- `, optional
+ mass_fraction: ~gemd.entity.value.continuous_value.ContinuousValue, optional
The mass fraction of the ingredient in the process.
- volume_fraction: :class:`ContinuousValue \
- `, optional
+ volume_fraction: ~gemd.entity.value.continuous_value.ContinuousValue, optional
The volume fraction of the ingredient in the process.
- number_fraction: :class:`ContinuousValue \
- `, optional
+ number_fraction: ~gemd.entity.value.continuous_value.ContinuousValue, optional
The number fraction of the ingredient in the process.
- absolute_quantity: :class:`ContinuousValue \
- `, optional
+ absolute_quantity: ~gemd.entity.value.continuous_value.ContinuousValue, optional
The absolute quantity of the ingredient in the process.
labels: List[str], optional
Additional labels on the ingredient that must be unique.
- file_links: List[:class:`FileLink `], optional
+ file_links: List[~gemd.entity.file_link.FileLink], optional
Links to associated files, with resource paths into the files API.
"""
diff --git a/gemd/entity/object/material_run.py b/gemd/entity/object/material_run.py
index 5d4a5348..a99fd703 100644
--- a/gemd/entity/object/material_run.py
+++ b/gemd/entity/object/material_run.py
@@ -8,7 +8,10 @@
from gemd.entity.link_by_uid import LinkByUID
from gemd.entity.setters import validate_list
-from typing import Optional, Union, Iterable, List, Mapping, Type, Any
+from typing import TypeVar, Optional, Union, Iterable, List, Mapping, Type, Any
+
+__all__ = ["MaterialRun"]
+MeasurementRunType = TypeVar("MeasurementRunType", bound="MeasurementRun") # noqa: F821
class MaterialRun(BaseObject, HasSpec, HasProcess, typ="material_run", skip={"_measurements"}):
@@ -31,23 +34,16 @@ class MaterialRun(BaseObject, HasSpec, HasProcess, typ="material_run", skip={"_m
for filtering and discoverability.
notes: str, optional
Long-form notes about the material run.
- process: :class:`ProcessRun `
+ process: ~gemd.entity.object.process_run.ProcessRun
Process that produces this material.
sample_type: str, optional
The form of this sample. Optionals are "experimental", "virtual", "production", or
"unknown." Default is "unknown."
- spec: :class:`MaterialSpec `
+ spec: :class:`~gemd.entity.object.material_spec.MaterialSpec`
The material specification of which this is an instance.
- file_links: List[:class:`FileLink `], optional
+ file_links: List[~gemd.entity.file_link.FileLink], optional
Links to associated files, with resource paths into the files API.
- Attributes
- ----------
- measurements: List[:class:`MeasurementRun\
- `], optional
- Measurements performed on this material. The link is established by creating the
- measurement run and settings its `material` field to this material run.
-
"""
def __init__(self,
@@ -91,8 +87,13 @@ def process(self, process: Union[ProcessRun, LinkByUID]):
raise TypeError("process must be a ProcessRun or LinkByUID: {}".format(process))
@property
- def measurements(self) -> List["MeasurementRun"]: # noqa: F821
- """Get a read-only list of the measurement runs."""
+ def measurements(self) -> List[MeasurementRunType]:
+ """Measurements performed on this material.
+
+ The link is established by creating the measurement run and settings its
+ `material` field to this material run.
+
+ """
return self._measurements
@property
diff --git a/gemd/entity/object/material_spec.py b/gemd/entity/object/material_spec.py
index c676a7a0..3410028e 100644
--- a/gemd/entity/object/material_spec.py
+++ b/gemd/entity/object/material_spec.py
@@ -13,6 +13,8 @@
from typing import Optional, Union, Iterable, List, Set, Mapping, Type
+__all__ = ["MaterialSpec"]
+
class MaterialSpec(BaseObject, HasTemplate, HasProcess, HasProperties, typ="material_spec"):
"""
@@ -34,16 +36,15 @@ class MaterialSpec(BaseObject, HasTemplate, HasProcess, HasProperties, typ="mate
for filtering and discoverability.
notes: str, optional
Long-form notes about the material spec.
- process: :class:`ProcessSpec `
+ process: ~gemd.entity.object.process_spec.ProcessSpec
Process that produces this material.
- properties: List[:class:`PropertyAndConditions\
- `], optional
+ properties: List[~gemd.entity.attribute.property_and_conditions.PropertyAndConditions], \
+ optional
Properties of the material, along with an optional list of conditions under which
those properties are measured.
- template: :class:`MaterialTemplate\
- `, optional
+ template: ~gemd.entity.template.material_template.MaterialTemplate, optional
A template bounding the valid values for this material's properties.
- file_links: List[:class:`FileLink `], optional
+ file_links: List[~gemd.entity.file_link.FileLink], optional
Links to associated files, with resource paths into the files API.
"""
diff --git a/gemd/entity/object/measurement_run.py b/gemd/entity/object/measurement_run.py
index cb10ee8a..60e42302 100644
--- a/gemd/entity/object/measurement_run.py
+++ b/gemd/entity/object/measurement_run.py
@@ -16,6 +16,8 @@
from typing import Optional, Union, Iterable, Mapping, Type
+__all__ = ["MeasurementRun"]
+
class MeasurementRun(BaseObject, HasMaterial, HasSpec, HasConditions, HasProperties,
HasParameters, HasSource, typ="measurement_run"):
@@ -39,22 +41,21 @@ class MeasurementRun(BaseObject, HasMaterial, HasSpec, HasConditions, HasPropert
for filtering and discoverability.
notes: str, optional
Long-form notes about the measurement run.
- conditions: List[:class:`Condition `], optional
+ conditions: List[~gemd.entity.attribute.condition.Condition], optional
Conditions under which this measurement run occurs.
- parameters: List[:class:`Parameter `], optional
+ parameters: List[~gemd.entity.attribute.parameter.Parameter], optional
Parameters of this measurement run.
- properties: List[:class:`Property `], optional
+ properties: List[~gemd.entity.attribute.property.Property], optional
Properties that are measured during this measurement run.
- spec: :class:`MeasurementSpec `
+ spec: ~gemd.entity.object.measurement_spec.MeasurementSpec`
The measurement specification of which this is an instance.
- material: :class:`MaterialRun `
+ material: ~gemd.entity.object.material_run.MaterialRun`
The material run being measured.
- spec: :class:`MaterialSpec `
+ spec: ~gemd.entity.object.material_spec.MaterialSpec`
The material specification of which this is an instance.
- file_links: List[:class:`FileLink `], optional
+ file_links: List[~gemd.entity.file_link.FileLink], optional
Links to associated files, with resource paths into the files API.
- source: :class:`PerformedSource\
- `, optional
+ source: ~gemd.entity.source.performed_source.PerformedSource, optional
Information about the person who performed the run and when.
"""
diff --git a/gemd/entity/object/measurement_spec.py b/gemd/entity/object/measurement_spec.py
index d8637e22..6997002d 100644
--- a/gemd/entity/object/measurement_spec.py
+++ b/gemd/entity/object/measurement_spec.py
@@ -10,6 +10,8 @@
from typing import Optional, Union, Iterable, Mapping, Type
+__all__ = ["MeasurementSpec"]
+
class MeasurementSpec(BaseObject,
HasTemplate, HasParameters, HasConditions,
@@ -34,15 +36,14 @@ class MeasurementSpec(BaseObject,
for filtering and discoverability.
notes: str, optional
Long-form notes about the measurement spec.
- conditions: List[:class:`Condition `], optional
+ conditions: List[~gemd.entity.attribute.condition.Condition], optional
Conditions under which this measurement spec occurs.
- parameters: List[:class:`Parameter `], optional
+ parameters: List[~gemd.entity.attribute.parameter.Parameter], optional
Parameters of this measurement spec.
- template: :class:`MeasurementTemplate\
- `
+ template: ~gemd.entity.object.measurement_template.MeasurementTemplate
A template bounding the valid values for the measurement's properties, parameters,
and conditions.
- file_links: List[:class:`FileLink `], optional
+ file_links: List[~gemd.entity.file_link.FileLink], optional
Links to associated files, with resource paths into the files API.
"""
diff --git a/gemd/entity/object/process_run.py b/gemd/entity/object/process_run.py
index eb72cfca..f1c73289 100644
--- a/gemd/entity/object/process_run.py
+++ b/gemd/entity/object/process_run.py
@@ -11,7 +11,11 @@
from gemd.entity.link_by_uid import LinkByUID
from gemd.entity.setters import validate_list
-from typing import Optional, Union, Iterable, List, Mapping, Dict, Type, Any
+from typing import TypeVar, Optional, Union, Iterable, List, Mapping, Dict, Type, Any
+
+__all__ = ["ProcessRun"]
+MaterialRunType = TypeVar("MaterialRunType", bound="MaterialRun") # noqa: F821
+IngredientRunType = TypeVar("IngredientRunType", bound="IngredientRun") # noqa: F821
class ProcessRun(BaseObject,
@@ -38,28 +42,17 @@ class ProcessRun(BaseObject,
for filtering and discoverability.
notes: str, optional
Long-form notes about the process run.
- conditions: List[:class:`Condition `], optional
+ conditions: List[~gemd.entity.attribute.condition.Condition], optional
Conditions under which this process run occurs.
- parameters: List[:class:`Parameter `], optional
+ parameters: List[~gemd.entity.attribute.parameter.Parameter], optional
Parameters of this process run.
- spec: :class:`ProcessSpec `
+ spec: ~gemd.entity.object.process_spec.ProcessSpec
Spec for this process run.
- file_links: List[:class:`FileLink `], optional
+ file_links: List[~gemd.entity.file_link.FileLink], optional
Links to associated files, with resource paths into the files API.
- source: :class:`PerformedSource\
- `, optional
+ source: ~gemd.entity.source.performed_source.PerformedSource, optional
Information about the person who performed the run and when.
- Attributes
- ----------
- output_material: :class:`MaterialRun `
- The material run that this process run produces. The link is established by creating
- the material run and settings its `process` field to this process run.
-
- ingredients: List[:class:`IngredientRun `]
- Ingredient runs that act as inputs to this process run. The link is established by
- creating each ingredient run and setting its `process` field to this process run.
-
"""
def __init__(self,
@@ -86,13 +79,23 @@ def __init__(self,
self._output_material = None
@property
- def output_material(self) -> Optional["MaterialRun"]: # noqa: F821
- """Get the output material run."""
+ def output_material(self) -> Optional[MaterialRunType]:
+ """The material run that this process run produces.
+
+ The link is established by creating the material run and settings its
+ `process` field to this process run.
+
+ """
return self._output_material
@property
- def ingredients(self) -> List["IngredientRun"]: # noqa: F821
- """Get the input ingredient runs."""
+ def ingredients(self) -> List[IngredientRunType]:
+ """Ingredient runs that act as inputs to this process run.
+
+ The link is established by creating each ingredient run and setting its
+ `process` field to this process run.
+
+ """
return self._ingredients
@staticmethod
diff --git a/gemd/entity/object/process_spec.py b/gemd/entity/object/process_spec.py
index ac5039ac..40bcb185 100644
--- a/gemd/entity/object/process_spec.py
+++ b/gemd/entity/object/process_spec.py
@@ -9,7 +9,11 @@
from gemd.entity.link_by_uid import LinkByUID
from gemd.entity.setters import validate_list
-from typing import Optional, Union, Iterable, List, Mapping, Dict, Type, Any
+from typing import TypeVar, Optional, Union, Iterable, List, Mapping, Dict, Type, Any
+
+__all__ = ["ProcessSpec"]
+IngredientSpecType = TypeVar("IngredientSpecType", bound="IngredientSpec") # noqa: F821
+MaterialSpecType = TypeVar("MaterialSpecType", bound="MaterialSpec") # noqa: F821
class ProcessSpec(BaseObject,
@@ -36,27 +40,15 @@ class ProcessSpec(BaseObject,
for filtering and discoverability.
notes: str, optional
Long-form notes about the process spec.
- conditions: List[:class:`Condition `], optional
+ conditions: List[~gemd.entity.attribute.condition.Condition], optional
Conditions under which this process spec occurs.
- parameters: List[:class:`Parameter `], optional
+ parameters: List[~gemd.entity.attribute.parameter.Parameter], optional
Parameters of this process spec.
- template: :class:`ProcessTemplate\
- `, optional
+ template: ~gemd.entity.template.process_template.ProcessTemplate, optional
A template bounding the valid values for this process's parameters and conditions.
- file_links: List[:class:`FileLink `], optional
+ file_links: List[~gemd.entity.file_link.FileLink], optional
Links to associated files, with resource paths into the files API.
- Attributes
- ----------
- output_material: :class:`MaterialSpec `
- The material spec that this process spec produces. The link is established by creating
- the material spec and settings its `process` field to this process spec.
-
- ingredients: List[:class:`IngredientSpec\
- `], optional
- Ingredient specs that act as inputs to this process spec. The link is established by
- creating each ingredient spec and setting its `process` field to this process spec.
-
"""
def __init__(self,
@@ -90,13 +82,23 @@ def _template_type() -> Type:
return ProcessTemplate
@property
- def ingredients(self) -> List["IngredientSpec"]: # noqa: F821
- """Get the list of input ingredient specs."""
+ def ingredients(self) -> List[IngredientSpecType]:
+ """Ingredient specs that act as inputs to this process spec.
+
+ The link is established by creating each ingredient spec and setting its
+ `process` field to this process spec.
+
+ """
return self._ingredients
@property
- def output_material(self) -> Optional["MaterialSpec"]: # noqa: F821
- """Get the output material spec."""
+ def output_material(self) -> Optional[MaterialSpecType]:
+ """The material spec that this process spec produces.
+
+ The link is established by creating the material spec and settings its
+ `process` field to this process spec.
+
+ """
return self._output_material
def _dict_for_compare(self) -> Dict[str, Any]:
diff --git a/gemd/entity/setters.py b/gemd/entity/setters.py
index dbbff2b3..6a86e64d 100644
--- a/gemd/entity/setters.py
+++ b/gemd/entity/setters.py
@@ -3,6 +3,8 @@
from typing import Union, Iterable, Optional, Callable, Type, TypeVar
+__all__ = ["validate_list", "validate_str"]
+
T = TypeVar('T')
diff --git a/gemd/entity/source/performed_source.py b/gemd/entity/source/performed_source.py
index a2834f2d..3a9823e8 100644
--- a/gemd/entity/source/performed_source.py
+++ b/gemd/entity/source/performed_source.py
@@ -1,5 +1,7 @@
from gemd.entity.dict_serializable import DictSerializable
+__all__ = ["PerformedSource"]
+
class PerformedSource(DictSerializable, typ="performed_source"):
"""
diff --git a/gemd/entity/template/attribute_template.py b/gemd/entity/template/attribute_template.py
index 6af0f5ae..c74ccd43 100644
--- a/gemd/entity/template/attribute_template.py
+++ b/gemd/entity/template/attribute_template.py
@@ -2,6 +2,8 @@
from gemd.entity.base_entity import BaseEntity
from gemd.entity.bounds.base_bounds import BaseBounds
+__all__ = ["AttributeTemplate"]
+
class AttributeTemplate(BaseEntity):
"""
@@ -11,7 +13,7 @@ class AttributeTemplate(BaseEntity):
----------
name: str, required
The name of the attribute template.
- bounds: :py:class:`BaseBounds `
+ bounds: ~gemd.entity.bounds.base_bounds.BaseBounds
Bounds circumscribe the values that are valid according to this attribute template.
description: str, optional
A long-form description of the attribute template.
@@ -39,15 +41,16 @@ def __init__(self, name, *, description=None, bounds=None, uids=None, tags=None)
@property
def bounds(self):
- """Get the bounds."""
+ """Bounds circumscribe the values that are valid according to this attribute template."""
return self._bounds
@bounds.setter
def bounds(self, bounds):
+ """Set the bounds."""
if bounds is None:
- raise ValueError("Bounds are required on AttributeTemplate")
+ raise ValueError(f"Bounds are required on {type(self).__name__}s")
if not isinstance(bounds, BaseBounds):
- raise TypeError("Bounds must be an instance of BaseBounds: {}".format(bounds))
+ raise TypeError(f"Bounds must be an instance of BaseBounds: {bounds}")
self._bounds = bounds
def all_dependencies(self):
diff --git a/gemd/entity/template/base_template.py b/gemd/entity/template/base_template.py
index 9161ac71..7620e43e 100644
--- a/gemd/entity/template/base_template.py
+++ b/gemd/entity/template/base_template.py
@@ -6,6 +6,8 @@
from typing import Union, Iterable, Mapping
+__all__ = ["BaseTemplate"]
+
class BaseTemplate(BaseEntity):
"""
diff --git a/gemd/entity/template/condition_template.py b/gemd/entity/template/condition_template.py
index 7a03963c..0a6cfac8 100644
--- a/gemd/entity/template/condition_template.py
+++ b/gemd/entity/template/condition_template.py
@@ -1,5 +1,7 @@
from gemd.entity.template.attribute_template import AttributeTemplate
+__all__ = ["ConditionTemplate"]
+
class ConditionTemplate(AttributeTemplate, typ="condition_template"):
"""A template for a condition attribute.
@@ -8,7 +10,7 @@ class ConditionTemplate(AttributeTemplate, typ="condition_template"):
----------
name: str, required
The name of the condition template.
- bounds: :py:class:`BaseBounds `
+ bounds: ~gemd.entity.bounds.base_bounds.BaseBounds
Bounds circumscribe the values that are valid according to this condition template.
description: str, optional
A long-form description of the attribute template.
diff --git a/gemd/entity/template/has_condition_templates.py b/gemd/entity/template/has_condition_templates.py
index 927b6795..6714b10e 100644
--- a/gemd/entity/template/has_condition_templates.py
+++ b/gemd/entity/template/has_condition_templates.py
@@ -6,7 +6,11 @@
from gemd.entity.template.condition_template import ConditionTemplate
from gemd.entity.bounds.base_bounds import BaseBounds
-from typing import Optional, Union, Iterable, List, Tuple, Set
+from typing import TypeVar, Optional, Union, Iterable, List, Tuple, Set
+
+__all__ = ["HasConditionTemplates"]
+BaseEntityType = TypeVar("BaseEntityType", bound="BaseEntity") # noqa: F821
+ConditionType = TypeVar("ConditionType", bound="Condition") # noqa: F821
class HasConditionTemplates(HasDependencies):
@@ -15,7 +19,7 @@ class HasConditionTemplates(HasDependencies):
Parameters
----------
- conditions: List[(ConditionTemplate, BaseBounds)]
+ conditions: List[(~gemd.entity.template.condition_template.ConditionTemplate, BaseBounds)]
A list of tuples containing this entity's condition templates as well
as any restrictions on those templates' bounds.
@@ -34,7 +38,7 @@ def conditions(self) -> List[Union[ConditionTemplate, LinkByUID]]:
Returns
-------
- List[(ConditionTemplate, bounds)]
+ List[(~gemd.entity.template.condition_template.ConditionTemplate, BaseBounds)]
List of this entity's condition template/bounds pairs
"""
@@ -49,13 +53,13 @@ def conditions(self, conditions: Iterable[Union[Union[ConditionTemplate, LinkByU
Parameters
----------
- conditions: List[(ConditionTemplate, bounds)]
+ conditions: List[(~gemd.entity.template.condition_template.ConditionTemplate, BaseBounds)]
A list of tuples containing this entity's condition templates as well
as any restrictions on those templates' bounds.
Returns
-------
- List[(ConditionTemplate, bounds)]
+ List[(~gemd.entity.template.condition_template.ConditionTemplate, BaseBounds)]
List of this entity's condition template/bounds pairs
"""
@@ -67,7 +71,7 @@ def conditions(self, conditions: Iterable[Union[Union[ConditionTemplate, LinkByU
trigger=BaseTemplate._homogenize_ranges
)
- def validate_condition(self, condition: "Condition") -> bool: # noqa: F821
+ def validate_condition(self, condition: ConditionType) -> bool:
"""Check if the condition is consistent w/ this template."""
if condition.template is not None:
attr, bnd = next((x for x in self.conditions if condition.template == x[0]),
@@ -83,6 +87,6 @@ def validate_condition(self, condition: "Condition") -> bool: # noqa: F821
else:
return True # Nothing to check against
- def _local_dependencies(self) -> Set[Union["BaseEntity", "LinkByUID"]]: # noqa: F821
+ def _local_dependencies(self) -> Set[Union[BaseEntityType, LinkByUID]]:
"""Return a set of all immediate dependencies (no recursion)."""
return {attr[0] for attr in self.conditions}
diff --git a/gemd/entity/template/has_parameter_templates.py b/gemd/entity/template/has_parameter_templates.py
index 29288b41..423c3eba 100644
--- a/gemd/entity/template/has_parameter_templates.py
+++ b/gemd/entity/template/has_parameter_templates.py
@@ -6,7 +6,11 @@
from gemd.entity.template.parameter_template import ParameterTemplate
from gemd.entity.bounds.base_bounds import BaseBounds
-from typing import Optional, Union, Iterable, List, Tuple, Set
+from typing import TypeVar, Optional, Union, Iterable, List, Tuple, Set
+
+__all__ = ["HasParameterTemplates"]
+ParameterType = TypeVar("ParameterType", bound="Parameter") # noqa: F821
+BaseEntityType = TypeVar("BaseEntityType", bound="BaseEntity") # noqa: F821
class HasParameterTemplates(HasDependencies):
@@ -15,7 +19,7 @@ class HasParameterTemplates(HasDependencies):
Parameters
----------
- parameters: List[(ParameterTemplate, BaseBounds)]
+ parameters: List[(~gemd.entity.template.parameter_template.ParameterTemplate, BaseBounds)]
A list of tuples containing this entity's parameter templates as well
as any restrictions on those templates' bounds.
@@ -34,7 +38,7 @@ def parameters(self) -> List[Union[ParameterTemplate, LinkByUID]]:
Returns
-------
- List[(ParameterTemplate, bounds)]
+ List[(~gemd.entity.template.parameter_template.ParameterTemplate, BaseBounds)]
List of this entity's parameter template/bounds pairs
"""
@@ -49,13 +53,13 @@ def parameters(self, parameters: Iterable[Union[Union[ParameterTemplate, LinkByU
Parameters
----------
- parameters: List[(ParameterTemplate, bounds)]
+ parameters: List[(~gemd.entity.template.parameter_template.ParameterTemplate, BaseBounds)]
A list of tuples containing this entity's parameter templates as well
as any restrictions on those templates' bounds.
Returns
-------
- List[(ParameterTemplate, bounds)]
+ List[(~gemd.entity.template.parameter_template.ParameterTemplate, BaseBounds)]
List of this entity's parameter template/bounds pairs
"""
@@ -67,7 +71,7 @@ def parameters(self, parameters: Iterable[Union[Union[ParameterTemplate, LinkByU
trigger=BaseTemplate._homogenize_ranges
)
- def validate_parameter(self, parameter: "Parameter") -> bool: # noqa: F821
+ def validate_parameter(self, parameter: ParameterType) -> bool:
"""Check if the parameter is consistent w/ this template."""
if parameter.template is not None:
attr, bnd = next((x for x in self.parameters if parameter.template == x[0]),
@@ -83,6 +87,6 @@ def validate_parameter(self, parameter: "Parameter") -> bool: # noqa: F821
else:
return True # Nothing to check against
- def _local_dependencies(self) -> Set[Union["BaseEntity", "LinkByUID"]]: # noqa: F821
+ def _local_dependencies(self) -> Set[Union[BaseEntityType, LinkByUID]]:
"""Return a set of all immediate dependencies (no recursion)."""
return {attr[0] for attr in self.parameters}
diff --git a/gemd/entity/template/has_property_templates.py b/gemd/entity/template/has_property_templates.py
index 5cb6810e..0495fd2a 100644
--- a/gemd/entity/template/has_property_templates.py
+++ b/gemd/entity/template/has_property_templates.py
@@ -6,7 +6,13 @@
from gemd.entity.template.property_template import PropertyTemplate
from gemd.entity.bounds.base_bounds import BaseBounds
-from typing import Optional, Union, Iterable, List, Set, Tuple
+from typing import TypeVar, Optional, Union, Iterable, List, Set, Tuple
+
+__all__ = ["HasPropertyTemplates"]
+BaseEntityType = TypeVar("BaseEntityType", bound="BaseEntity") # noqa: F821
+PropertyType = TypeVar("PropertyType", bound="Property") # noqa: F821
+PropertyAndConditionsType = TypeVar("PropertyAndConditionsType",
+ bound="PropertyAndConditions") # noqa: F821
class HasPropertyTemplates(HasDependencies):
@@ -15,7 +21,7 @@ class HasPropertyTemplates(HasDependencies):
Parameters
----------
- properties: List[(PropertyTemplate, BaseBounds)]
+ properties: List[(~gemd.entity.template.property_template.PropertyTemplate, BaseBounds)]
A list of tuples containing this entity's property templates as well
as any restrictions on those templates' bounds.
@@ -35,7 +41,7 @@ def properties(self) -> List[Tuple[Union[PropertyTemplate, LinkByUID],
Returns
-------
- List[(PropertyTemplate, bounds)]
+ List[(~gemd.entity.template.property_template.PropertyTemplate, BaseBounds)]
List of this entity's property template/bounds pairs
"""
@@ -46,11 +52,11 @@ def properties(self, properties: Iterable[Union[Union[PropertyTemplate, LinkByUI
Tuple[Union[PropertyTemplate, LinkByUID],
Optional[BaseBounds]]]]):
"""
- Set the list of parameter templates.
+ Set the list of property templates.
Parameters
----------
- properties: List[(PropertyTemplate, bounds)]
+ properties: List[(~gemd.entity.template.property_template.PropertyTemplate, BaseBounds)]
A list of tuples containing this entity's property templates as well
as any restrictions on those templates' bounds.
@@ -63,9 +69,7 @@ def properties(self, properties: Iterable[Union[Union[PropertyTemplate, LinkByUI
trigger=BaseTemplate._homogenize_ranges
)
- def validate_property(self,
- prop: Union["Property", "PropertyAndConditions"] # noqa: F821
- ) -> bool: # noqa: F821
+ def validate_property(self, prop: Union[PropertyType, PropertyAndConditionsType]) -> bool:
"""Check if the property is consistent w/ this template."""
from gemd.entity.attribute import PropertyAndConditions
if isinstance(prop, PropertyAndConditions):
@@ -85,6 +89,6 @@ def validate_property(self,
else:
return True # Nothing to check against
- def _local_dependencies(self) -> Set[Union["BaseEntity", "LinkByUID"]]: # noqa: F821
+ def _local_dependencies(self) -> Set[Union[BaseEntityType, LinkByUID]]:
"""Return a set of all immediate dependencies (no recursion)."""
return {attr[0] for attr in self.properties}
diff --git a/gemd/entity/template/material_template.py b/gemd/entity/template/material_template.py
index b2ceb078..bf5e140a 100644
--- a/gemd/entity/template/material_template.py
+++ b/gemd/entity/template/material_template.py
@@ -2,6 +2,8 @@
from gemd.entity.template.base_template import BaseTemplate
from gemd.entity.template.has_property_templates import HasPropertyTemplates
+__all__ = ["MaterialTemplate"]
+
class MaterialTemplate(BaseTemplate, HasPropertyTemplates, typ="material_template"):
"""
@@ -25,10 +27,9 @@ class MaterialTemplate(BaseTemplate, HasPropertyTemplates, typ="material_templat
`Tags `_
are hierarchical strings that store information about an entity. They can be used
for filtering and discoverability.
- properties: List[:class:`PropertyTemplate \
- `] or \
- List[:class:`PropertyTemplate `,\
- :py:class:`BaseBounds `], optional
+ properties: ~gemd.entity.template.property_template.PropertyTemplate or \
+ List[~gemd.entity.template.property_template.PropertyTemplate, \
+ ~gemd.entity.bounds.base_bounds.BaseBounds], optional
Templates for associated properties. Each template can be provided by itself, or as a list
with the second entry being a separate, *more restrictive* Bounds object that defines
the limits of the value for this property.
diff --git a/gemd/entity/template/measurement_template.py b/gemd/entity/template/measurement_template.py
index bd8b6838..23104c61 100644
--- a/gemd/entity/template/measurement_template.py
+++ b/gemd/entity/template/measurement_template.py
@@ -4,6 +4,8 @@
from gemd.entity.template.has_parameter_templates import HasParameterTemplates
from gemd.entity.template.has_property_templates import HasPropertyTemplates
+__all__ = ["MeasurementTemplate"]
+
class MeasurementTemplate(BaseTemplate,
HasPropertyTemplates, HasConditionTemplates, HasParameterTemplates,
@@ -29,24 +31,21 @@ class MeasurementTemplate(BaseTemplate,
`Tags `_
are hierarchical strings that store information about an entity. They can be used
for filtering and discoverability.
- conditions: List[:class:`ConditionTemplate \
- `] or \
- List[:class:`ConditionTemplate `,\
- :py:class:`BaseBounds `], optional
+ conditions: List[~gemd.entity.template.condition_template.ConditionTemplate] or \
+ List[~gemd.entity.template.condition_template.ConditionTemplate,\
+ ~gemd.entity.bounds.base_bounds.BaseBounds], optional
Templates for associated conditions. Each template can be provided by itself, or as a list
with the second entry being a separate, *more restrictive* Bounds object that defines
the limits of the value for this condition.
- parameters: List[:class:`ParameterTemplate \
- `] or \
- List[:class:`ParameterTemplate `,\
- :py:class:`BaseBounds `], optional
+ parameters: List[~gemd.entity.template.parameter_template.ParameterTemplate] or \
+ List[~gemd.entity.template.parameter_template.ParameterTemplate,\
+ ~gemd.entity.bounds.base_bounds.BaseBounds], optional
Templates for associated parameters. Each template can be provided by itself, or as a list
with the second entry being a separate, *more restrictive* Bounds object that defines
the limits of the value for this parameter.
- properties: List[:class:`PropertyTemplate \
- `] or \
- List[:class:`PropertyTemplate `,\
- :py:class:`BaseBounds `], optional
+ properties: List[~gemd.entity.template.property_template.PropertyTemplate] or \
+ List[~gemd.entity.template.property_template.PropertyTemplate,\
+ ~gemd.entity.bounds.base_bounds.BaseBounds], optional
Templates for associated properties. Each template can be provided by itself, or as a list
with the second entry being a separate, *more restrictive* Bounds object that defines
the limits of the value for this property.
diff --git a/gemd/entity/template/parameter_template.py b/gemd/entity/template/parameter_template.py
index c8e8c4ce..2b733258 100644
--- a/gemd/entity/template/parameter_template.py
+++ b/gemd/entity/template/parameter_template.py
@@ -1,14 +1,16 @@
from gemd.entity.template.attribute_template import AttributeTemplate
+__all__ = ["ParameterTemplate"]
+
class ParameterTemplate(AttributeTemplate, typ="parameter_template"):
"""A template for the parameter attribute.
- Parameters
+ Parameters
----------
name: str, required
The name of the parameter template.
- bounds: :py:class:`BaseBounds `
+ bounds: ~gemd.entity.bounds.base_bounds.BaseBounds
Bounds circumscribe the values that are valid according to this parameter template.
description: str, optional
A long-form description of the attribute template.
diff --git a/gemd/entity/template/process_template.py b/gemd/entity/template/process_template.py
index 307266f8..7325e6fa 100644
--- a/gemd/entity/template/process_template.py
+++ b/gemd/entity/template/process_template.py
@@ -4,6 +4,8 @@
from gemd.entity.template.has_condition_templates import HasConditionTemplates
from gemd.entity.template.has_parameter_templates import HasParameterTemplates
+__all__ = ["ProcessTemplate"]
+
class ProcessTemplate(BaseTemplate,
HasConditionTemplates, HasParameterTemplates,
@@ -33,17 +35,15 @@ class ProcessTemplate(BaseTemplate,
The set of names that a process' ingredients are allowed to use in their name field.
allowed_labels: List[str], optional
The set of labels that a process' ingredients are allowed to use in their labels field.
- conditions: List[:class:`ConditionTemplate \
- `] or \
- List[:class:`ConditionTemplate `,\
- :py:class:`BaseBounds `], optional
+ conditions: List[~gemd.entity.template.condition_template.ConditionTemplate] or \
+ List[~gemd.entity.template.condition_template.ConditionTemplate,\
+ ~gemd.entity.bounds.base_bounds.BaseBounds], optional
Templates for associated conditions. Each template can be provided by itself, or as a list
with the second entry being a separate, *more restrictive* Bounds object that defines
the limits of the value for this condition.
- parameters: List[:class:`ParameterTemplate \
- `] or \
- List[:class:`ParameterTemplate `,\
- :py:class:`BaseBounds `], optional
+ parameters: List[~gemd.entity.template.parameter_template.ParameterTemplate] or \
+ List[~gemd.entity.template.parameter_template.ParameterTemplate,\
+ ~gemd.entity.bounds.base_bounds.BaseBounds], optional
Templates for associated parameters. Each template can be provided by itself, or as a list
with the second entry being a separate, *more restrictive* Bounds object that defines
the limits of the value for this parameter.
diff --git a/gemd/entity/template/property_template.py b/gemd/entity/template/property_template.py
index f0608333..eb14a300 100644
--- a/gemd/entity/template/property_template.py
+++ b/gemd/entity/template/property_template.py
@@ -1,5 +1,7 @@
from gemd.entity.template.attribute_template import AttributeTemplate
+__all__ = ["PropertyTemplate"]
+
class PropertyTemplate(AttributeTemplate, typ="property_template"):
"""A template for the property attribute.
@@ -8,7 +10,7 @@ class PropertyTemplate(AttributeTemplate, typ="property_template"):
----------
name: str, required
The name of the property template.
- bounds: :py:class:`BaseBounds `
+ bounds: ~gemd.entity.bounds.base_bounds.BaseBounds
Bounds circumscribe the values that are valid according to this property template.
description: str, optional
A long-form description of the attribute template.
diff --git a/gemd/entity/util.py b/gemd/entity/util.py
index 23592495..1cb8585a 100644
--- a/gemd/entity/util.py
+++ b/gemd/entity/util.py
@@ -3,6 +3,8 @@
from typing import List, Dict, Any
+__all__ = ["make_instance", "array_like", "complete_material_history"]
+
def make_instance(base_spec):
"""
@@ -104,7 +106,7 @@ def complete_material_history(mat) -> List[Dict[str, Any]]:
Parameters
---------
- mat: MaterialRun
+ mat: ~gemd.entity.object.material_run.MaterialRun
root material run
Returns
-------
diff --git a/gemd/entity/valid_list.py b/gemd/entity/valid_list.py
index 926b251f..52647823 100644
--- a/gemd/entity/valid_list.py
+++ b/gemd/entity/valid_list.py
@@ -1,6 +1,8 @@
"""A list that can validate its contents."""
from typing import Optional, Union, Iterable, Callable, Type, TypeVar
+__all__ = ["ValidList"]
+
T = TypeVar('T')
diff --git a/gemd/entity/value/base_value.py b/gemd/entity/value/base_value.py
index 18a0ff6a..b02c25f3 100644
--- a/gemd/entity/value/base_value.py
+++ b/gemd/entity/value/base_value.py
@@ -4,6 +4,8 @@
from abc import abstractmethod
+__all__ = ["BaseValue"]
+
class BaseValue(DictSerializable):
"""
@@ -11,7 +13,6 @@ class BaseValue(DictSerializable):
"Value" is a generic term for the information contained in an
:class:`attribute `.
- A value may be one of the following types: `RealValue`, `IntegerValue`, `Categorical`.
"""
@abstractmethod
@@ -22,7 +23,6 @@ def _to_bounds(self) -> BaseBounds:
Returns
-------
BaseBounds
- The minimally consistent
- :class:`bounds `.
+ The minimally consistent :class:`bounds `.
"""
diff --git a/gemd/entity/value/categorical_value.py b/gemd/entity/value/categorical_value.py
index 29d8cf90..ddee8992 100644
--- a/gemd/entity/value/categorical_value.py
+++ b/gemd/entity/value/categorical_value.py
@@ -4,6 +4,8 @@
from abc import abstractmethod
+__all__ = ["CategoricalValue"]
+
class CategoricalValue(BaseValue):
"""
@@ -21,6 +23,6 @@ def _to_bounds(self) -> CategoricalBounds:
-------
CategoricalBounds
The minimally consistent
- :class:`bounds `.
+ :class:`gemd.entity.bounds.categorical_bounds.CategoricalBounds`.
"""
diff --git a/gemd/entity/value/composition_value.py b/gemd/entity/value/composition_value.py
index de63835b..511528ca 100644
--- a/gemd/entity/value/composition_value.py
+++ b/gemd/entity/value/composition_value.py
@@ -4,6 +4,8 @@
from abc import abstractmethod
+__all__ = ["CompositionValue"]
+
class CompositionValue(BaseValue):
"""Base class for composition values."""
@@ -17,6 +19,6 @@ def _to_bounds(self) -> CompositionBounds:
-------
CompositionBounds
The minimally consistent
- :class:`bounds `.
+ :class:`~gemd.entity.bounds.composition_bounds.CompositionBounds`.
"""
diff --git a/gemd/entity/value/continuous_value.py b/gemd/entity/value/continuous_value.py
index bc074ee9..9bae50af 100644
--- a/gemd/entity/value/continuous_value.py
+++ b/gemd/entity/value/continuous_value.py
@@ -5,6 +5,8 @@
from abc import abstractmethod
+__all__ = ["ContinuousValue"]
+
class ContinuousValue(BaseValue):
"""
@@ -47,7 +49,6 @@ def _to_bounds(self) -> RealBounds:
Returns
-------
RealBounds
- The minimally consistent
- :class:`bounds `.
+ The minimally consistent :class:`~gemd.entity.bounds.real_bounds.RealBounds`.
"""
diff --git a/gemd/entity/value/discrete_categorical.py b/gemd/entity/value/discrete_categorical.py
index b1f5e4f9..6d3c1c1b 100644
--- a/gemd/entity/value/discrete_categorical.py
+++ b/gemd/entity/value/discrete_categorical.py
@@ -1,8 +1,12 @@
"""Discrete distribution across several categories."""
+from typing import Optional, Union, Mapping
+
from gemd.entity.setters import validate_str
from gemd.entity.value.categorical_value import CategoricalValue
from gemd.entity.bounds import CategoricalBounds
+__all__ = ["DiscreteCategorical"]
+
class DiscreteCategorical(CategoricalValue, typ="discrete_categorical"):
"""
@@ -21,17 +25,18 @@ class DiscreteCategorical(CategoricalValue, typ="discrete_categorical"):
"""
- def __init__(self, probabilities=None):
+ def __init__(self, probabilities: Union[str, Mapping[str, float]] = None):
self._probabilities = None
self.probabilities = probabilities
@property
- def probabilities(self) -> dict:
+ def probabilities(self) -> Mapping[str, float]:
"""Get the map from categories to probabilities."""
return self._probabilities
@probabilities.setter
- def probabilities(self, probabilities: dict):
+ def probabilities(self, probabilities: Optional[Union[str, Mapping[str, float]]]):
+ """Set the map from categories to probabilities."""
if probabilities is None:
self._probabilities = None
elif isinstance(probabilities, str):
@@ -51,7 +56,7 @@ def _to_bounds(self) -> CategoricalBounds:
-------
BaseBounds
The minimally consistent
- :class:`bounds `.
+ :class:`~gemd.entity.bounds.categorical_bounds.CategoricalBounds`.
"""
return CategoricalBounds(categories=set(self.probabilities))
diff --git a/gemd/entity/value/empirical_formula.py b/gemd/entity/value/empirical_formula.py
index 4701b511..b52d9cc0 100644
--- a/gemd/entity/value/empirical_formula.py
+++ b/gemd/entity/value/empirical_formula.py
@@ -2,6 +2,8 @@
from gemd.entity.value.composition_value import CompositionValue
from gemd.entity.bounds import CompositionBounds
+__all__ = ["EmpiricalFormula"]
+
_all_elements = {
'Tb', 'Be', 'Sb', 'Re', 'Sr', 'Ac', 'Ho', 'Ir', 'Cr', 'Os', 'S', 'Pt', 'Si', 'C', 'V', 'Bi',
@@ -61,7 +63,7 @@ def _to_bounds(self) -> CompositionBounds:
-------
BaseBounds
The minimally consistent
- :class:`bounds `.
+ :class:`~gemd.entity.bounds.categorical_bounds.CategoricalBounds`.
"""
return CompositionBounds(components=EmpiricalFormula._elements(self.formula))
diff --git a/gemd/entity/value/inchi_value.py b/gemd/entity/value/inchi_value.py
index 1e8d0ed6..4e7ba263 100644
--- a/gemd/entity/value/inchi_value.py
+++ b/gemd/entity/value/inchi_value.py
@@ -2,6 +2,8 @@
from gemd.entity.value.molecular_value import MolecularValue
from gemd.entity.bounds import MolecularStructureBounds
+__all__ = ["InChI"]
+
class InChI(MolecularValue, typ="inchi"):
"""
@@ -47,8 +49,7 @@ def _to_bounds(self) -> MolecularStructureBounds:
-------
MolecularStructureBounds
The minimally consistent
- :class:`bounds
- `.
+ :class:`~gemd.entity.bounds.molecular_structure_bounds.MolecularStructureBounds`.
"""
return MolecularStructureBounds()
diff --git a/gemd/entity/value/integer_value.py b/gemd/entity/value/integer_value.py
index edac729a..43283b56 100644
--- a/gemd/entity/value/integer_value.py
+++ b/gemd/entity/value/integer_value.py
@@ -4,6 +4,8 @@
from abc import abstractmethod
+__all__ = ["IntegerValue"]
+
class IntegerValue(BaseValue):
"""A base class for values that correspond to a distribution over the integers."""
@@ -17,6 +19,6 @@ def _to_bounds(self) -> IntegerBounds:
-------
IntegerBounds
The minimally consistent
- :class:`bounds `.
+ :class:`~gemd.entity.bounds.integer_bounds.IntegerBounds`.
"""
diff --git a/gemd/entity/value/molecular_value.py b/gemd/entity/value/molecular_value.py
index a3e8d6cd..3318cea7 100644
--- a/gemd/entity/value/molecular_value.py
+++ b/gemd/entity/value/molecular_value.py
@@ -4,6 +4,8 @@
from abc import abstractmethod
+__all__ = ["MolecularValue"]
+
class MolecularValue(BaseValue):
"""Base class for molecular structure values."""
@@ -17,7 +19,6 @@ def _to_bounds(self) -> MolecularStructureBounds:
-------
MolecularStructureBounds
The minimally consistent
- :class:`bounds
- `.
+ :class:`~gemd.entity.bounds.molecular_structure_bounds.MolecularStructureBounds`.
"""
diff --git a/gemd/entity/value/nominal_categorical.py b/gemd/entity/value/nominal_categorical.py
index 6c6c9c98..5f738619 100644
--- a/gemd/entity/value/nominal_categorical.py
+++ b/gemd/entity/value/nominal_categorical.py
@@ -3,6 +3,8 @@
from gemd.entity.value.categorical_value import CategoricalValue
from gemd.entity.bounds import CategoricalBounds
+__all__ = ["NominalCategorical"]
+
class NominalCategorical(CategoricalValue, typ="nominal_categorical"):
"""
@@ -39,7 +41,7 @@ def _to_bounds(self) -> CategoricalBounds:
-------
BaseBounds
The minimally consistent
- :class:`bounds `.
+ :class:`~gemd.entity.bounds.categorical_bounds.CategoricalBounds`.
"""
return CategoricalBounds(categories={self.category})
diff --git a/gemd/entity/value/nominal_composition.py b/gemd/entity/value/nominal_composition.py
index a02233cb..ca3f891a 100644
--- a/gemd/entity/value/nominal_composition.py
+++ b/gemd/entity/value/nominal_composition.py
@@ -2,6 +2,8 @@
from gemd.entity.value.composition_value import CompositionValue
from gemd.entity.bounds import CompositionBounds
+__all__ = ["NominalComposition"]
+
class NominalComposition(CompositionValue, typ="nominal_composition"):
"""
@@ -50,7 +52,7 @@ def _to_bounds(self) -> CompositionBounds:
-------
BaseBounds
The minimally consistent
- :class:`bounds `.
+ :class:`~gemd.entity.bounds.categorical_bounds.CategoricalBounds`.
"""
return CompositionBounds(components=set(self.quantities))
diff --git a/gemd/entity/value/nominal_integer.py b/gemd/entity/value/nominal_integer.py
index 94f090ea..5be33d5c 100644
--- a/gemd/entity/value/nominal_integer.py
+++ b/gemd/entity/value/nominal_integer.py
@@ -2,6 +2,8 @@
from gemd.entity.value.integer_value import IntegerValue
from gemd.entity.bounds import IntegerBounds
+__all__ = ["NominalInteger"]
+
class NominalInteger(IntegerValue, typ="nominal_integer"):
"""
@@ -40,7 +42,7 @@ def _to_bounds(self) -> IntegerBounds:
-------
IntegerBounds
The minimally consistent
- :class:`bounds `.
+ :class:`~gemd.entity.bounds.integer_bounds.IntegerBounds`.
"""
return IntegerBounds(lower_bound=self.nominal, upper_bound=self.nominal)
diff --git a/gemd/entity/value/nominal_real.py b/gemd/entity/value/nominal_real.py
index 7eeb7608..3a79028d 100644
--- a/gemd/entity/value/nominal_real.py
+++ b/gemd/entity/value/nominal_real.py
@@ -2,6 +2,8 @@
from gemd.entity.value.continuous_value import ContinuousValue
from gemd.entity.bounds import RealBounds
+__all__ = ["NominalReal"]
+
class NominalReal(ContinuousValue, typ="nominal_real"):
"""
@@ -31,7 +33,7 @@ def _to_bounds(self) -> RealBounds:
-------
RealBounds
The minimally consistent
- :class:`bounds `.
+ :class:`~gemd.entity.bounds.real_bounds.RealBounds`.
"""
return RealBounds(lower_bound=self.nominal,
diff --git a/gemd/entity/value/normal_real.py b/gemd/entity/value/normal_real.py
index 57915226..4ce1908d 100644
--- a/gemd/entity/value/normal_real.py
+++ b/gemd/entity/value/normal_real.py
@@ -2,6 +2,8 @@
from gemd.entity.value.continuous_value import ContinuousValue
from gemd.entity.bounds import RealBounds
+__all__ = ["NormalReal"]
+
class NormalReal(ContinuousValue, typ="normal_real"):
"""
@@ -32,7 +34,7 @@ def _to_bounds(self) -> RealBounds:
-------
RealBounds
The minimally consistent
- :class:`bounds `.
+ :class:`~gemd.entity.bounds.real_bounds.RealBounds`.
"""
return RealBounds(lower_bound=self.mean,
diff --git a/gemd/entity/value/smiles_value.py b/gemd/entity/value/smiles_value.py
index e871f77f..cfeb2b53 100644
--- a/gemd/entity/value/smiles_value.py
+++ b/gemd/entity/value/smiles_value.py
@@ -2,6 +2,8 @@
from gemd.entity.value.molecular_value import MolecularValue
from gemd.entity.bounds import MolecularStructureBounds
+__all__ = ["Smiles"]
+
class Smiles(MolecularValue, typ="smiles"):
"""
@@ -41,8 +43,7 @@ def _to_bounds(self) -> MolecularStructureBounds:
-------
MolecularStructureBounds
The minimally consistent
- :class:`bounds
- `.
+ :class:`~gemd.entity.bounds.molecular_structure_bounds.MolecularStructureBounds`.
"""
return MolecularStructureBounds()
diff --git a/gemd/entity/value/uniform_integer.py b/gemd/entity/value/uniform_integer.py
index 4cc47f67..40cdb938 100644
--- a/gemd/entity/value/uniform_integer.py
+++ b/gemd/entity/value/uniform_integer.py
@@ -2,6 +2,8 @@
from gemd.entity.value.integer_value import IntegerValue
from gemd.entity.bounds import IntegerBounds
+__all__ = ["UniformInteger"]
+
class UniformInteger(IntegerValue, typ="uniform_integer"):
"""
@@ -68,7 +70,7 @@ def _to_bounds(self) -> IntegerBounds:
-------
IntegerBounds
The minimally consistent
- :class:`bounds `.
+ :class:`~gemd.entity.bounds.integer_bounds.IntegerBounds`.
"""
return IntegerBounds(lower_bound=self.lower_bound, upper_bound=self.upper_bound)
diff --git a/gemd/entity/value/uniform_real.py b/gemd/entity/value/uniform_real.py
index eca0b004..757c68d0 100644
--- a/gemd/entity/value/uniform_real.py
+++ b/gemd/entity/value/uniform_real.py
@@ -2,6 +2,8 @@
from gemd.entity.value.continuous_value import ContinuousValue
from gemd.entity.bounds import RealBounds
+__all__ = ["UniformReal"]
+
class UniformReal(ContinuousValue, typ="uniform_real"):
"""
@@ -40,7 +42,7 @@ def _to_bounds(self) -> RealBounds:
-------
RealBounds
The minimally consistent
- :class:`bounds `.
+ :class:`~gemd.entity.bounds.real_bounds.RealBounds`.
"""
return RealBounds(lower_bound=self.lower_bound,
diff --git a/gemd/enumeration/__init__.py b/gemd/enumeration/__init__.py
index 2cfcb00b..77c1167f 100644
--- a/gemd/enumeration/__init__.py
+++ b/gemd/enumeration/__init__.py
@@ -2,3 +2,4 @@
from .origin import Origin
from .sample_type import SampleType
+__all__ = ["Origin", "SampleType"]
diff --git a/gemd/enumeration/base_enumeration.py b/gemd/enumeration/base_enumeration.py
index cb8a3df5..849695e9 100644
--- a/gemd/enumeration/base_enumeration.py
+++ b/gemd/enumeration/base_enumeration.py
@@ -4,26 +4,25 @@
from typing import Optional, Type, Callable
from warnings import warn
+__all__ = ["BaseEnumeration"]
+
class BaseEnumeration(str, Enum):
- """
- Enumeration class that can convert between enumerations and associated values.
+ """Enumeration class that can convert between enumerations and associated values.
BaseEnumeration is a powerful support class for string enumerations. It inherits
from both str and Enum to enable a class with str capabilities but still a
restricted data space. All constructors are case-insensitive on input and a given
enumeration can recognize multiple synonyms for input, though only one value will
- correspond to the value itsself. For example:
+ correspond to the value itself. For example:
- ```
- Fruits(BaseEnumeration):
- APPLE = "Apple"
- AVOCADO = "Avocado", "Alligator Pear"
- ```
+ >>> class Fruits(BaseEnumeration):
+ ... APPLE = "Apple"
+ ... AVOCADO = "Avocado", "Alligator Pear"
- will recognize "apple", "APPLE" and " aPpLe " as referring to Fruits.APPLE,
- and "avocado" and "alligator pear" as referring to Fruits.AVOCADO. However,
- since str(Fruits.AVOCADO) is "Avocado", Fruits.AVOCADO != "Alligator Pear".
+ will recognize ``"apple"``, ``"APPLE"`` and ``" aPpLe "`` as referring to Fruits.APPLE,
+ and ``"avocado"`` and ``"alligator pear"`` as referring to Fruits.AVOCADO. However,
+ since str(Fruits.AVOCADO) is ``"Avocado"``, Fruits.AVOCADO != ``"Alligator Pear"``.
"""
@@ -84,7 +83,7 @@ def get_value(cls, name: str) -> str:
@classmethod
@deprecated(deprecated_in="1.15.0",
removed_in="2.0.0",
- details="Use from_str for retreiving the correct Enum object.")
+ details="Use from_str for retrieving the correct Enum object.")
def get_enum(cls, name: str) -> "BaseEnumeration":
"""
Return the enumeration associated with name.
diff --git a/gemd/enumeration/origin.py b/gemd/enumeration/origin.py
index d1ff78dd..c6817275 100644
--- a/gemd/enumeration/origin.py
+++ b/gemd/enumeration/origin.py
@@ -1,6 +1,8 @@
"""All possible origins of an attribute."""
from gemd.enumeration.base_enumeration import BaseEnumeration
+__all__ = ["Origin"]
+
class Origin(BaseEnumeration):
"""Enumeration containing all possible origins for an attribute."""
diff --git a/gemd/enumeration/sample_type.py b/gemd/enumeration/sample_type.py
index 32209a8c..b8193f0d 100644
--- a/gemd/enumeration/sample_type.py
+++ b/gemd/enumeration/sample_type.py
@@ -1,6 +1,8 @@
"""All possible types of samples."""
from gemd.enumeration.base_enumeration import BaseEnumeration
+__all__ = ["SampleType"]
+
class SampleType(BaseEnumeration):
"""Enumeration containing all possible sample types for a MaterialRun."""
diff --git a/gemd/json/__init__.py b/gemd/json/__init__.py
index f4f6c729..608536ec 100644
--- a/gemd/json/__init__.py
+++ b/gemd/json/__init__.py
@@ -10,8 +10,8 @@
These methods should provide drop-in support for serialization and deserialization of
gemd-containing data structures by replacing imports of ``json`` with those of ``gemd.json``.
-It also provides convenience imports of :class:`~gemd_encoder.GEMDEncoder`
-and :class:`~gemd_json.GEMDJson`.
+It also provides convenience imports of :class:`~gemd.json.gemd_encoder.GEMDEncoder`
+and :class:`~gemd.json.gemd_json.GEMDJson`.
These classes can be used by developers to integrate gemd with other tools by extending the
JSON support provided here to those tools.
"""
@@ -19,6 +19,11 @@
from .gemd_encoder import GEMDEncoder # noqa: F401
from .gemd_json import GEMDJson
+__all__ = [
+ "GEMDEncoder", "GEMDJson",
+ "loads", "dumps", "load", "dump"
+]
+
__default = GEMDJson()
diff --git a/gemd/json/gemd_encoder.py b/gemd/json/gemd_encoder.py
index 0d8436b1..906b68b8 100644
--- a/gemd/json/gemd_encoder.py
+++ b/gemd/json/gemd_encoder.py
@@ -3,6 +3,8 @@
from gemd.entity.dict_serializable import DictSerializable
+__all__ = ["GEMDEncoder"]
+
class GEMDEncoder(JSONEncoder):
"""Rules for encoding gemd objects as json strings."""
diff --git a/gemd/json/gemd_json.py b/gemd/json/gemd_json.py
index f01276dc..5017b2d3 100644
--- a/gemd/json/gemd_json.py
+++ b/gemd/json/gemd_json.py
@@ -1,5 +1,6 @@
import inspect
from deprecation import deprecated
+import json as json_builtin
from typing import Dict, Any, Type
from gemd.entity.dict_serializable import DictSerializable
@@ -7,7 +8,8 @@
from gemd.entity.link_by_uid import LinkByUID
from gemd.json import GEMDEncoder
from gemd.util import flatten, substitute_links, set_uuids
-import json as json_builtin
+
+__all__ = ["GEMDJson"]
class GEMDJson(object):
diff --git a/gemd/units/__init__.py b/gemd/units/__init__.py
index 74a96069..5b8ce3c8 100644
--- a/gemd/units/__init__.py
+++ b/gemd/units/__init__.py
@@ -2,5 +2,7 @@
from .impl import parse_units, convert_units, get_base_units, change_definitions_file, \
UndefinedUnitError, IncompatibleUnitsError, DefinitionSyntaxError
-__all__ = [parse_units, convert_units, get_base_units, change_definitions_file,
- UndefinedUnitError, IncompatibleUnitsError, DefinitionSyntaxError]
+__all__ = [
+ "parse_units", "convert_units", "get_base_units", "change_definitions_file",
+ "UndefinedUnitError", "IncompatibleUnitsError", "DefinitionSyntaxError"
+]
diff --git a/gemd/units/impl.py b/gemd/units/impl.py
index 6fe24b7e..47f1f534 100644
--- a/gemd/units/impl.py
+++ b/gemd/units/impl.py
@@ -21,6 +21,11 @@
# Store directories so they don't get auto-cleaned until exit
_TEMP_DIRECTORY = TemporaryDirectory()
+__all__ = [
+ "parse_units", "convert_units", "get_base_units", "change_definitions_file",
+ "UndefinedUnitError", "IncompatibleUnitsError", "DefinitionSyntaxError"
+]
+
def _deploy_default_files() -> str:
"""Copy the units & constants file into a temporary directory."""
@@ -264,15 +269,15 @@ def parse_units(units: Union[str, Unit, None],
Parameters
----------
- units: Union[str, Unit, None]
+ units: str, Unit, or None
The string or Unit representation of the object we wish to display
return_unit: boolean
- Whether to return a Unit object, vs. whatever was initially passed
+ Whether to return a pint Unit object, vs. whatever was initially passed
Returns
-------
- [Union[str, Unit, None]]
- The representation; note that the same type that was passed is returned
+ str, Unit, or None
+ The representation; note that `return_unit` controls the return type
"""
if units is None:
@@ -299,13 +304,14 @@ def get_base_units(units: Union[str, Unit]) -> Tuple[Unit, float, float]:
Parameters
----------
- units: Union[str, Unit, None]
- The string or Unit representation of the object we wish to display
+ units: str, Unit, or None
+ The representation of the object we wish to display
Returns
-------
- Tuple[Unit, Number, float]
- The base unit, its
+ Tuple[Unit, float, float]
+ A tuple of the base unit, its multiplicative conversion factor, and its
+ additive offset, in that order.
"""
if isinstance(units, str):
diff --git a/gemd/util/impl.py b/gemd/util/impl.py
index 64f64acb..d3ebf1e1 100644
--- a/gemd/util/impl.py
+++ b/gemd/util/impl.py
@@ -38,7 +38,7 @@ def func(base_obj):
def cached_isinstance(
obj: object,
- class_or_tuple: Union[Type, Tuple[Union[Type, Tuple[Type]]]]) -> bool:
+ class_or_tuple: Union[Type, Tuple[Type]]) -> bool:
"""
Emulate isinstance builtin to take advantage of functools caching.
@@ -46,7 +46,7 @@ def cached_isinstance(
----------
obj: object
- class_or_tuple: Union[Type, Tuple[Union[Type, Tuple[Type]]]]
+ class_or_tuple: Type or Tuple[Type]
A single type, a tuple of types (potentially nested)
Returns
@@ -66,7 +66,7 @@ def cached_isinstance(
@functools.lru_cache(maxsize=1024)
def _cached_issubclass(
cls: Type,
- class_or_tuple: Union[Type, Tuple[Union[Type, Tuple[Type]]]]) -> bool:
+ class_or_tuple: Union[Type, Tuple[Type]]) -> bool:
"""
Emulate issubclass builtin to take advantage of functools caching.
@@ -74,7 +74,7 @@ def _cached_issubclass(
----------
cls: type
The class to evaluate
- class_or_tuple: Union[Type, Tuple[Union[Type, Tuple[Type]]]]
+ class_or_tuple: Type or Tuple[Type]
A single type, a tuple of types (potentially nested)
Returns
@@ -254,7 +254,7 @@ def make_index(obj: Union[Iterable, BaseEntity, DictSerializable]):
Parameters
----------
- obj: Union[Iterable, Mapping, BaseEntity, DictSerializable]
+ obj: BaseEntity or Iterable[BaseEntity]
target container (dict, list, ...) from which to create an index of GEMD objects
"""
@@ -399,23 +399,23 @@ def _flatten(base_obj: BaseEntity):
return sorted([substitute_links(x) for x in res], key=lambda x: writable_sort_order(x))
-def recursive_foreach(obj: Union[Iterable, BaseEntity, DictSerializable],
+def recursive_foreach(obj: Union[Iterable, DictSerializable],
func: Callable[[BaseEntity], None],
*,
apply_first=False):
"""
Apply a function recursively to each BaseEntity object.
- Only objects of type BaseEntity will have the function applied, but the recursion will walk
+ Only :class:`BaseEntity` objects will have the function applied, but the recursion will walk
through all objects. For example, BaseEntity -> list -> BaseEntity will have func applied
to both base entities.
Parameters
----------
- obj: Union[Iterable, Mapping, BaseEntity, DictSerializable]
+ obj: DictSerializable or Iterable[DictSerializable], or Iterable[...]
target of the operation
func: Callable[[BaseEntity], None]
- to apply to each contained BaseEntity
+ function to apply to :class:`BaseEntity` elements
apply_first: bool
whether to apply the func before applying it to members (default: false)
@@ -455,19 +455,23 @@ def recursive_foreach(obj: Union[Iterable, BaseEntity, DictSerializable],
return
-def recursive_flatmap(obj: Union[Iterable, BaseEntity, DictSerializable],
+def recursive_flatmap(obj: Union[Iterable, DictSerializable],
func: Callable[[BaseEntity], Iterable],
*,
unidirectional=True) -> List:
"""
Recursively apply and accumulate a list-valued function to BaseEntity members.
+ Only :class:`BaseEntity` objects will have the function applied, but the recursion will walk
+ through all objects. For example, BaseEntity -> list -> BaseEntity will have func applied
+ to both base entities.
+
Parameters
----------
- obj: Union[Iterable, Mapping, BaseEntity, DictSerializable]
+ obj: DictSerializable or Iterable[DictSerializable], or Iterable[...]
target of the operation
- func: Callable[[BaseEntity], Iterable]
- function to apply; must be list-valued
+ func: Callable[[BaseEntity], Iterable[Any]]
+ function to apply to :class:`BaseEntity` elements; must be list-valued
unidirectional: bool
only recurse through the writeable direction of bidirectional links
diff --git a/scripts/build_docs.sh b/scripts/build_docs.sh
old mode 100644
new mode 100755
diff --git a/scripts/run_tests.sh b/scripts/run_tests.sh
index 13683a4a..a44c40b4 100755
--- a/scripts/run_tests.sh
+++ b/scripts/run_tests.sh
@@ -36,7 +36,7 @@ then python $REPO_DIR/scripts/validate_version_bump.py ||
fi
flake8 $REPO_DIR/gemd || exit 1;
-derp $REPO_DIR $REPO_DIR/setup.py || exit 1;
+derp $REPO_DIR $REPO_DIR/gemd/__version__.py || exit 1;
pytest $QUIET $EXITFIRST --cov=$REPO_DIR/gemd \
--cov-report term-missing:skip-covered \
--cov-config=$REPO_DIR/tox.ini --no-cov-on-fail --cov-fail-under=100 \
diff --git a/scripts/validate_version_bump.py b/scripts/validate_version_bump.py
index e6a66ca9..fbf4097a 100755
--- a/scripts/validate_version_bump.py
+++ b/scripts/validate_version_bump.py
@@ -9,7 +9,7 @@
def main():
repo_dir = popen("git rev-parse --show-toplevel", mode="r").read().rstrip()
- version_path = relpath(f'{repo_dir}/setup.py', getcwd())
+ version_path = relpath(f'{repo_dir}/gemd/__version__.py', getcwd())
try:
with open(version_path, "r") as fh:
diff --git a/setup.py b/setup.py
index afbb3375..a127cd1c 100644
--- a/setup.py
+++ b/setup.py
@@ -1,10 +1,23 @@
from setuptools import setup, find_packages
+from os import path
+from packaging.version import Version
+import re
packages = find_packages()
-packages.append("")
+
+this_directory = path.abspath(path.dirname(__file__))
+version_file = path.join(this_directory, 'gemd', '__version__.py')
+version_re = r'''^__version__\s*=\s*(['"])([\w\.]+)\1$'''
+with open(version_file, 'r') as f:
+ mo = re.search(version_re, f.read(), re.M)
+ if mo:
+ version = Version(mo.group(2))
+ else:
+ raise RuntimeError(f"Unable to find version string in {version_file}")
setup(name='gemd',
- version='1.18.0',
+ # Update this in gemd/__version__.py
+ version=str(version),
python_requires='>=3.8',
url='http://github.com/CitrineInformatics/gemd-python',
description="Python binding for Citrine's GEMD data model",
diff --git a/test_requirements.txt b/test_requirements.txt
index 8d88ee33..c27fa53b 100644
--- a/test_requirements.txt
+++ b/test_requirements.txt
@@ -5,6 +5,6 @@ pytest-cov==4.0.0
pandas==1.5.0
toolz==0.12.0
derp==0.1.1
-sphinx==4.3.0
-sphinxcontrib-apidoc==0.3.0
+sphinx==5.0.0
sphinx-rtd-theme==1.0.0
+sphinxcontrib-apidoc==0.3.0