Source code for sire.base

__all__ = ["create_map", "wrap", "PropertyMap", "ProgressBar", "Properties"]

from ..legacy import Base as _Base

from .. import use_new_api as _use_new_api

from ..legacy.Base import PropertyMap, Properties

from ._progressbar import ProgressBar

_use_new_api(is_base=True)

wrap = _Base.wrap


def _fix_wrapped_property_base_type(CLASS):
    """Private function that adds in all of the operators so that,
    as much as possible, the base type PropertyWrappers (e.g.
    NumberProperty, StringProperty) behave like numbers or
    strings, and can auto-convert to those types as needed.
    """

    def __value(v):
        try:
            v = v.value()
        except Exception:
            pass

        try:
            if v.is_integer():
                return int(v)
        except Exception:
            pass

        return v

    def __add__(obj, other):
        return __value(obj) + __value(other)

    CLASS.__add__ = __add__
    CLASS.__radd__ = __add__

    def __sub__(obj, other):
        return __value(obj) - __value(other)

    def __rsub__(obj, other):
        return __value(other) - __value(obj)

    CLASS.__sub__ = __sub__
    CLASS.__rsub__ = __rsub__

    def __eq__(obj, other):
        return __value(obj) == __value(other)

    CLASS.__eq__ = __eq__

    def __ne__(obj, other):
        return __value(obj) != __value(other)

    CLASS.__ne__ = __ne__

    def __gt__(obj, other):
        return __value(obj) > __value(other)

    CLASS.__gt__ = __gt__

    def __ge__(obj, other):
        return __value(obj) >= __value(other)

    CLASS.__ge__ = __ge__

    def __lt__(obj, other):
        return __value(obj) < __value(other)

    CLASS.__lt__ = __lt__

    def __le__(obj, other):
        return __value(obj) <= __value(other)

    CLASS.__le__ = __le__

    def __float__(obj):
        return float(obj.value())

    CLASS.__float__ = __float__

    def __int__(obj):
        return int(obj.value())

    CLASS.__int__ = __int__

    def __str__(obj):
        return str(__value(obj))

    CLASS.__str__ = __str__


_fix_wrapped_property_base_type(_Base.BooleanProperty)
_fix_wrapped_property_base_type(_Base.NumberProperty)
_fix_wrapped_property_base_type(_Base.StringProperty)


if not hasattr(PropertyMap, "__orig__set"):
    PropertyMap.__str__ = lambda x: str(x.to_dict())
    PropertyMap.__repr__ = PropertyMap.__str__

    def __propertymap_set(obj, key, value):
        try:
            obj.__orig__set(key, value)
            return
        except Exception:
            pass

        try:
            obj.__orig__set(key, _Base.PropertyName(value))
            return
        except Exception:
            pass

        obj.__orig__set(key, _Base.PropertyName(wrap(value)))

    PropertyMap.__orig__set = PropertyMap.set
    PropertyMap.set = __propertymap_set

    def __propertymap_get_string(obj, key: str):
        """
        Return the string value associated with the passed 'key'

        This returns 'key' if there is no value associated
        """
        key = str(key)
        if obj.specified(key):
            val = obj[key]

            if val.has_value():
                return val.value().as_string()
            else:
                return val.source()
        else:
            return key

    PropertyMap.get_string = __propertymap_get_string


[docs] def create_map(values, extras=None): """Construct a PropertyMap from the passed values. A PropertyMap is a class that lets you either provide extra options to some of the C++ functions, or to map the default keys used to find properties to your own keys You normally wouldn't use the class yourself. Instead, objects of this class will be created automatically from dictionaries, e.g. >>> mol.energy(map={"cutoff": 5*angstrom}) would automatically create a PropertyMap, and is equivalent to writing >>> mol.energy(map=create_map({"cutoff": 5*angstrom})) In the above case you are providing an extra "cutoff" option, and are passing the value "5*angstrom". You can also use the map to change the keys used to find properties, e.g. >>> mol.energy(map={"coordinates": "my_coords"}) would map the default "coordinates" property to your "my_coords" property. This means that the coordinates for the energy would be found at "my_coords" rather than "coordinates". You can map as many properties, and provide as many extra options as you want. """ if values is None and extras is None: return PropertyMap() elif values is None: return create_map(extras) try: map = PropertyMap(values) except Exception: map = None if map is None: wrapped_values = {} for key, value in values.items(): try: wrapped_values[key] = _Base.PropertyName(value) except Exception: try: wrapped_values[key] = _Base.PropertyName(wrap(value)) except Exception: raise ValueError( f"Unable to set the property {key} to {value} " "because we cannot convert this to a C++ type." ) map = PropertyMap(wrapped_values) if extras is not None: return map + create_map(extras) else: return map