Source code for free_properties._free_property

# -*- coding: utf-8 -*-
"""
Created on Fri Jan 18 14:19:03 2019

@author: Guest Group
"""

__all__ = ('FreeProperty',)

# %% Metaclasses

# Do not include: '__new__', '__init__', '__del__', '__bytes__', '__repr__',
# '__str__', '__getattr__', '__getattribute__', '__hash__',
# '__setattr__', '__delattr__', '__dir__', '__get__', '__set__',
# '__delete__', '__set_name__',

self_magic_names = ('__str__', '__format__', '__len__', 
                    '__float__', '__invert__', '__complex__', '__int__',
                    '__index__', '__round__', '__trunc__', '__floor__',
                    '__ceil__', '__enter__', '__exit__', '__await__', '__aiter__',
                    '__anext__', '__aenter__', '__aexit__', '__reversed__',
                    '__neg__', '__pos__', '__abs__')

multi_magic_names = ('__call__',)

other_magic_names = ('__lt__', '__le__', '__eq__', '__ne__', 
                      '__gt__', '__ge__', '__bool__', '__getitem__',
                      '__setitem__', '__delitem__', '__missing__',
                      '__contains__', '__add__', '__sub__', '__mul__', '__matmul__',
                      '__truediv__', '__floordiv__', '__mod__', '__divmod__',
                      '__pow__', '__lshift__', '__rshift__', '__and__', '__or__',
                      '__radd__', '__rsub__', '__rmul__', '__rmatmul__',
                      '__rtruediv__', '__rfloordiv__', '__rmod__', '__rdivmod__',
                      '__rpow__', '__rlshift__', '__rrshift__', '__rand__',
                      '__rxor__', '__ror__') 
    
inplace_magic_names = ('__iadd__', '__isub__', '__imul__', '__imatmul__',
                        '__itruediv__', '__idiv__', '__ifloordiv__',
                        '__imod__', '__ipow__', '__ilshift__', '__irshift__',
                        '__iand__', '__ixor__', '__ior__')

class metaProperty(type):
    """Metaclass for FreeProperty and subclasses."""
    
    @property
    def units(cls):
        return cls._units
    
    @units.setter
    def units(cls, units):
        cls._units = units
    
    def getter(cls, fget):
        cls.value = cls.value.getter(fget)
        return cls
    
    def setter(cls, fset):
        cls.value = cls.value.setter(fset)
        return cls


# %% Abstract Property Class

isa = isinstance

