Source code for qupulse.utils.types

import typing
import abc
import inspect
import numbers
import fractions
import warnings

import numpy

__all__ = ["MeasurementWindow", "ChannelID", "HashableNumpyArray", "TimeType", "time_from_float", "DocStringABCMeta",
           "SingletonABCMeta"]

MeasurementWindow = typing.Tuple[str, numbers.Real, numbers.Real]
ChannelID = typing.Union[str, int]


try:
    import gmpy2
    TimeType = gmpy2.mpq

    def time_from_float(time: float, absolute_error: float=1e-12) -> TimeType:
        # gmpy2 is at least an order of magnitude faster than fractions.Fraction
        return gmpy2.mpq(gmpy2.f2q(time, absolute_error))
except ImportError:
    warnings.warn('gmpy2 not found. Using fractions.Fraction as fallback. Install gmpy2 for better performance.')

    TimeType = fractions.Fraction

[docs] def time_from_float(time: float, absolute_error: float = 1e-12) -> TimeType: return fractions.Fraction(time).limit_denominator(int(1/absolute_error))
[docs]class DocStringABCMeta(abc.ABCMeta): """Metaclass that copies/refers to docstrings of the super class.""" def __new__(mcls, classname, bases, cls_dict): cls = super().__new__(mcls, classname, bases, cls_dict) abstract_bases = tuple(base for base in reversed(inspect.getmro(cls)) if hasattr(base, '__abstractmethods__'))[:-1] for name, member in cls_dict.items(): if not getattr(member, '__doc__'): if isinstance(member, property): member_type = ':py:attr:' else: member_type = ':func:' for base in abstract_bases: if name in base.__dict__ and name in base.__abstractmethods__: base_member = getattr(base, name) if member is base_member or not base_member.__doc__: continue base_member_name = '.'.join([base.__module__, base.__qualname__, name]) member.__doc__ = 'Implements {}`~{}`.'.format(member_type, base_member_name) break return cls
T = typing.TypeVar('T')
[docs]class SingletonABCMeta(DocStringABCMeta): """Metaclass that enforces singletons""" def __call__(cls: typing.Type[T]) -> T: return cls._instance def __init__(cls, name, bases, dct): super().__init__(name, bases, dct) cls._instance = super(SingletonABCMeta, cls).__call__()
[docs]class HashableNumpyArray(numpy.ndarray): """Make numpy arrays hashable. Example usage: my_array = np.zeros([1, 2, 3, 4]) hashable = my_array.view(HashableNumpyArray) """ def __hash__(self): return hash(self.tobytes())