Improved Enums for Metainfo2
I noticed that the new metainfo supports Enum types, which is really nice.
In order to build logic around those enums, it would be nice if the enum values could be tied to variables. For example, currently checking against a specific value requires a string comparison, which is really prone to typos in the long term. Compare e.g. material.system_type == "bulk"
vs material.system_type == Material.system_type.type.bulk
: If there is a typo, the latter will fail due to a missing enum at run time, the first one will run happily and will screw up the logic.
My proposed solution would be the following class (notice that I would suggest using the name MEnum to avoid mixups with the native Enum type in python):
class MEnum():
"""Allows to define str types with values limited to a pre-set list of possible values."""
def __init__(self, *args, **kwargs):
# Supports one big list in place of args
if len(args) == 1 and isinstance(args[0], list):
args = args[0]
# If non-named arguments are given, the default is to have them placed
# into a dictionary with their string value as both the enum name and
# the value.
for arg in args:
if arg in kwargs:
raise ValueError("Duplicate value '{}' provided for enum".format(arg))
kwargs[arg] = arg
self._values = set(kwargs.values()) # For allowing constant time member check
self._map = kwargs
def __getattr__(self, attr):
return self._map[attr]
This class could be called with the old syntax:
type=MEnum(['disorder', 'unknown_positions', 'assemblies'])
type=MEnum('disorder', 'unknown_positions', 'assemblies')
Or if you want access through a variable, you would specify a variable name with:
type=MEnum(disorder='disorder', unknown_positions='unknown_positions', assemblies='assemblies')
after which the enum value would be made available under e.g. SectionName.quantity_name.type.disorder
What do you think? I'm suggesting this because I will have to perform quite a lot of enum checks to build the Encyclopedia logic, and I would assume that the other normalizers will also want to check for enum values at some point.