[docs]class FreeProperty(metaclass=metaProperty): """Abstract Property class. Child classes must include a 'value' property.""" __slots__ = () _units = '' @property def base(self): return self def __init__(self, *args, **kwargs): setfield = setattr for i, j in zip(self.__slots__, args): setfield(self, i, j) for i, j in kwargs.items(): setfield(self, i, j) def __call__(self, *args, **kwargs): return self.value(*args, **kwargs) def __len__(self): return self.value.__len__() def __float__(self): return self.value.__float__() def __invert__(self): return self.value.__invert__() def __complex__(self): return self.value.__complex__() def __int__(self): return self.value.__int__() def __index__(self): return self.value.__index__() def __round__(self): return self.value.__round__() def __trunc__(self): return self.value.__trunc__() def __floor__(self): return self.value.__floor__() def __ceil__(self): return self.value.__ceil__() def __enter__(self): return self.value.__enter__() def __exit__(self): return self.value.__exit__() def __await__(self): return self.value.__await__() def __aiter__(self): return self.value.__aiter__() def __anext__(self): return self.value.__anext__() def __aenter__(self): return self.value.__aenter__() def __aexit__(self): return self.value.__aexit__() def __reversed__(self): return self.value.__reversed__() def __neg__(self): return self.value.__neg__() def __pos__(self): return self.value.__pos__() def __abs__(self): return self.value.__abs__() def __bool__(self): return self.value.__bool__() def __format__(self, other): return self.value.__format__(other) def __lt__(self, other): return self.value.__lt__(other.value if isa(other, FreeProperty) else other) def __le__(self, other): return self.value.__le__(other.value if isa(other, FreeProperty) else other) def __eq__(self, other): return self.value.__eq__(other.value if isa(other, FreeProperty) else other) def __ne__(self, other): return self.value.__ne__(other.value if isa(other, FreeProperty) else other) def __gt__(self, other): return self.value.__gt__(other.value if isa(other, FreeProperty) else other) def __ge__(self, other): return self.value.__ge__(other.value if isa(other, FreeProperty) else other) def __getitem__(self, other): return self.value.__getitem__(other.value if isa(other, FreeProperty) else other) def __setitem__(self, other): return self.value.__setitem__(other.value if isa(other, FreeProperty) else other) def __delitem__(self, other): return self.value.__delitem__(other.value if isa(other, FreeProperty) else other) def __missing__(self, other): return self.value.__missing__(other.value if isa(other, FreeProperty) else other) def __contains__(self, other): return self.value.__contains__(other.value if isa(other, FreeProperty) else other) def __add__(self, other): return self.value.__add__(other.value if isa(other, FreeProperty) else other) def __sub__(self, other): return self.value.__sub__(other.value if isa(other, FreeProperty) else other) def __mul__(self, other): return self.value.__mul__(other.value if isa(other, FreeProperty) else other) def __matmul__(self, other): return self.value.__matmul__(other.value if isa(other, FreeProperty) else other) def __truediv__(self, other): return self.value.__truediv__(other.value if isa(other, FreeProperty) else other) def __floordiv__(self, other): return self.value.__floordiv__(other.value if isa(other, FreeProperty) else other) def __mod__(self, other): return self.value.__mod__(other.value if isa(other, FreeProperty) else other) def __divmod__(self, other): return self.value.__divmod__(other.value if isa(other, FreeProperty) else other) def __pow__(self, other): return self.value.__pow__(other.value if isa(other, FreeProperty) else other) def __lshift__(self, other): return self.value.__lshift__(other.value if isa(other, FreeProperty) else other) def __rshift__(self, other): return self.value.__rshift__(other.value if isa(other, FreeProperty) else other) def __and__(self, other): return self.value.__and__(other.value if isa(other, FreeProperty) else other) def __or__(self, other): return self.value.__or__(other.value if isa(other, FreeProperty) else other) def __radd__(self, other): return self.value.__radd__(other.value if isa(other, FreeProperty) else other) def __rsub__(self, other): return self.value.__rsub__(other.value if isa(other, FreeProperty) else other) def __rmul__(self, other): return self.value.__rmul__(other.value if isa(other, FreeProperty) else other) def __rmatmul__(self, other): return self.value.__rmatmul__(other.value if isa(other, FreeProperty) else other) def __rtruediv__(self, other): return self.value.__rtruediv__(other.value if isa(other, FreeProperty) else other) def __rfloordiv__(self, other): return self.value.__rfloordiv__(other.value if isa(other, FreeProperty) else other) def __rmod__(self, other): return self.value.__rmod__(other.value if isa(other, FreeProperty) else other) def __rdivmod__(self, other): return self.value.__rdivmod__(other.value if isa(other, FreeProperty) else other) def __rpow__(self, other): return self.value.__rpow__(other.value if isa(other, FreeProperty) else other) def __rlshift__(self, other): return self.value.__rlshift__(other.value if isa(other, FreeProperty) else other) def __rrshift__(self, other): return self.value.__rrshift__(other.value if isa(other, FreeProperty) else other) def __rand__(self, other): return self.value.__rand__(other.value if isa(other, FreeProperty) else other) def __rxor__(self, other): return self.value.__rxor__(other.value if isa(other, FreeProperty) else other) def __ror__(self, other): return self.value.__ror__(other.value if isa(other, FreeProperty) else other) def __iadd__(self, other): self.value = self.value.__add__(other.value if isa(other, FreeProperty) else other) return self def __isub__(self, other): self.value = self.value.__sub__(other.value if isa(other, FreeProperty) else other) return self def __imul__(self, other): self.value = self.value.__mul__(other.value if isa(other, FreeProperty) else other) return self def __imatmul__(self, other): self.value = self.value.__matmul__(other.value if isa(other, FreeProperty) else other) return self def __itruediv__(self, other): self.value = self.value.__truediv__(other.value if isa(other, FreeProperty) else other) return self def __ifloordiv__(self, other): self.value = self.value.__floordiv__(other.value if isa(other, FreeProperty) else other) return self def __imod__(self, other): self.value = self.value.__mod__(other.value if isa(other, FreeProperty) else other) return self def __ipow__(self, other): self.value = self.value.__pow__(other.value if isa(other, FreeProperty) else other) return self def __ilshift__(self, other): self.value = self.value.__lshift__(other.value if isa(other, FreeProperty) else other) return self def __irshift__(self, other): self.value = self.value.__rshift__(other.value if isa(other, FreeProperty) else other) return self def __iand__(self, other): self.value = self.value.__and__(other.value if isa(other, FreeProperty) else other) return self def __ixor__(self, other): self.value = self.value.__xor__(other.value if isa(other, FreeProperty) else other) return self def __ior__(self, other): self.value = self.value.__or__(other.value if isa(other, FreeProperty) else other) return self def __repr__(self): units = self._units units = f' {units}' if units else '' value = self.value try: value = format(value, '.5g') except: pass return f'<{self.name}: {value}{units}>'