From 4aace7d6b536ebea869fb9c6f33d32dfbbae845f Mon Sep 17 00:00:00 2001 From: Ken Kroenlein Date: Mon, 8 Jan 2024 15:40:31 -0700 Subject: [PATCH 1/9] Remove documentation build bugs --- docs/source/_static/favicon.png | Bin 0 -> 2206 bytes docs/source/_static/logo.png | Bin 0 -> 36915 bytes docs/source/conf.py | 21 +++++++++++---- docs/source/depth/index.rst | 9 ------- docs/source/depth/unit_parsing.rst | 7 ++++- docs/source/index.rst | 24 +++++++++++++++--- docs/source/modules.rst | 4 --- docs/source/setup.rst | 7 ----- gemd/__init__.py | 4 +-- gemd/__version__.py | 1 + gemd/builders/__init__.py | 4 +++ gemd/builders/impl.py | 4 +++ gemd/demo/cake.py | 4 +++ gemd/demo/strehlow_and_cook.py | 6 +++++ gemd/entity/attribute/condition.py | 2 ++ gemd/entity/attribute/parameter.py | 2 ++ gemd/entity/attribute/property.py | 2 ++ .../attribute/property_and_conditions.py | 2 ++ gemd/entity/base_entity.py | 2 ++ gemd/entity/bounds/base_bounds.py | 2 ++ gemd/entity/bounds/categorical_bounds.py | 2 ++ gemd/entity/bounds/composition_bounds.py | 2 ++ gemd/entity/bounds/integer_bounds.py | 2 ++ .../bounds/molecular_structure_bounds.py | 2 ++ gemd/entity/bounds/real_bounds.py | 2 ++ gemd/entity/bounds_validation.py | 2 ++ gemd/entity/case_insensitive_dict.py | 2 ++ gemd/entity/dict_serializable.py | 2 ++ gemd/entity/file_link.py | 2 ++ gemd/entity/has_dependencies.py | 2 ++ gemd/entity/link_by_uid.py | 2 ++ gemd/entity/object/base_object.py | 2 ++ gemd/entity/object/has_conditions.py | 2 ++ gemd/entity/object/has_material.py | 2 ++ gemd/entity/object/has_parameters.py | 2 ++ gemd/entity/object/has_process.py | 2 ++ gemd/entity/object/has_properties.py | 2 ++ gemd/entity/object/has_quantities.py | 2 ++ gemd/entity/object/has_source.py | 2 ++ gemd/entity/object/has_spec.py | 2 ++ gemd/entity/object/has_template.py | 2 ++ .../object/has_template_check_generator.py | 2 ++ gemd/entity/object/ingredient_run.py | 2 ++ gemd/entity/object/ingredient_spec.py | 2 ++ gemd/entity/object/material_run.py | 2 ++ gemd/entity/object/material_spec.py | 2 ++ gemd/entity/object/measurement_run.py | 2 ++ gemd/entity/object/measurement_spec.py | 2 ++ gemd/entity/object/process_run.py | 2 ++ gemd/entity/object/process_spec.py | 2 ++ gemd/entity/setters.py | 2 ++ gemd/entity/source/performed_source.py | 2 ++ gemd/entity/template/attribute_template.py | 2 ++ gemd/entity/template/base_template.py | 2 ++ gemd/entity/template/condition_template.py | 2 ++ .../template/has_condition_templates.py | 2 ++ .../template/has_parameter_templates.py | 2 ++ .../entity/template/has_property_templates.py | 2 ++ gemd/entity/template/material_template.py | 2 ++ gemd/entity/template/measurement_template.py | 2 ++ gemd/entity/template/parameter_template.py | 4 ++- gemd/entity/template/process_template.py | 2 ++ gemd/entity/template/property_template.py | 2 ++ gemd/entity/util.py | 2 ++ gemd/entity/valid_list.py | 2 ++ gemd/entity/value/base_value.py | 2 ++ gemd/entity/value/categorical_value.py | 2 ++ gemd/entity/value/composition_value.py | 2 ++ gemd/entity/value/continuous_value.py | 2 ++ gemd/entity/value/discrete_categorical.py | 2 ++ gemd/entity/value/empirical_formula.py | 2 ++ gemd/entity/value/inchi_value.py | 2 ++ gemd/entity/value/integer_value.py | 2 ++ gemd/entity/value/molecular_value.py | 2 ++ gemd/entity/value/nominal_categorical.py | 2 ++ gemd/entity/value/nominal_composition.py | 2 ++ gemd/entity/value/nominal_integer.py | 2 ++ gemd/entity/value/nominal_real.py | 2 ++ gemd/entity/value/normal_real.py | 2 ++ gemd/entity/value/smiles_value.py | 2 ++ gemd/entity/value/uniform_integer.py | 2 ++ gemd/entity/value/uniform_real.py | 2 ++ gemd/enumeration/__init__.py | 1 + gemd/enumeration/base_enumeration.py | 23 ++++++++--------- gemd/enumeration/origin.py | 2 ++ gemd/enumeration/sample_type.py | 2 ++ gemd/json/__init__.py | 5 ++++ gemd/json/gemd_encoder.py | 2 ++ gemd/json/gemd_json.py | 4 ++- gemd/units/__init__.py | 6 +++-- gemd/units/impl.py | 5 ++++ scripts/build_docs.sh | 0 scripts/run_tests.sh | 2 +- scripts/validate_version_bump.py | 2 +- setup.py | 10 ++++++-- 95 files changed, 246 insertions(+), 51 deletions(-) create mode 100644 docs/source/_static/favicon.png create mode 100644 docs/source/_static/logo.png delete mode 100644 docs/source/depth/index.rst delete mode 100644 docs/source/modules.rst delete mode 100644 docs/source/setup.rst create mode 100644 gemd/__version__.py mode change 100644 => 100755 scripts/build_docs.sh diff --git a/docs/source/_static/favicon.png b/docs/source/_static/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..62a362ea784cad11326b407a74d4ecc10d2b6e0b GIT binary patch literal 2206 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 literal 0 HcmV?d00001 diff --git a/docs/source/conf.py b/docs/source/conf.py index a6c8a9f9..4f47493c 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 --------------------------------------------------- @@ -45,6 +48,7 @@ apidoc_output_dir = 'reference' apidoc_excluded_paths = ['tests'] 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,13 @@ # 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 +} + +suppress_warnings = [ + 'ref' +] 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..ef2349d8 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/stable/ .. _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..44bd22f8 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:: + + pip install gemd + +or a specific version can be installed, for example: + +.. code:: + + pip install gemd==1.0.0 + Table of Contents ----------------- @@ -18,7 +35,8 @@ Table of Contents :maxdepth: 2 :numbered: 4 - depth/index + depth/unit_parsing + depth/serialization Indices and tables ------------------ 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..c7bbe496 --- /dev/null +++ b/gemd/__version__.py @@ -0,0 +1 @@ +__version__ = "1.17.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..d0b66728 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, *, 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/condition.py b/gemd/entity/attribute/condition.py index 90315d1b..e0dfc8ac 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"): """ diff --git a/gemd/entity/attribute/parameter.py b/gemd/entity/attribute/parameter.py index 5d8615e3..0a558b66 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"): """ diff --git a/gemd/entity/attribute/property.py b/gemd/entity/attribute/property.py index 6528fc92..a099596d 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"): """ diff --git a/gemd/entity/attribute/property_and_conditions.py b/gemd/entity/attribute/property_and_conditions.py index 192d5af9..3960c047 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"): """ diff --git a/gemd/entity/base_entity.py b/gemd/entity/base_entity.py index c1d72289..967e86f3 100644 --- a/gemd/entity/base_entity.py +++ b/gemd/entity/base_entity.py @@ -6,6 +6,8 @@ from gemd.entity.case_insensitive_dict import CaseInsensitiveDict from gemd.entity.setters import validate_list +__all__ = ["BaseEntity"] + class BaseEntity(DictSerializable): """ diff --git a/gemd/entity/bounds/base_bounds.py b/gemd/entity/bounds/base_bounds.py index fb6b4236..68f7535f 100644 --- a/gemd/entity/bounds/base_bounds.py +++ b/gemd/entity/bounds/base_bounds.py @@ -4,6 +4,8 @@ from gemd.entity.dict_serializable import DictSerializable +__all__ = ["BaseBounds"] + class BaseBounds(DictSerializable): """Base class for bounds, including RealBounds and CategoricalBounds.""" diff --git a/gemd/entity/bounds/categorical_bounds.py b/gemd/entity/bounds/categorical_bounds.py index bad59205..b9884876 100644 --- a/gemd/entity/bounds/categorical_bounds.py +++ b/gemd/entity/bounds/categorical_bounds.py @@ -4,6 +4,8 @@ from typing import Union, Set, Optional, Iterable +__all__ = ["CategoricalBounds"] + class CategoricalBounds(BaseBounds, typ="categorical_bounds"): """ diff --git a/gemd/entity/bounds/composition_bounds.py b/gemd/entity/bounds/composition_bounds.py index db399d5c..6ed37169 100644 --- a/gemd/entity/bounds/composition_bounds.py +++ b/gemd/entity/bounds/composition_bounds.py @@ -4,6 +4,8 @@ from typing import Union +__all__ = ["CompositionBounds"] + class CompositionBounds(BaseBounds, typ="composition_bounds"): """ diff --git a/gemd/entity/bounds/integer_bounds.py b/gemd/entity/bounds/integer_bounds.py index 7c8f0ef3..61fde3f7 100644 --- a/gemd/entity/bounds/integer_bounds.py +++ b/gemd/entity/bounds/integer_bounds.py @@ -3,6 +3,8 @@ from typing import Union +__all__ = ["IntegerBounds"] + class IntegerBounds(BaseBounds, typ="integer_bounds"): """ diff --git a/gemd/entity/bounds/molecular_structure_bounds.py b/gemd/entity/bounds/molecular_structure_bounds.py index de08b369..dd1eb451 100644 --- a/gemd/entity/bounds/molecular_structure_bounds.py +++ b/gemd/entity/bounds/molecular_structure_bounds.py @@ -7,6 +7,8 @@ from typing import Union +__all__ = ["MolecularStructureBounds"] + class MolecularStructureBounds(BaseBounds, typ="molecular_structure_bounds"): """Molecular bounds, with no component or substructural restrictions (yet).""" diff --git a/gemd/entity/bounds/real_bounds.py b/gemd/entity/bounds/real_bounds.py index c49c9455..8d6a2531 100644 --- a/gemd/entity/bounds/real_bounds.py +++ b/gemd/entity/bounds/real_bounds.py @@ -4,6 +4,8 @@ from typing import Union +__all__ = ["RealBounds"] + class RealBounds(BaseBounds, typ="real_bounds"): """ 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..71740dd7 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__) 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..2362d651 100644 --- a/gemd/entity/has_dependencies.py +++ b/gemd/entity/has_dependencies.py @@ -2,6 +2,8 @@ from abc import ABC, abstractmethod from typing import Union, Set +__all__ = ["HasDependencies"] + class HasDependencies(ABC): """Mix-in trait for objects that reference other objects.""" diff --git a/gemd/entity/link_by_uid.py b/gemd/entity/link_by_uid.py index bec0b045..b532e077 100644 --- a/gemd/entity/link_by_uid.py +++ b/gemd/entity/link_by_uid.py @@ -4,6 +4,8 @@ from gemd.entity.dict_serializable import DictSerializable +__all__ = ["LinkByUID"] + class LinkByUID(DictSerializable, typ="link_by_uid"): """ diff --git a/gemd/entity/object/base_object.py b/gemd/entity/object/base_object.py index 4020e12e..59499415 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): """ diff --git a/gemd/entity/object/has_conditions.py b/gemd/entity/object/has_conditions.py index e0287407..dc41ebed 100644 --- a/gemd/entity/object/has_conditions.py +++ b/gemd/entity/object/has_conditions.py @@ -8,6 +8,8 @@ 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. diff --git a/gemd/entity/object/has_material.py b/gemd/entity/object/has_material.py index 7a9d5f5b..a170dd89 100644 --- a/gemd/entity/object/has_material.py +++ b/gemd/entity/object/has_material.py @@ -6,6 +6,8 @@ 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.""" diff --git a/gemd/entity/object/has_parameters.py b/gemd/entity/object/has_parameters.py index 28a18e67..830bf2f1 100644 --- a/gemd/entity/object/has_parameters.py +++ b/gemd/entity/object/has_parameters.py @@ -8,6 +8,8 @@ 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. diff --git a/gemd/entity/object/has_process.py b/gemd/entity/object/has_process.py index d26b05d8..80147430 100644 --- a/gemd/entity/object/has_process.py +++ b/gemd/entity/object/has_process.py @@ -6,6 +6,8 @@ from abc import abstractmethod from typing import Union, Set +__all__ = ["HasProcess"] + class HasProcess(HasDependencies): """Mix-in trait for objects that can be assigned materials.""" diff --git a/gemd/entity/object/has_properties.py b/gemd/entity/object/has_properties.py index d247db9e..d773a55a 100644 --- a/gemd/entity/object/has_properties.py +++ b/gemd/entity/object/has_properties.py @@ -8,6 +8,8 @@ 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. diff --git a/gemd/entity/object/has_quantities.py b/gemd/entity/object/has_quantities.py index bc7ea8ff..e6d68ee9 100644 --- a/gemd/entity/object/has_quantities.py +++ b/gemd/entity/object/has_quantities.py @@ -7,6 +7,8 @@ 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. diff --git a/gemd/entity/object/has_source.py b/gemd/entity/object/has_source.py index a4b04bb1..2238caf5 100644 --- a/gemd/entity/object/has_source.py +++ b/gemd/entity/object/has_source.py @@ -1,6 +1,8 @@ """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). diff --git a/gemd/entity/object/has_spec.py b/gemd/entity/object/has_spec.py index d91ca213..475666f0 100644 --- a/gemd/entity/object/has_spec.py +++ b/gemd/entity/object/has_spec.py @@ -7,6 +7,8 @@ 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. diff --git a/gemd/entity/object/has_template.py b/gemd/entity/object/has_template.py index c968f9fa..0441d883 100644 --- a/gemd/entity/object/has_template.py +++ b/gemd/entity/object/has_template.py @@ -6,6 +6,8 @@ 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. diff --git a/gemd/entity/object/has_template_check_generator.py b/gemd/entity/object/has_template_check_generator.py index 6fa49dee..592b6478 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') diff --git a/gemd/entity/object/ingredient_run.py b/gemd/entity/object/ingredient_run.py index ad53ffc9..7904df5e 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, diff --git a/gemd/entity/object/ingredient_spec.py b/gemd/entity/object/ingredient_spec.py index 614b6370..19dca755 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, diff --git a/gemd/entity/object/material_run.py b/gemd/entity/object/material_run.py index 5d4a5348..c71e0baa 100644 --- a/gemd/entity/object/material_run.py +++ b/gemd/entity/object/material_run.py @@ -10,6 +10,8 @@ from typing import Optional, Union, Iterable, List, Mapping, Type, Any +__all__ = ["MaterialRun"] + class MaterialRun(BaseObject, HasSpec, HasProcess, typ="material_run", skip={"_measurements"}): """ diff --git a/gemd/entity/object/material_spec.py b/gemd/entity/object/material_spec.py index c676a7a0..113fdcc2 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"): """ diff --git a/gemd/entity/object/measurement_run.py b/gemd/entity/object/measurement_run.py index cb10ee8a..aae30506 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"): diff --git a/gemd/entity/object/measurement_spec.py b/gemd/entity/object/measurement_spec.py index d8637e22..b795bfcc 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, diff --git a/gemd/entity/object/process_run.py b/gemd/entity/object/process_run.py index eb72cfca..03b0a8fc 100644 --- a/gemd/entity/object/process_run.py +++ b/gemd/entity/object/process_run.py @@ -13,6 +13,8 @@ from typing import Optional, Union, Iterable, List, Mapping, Dict, Type, Any +__all__ = ["ProcessRun"] + class ProcessRun(BaseObject, HasSpec, HasConditions, HasParameters, HasSource, diff --git a/gemd/entity/object/process_spec.py b/gemd/entity/object/process_spec.py index ac5039ac..2dd67c0a 100644 --- a/gemd/entity/object/process_spec.py +++ b/gemd/entity/object/process_spec.py @@ -11,6 +11,8 @@ from typing import Optional, Union, Iterable, List, Mapping, Dict, Type, Any +__all__ = ["ProcessSpec"] + class ProcessSpec(BaseObject, HasTemplate, HasParameters, HasConditions, 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..2e66404b 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): """ 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..c20b0fd1 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. diff --git a/gemd/entity/template/has_condition_templates.py b/gemd/entity/template/has_condition_templates.py index 927b6795..5edf5e18 100644 --- a/gemd/entity/template/has_condition_templates.py +++ b/gemd/entity/template/has_condition_templates.py @@ -8,6 +8,8 @@ from typing import Optional, Union, Iterable, List, Tuple, Set +__all__ = ["HasConditionTemplates"] + class HasConditionTemplates(HasDependencies): """ diff --git a/gemd/entity/template/has_parameter_templates.py b/gemd/entity/template/has_parameter_templates.py index 29288b41..fbfc8071 100644 --- a/gemd/entity/template/has_parameter_templates.py +++ b/gemd/entity/template/has_parameter_templates.py @@ -8,6 +8,8 @@ from typing import Optional, Union, Iterable, List, Tuple, Set +__all__ = ["HasParameterTemplates"] + class HasParameterTemplates(HasDependencies): """ diff --git a/gemd/entity/template/has_property_templates.py b/gemd/entity/template/has_property_templates.py index 5cb6810e..32a58cc6 100644 --- a/gemd/entity/template/has_property_templates.py +++ b/gemd/entity/template/has_property_templates.py @@ -8,6 +8,8 @@ from typing import Optional, Union, Iterable, List, Set, Tuple +__all__ = ["HasPropertyTemplates"] + class HasPropertyTemplates(HasDependencies): """ diff --git a/gemd/entity/template/material_template.py b/gemd/entity/template/material_template.py index b2ceb078..728d3e7e 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"): """ diff --git a/gemd/entity/template/measurement_template.py b/gemd/entity/template/measurement_template.py index bd8b6838..a8402055 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, diff --git a/gemd/entity/template/parameter_template.py b/gemd/entity/template/parameter_template.py index c8e8c4ce..c7bc43cc 100644 --- a/gemd/entity/template/parameter_template.py +++ b/gemd/entity/template/parameter_template.py @@ -1,10 +1,12 @@ 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. diff --git a/gemd/entity/template/process_template.py b/gemd/entity/template/process_template.py index 307266f8..e6260c5c 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, diff --git a/gemd/entity/template/property_template.py b/gemd/entity/template/property_template.py index f0608333..e2640f77 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. diff --git a/gemd/entity/util.py b/gemd/entity/util.py index 23592495..1d189348 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): """ 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..d47a9d67 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): """ diff --git a/gemd/entity/value/categorical_value.py b/gemd/entity/value/categorical_value.py index 29d8cf90..888b4468 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): """ diff --git a/gemd/entity/value/composition_value.py b/gemd/entity/value/composition_value.py index de63835b..e83d64de 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.""" diff --git a/gemd/entity/value/continuous_value.py b/gemd/entity/value/continuous_value.py index bc074ee9..6452daac 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): """ diff --git a/gemd/entity/value/discrete_categorical.py b/gemd/entity/value/discrete_categorical.py index b1f5e4f9..e8559db9 100644 --- a/gemd/entity/value/discrete_categorical.py +++ b/gemd/entity/value/discrete_categorical.py @@ -3,6 +3,8 @@ from gemd.entity.value.categorical_value import CategoricalValue from gemd.entity.bounds import CategoricalBounds +__all__ = ["DiscreteCategorical"] + class DiscreteCategorical(CategoricalValue, typ="discrete_categorical"): """ diff --git a/gemd/entity/value/empirical_formula.py b/gemd/entity/value/empirical_formula.py index 4701b511..7a0b1949 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', diff --git a/gemd/entity/value/inchi_value.py b/gemd/entity/value/inchi_value.py index 1e8d0ed6..36746130 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"): """ diff --git a/gemd/entity/value/integer_value.py b/gemd/entity/value/integer_value.py index edac729a..242b5980 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.""" diff --git a/gemd/entity/value/molecular_value.py b/gemd/entity/value/molecular_value.py index a3e8d6cd..00c65c06 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.""" diff --git a/gemd/entity/value/nominal_categorical.py b/gemd/entity/value/nominal_categorical.py index 6c6c9c98..91b5a333 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"): """ diff --git a/gemd/entity/value/nominal_composition.py b/gemd/entity/value/nominal_composition.py index a02233cb..833d554b 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"): """ diff --git a/gemd/entity/value/nominal_integer.py b/gemd/entity/value/nominal_integer.py index 94f090ea..48d645b5 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"): """ diff --git a/gemd/entity/value/nominal_real.py b/gemd/entity/value/nominal_real.py index 7eeb7608..9cd0016b 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"): """ diff --git a/gemd/entity/value/normal_real.py b/gemd/entity/value/normal_real.py index 57915226..e3ab0fbc 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"): """ diff --git a/gemd/entity/value/smiles_value.py b/gemd/entity/value/smiles_value.py index e871f77f..b7972d29 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"): """ diff --git a/gemd/entity/value/uniform_integer.py b/gemd/entity/value/uniform_integer.py index 4cc47f67..2b43f61d 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"): """ diff --git a/gemd/entity/value/uniform_real.py b/gemd/entity/value/uniform_real.py index eca0b004..74c0e3c6 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"): """ 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..3282c3a3 100644 --- a/gemd/json/__init__.py +++ b/gemd/json/__init__.py @@ -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..b0ecbba0 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.""" 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 ae5cc13d..c123aea4 100644 --- a/setup.py +++ b/setup.py @@ -1,10 +1,16 @@ from setuptools import setup, find_packages +from os import path packages = find_packages() -packages.append("") + +this_directory = path.abspath(path.dirname(__file__)) +about = {} +with open(path.join(this_directory, 'gemd', '__version__.py'), 'r') as f: + exec(f.read(), about) setup(name='gemd', - version='1.17.0', + # Update this in gemd/__version__.py + version=about['__version__'], python_requires='>=3.8', url='http://github.com/CitrineInformatics/gemd-python', description="Python binding for Citrine's GEMD data model", From 15c174abe5f9f010b0399f8824918540b57b877f Mon Sep 17 00:00:00 2001 From: Ken Kroenlein Date: Tue, 9 Jan 2024 14:34:48 -0700 Subject: [PATCH 2/9] PR feedback --- docs/source/conf.py | 14 ++++++++++++-- docs/source/depth/unit_parsing.rst | 2 +- docs/source/index.rst | 6 +++--- gemd/__version__.py | 2 +- 4 files changed, 17 insertions(+), 7 deletions(-) diff --git a/docs/source/conf.py b/docs/source/conf.py index 4f47493c..c5b30085 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -47,7 +47,7 @@ apidoc_module_dir = '../../gemd' apidoc_output_dir = 'reference' apidoc_excluded_paths = ['tests'] -apidoc_separate_modules = True +apidoc_separate_modules = False apidoc_toc_file = False # Add any paths that contain templates here, relative to this directory. @@ -88,5 +88,15 @@ } suppress_warnings = [ - 'ref' + # 'app', + # 'autosectionlabel', + # 'download', + # 'epub', + # 'i18n', + # 'index', + # 'image', + # 'ref', + 'ref.python' + # 'misc', + # 'toc' ] diff --git a/docs/source/depth/unit_parsing.rst b/docs/source/depth/unit_parsing.rst index ef2349d8..d7430b3c 100644 --- a/docs/source/depth/unit_parsing.rst +++ b/docs/source/depth/unit_parsing.rst @@ -14,6 +14,6 @@ as originally reported, thus creating a potential source of error during the inp 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/stable/ +.. _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 44bd22f8..11fb9536 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -18,15 +18,15 @@ Installation The latest release can be installed via `pip`: -.. code:: +.. code:: bash pip install gemd or a specific version can be installed, for example: -.. code:: +.. code:: bash - pip install gemd==1.0.0 + pip install gemd==1.17.1 Table of Contents ----------------- diff --git a/gemd/__version__.py b/gemd/__version__.py index c7bbe496..0daeee7b 100644 --- a/gemd/__version__.py +++ b/gemd/__version__.py @@ -1 +1 @@ -__version__ = "1.17.1" +__version__ = "1.17.2" From 5d784c0ad86cce3e8ca1a3a07407bf716a2442e2 Mon Sep 17 00:00:00 2001 From: Ken Kroenlein Date: Tue, 9 Jan 2024 14:35:45 -0700 Subject: [PATCH 3/9] Comment cleanup --- docs/source/conf.py | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/docs/source/conf.py b/docs/source/conf.py index c5b30085..5cf34502 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -88,15 +88,5 @@ } suppress_warnings = [ - # 'app', - # 'autosectionlabel', - # 'download', - # 'epub', - # 'i18n', - # 'index', - # 'image', - # 'ref', - 'ref.python' - # 'misc', - # 'toc' + 'ref.python' ] From ee46e55cdd6e2e9e383af69cf953bf0b5aee554d Mon Sep 17 00:00:00 2001 From: Ken Kroenlein Date: Tue, 16 Jan 2024 16:49:16 -0700 Subject: [PATCH 4/9] Make documentation referencing consistent --- docs/source/conf.py | 6 +- docs/source/index.rst | 7 +- gemd/builders/impl.py | 107 +++++++++++------- gemd/entity/attribute/base_attribute.py | 23 ++-- gemd/entity/attribute/condition.py | 7 +- gemd/entity/attribute/parameter.py | 7 +- gemd/entity/attribute/property.py | 7 +- .../attribute/property_and_conditions.py | 4 +- gemd/entity/base_entity.py | 38 +++---- gemd/entity/bounds/categorical_bounds.py | 7 +- gemd/entity/bounds/composition_bounds.py | 11 +- gemd/entity/bounds/integer_bounds.py | 19 +++- .../bounds/molecular_structure_bounds.py | 6 +- gemd/entity/bounds/real_bounds.py | 11 +- gemd/entity/object/base_object.py | 7 +- gemd/entity/object/has_conditions.py | 11 +- gemd/entity/object/has_parameters.py | 11 +- gemd/entity/object/has_properties.py | 11 +- gemd/entity/object/has_quantities.py | 27 +---- gemd/entity/object/has_source.py | 12 +- gemd/entity/object/has_spec.py | 11 +- gemd/entity/object/has_template.py | 11 +- .../object/has_template_check_generator.py | 4 +- gemd/entity/object/ingredient_run.py | 20 ++-- gemd/entity/object/ingredient_spec.py | 18 ++- gemd/entity/object/material_run.py | 20 ++-- gemd/entity/object/material_spec.py | 11 +- gemd/entity/object/measurement_run.py | 17 ++- gemd/entity/object/measurement_spec.py | 9 +- gemd/entity/object/process_run.py | 35 +++--- gemd/entity/object/process_spec.py | 34 +++--- gemd/entity/template/attribute_template.py | 9 +- gemd/entity/template/condition_template.py | 2 +- .../template/has_condition_templates.py | 8 +- .../template/has_parameter_templates.py | 8 +- .../entity/template/has_property_templates.py | 8 +- gemd/entity/template/material_template.py | 7 +- gemd/entity/template/measurement_template.py | 21 ++-- gemd/entity/template/parameter_template.py | 2 +- gemd/entity/template/process_template.py | 14 +-- gemd/entity/template/property_template.py | 2 +- gemd/entity/util.py | 2 +- gemd/entity/value/base_value.py | 4 +- gemd/entity/value/categorical_value.py | 2 +- gemd/entity/value/composition_value.py | 2 +- gemd/entity/value/continuous_value.py | 3 +- gemd/entity/value/discrete_categorical.py | 11 +- gemd/entity/value/empirical_formula.py | 2 +- gemd/entity/value/inchi_value.py | 3 +- gemd/entity/value/integer_value.py | 2 +- gemd/entity/value/molecular_value.py | 3 +- gemd/entity/value/nominal_categorical.py | 2 +- gemd/entity/value/nominal_composition.py | 2 +- gemd/entity/value/nominal_integer.py | 2 +- gemd/entity/value/nominal_real.py | 2 +- gemd/entity/value/normal_real.py | 2 +- gemd/entity/value/smiles_value.py | 3 +- gemd/entity/value/uniform_integer.py | 2 +- gemd/entity/value/uniform_real.py | 2 +- gemd/json/__init__.py | 4 +- gemd/units/impl.py | 8 +- 61 files changed, 318 insertions(+), 355 deletions(-) diff --git a/docs/source/conf.py b/docs/source/conf.py index 5cf34502..0779b6cf 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -47,7 +47,7 @@ apidoc_module_dir = '../../gemd' apidoc_output_dir = 'reference' apidoc_excluded_paths = ['tests'] -apidoc_separate_modules = False +apidoc_separate_modules = True apidoc_toc_file = False # Add any paths that contain templates here, relative to this directory. @@ -86,7 +86,3 @@ 'sticky_navigation': False, 'logo_only': True } - -suppress_warnings = [ - 'ref.python' -] diff --git a/docs/source/index.rst b/docs/source/index.rst index 11fb9536..a49d07df 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -38,9 +38,14 @@ Table of Contents depth/unit_parsing depth/serialization -Indices and tables +Indices ------------------ * :ref:`genindex` * :ref:`modindex` * :ref:`search` + +.. toctree:: + :maxdepth: 1 + + reference/gemd diff --git a/gemd/builders/impl.py b/gemd/builders/impl.py index d0b66728..2ad855c1 100644 --- a/gemd/builders/impl.py +++ b/gemd/builders/impl.py @@ -34,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: @@ -94,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 @@ -175,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: @@ -230,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. + The :attr:`~BaseAttribute.template` 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.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 -------- @@ -276,9 +305,9 @@ def make_attribute(template: Union[PropertyTemplate, ConditionTemplate, Paramete Parameters ---------- template: AttributeTemplate - The AttributeTemplate for the attribute. + The :attr:`~BaseAttribute.template` for the attribute. value: Union[BaseValue, str, float, int] - The value for the attribute. Accepts any GEMD Value type, or will + 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 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 e0dfc8ac..b46926dd 100644 --- a/gemd/entity/attribute/condition.py +++ b/gemd/entity/attribute/condition.py @@ -19,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: :class:`~gemd.entity.value.base_value.BaseValue` The value of the attribute. - template: :class:`AttributeTemplate \ - ` + template: :class:`~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 0a558b66..4e21fc59 100644 --- a/gemd/entity/attribute/parameter.py +++ b/gemd/entity/attribute/parameter.py @@ -20,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: :class:`~gemd.entity.value.base_value.BaseValue` The value of the attribute. - template: :class:`AttributeTemplate \ - ` + template: :class:`~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[:class:`~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 a099596d..982fe635 100644 --- a/gemd/entity/attribute/property.py +++ b/gemd/entity/attribute/property.py @@ -19,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: :class:`~gemd.entity.value.base_value.BaseValue` The value of the attribute. - template: :class:`AttributeTemplate \ - ` + template: :class:`~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[:class:`~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 3960c047..d9c0b603 100644 --- a/gemd/entity/attribute/property_and_conditions.py +++ b/gemd/entity/attribute/property_and_conditions.py @@ -19,9 +19,9 @@ class PropertyAndConditions(DictSerializable, typ="property_and_conditions"): Parameters ---------- - property: :class:`Property ` + property: :class:`~gemd.entity.attribute.property.Property` A property attribute - conditions: List[:class:`Condition `] + conditions: List[:class:`~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 967e86f3..c6eb1dcd 100644 --- a/gemd/entity/base_entity.py +++ b/gemd/entity/base_entity.py @@ -10,21 +10,7 @@ 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. - - """ + """Base class for any entity, which includes objects and templates.""" def __init__(self, uids: Mapping[str, str], tags: Iterable[str]): self._tags = None @@ -35,20 +21,34 @@ 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.""" + """ + 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]): + """Set the uids.""" if uids is None: self._uids = CaseInsensitiveDict() elif isinstance(uids, Mapping): @@ -75,7 +75,7 @@ def to_link(self, *, allow_fallback: bool = False) -> 'LinkByUID': # noqa: F821 """ - Generate a LinkByUID for this object. + Generate a ~gemd.entity.link_by_uid.LinkByUID for this object. Parameters ---------- @@ -86,7 +86,7 @@ def to_link(self, Returns ------- - LinkByUID + ~gemd.entity.link_by_uid.LinkByUID """ from gemd.entity.link_by_uid import LinkByUID diff --git a/gemd/entity/bounds/categorical_bounds.py b/gemd/entity/bounds/categorical_bounds.py index b9884876..0d8af7a1 100644 --- a/gemd/entity/bounds/categorical_bounds.py +++ b/gemd/entity/bounds/categorical_bounds.py @@ -1,4 +1,3 @@ -"""A restricted set of categories.""" from gemd.entity.bounds.base_bounds import BaseBounds from gemd.entity.util import array_like @@ -24,7 +23,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 @@ -80,7 +79,7 @@ def union(self, Parameters ---------- - others: Union[CategoricalBounds, CategoricalValue] + others: Union[CategoricalBounds, ~gemd.value.categorical_value.CategoricalValue] Other bounds or value objects to include. Returns @@ -112,7 +111,7 @@ def update(self, *others: Union["CategoricalBounds", "CategoricalValue"]): # no Parameters ---------- - others: Union[CategoricalBounds, CategoricalValue] + others: Union[CategoricalBounds, ~gemd.entity.value.categorical_value.CategoricalValue] Other bounds or value objects to include. """ diff --git a/gemd/entity/bounds/composition_bounds.py b/gemd/entity/bounds/composition_bounds.py index 6ed37169..f3862a64 100644 --- a/gemd/entity/bounds/composition_bounds.py +++ b/gemd/entity/bounds/composition_bounds.py @@ -24,11 +24,12 @@ def __init__(self, components=None): @property def components(self): - """Get the allowed components.""" + """Get the collection of the components that are allowed in the composition.""" return self._components @components.setter def components(self, value): + """Set collection of the components that are allowed in the composition.""" if value is None: self._components = set() elif isinstance(value, array_like()): @@ -80,12 +81,12 @@ def union(self, Parameters ---------- - others: Union[CompositionBounds, CompositionValue] + others: Union[CompositionBounds, , ~gemd.entity.value.compositional_value.CompositionValue] Other bounds or value objects to include. Returns ------- - CategoricalBounds + CompositionBounds The union of this bounds and the passed bounds """ @@ -108,11 +109,11 @@ def update(self, *others: Union["CompositionBounds", "CompositionValue"]): # no """ 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] + others: Union[CompositionBounds, ~gemd.entity.value.compositional_value.CompositionValue] Other bounds or value objects to include. """ diff --git a/gemd/entity/bounds/integer_bounds.py b/gemd/entity/bounds/integer_bounds.py index 693910cb..e8cc7763 100644 --- a/gemd/entity/bounds/integer_bounds.py +++ b/gemd/entity/bounds/integer_bounds.py @@ -6,11 +6,18 @@ __all__ = ["IntegerBounds"] -__all__ = ["IntegerBounds"] - 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 @@ -88,7 +95,7 @@ def union(self, Parameters ---------- - others: Union[IntegerBounds, IntegerValue] + others: Union[IntegerBounds, ~gemd.entity.value.integer_value.IntegerValue] Other bounds or value objects to include. Returns @@ -119,11 +126,11 @@ def update(self, *others: Union["IntegerBounds", "IntegerValue"]): # noqa: F821 """ 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] + others: Union[IntegerBounds, ~gemd.entity.value.integer_value.IntegerValue] Other bounds or value objects to include. """ diff --git a/gemd/entity/bounds/molecular_structure_bounds.py b/gemd/entity/bounds/molecular_structure_bounds.py index dd1eb451..1929c230 100644 --- a/gemd/entity/bounds/molecular_structure_bounds.py +++ b/gemd/entity/bounds/molecular_structure_bounds.py @@ -52,12 +52,12 @@ def union(self, Parameters ---------- - others: Union[MolecularStructureBounds, MolecularValue] + others: Union[MolecularStructureBounds, ~gemd.entity.value.molecular_value.MolecularValue] Other bounds or value objects to include. Returns ------- - CategoricalBounds + MolecularStructureBounds The union of this bounds and the passed bounds """ @@ -79,7 +79,7 @@ def update(self, *others: Union["MolecularStructureBounds", "MolecularValue"]): Parameters ---------- - others: Union[MolecularStructureBounds, MolecularValue] + others: Union[MolecularStructureBounds, ~gemd.entity.value.molecular_value.MolecularValue] Other bounds or value objects to include. """ diff --git a/gemd/entity/bounds/real_bounds.py b/gemd/entity/bounds/real_bounds.py index 7b66bd2a..f62dee73 100644 --- a/gemd/entity/bounds/real_bounds.py +++ b/gemd/entity/bounds/real_bounds.py @@ -9,7 +9,16 @@ 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 diff --git a/gemd/entity/object/base_object.py b/gemd/entity/object/base_object.py index 59499415..6078e83c 100644 --- a/gemd/entity/object/base_object.py +++ b/gemd/entity/object/base_object.py @@ -29,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. """ @@ -63,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 dc41ebed..d0e38f54 100644 --- a/gemd/entity/object/has_conditions.py +++ b/gemd/entity/object/has_conditions.py @@ -12,14 +12,7 @@ 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. - - """ + """Mixin-trait for entities that include conditions.""" def __init__(self, conditions: Union[Condition, Iterable[Condition]]): self._conditions = None @@ -27,7 +20,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 diff --git a/gemd/entity/object/has_parameters.py b/gemd/entity/object/has_parameters.py index 830bf2f1..3c52caf6 100644 --- a/gemd/entity/object/has_parameters.py +++ b/gemd/entity/object/has_parameters.py @@ -12,14 +12,7 @@ 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. - - """ + """Mixin-trait for entities that include parameters.""" def __init__(self, parameters: Union[Parameter, Iterable[Parameter]]): self._parameters = None @@ -27,7 +20,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 diff --git a/gemd/entity/object/has_properties.py b/gemd/entity/object/has_properties.py index d773a55a..e700d86a 100644 --- a/gemd/entity/object/has_properties.py +++ b/gemd/entity/object/has_properties.py @@ -12,14 +12,7 @@ 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 - - """ + """Mixin-trait for entities that include properties.""" def __init__(self, properties: Union[Property, Iterable[Property]]): self._properties = None @@ -27,7 +20,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 diff --git a/gemd/entity/object/has_quantities.py b/gemd/entity/object/has_quantities.py index e6d68ee9..5c366eb3 100644 --- a/gemd/entity/object/has_quantities.py +++ b/gemd/entity/object/has_quantities.py @@ -11,24 +11,7 @@ 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, @@ -62,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 @@ -77,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 @@ -92,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 @@ -107,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 2238caf5..f14dcc5c 100644 --- a/gemd/entity/object/has_source.py +++ b/gemd/entity/object/has_source.py @@ -5,15 +5,7 @@ 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. - - """ + """Mixin-trait for entities that include sources (data provenance).""" def __init__(self, source: PerformedSource): self._source = None @@ -21,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 475666f0..9c67739e 100644 --- a/gemd/entity/object/has_spec.py +++ b/gemd/entity/object/has_spec.py @@ -11,14 +11,7 @@ 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. - - """ + """Mix-in trait for objects that can be assigned specs.""" def __init__(self, spec: Union[HasTemplate, LinkByUID] = None): self._spec = None @@ -26,7 +19,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 diff --git a/gemd/entity/object/has_template.py b/gemd/entity/object/has_template.py index 0441d883..b9c911fe 100644 --- a/gemd/entity/object/has_template.py +++ b/gemd/entity/object/has_template.py @@ -10,14 +10,7 @@ class HasTemplate(HasDependencies): - """Mix-in trait for objects that can be assigned templates. - - Parameters - ---------- - template: :class:`BaseTemplate ` - A template that defines the allowed values. - - """ + """Mix-in trait for objects that can be assigned templates.""" def __init__(self, template: Optional[Union[BaseTemplate, LinkByUID]] = None): self._template = None @@ -30,7 +23,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 diff --git a/gemd/entity/object/has_template_check_generator.py b/gemd/entity/object/has_template_check_generator.py index 592b6478..23b936ba 100644 --- a/gemd/entity/object/has_template_check_generator.py +++ b/gemd/entity/object/has_template_check_generator.py @@ -32,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 7904df5e..4be4a690 100644 --- a/gemd/entity/object/ingredient_run.py +++ b/gemd/entity/object/ingredient_run.py @@ -37,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 19dca755..dde003a1 100644 --- a/gemd/entity/object/ingredient_spec.py +++ b/gemd/entity/object/ingredient_spec.py @@ -37,25 +37,21 @@ class IngredientSpec(BaseObject, for filtering and discoverability. notes: str, optional Long-form notes about the ingredient spec. - material: :class:`MaterialSpec ` + material: :class:`~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 c71e0baa..491f431f 100644 --- a/gemd/entity/object/material_run.py +++ b/gemd/entity/object/material_run.py @@ -33,23 +33,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: :class:`~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, @@ -94,7 +87,12 @@ def process(self, process: Union[ProcessRun, LinkByUID]): @property def measurements(self) -> List["MeasurementRun"]: # noqa: F821 - """Get a read-only list of the measurement runs.""" + """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 113fdcc2..3410028e 100644 --- a/gemd/entity/object/material_spec.py +++ b/gemd/entity/object/material_spec.py @@ -36,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 aae30506..60e42302 100644 --- a/gemd/entity/object/measurement_run.py +++ b/gemd/entity/object/measurement_run.py @@ -41,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 b795bfcc..6997002d 100644 --- a/gemd/entity/object/measurement_spec.py +++ b/gemd/entity/object/measurement_spec.py @@ -36,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 03b0a8fc..da1ed358 100644 --- a/gemd/entity/object/process_run.py +++ b/gemd/entity/object/process_run.py @@ -40,28 +40,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, @@ -89,12 +78,22 @@ def __init__(self, @property def output_material(self) -> Optional["MaterialRun"]: # noqa: F821 - """Get the output material run.""" + """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.""" + """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 2dd67c0a..69f80b2c 100644 --- a/gemd/entity/object/process_spec.py +++ b/gemd/entity/object/process_spec.py @@ -38,27 +38,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, @@ -93,12 +81,22 @@ def _template_type() -> Type: @property def ingredients(self) -> List["IngredientSpec"]: # noqa: F821 - """Get the list of input ingredient specs.""" + """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.""" + """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/template/attribute_template.py b/gemd/entity/template/attribute_template.py index 2e66404b..c74ccd43 100644 --- a/gemd/entity/template/attribute_template.py +++ b/gemd/entity/template/attribute_template.py @@ -13,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. @@ -41,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/condition_template.py b/gemd/entity/template/condition_template.py index c20b0fd1..0a6cfac8 100644 --- a/gemd/entity/template/condition_template.py +++ b/gemd/entity/template/condition_template.py @@ -10,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 5edf5e18..6aa98870 100644 --- a/gemd/entity/template/has_condition_templates.py +++ b/gemd/entity/template/has_condition_templates.py @@ -17,7 +17,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. @@ -36,7 +36,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 """ @@ -51,13 +51,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 """ diff --git a/gemd/entity/template/has_parameter_templates.py b/gemd/entity/template/has_parameter_templates.py index fbfc8071..8927d77c 100644 --- a/gemd/entity/template/has_parameter_templates.py +++ b/gemd/entity/template/has_parameter_templates.py @@ -17,7 +17,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. @@ -36,7 +36,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 """ @@ -51,13 +51,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 """ diff --git a/gemd/entity/template/has_property_templates.py b/gemd/entity/template/has_property_templates.py index 32a58cc6..40f350b5 100644 --- a/gemd/entity/template/has_property_templates.py +++ b/gemd/entity/template/has_property_templates.py @@ -17,7 +17,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. @@ -37,7 +37,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 """ @@ -48,11 +48,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. diff --git a/gemd/entity/template/material_template.py b/gemd/entity/template/material_template.py index 728d3e7e..bf5e140a 100644 --- a/gemd/entity/template/material_template.py +++ b/gemd/entity/template/material_template.py @@ -27,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 a8402055..23104c61 100644 --- a/gemd/entity/template/measurement_template.py +++ b/gemd/entity/template/measurement_template.py @@ -31,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 c7bc43cc..8ab7b3a0 100644 --- a/gemd/entity/template/parameter_template.py +++ b/gemd/entity/template/parameter_template.py @@ -10,7 +10,7 @@ class ParameterTemplate(AttributeTemplate, typ="parameter_template"): ---------- name: str, required The name of the parameter template. - bounds: :py:class:`BaseBounds ` + bounds: :class:`~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 e6260c5c..7325e6fa 100644 --- a/gemd/entity/template/process_template.py +++ b/gemd/entity/template/process_template.py @@ -35,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 e2640f77..e6ce7536 100644 --- a/gemd/entity/template/property_template.py +++ b/gemd/entity/template/property_template.py @@ -10,7 +10,7 @@ class PropertyTemplate(AttributeTemplate, typ="property_template"): ---------- name: str, required The name of the property template. - bounds: :py:class:`BaseBounds ` + bounds: :class:`~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 1d189348..1cb8585a 100644 --- a/gemd/entity/util.py +++ b/gemd/entity/util.py @@ -106,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/value/base_value.py b/gemd/entity/value/base_value.py index d47a9d67..b02c25f3 100644 --- a/gemd/entity/value/base_value.py +++ b/gemd/entity/value/base_value.py @@ -13,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 @@ -24,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 888b4468..ddee8992 100644 --- a/gemd/entity/value/categorical_value.py +++ b/gemd/entity/value/categorical_value.py @@ -23,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 e83d64de..511528ca 100644 --- a/gemd/entity/value/composition_value.py +++ b/gemd/entity/value/composition_value.py @@ -19,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 6452daac..9bae50af 100644 --- a/gemd/entity/value/continuous_value.py +++ b/gemd/entity/value/continuous_value.py @@ -49,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 e8559db9..6d3c1c1b 100644 --- a/gemd/entity/value/discrete_categorical.py +++ b/gemd/entity/value/discrete_categorical.py @@ -1,4 +1,6 @@ """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 @@ -23,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): @@ -53,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 7a0b1949..b52d9cc0 100644 --- a/gemd/entity/value/empirical_formula.py +++ b/gemd/entity/value/empirical_formula.py @@ -63,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 36746130..4e7ba263 100644 --- a/gemd/entity/value/inchi_value.py +++ b/gemd/entity/value/inchi_value.py @@ -49,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 242b5980..43283b56 100644 --- a/gemd/entity/value/integer_value.py +++ b/gemd/entity/value/integer_value.py @@ -19,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 00c65c06..3318cea7 100644 --- a/gemd/entity/value/molecular_value.py +++ b/gemd/entity/value/molecular_value.py @@ -19,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 91b5a333..5f738619 100644 --- a/gemd/entity/value/nominal_categorical.py +++ b/gemd/entity/value/nominal_categorical.py @@ -41,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 833d554b..ca3f891a 100644 --- a/gemd/entity/value/nominal_composition.py +++ b/gemd/entity/value/nominal_composition.py @@ -52,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 48d645b5..5be33d5c 100644 --- a/gemd/entity/value/nominal_integer.py +++ b/gemd/entity/value/nominal_integer.py @@ -42,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 9cd0016b..3a79028d 100644 --- a/gemd/entity/value/nominal_real.py +++ b/gemd/entity/value/nominal_real.py @@ -33,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 e3ab0fbc..4ce1908d 100644 --- a/gemd/entity/value/normal_real.py +++ b/gemd/entity/value/normal_real.py @@ -34,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 b7972d29..cfeb2b53 100644 --- a/gemd/entity/value/smiles_value.py +++ b/gemd/entity/value/smiles_value.py @@ -43,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 2b43f61d..40cdb938 100644 --- a/gemd/entity/value/uniform_integer.py +++ b/gemd/entity/value/uniform_integer.py @@ -70,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 74c0e3c6..757c68d0 100644 --- a/gemd/entity/value/uniform_real.py +++ b/gemd/entity/value/uniform_real.py @@ -42,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/json/__init__.py b/gemd/json/__init__.py index 3282c3a3..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. """ diff --git a/gemd/units/impl.py b/gemd/units/impl.py index b0ecbba0..d6cd6629 100644 --- a/gemd/units/impl.py +++ b/gemd/units/impl.py @@ -21,10 +21,10 @@ # 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" -] +# __all__ = [ +# "parse_units", "convert_units", "get_base_units", "change_definitions_file", +# "UndefinedUnitError", "IncompatibleUnitsError", "DefinitionSyntaxError" +# ] def _deploy_default_files() -> str: From 1f51b9921fa4c20d833ee656d389199ce7fc980a Mon Sep 17 00:00:00 2001 From: Ken Kroenlein Date: Tue, 16 Jan 2024 17:30:04 -0700 Subject: [PATCH 5/9] Remove exec from version import --- setup.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/setup.py b/setup.py index c123aea4..a127cd1c 100644 --- a/setup.py +++ b/setup.py @@ -1,16 +1,23 @@ from setuptools import setup, find_packages from os import path +from packaging.version import Version +import re packages = find_packages() this_directory = path.abspath(path.dirname(__file__)) -about = {} -with open(path.join(this_directory, 'gemd', '__version__.py'), 'r') as f: - exec(f.read(), about) +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', # Update this in gemd/__version__.py - version=about['__version__'], + version=str(version), python_requires='>=3.8', url='http://github.com/CitrineInformatics/gemd-python', description="Python binding for Citrine's GEMD data model", From 66a45130fd6b4da34f71958e2d70c047816d3459 Mon Sep 17 00:00:00 2001 From: Ken Kroenlein Date: Tue, 16 Jan 2024 19:40:39 -0700 Subject: [PATCH 6/9] Update Sphinx version and clear warnings --- gemd/entity/base_entity.py | 22 +++++++++++-------- gemd/entity/has_dependencies.py | 5 ++++- gemd/entity/object/has_conditions.py | 5 ++++- gemd/entity/object/has_material.py | 5 ++++- gemd/entity/object/has_parameters.py | 5 ++++- gemd/entity/object/has_process.py | 5 ++++- gemd/entity/object/has_properties.py | 5 ++++- gemd/entity/object/has_spec.py | 5 ++++- gemd/entity/object/has_template.py | 5 ++++- gemd/entity/object/material_run.py | 4 +++- gemd/entity/object/process_run.py | 8 +++++-- gemd/entity/object/process_spec.py | 8 +++++-- .../template/has_condition_templates.py | 8 +++++-- .../template/has_parameter_templates.py | 9 ++++++-- .../entity/template/has_property_templates.py | 15 +++++++++---- test_requirements.txt | 6 ++--- 16 files changed, 87 insertions(+), 33 deletions(-) diff --git a/gemd/entity/base_entity.py b/gemd/entity/base_entity.py index c6eb1dcd..cf87bebb 100644 --- a/gemd/entity/base_entity.py +++ b/gemd/entity/base_entity.py @@ -1,5 +1,5 @@ """Base class for all entities.""" -from typing import Optional, Union, Iterable, List, Set, FrozenSet, Mapping, Dict +from typing import Optional, Union, Iterable, List, Set, FrozenSet, MutableMapping, Dict from gemd.entity.dict_serializable import DictSerializable from gemd.entity.has_dependencies import HasDependencies @@ -12,7 +12,7 @@ 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 @@ -35,7 +35,7 @@ def tags(self, tags: Iterable[str]): self._tags = validate_list(tags, str) @property - def uids(self) -> Mapping[str, str]: + def uids(self) -> MutableMapping[str, str]: """ A collection of unique IDs. @@ -47,11 +47,11 @@ def uids(self) -> Mapping[str, str]: 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]}) @@ -73,7 +73,8 @@ 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 + ) -> "gemd.entity.link_by_uid.LinkByUID": # noqa: F821 """ Generate a ~gemd.entity.link_by_uid.LinkByUID for this object. @@ -102,7 +103,10 @@ 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["gemd.entity.base_entity.BaseEntity", # noqa: F821 + "gemd.entity.link_by_uid.LinkByUID"]]: # noqa: F821 """Return a set of all immediate dependencies (no recursion).""" result = set() queue = [type(self)] @@ -115,8 +119,8 @@ 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]: """ diff --git a/gemd/entity/has_dependencies.py b/gemd/entity/has_dependencies.py index 2362d651..0246e919 100644 --- a/gemd/entity/has_dependencies.py +++ b/gemd/entity/has_dependencies.py @@ -9,5 +9,8 @@ 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["gemd.entity.base_entity.BaseEntity", # noqa: F821 + "gemd.entity.link_by_uid.LinkByUID"]]: # noqa: F821 """All dependencies (objects) that this class introduces.""" diff --git a/gemd/entity/object/has_conditions.py b/gemd/entity/object/has_conditions.py index d0e38f54..fb9b60c2 100644 --- a/gemd/entity/object/has_conditions.py +++ b/gemd/entity/object/has_conditions.py @@ -29,6 +29,9 @@ 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["gemd.entity.base_entity.BaseEntity", # noqa: F821 + "gemd.entity.link_by_uid.LinkByUID"]]: # noqa: F821 """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 a170dd89..94d2f5fa 100644 --- a/gemd/entity/object/has_material.py +++ b/gemd/entity/object/has_material.py @@ -22,6 +22,9 @@ 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["gemd.entity.base_entity.BaseEntity", # noqa: F821 + "gemd.entity.link_by_uid.LinkByUID"]]: # noqa: F821 """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 3c52caf6..bdb0a29b 100644 --- a/gemd/entity/object/has_parameters.py +++ b/gemd/entity/object/has_parameters.py @@ -29,6 +29,9 @@ 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["gemd.entity.base_entity.BaseEntity", # noqa: F821 + "gemd.entity.link_by_uid.LinkByUID"]]: # noqa: F821 """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 80147430..b664f29f 100644 --- a/gemd/entity/object/has_process.py +++ b/gemd/entity/object/has_process.py @@ -22,6 +22,9 @@ 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["gemd.entity.base_entity.BaseEntity", # noqa: F821 + "gemd.entity.link_by_uid.LinkByUID"]]: # noqa: F821 """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 e700d86a..534d2007 100644 --- a/gemd/entity/object/has_properties.py +++ b/gemd/entity/object/has_properties.py @@ -29,6 +29,9 @@ 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["gemd.entity.base_entity.BaseEntity", # noqa: F821 + "gemd.entity.link_by_uid.LinkByUID"]]: # noqa: F821 """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_spec.py b/gemd/entity/object/has_spec.py index 9c67739e..176a9bea 100644 --- a/gemd/entity/object/has_spec.py +++ b/gemd/entity/object/has_spec.py @@ -46,6 +46,9 @@ 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["gemd.entity.base_entity.BaseEntity", # noqa: F821 + "gemd.entity.link_by_uid.LinkByUID"]]: # noqa: F821 """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 b9c911fe..072ce166 100644 --- a/gemd/entity/object/has_template.py +++ b/gemd/entity/object/has_template.py @@ -37,6 +37,9 @@ 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["gemd.entity.base_entity.BaseEntity", # noqa: F821 + "gemd.entity.link_by_uid.LinkByUID"]]: # noqa: F821 """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/material_run.py b/gemd/entity/object/material_run.py index 491f431f..efd23923 100644 --- a/gemd/entity/object/material_run.py +++ b/gemd/entity/object/material_run.py @@ -86,7 +86,9 @@ 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 + def measurements( + self + ) -> List["gemd.entity.object.measurement_run.MeasurementRun"]: # noqa: F821 """Measurements performed on this material. The link is established by creating the measurement run and settings its diff --git a/gemd/entity/object/process_run.py b/gemd/entity/object/process_run.py index da1ed358..b7347dcd 100644 --- a/gemd/entity/object/process_run.py +++ b/gemd/entity/object/process_run.py @@ -77,7 +77,9 @@ def __init__(self, self._output_material = None @property - def output_material(self) -> Optional["MaterialRun"]: # noqa: F821 + def output_material( + self + ) -> Optional["gemd.entity.object.material_run.MaterialRun"]: # noqa: F821 """The material run that this process run produces. The link is established by creating the material run and settings its @@ -87,7 +89,9 @@ def output_material(self) -> Optional["MaterialRun"]: # noqa: F821 return self._output_material @property - def ingredients(self) -> List["IngredientRun"]: # noqa: F821 + def ingredients( + self + ) -> List["gemd.entity.object.ingredient_run.IngredientRun"]: # noqa: F821 """Ingredient runs that act as inputs to this process run. The link is established by creating each ingredient run and setting its diff --git a/gemd/entity/object/process_spec.py b/gemd/entity/object/process_spec.py index 69f80b2c..bcea854d 100644 --- a/gemd/entity/object/process_spec.py +++ b/gemd/entity/object/process_spec.py @@ -80,7 +80,9 @@ def _template_type() -> Type: return ProcessTemplate @property - def ingredients(self) -> List["IngredientSpec"]: # noqa: F821 + def ingredients( + self + ) -> List["gemd.entity.object.ingredient_spec.IngredientSpec"]: # noqa: F821 """Ingredient specs that act as inputs to this process spec. The link is established by creating each ingredient spec and setting its @@ -90,7 +92,9 @@ def ingredients(self) -> List["IngredientSpec"]: # noqa: F821 return self._ingredients @property - def output_material(self) -> Optional["MaterialSpec"]: # noqa: F821 + def output_material( + self + ) -> Optional["gemd.entity.object.material_spec.MaterialSpec"]: # noqa: F821 """The material spec that this process spec produces. The link is established by creating the material spec and settings its diff --git a/gemd/entity/template/has_condition_templates.py b/gemd/entity/template/has_condition_templates.py index 6aa98870..dbcd5056 100644 --- a/gemd/entity/template/has_condition_templates.py +++ b/gemd/entity/template/has_condition_templates.py @@ -69,7 +69,9 @@ 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: "gemd.entity.attribute.condition.Condition" # noqa: F821 + ) -> 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]), @@ -85,6 +87,8 @@ 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["gemd.entity.base_entity.BaseEntity", # noqa: F821 + "gemd.entity.link_by_uid.LinkByUID"]]: # noqa: F821 """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 8927d77c..a97a537e 100644 --- a/gemd/entity/template/has_parameter_templates.py +++ b/gemd/entity/template/has_parameter_templates.py @@ -69,7 +69,9 @@ 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: "gemd.entity.attribute.parameter.Parameter" # noqa: F821 + ) -> 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]), @@ -85,6 +87,9 @@ 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["gemd.entity.base_entity.BaseEntity", # noqa: F821 + "gemd.entity.link_by_uid.LinkByUID"]]: # noqa: F821 """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 40f350b5..6255de5c 100644 --- a/gemd/entity/template/has_property_templates.py +++ b/gemd/entity/template/has_property_templates.py @@ -65,9 +65,13 @@ 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[ + "gemd.entity.attribute.property.Property", # noqa: F821 + "gemd.entity.attribute.property_and_conditions.PropertyAndConditions" # noqa: F821 + ] + ) -> bool: """Check if the property is consistent w/ this template.""" from gemd.entity.attribute import PropertyAndConditions if isinstance(prop, PropertyAndConditions): @@ -87,6 +91,9 @@ 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["gemd.entity.base_entity.BaseEntity", # noqa: F821 + "gemd.entity.link_by_uid.LinkByUID"]]: # noqa: F821 """Return a set of all immediate dependencies (no recursion).""" return {attr[0] for attr in self.properties} diff --git a/test_requirements.txt b/test_requirements.txt index 8d88ee33..d4fec3f8 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-rtd-theme==1.0.0 +sphinx==7.2.6 +sphinx-rtd-theme==2.0.0 +sphinxcontrib-apidoc==0.5.0 From 49f98537c28419b1d95111b128a8a11b566b3ffe Mon Sep 17 00:00:00 2001 From: Ken Kroenlein Date: Tue, 16 Jan 2024 19:45:09 -0700 Subject: [PATCH 7/9] Move to Sphinx version w/ binary distribution --- test_requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test_requirements.txt b/test_requirements.txt index d4fec3f8..dec07f5f 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==7.2.6 +sphinx==7.1.2 sphinx-rtd-theme==2.0.0 sphinxcontrib-apidoc==0.5.0 From 0152e70336cb404f1e7bca2f90692e5ec40bb8e1 Mon Sep 17 00:00:00 2001 From: Ken Kroenlein Date: Fri, 19 Jan 2024 15:00:16 -0700 Subject: [PATCH 8/9] Boost Sphinx to 5; resolve forward reference warnings --- gemd/entity/attribute/condition.py | 4 ++-- gemd/entity/attribute/parameter.py | 6 +++--- gemd/entity/attribute/property.py | 6 +++--- .../attribute/property_and_conditions.py | 4 ++-- gemd/entity/base_entity.py | 16 ++++++++-------- gemd/entity/bounds/base_bounds.py | 11 ++++++----- gemd/entity/bounds/categorical_bounds.py | 17 ++++++++++------- gemd/entity/bounds/composition_bounds.py | 13 ++++++++----- gemd/entity/bounds/integer_bounds.py | 13 ++++++++----- .../bounds/molecular_structure_bounds.py | 13 ++++++++----- gemd/entity/bounds/real_bounds.py | 13 +++++++++---- gemd/entity/dict_serializable.py | 2 +- gemd/entity/has_dependencies.py | 9 ++++----- gemd/entity/link_by_uid.py | 4 +++- gemd/entity/object/has_conditions.py | 7 +++---- gemd/entity/object/has_material.py | 8 +++----- gemd/entity/object/has_parameters.py | 7 +++---- gemd/entity/object/has_process.py | 8 +++----- gemd/entity/object/has_properties.py | 7 +++---- gemd/entity/object/has_spec.py | 8 +++----- gemd/entity/object/has_template.py | 8 +++----- gemd/entity/object/ingredient_spec.py | 2 +- gemd/entity/object/material_run.py | 9 ++++----- gemd/entity/object/process_run.py | 12 +++++------- gemd/entity/object/process_spec.py | 12 +++++------- .../template/has_condition_templates.py | 12 +++++------- .../template/has_parameter_templates.py | 13 +++++-------- .../entity/template/has_property_templates.py | 19 +++++++------------ gemd/entity/template/parameter_template.py | 2 +- gemd/entity/template/property_template.py | 2 +- test_requirements.txt | 6 +++--- 31 files changed, 133 insertions(+), 140 deletions(-) diff --git a/gemd/entity/attribute/condition.py b/gemd/entity/attribute/condition.py index b46926dd..aff09882 100644 --- a/gemd/entity/attribute/condition.py +++ b/gemd/entity/attribute/condition.py @@ -19,9 +19,9 @@ 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:`~gemd.entity.value.base_value.BaseValue` + value: ~gemd.entity.value.base_value.BaseValue The value of the attribute. - template: :class:`~gemd.entity.template.attribute_template.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 diff --git a/gemd/entity/attribute/parameter.py b/gemd/entity/attribute/parameter.py index 4e21fc59..d8bf136c 100644 --- a/gemd/entity/attribute/parameter.py +++ b/gemd/entity/attribute/parameter.py @@ -20,15 +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:`~gemd.entity.value.base_value.BaseValue` + value: ~gemd.entity.value.base_value.BaseValue The value of the attribute. - template: :class:`~gemd.entity.template.attribute_template.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:`~gemd.entity.file_link.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 982fe635..bdc0277c 100644 --- a/gemd/entity/attribute/property.py +++ b/gemd/entity/attribute/property.py @@ -19,15 +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:`~gemd.entity.value.base_value.BaseValue` + value: ~gemd.entity.value.base_value.BaseValue The value of the attribute. - template: :class:`~gemd.entity.template.attribute_template.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:`~gemd.entity.file_link.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 d9c0b603..040f77da 100644 --- a/gemd/entity/attribute/property_and_conditions.py +++ b/gemd/entity/attribute/property_and_conditions.py @@ -19,9 +19,9 @@ class PropertyAndConditions(DictSerializable, typ="property_and_conditions"): Parameters ---------- - property: :class:`~gemd.entity.attribute.property.Property` + property: ~gemd.entity.attribute.property.Property A property attribute - conditions: List[:class:`~gemd.entity.attribute.condition.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 cf87bebb..06d169e8 100644 --- a/gemd/entity/base_entity.py +++ b/gemd/entity/base_entity.py @@ -1,5 +1,5 @@ """Base class for all entities.""" -from typing import Optional, Union, Iterable, List, Set, FrozenSet, MutableMapping, 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 @@ -7,6 +7,8 @@ from gemd.entity.setters import validate_list __all__ = ["BaseEntity"] +BaseEntityType = TypeVar("BaseEntityType", bound="BaseEntity") +LinkByUIDType = TypeVar("LinkByUIDType", bound="LinkByUID") # noqa: F821 class BaseEntity(DictSerializable): @@ -35,7 +37,7 @@ def tags(self, tags: Iterable[str]): self._tags = validate_list(tags, str) @property - def uids(self) -> MutableMapping[str, str]: + def uids(self) -> Dict[str, str]: """ A collection of unique IDs. @@ -74,7 +76,7 @@ def to_link(self, scope: Optional[str] = None, *, allow_fallback: bool = False - ) -> "gemd.entity.link_by_uid.LinkByUID": # noqa: F821 + ) -> LinkByUIDType: """ Generate a ~gemd.entity.link_by_uid.LinkByUID for this object. @@ -103,10 +105,7 @@ def to_link(self, return LinkByUID(scope=scope, id=uid) - def all_dependencies( - self - ) -> Set[Union["gemd.entity.base_entity.BaseEntity", # noqa: F821 - "gemd.entity.link_by_uid.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)] @@ -122,7 +121,8 @@ def all_dependencies( 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 68f7535f..b960d25d 100644 --- a/gemd/entity/bounds/base_bounds.py +++ b/gemd/entity/bounds/base_bounds.py @@ -1,17 +1,19 @@ """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. @@ -38,7 +40,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. @@ -55,10 +57,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. diff --git a/gemd/entity/bounds/categorical_bounds.py b/gemd/entity/bounds/categorical_bounds.py index 0d8af7a1..3d996aab 100644 --- a/gemd/entity/bounds/categorical_bounds.py +++ b/gemd/entity/bounds/categorical_bounds.py @@ -1,9 +1,12 @@ +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"): @@ -40,7 +43,7 @@ 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. @@ -70,8 +73,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. @@ -103,7 +106,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. @@ -117,7 +120,7 @@ def update(self, *others: Union["CategoricalBounds", "CategoricalValue"]): # no """ 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 f3862a64..47481a2b 100644 --- a/gemd/entity/bounds/composition_bounds.py +++ b/gemd/entity/bounds/composition_bounds.py @@ -2,9 +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 __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"): @@ -42,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. @@ -72,8 +75,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. @@ -105,7 +108,7 @@ 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. diff --git a/gemd/entity/bounds/integer_bounds.py b/gemd/entity/bounds/integer_bounds.py index e8cc7763..e17f0549 100644 --- a/gemd/entity/bounds/integer_bounds.py +++ b/gemd/entity/bounds/integer_bounds.py @@ -1,10 +1,13 @@ """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"): @@ -56,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. @@ -86,8 +89,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. @@ -122,7 +125,7 @@ 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. diff --git a/gemd/entity/bounds/molecular_structure_bounds.py b/gemd/entity/bounds/molecular_structure_bounds.py index 1929c230..c1fc5b2e 100644 --- a/gemd/entity/bounds/molecular_structure_bounds.py +++ b/gemd/entity/bounds/molecular_structure_bounds.py @@ -5,15 +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. @@ -43,8 +46,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. @@ -71,7 +74,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. diff --git a/gemd/entity/bounds/real_bounds.py b/gemd/entity/bounds/real_bounds.py index f62dee73..f5c9b646 100644 --- a/gemd/entity/bounds/real_bounds.py +++ b/gemd/entity/bounds/real_bounds.py @@ -1,11 +1,14 @@ """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"): @@ -77,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. @@ -112,7 +115,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. @@ -151,7 +156,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. diff --git a/gemd/entity/dict_serializable.py b/gemd/entity/dict_serializable.py index 71740dd7..664af86b 100644 --- a/gemd/entity/dict_serializable.py +++ b/gemd/entity/dict_serializable.py @@ -125,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/has_dependencies.py b/gemd/entity/has_dependencies.py index 0246e919..ce57b0ee 100644 --- a/gemd/entity/has_dependencies.py +++ b/gemd/entity/has_dependencies.py @@ -1,16 +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["gemd.entity.base_entity.BaseEntity", # noqa: F821 - "gemd.entity.link_by_uid.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 b532e077..27302685 100644 --- a/gemd/entity/link_by_uid.py +++ b/gemd/entity/link_by_uid.py @@ -1,10 +1,12 @@ """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"): @@ -29,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/has_conditions.py b/gemd/entity/object/has_conditions.py index fb9b60c2..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 @@ -29,9 +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["gemd.entity.base_entity.BaseEntity", # noqa: F821 - "gemd.entity.link_by_uid.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 94d2f5fa..dd8c326a 100644 --- a/gemd/entity/object/has_material.py +++ b/gemd/entity/object/has_material.py @@ -1,7 +1,8 @@ """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 @@ -22,9 +23,6 @@ def material(self) -> Union[BaseObject, LinkByUID]: def material(self, spec: Union[BaseObject, LinkByUID]): """Set the material.""" - def _local_dependencies( - self - ) -> Set[Union["gemd.entity.base_entity.BaseEntity", # noqa: F821 - "gemd.entity.link_by_uid.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 bdb0a29b..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 @@ -29,9 +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["gemd.entity.base_entity.BaseEntity", # noqa: F821 - "gemd.entity.link_by_uid.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 b664f29f..9f686e68 100644 --- a/gemd/entity/object/has_process.py +++ b/gemd/entity/object/has_process.py @@ -1,7 +1,8 @@ """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 @@ -22,9 +23,6 @@ def process(self) -> Union[BaseObject, LinkByUID]: def process(self, process: Union[BaseObject, LinkByUID]): """Set the process.""" - def _local_dependencies( - self - ) -> Set[Union["gemd.entity.base_entity.BaseEntity", # noqa: F821 - "gemd.entity.link_by_uid.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 534d2007..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 @@ -29,9 +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["gemd.entity.base_entity.BaseEntity", # noqa: F821 - "gemd.entity.link_by_uid.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_spec.py b/gemd/entity/object/has_spec.py index 176a9bea..7772cde3 100644 --- a/gemd/entity/object/has_spec.py +++ b/gemd/entity/object/has_spec.py @@ -1,8 +1,9 @@ """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 @@ -46,9 +47,6 @@ def template(self) -> Optional[Union[BaseTemplate, LinkByUID]]: else: return None - def _local_dependencies( - self - ) -> Set[Union["gemd.entity.base_entity.BaseEntity", # noqa: F821 - "gemd.entity.link_by_uid.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 072ce166..c38662e1 100644 --- a/gemd/entity/object/has_template.py +++ b/gemd/entity/object/has_template.py @@ -1,7 +1,8 @@ """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 @@ -37,9 +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["gemd.entity.base_entity.BaseEntity", # noqa: F821 - "gemd.entity.link_by_uid.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/ingredient_spec.py b/gemd/entity/object/ingredient_spec.py index dde003a1..7a2f8d41 100644 --- a/gemd/entity/object/ingredient_spec.py +++ b/gemd/entity/object/ingredient_spec.py @@ -37,7 +37,7 @@ class IngredientSpec(BaseObject, for filtering and discoverability. notes: str, optional Long-form notes about the ingredient spec. - material: :class:`~gemd.entity.object.material_spec.MaterialSpec` + material: ~gemd.entity.object.material_spec.MaterialSpec Material that this ingredient is. process: ~gemd.entity.object.process_spec.ProcessSpec Process that this ingredient is used in. diff --git a/gemd/entity/object/material_run.py b/gemd/entity/object/material_run.py index efd23923..a99fd703 100644 --- a/gemd/entity/object/material_run.py +++ b/gemd/entity/object/material_run.py @@ -8,9 +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"}): @@ -33,7 +34,7 @@ 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:`~gemd.entity.object.process_run.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 @@ -86,9 +87,7 @@ def process(self, process: Union[ProcessRun, LinkByUID]): raise TypeError("process must be a ProcessRun or LinkByUID: {}".format(process)) @property - def measurements( - self - ) -> List["gemd.entity.object.measurement_run.MeasurementRun"]: # noqa: F821 + def measurements(self) -> List[MeasurementRunType]: """Measurements performed on this material. The link is established by creating the measurement run and settings its diff --git a/gemd/entity/object/process_run.py b/gemd/entity/object/process_run.py index b7347dcd..f1c73289 100644 --- a/gemd/entity/object/process_run.py +++ b/gemd/entity/object/process_run.py @@ -11,9 +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, @@ -77,9 +79,7 @@ def __init__(self, self._output_material = None @property - def output_material( - self - ) -> Optional["gemd.entity.object.material_run.MaterialRun"]: # noqa: F821 + 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 @@ -89,9 +89,7 @@ def output_material( return self._output_material @property - def ingredients( - self - ) -> List["gemd.entity.object.ingredient_run.IngredientRun"]: # noqa: F821 + 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 diff --git a/gemd/entity/object/process_spec.py b/gemd/entity/object/process_spec.py index bcea854d..40bcb185 100644 --- a/gemd/entity/object/process_spec.py +++ b/gemd/entity/object/process_spec.py @@ -9,9 +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, @@ -80,9 +82,7 @@ def _template_type() -> Type: return ProcessTemplate @property - def ingredients( - self - ) -> List["gemd.entity.object.ingredient_spec.IngredientSpec"]: # noqa: F821 + 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 @@ -92,9 +92,7 @@ def ingredients( return self._ingredients @property - def output_material( - self - ) -> Optional["gemd.entity.object.material_spec.MaterialSpec"]: # noqa: F821 + 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 diff --git a/gemd/entity/template/has_condition_templates.py b/gemd/entity/template/has_condition_templates.py index dbcd5056..6714b10e 100644 --- a/gemd/entity/template/has_condition_templates.py +++ b/gemd/entity/template/has_condition_templates.py @@ -6,9 +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): @@ -69,9 +71,7 @@ def conditions(self, conditions: Iterable[Union[Union[ConditionTemplate, LinkByU trigger=BaseTemplate._homogenize_ranges ) - def validate_condition(self, - condition: "gemd.entity.attribute.condition.Condition" # noqa: F821 - ) -> bool: + 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]), @@ -87,8 +87,6 @@ def validate_condition(self, else: return True # Nothing to check against - def _local_dependencies(self)\ - -> Set[Union["gemd.entity.base_entity.BaseEntity", # noqa: F821 - "gemd.entity.link_by_uid.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 a97a537e..423c3eba 100644 --- a/gemd/entity/template/has_parameter_templates.py +++ b/gemd/entity/template/has_parameter_templates.py @@ -6,9 +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): @@ -69,9 +71,7 @@ def parameters(self, parameters: Iterable[Union[Union[ParameterTemplate, LinkByU trigger=BaseTemplate._homogenize_ranges ) - def validate_parameter(self, - parameter: "gemd.entity.attribute.parameter.Parameter" # noqa: F821 - ) -> bool: + 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]), @@ -87,9 +87,6 @@ def validate_parameter(self, else: return True # Nothing to check against - def _local_dependencies( - self - ) -> Set[Union["gemd.entity.base_entity.BaseEntity", # noqa: F821 - "gemd.entity.link_by_uid.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 6255de5c..0495fd2a 100644 --- a/gemd/entity/template/has_property_templates.py +++ b/gemd/entity/template/has_property_templates.py @@ -6,9 +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): @@ -65,13 +69,7 @@ def properties(self, properties: Iterable[Union[Union[PropertyTemplate, LinkByUI trigger=BaseTemplate._homogenize_ranges ) - def validate_property( - self, - prop: Union[ - "gemd.entity.attribute.property.Property", # noqa: F821 - "gemd.entity.attribute.property_and_conditions.PropertyAndConditions" # noqa: F821 - ] - ) -> bool: + 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): @@ -91,9 +89,6 @@ def validate_property( else: return True # Nothing to check against - def _local_dependencies( - self - ) -> Set[Union["gemd.entity.base_entity.BaseEntity", # noqa: F821 - "gemd.entity.link_by_uid.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/parameter_template.py b/gemd/entity/template/parameter_template.py index 8ab7b3a0..2b733258 100644 --- a/gemd/entity/template/parameter_template.py +++ b/gemd/entity/template/parameter_template.py @@ -10,7 +10,7 @@ class ParameterTemplate(AttributeTemplate, typ="parameter_template"): ---------- name: str, required The name of the parameter template. - bounds: :class:`~gemd.entity.bounds.base_bounds.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/property_template.py b/gemd/entity/template/property_template.py index e6ce7536..eb14a300 100644 --- a/gemd/entity/template/property_template.py +++ b/gemd/entity/template/property_template.py @@ -10,7 +10,7 @@ class PropertyTemplate(AttributeTemplate, typ="property_template"): ---------- name: str, required The name of the property template. - bounds: :class:`~gemd.entity.bounds.base_bounds.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/test_requirements.txt b/test_requirements.txt index dec07f5f..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==7.1.2 -sphinx-rtd-theme==2.0.0 -sphinxcontrib-apidoc==0.5.0 +sphinx==5.0.0 +sphinx-rtd-theme==1.0.0 +sphinxcontrib-apidoc==0.3.0 From 607d16acfac6bca47a4250cd3b7fb2a908947263 Mon Sep 17 00:00:00 2001 From: Ken Kroenlein Date: Fri, 19 Jan 2024 20:27:25 -0700 Subject: [PATCH 9/9] PR feedback --- docs/source/conf.py | 2 +- gemd/builders/impl.py | 6 ++-- gemd/entity/bounds/base_bounds.py | 20 ++++++++----- gemd/entity/bounds/categorical_bounds.py | 21 ++++++++----- gemd/entity/bounds/composition_bounds.py | 24 +++++++++------ gemd/entity/bounds/integer_bounds.py | 18 +++++++---- .../bounds/molecular_structure_bounds.py | 18 +++++++---- gemd/entity/bounds/real_bounds.py | 18 +++++++---- gemd/units/impl.py | 25 ++++++++-------- gemd/util/impl.py | 30 +++++++++++-------- 10 files changed, 111 insertions(+), 71 deletions(-) diff --git a/docs/source/conf.py b/docs/source/conf.py index 0779b6cf..94b60730 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -46,7 +46,7 @@ # 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 diff --git a/gemd/builders/impl.py b/gemd/builders/impl.py index 2ad855c1..395755d9 100644 --- a/gemd/builders/impl.py +++ b/gemd/builders/impl.py @@ -260,7 +260,7 @@ def add_attribute(target: Union[HasProperties, HasConditions, HasParameters], The object to attach the attribute to template: AttributeTemplate The :attr:`~BaseAttribute.template` for the attribute. - value: Union[BaseValue, str, float, int] + 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. @@ -306,7 +306,7 @@ def make_attribute(template: Union[PropertyTemplate, ConditionTemplate, Paramete ---------- template: AttributeTemplate The :attr:`~BaseAttribute.template` for the attribute. - value: Union[BaseValue, str, float, int] + 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. @@ -340,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/entity/bounds/base_bounds.py b/gemd/entity/bounds/base_bounds.py index b960d25d..93281264 100644 --- a/gemd/entity/bounds/base_bounds.py +++ b/gemd/entity/bounds/base_bounds.py @@ -19,14 +19,15 @@ def contains(self, bounds: Union[BaseBoundsType, BaseValueType]): 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 @@ -48,8 +49,10 @@ def union(self, *others: Union[BaseBoundsType, BaseValueType]) -> BaseBoundsType 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 ------- @@ -67,8 +70,9 @@ def update(self, *others: Union[BaseBoundsType, BaseValueType]): 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 3d996aab..20be8acf 100644 --- a/gemd/entity/bounds/categorical_bounds.py +++ b/gemd/entity/bounds/categorical_bounds.py @@ -45,15 +45,18 @@ def categories(self, categories: Optional[Iterable[str]]): 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 ------- @@ -82,8 +85,10 @@ def union(self, Parameters ---------- - others: Union[CategoricalBounds, ~gemd.value.categorical_value.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 ------- @@ -114,8 +119,10 @@ def update(self, *others: Union[CategoricalBoundsType, CategoricalValueType]): Parameters ---------- - others: Union[CategoricalBounds, ~gemd.entity.value.categorical_value.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 diff --git a/gemd/entity/bounds/composition_bounds.py b/gemd/entity/bounds/composition_bounds.py index 47481a2b..3b2ff8fd 100644 --- a/gemd/entity/bounds/composition_bounds.py +++ b/gemd/entity/bounds/composition_bounds.py @@ -2,7 +2,7 @@ from gemd.entity.bounds.base_bounds import BaseBounds from gemd.entity.util import array_like -from typing import TypeVar, Union +from typing import TypeVar, Union, Set, Iterable __all__ = ["CompositionBounds"] CompositionBoundsType = TypeVar("CompositionBoundsType", bound="CompositionBounds") @@ -26,12 +26,12 @@ def __init__(self, components=None): self.components = components @property - def components(self): + 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() @@ -54,8 +54,10 @@ def contains(self, bounds: Union[BaseBounds, BaseValueType]) -> bool: 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 ------- @@ -84,8 +86,10 @@ def union(self, Parameters ---------- - others: Union[CompositionBounds, , ~gemd.entity.value.compositional_value.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 ------- @@ -116,8 +120,10 @@ def update(self, *others: Union[CompositionBoundsType, CompositionValueType]): Parameters ---------- - others: Union[CompositionBounds, ~gemd.entity.value.compositional_value.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. """ self.components = self.union(*others).components diff --git a/gemd/entity/bounds/integer_bounds.py b/gemd/entity/bounds/integer_bounds.py index e17f0549..bd27b991 100644 --- a/gemd/entity/bounds/integer_bounds.py +++ b/gemd/entity/bounds/integer_bounds.py @@ -68,8 +68,10 @@ def contains(self, bounds: Union[BaseBounds, BaseValueType]) -> bool: 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 ------- @@ -98,8 +100,10 @@ def union(self, Parameters ---------- - others: Union[IntegerBounds, ~gemd.entity.value.integer_value.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 ------- @@ -133,8 +137,10 @@ def update(self, *others: Union[IntegerBoundsType, IntegerValueType]): Parameters ---------- - others: Union[IntegerBounds, ~gemd.entity.value.integer_value.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 c1fc5b2e..4586531e 100644 --- a/gemd/entity/bounds/molecular_structure_bounds.py +++ b/gemd/entity/bounds/molecular_structure_bounds.py @@ -25,8 +25,10 @@ def contains(self, bounds: Union[BaseBounds, BaseValueType]) -> bool: 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 ------- @@ -55,13 +57,15 @@ def union(self, Parameters ---------- - others: Union[MolecularStructureBounds, ~gemd.entity.value.molecular_value.MolecularValue] + others: MolecularStructureBounds or ~gemd.entity.value.molecular_value.MolecularValue Other bounds or value objects to include. Returns ------- MolecularStructureBounds - The union of this bounds and the passed bounds + 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 @@ -82,8 +86,10 @@ def update(self, *others: Union[MolecularBoundsType, MolecularValueType]): Parameters ---------- - others: Union[MolecularStructureBounds, ~gemd.entity.value.molecular_value.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 f5c9b646..041d0159 100644 --- a/gemd/entity/bounds/real_bounds.py +++ b/gemd/entity/bounds/real_bounds.py @@ -91,8 +91,10 @@ def contains(self, bounds: Union[BaseBounds, BaseValueType]) -> bool: 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 ------- @@ -125,8 +127,10 @@ def union(self, 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 ------- @@ -164,8 +168,10 @@ def update(self, *others: Union[RealBoundsType, ContinuousValueType]): 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/units/impl.py b/gemd/units/impl.py index d6cd6629..47f1f534 100644 --- a/gemd/units/impl.py +++ b/gemd/units/impl.py @@ -21,10 +21,10 @@ # 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" -# ] +__all__ = [ + "parse_units", "convert_units", "get_base_units", "change_definitions_file", + "UndefinedUnitError", "IncompatibleUnitsError", "DefinitionSyntaxError" +] def _deploy_default_files() -> str: @@ -269,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: @@ -304,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