Source code for schrodinger.application.jaguar.workflow_keywords

"""
This module documents all machinery for workflow input keywords.
"""

# Contributors: Mark A. Watson

from voluptuous import Any
from voluptuous import MultipleInvalid
from voluptuous import Required
from voluptuous import Schema

from schrodinger.application.jaguar import workflow_validation as wv

#------------------------------------------------------------------------------


[docs]class Choices(object):
[docs] def __init__(self, *choices): self.choices = choices
[docs]class WorkflowKeyword(object):
[docs] def __init__(self, name, valid_type, default, description): """ :type name: string :param name: unique name for keyword :type valid_type: python type :param valid_type: keyword type e.g. bool, int :type default: <valid_type> :param default: default keyword value :type description: string :param description: short description of what the keyword does """ # Define all keywords in lower case namel = name.lower() self._value = None # Define all keywords in lower case self._name = namel self._default = default self._description = description # Use Schema to establish the valid type(s) of this keyword req = Required(namel, default=default) if isinstance(valid_type, Choices): sch = {req: Any(*valid_type.choices)} self._type = valid_type.choices else: sch = {req: valid_type} self._type = valid_type self._schema = Schema(sch) self.validate()
def __repr__(self): return f"<{type(self).__name__} {self.name}: {repr(self.value)}>" @property def name(self): return self._name @property def valid_type(self): return self._type @property def default(self): return self._default @property def description(self): return self._description @property def value(self): """ Return user-set value. If None, return default value. """ if self._value is not None: return self._value else: return self._default @value.setter def value(self, value): self.setValue(value)
[docs] def setValue(self, value): """ Set to user-defined value. :type value: anything :type value: user-defined value (e.g. from input file) """ self._value = value self.validate()
[docs] def reset(self): """ Reset user-value to NoneType. """ self._value = None self.validate()
[docs] def isNonDefault(self): """ Return True if keyword user-value differs from default value. False otherwise. :rtype: bool """ return (self.value != self._default)
[docs] def validate(self): """ Raise MultipleInvalid or WorkflowKeywordException if keyword name/value don't conform to the schema. (i.e. type check) """ # Add an explicit check for integers since volutuous.Schema # apparently doesn't raise an Exception when a bool is offered # in place of an int. (JAGUAR-7460) if isinstance(self.value, bool) and self.valid_type != bool: raise wv.WorkflowKeywordValueTypeError(self.name, self.value, self.valid_type) # Check all other types using Schema try: self._schema({self.name: self.value}) except MultipleInvalid as e: wv.raise_voluptuous_exception(e, self)