# Source code for openff.evaluator.storage.attributes

    """
    A collection of descriptors used to add extra metadata
    to storage class attributes.
    """
    from openff.evaluator.attributes import UNDEFINED, Attribute

    class FilePath(str):
        """Represents a string file path.
        """

        pass

    class StorageAttribute(Attribute):
        """A descriptor used to mark attributes of a class as those
        which store information about a cached piece of data.
        """

        def __init__(
            self, docstring, type_hint, optional=False,
        ):
            super().__init__(docstring, type_hint, UNDEFINED, optional)

        def _set_value(self, instance, value):

            # Handle the special case of turning strings
            # into file path objects for convenience.
            if (
                isinstance(value, str)
                and isinstance(self.type_hint, type)
                and issubclass(self.type_hint, FilePath)
            ):
                # This is necessary as the json library currently doesn't
                # support custom serialization of IntFlag or IntEnum.
                value = FilePath(value)

            super(StorageAttribute, self)._set_value(instance, value)

    class QueryAttribute(Attribute):
        """A descriptor used to add additional metadata to
        attributes of a storage query.
        """

        def __init__(self, docstring, type_hint, optional=False, custom_match=False):

            """Initializes self.

            Parameters
            ----------
            custom_match: bool
                Whether a custom behaviour will be implemented when
                matching this attribute against the matching data object
                attribute.
            """
            super().__init__(docstring, type_hint, UNDEFINED, optional)
            self.custom_match = custom_match