Source code for custodian.ansible.interpreter
"""
This module implements a Modder class that performs modifications on objects
using support actions.
"""
import re
from custodian.ansible.actions import DictActions
[docs]class Modder:
"""
Class to modify a dict/file/any object using a mongo-like language.
Keywords are mostly adopted from mongo's syntax, but instead of $, an
underscore precedes action keywords. This is so that the modification can
be inserted into a mongo db easily.
Allowable actions are supplied as a list of classes as an argument. Refer
to the action classes on what the actions do. Action classes are in
pymatpro.ansible.actions.
Examples:
>>> modder = Modder()
>>> d = {"Hello": "World"}
>>> mod = {'_set': {'Hello':'Universe', 'Bye': 'World'}}
>>> modder.modify(mod, d)
>>> d['Bye']
'World'
>>> d['Hello']
'Universe'
"""
def __init__(self, actions=None, strict=True):
"""
Initializes a Modder from a list of supported actions.
Args:
actions ([Action]): A sequence of supported actions. See
:mod:`custodian.ansible.actions`. Default is None,
which means only DictActions are supported.
strict (bool): Indicating whether to use strict mode. In non-strict
mode, unsupported actions are simply ignored without any
errors raised. In strict mode, if an unsupported action is
supplied, a ValueError is raised. Defaults to True.
"""
self.supported_actions = {}
actions = actions if actions is not None else [DictActions]
for action in actions:
for i in dir(action):
if (not re.match(r"__\w+__", i)) and callable(getattr(action, i)):
self.supported_actions["_" + i] = getattr(action, i)
self.strict = strict
[docs] def modify(self, modification, obj):
"""
Note that modify makes actual in-place modifications. It does not
return a copy.
Args:
modification (dict): Modification must be {action_keyword :
settings}. E.g., {'_set': {'Hello':'Universe', 'Bye': 'World'}}
obj (dict/str/object): Object to modify depending on actions. For
example, for DictActions, obj will be a dict to be modified.
For FileActions, obj will be a string with a full pathname to a
file.
"""
for action, settings in modification.items():
if action in self.supported_actions:
self.supported_actions[action].__call__(obj, settings)
elif self.strict:
raise ValueError(f"{action} is not a supported action!")
[docs] def modify_object(self, modification, obj):
"""
Modify an object that supports pymatgen's as_dict() and from_dict API.
Args:
modification (dict): Modification must be {action_keyword :
settings}. E.g., {'_set': {'Hello':'Universe', 'Bye': 'World'}}
obj (object): Object to modify
"""
d = obj.as_dict()
self.modify(modification, d)
return obj.from_dict(d)
if __name__ == "__main__":
import doctest
doctest.testmod()