1*e1fe3e4aSElliott Hughes"""The module contains miscellaneous helpers. 2*e1fe3e4aSElliott HughesIt's not considered part of the public ufoLib API. 3*e1fe3e4aSElliott Hughes""" 4*e1fe3e4aSElliott Hughes 5*e1fe3e4aSElliott Hughesimport warnings 6*e1fe3e4aSElliott Hughesimport functools 7*e1fe3e4aSElliott Hughes 8*e1fe3e4aSElliott Hughes 9*e1fe3e4aSElliott HughesnumberTypes = (int, float) 10*e1fe3e4aSElliott Hughes 11*e1fe3e4aSElliott Hughes 12*e1fe3e4aSElliott Hughesdef deprecated(msg=""): 13*e1fe3e4aSElliott Hughes """Decorator factory to mark functions as deprecated with given message. 14*e1fe3e4aSElliott Hughes 15*e1fe3e4aSElliott Hughes >>> @deprecated("Enough!") 16*e1fe3e4aSElliott Hughes ... def some_function(): 17*e1fe3e4aSElliott Hughes ... "I just print 'hello world'." 18*e1fe3e4aSElliott Hughes ... print("hello world") 19*e1fe3e4aSElliott Hughes >>> some_function() 20*e1fe3e4aSElliott Hughes hello world 21*e1fe3e4aSElliott Hughes >>> some_function.__doc__ == "I just print 'hello world'." 22*e1fe3e4aSElliott Hughes True 23*e1fe3e4aSElliott Hughes """ 24*e1fe3e4aSElliott Hughes 25*e1fe3e4aSElliott Hughes def deprecated_decorator(func): 26*e1fe3e4aSElliott Hughes @functools.wraps(func) 27*e1fe3e4aSElliott Hughes def wrapper(*args, **kwargs): 28*e1fe3e4aSElliott Hughes warnings.warn( 29*e1fe3e4aSElliott Hughes f"{func.__name__} function is a deprecated. {msg}", 30*e1fe3e4aSElliott Hughes category=DeprecationWarning, 31*e1fe3e4aSElliott Hughes stacklevel=2, 32*e1fe3e4aSElliott Hughes ) 33*e1fe3e4aSElliott Hughes return func(*args, **kwargs) 34*e1fe3e4aSElliott Hughes 35*e1fe3e4aSElliott Hughes return wrapper 36*e1fe3e4aSElliott Hughes 37*e1fe3e4aSElliott Hughes return deprecated_decorator 38*e1fe3e4aSElliott Hughes 39*e1fe3e4aSElliott Hughes 40*e1fe3e4aSElliott Hughes# To be mixed with enum.Enum in UFOFormatVersion and GLIFFormatVersion 41*e1fe3e4aSElliott Hughesclass _VersionTupleEnumMixin: 42*e1fe3e4aSElliott Hughes @property 43*e1fe3e4aSElliott Hughes def major(self): 44*e1fe3e4aSElliott Hughes return self.value[0] 45*e1fe3e4aSElliott Hughes 46*e1fe3e4aSElliott Hughes @property 47*e1fe3e4aSElliott Hughes def minor(self): 48*e1fe3e4aSElliott Hughes return self.value[1] 49*e1fe3e4aSElliott Hughes 50*e1fe3e4aSElliott Hughes @classmethod 51*e1fe3e4aSElliott Hughes def _missing_(cls, value): 52*e1fe3e4aSElliott Hughes # allow to initialize a version enum from a single (major) integer 53*e1fe3e4aSElliott Hughes if isinstance(value, int): 54*e1fe3e4aSElliott Hughes return cls((value, 0)) 55*e1fe3e4aSElliott Hughes # or from None to obtain the current default version 56*e1fe3e4aSElliott Hughes if value is None: 57*e1fe3e4aSElliott Hughes return cls.default() 58*e1fe3e4aSElliott Hughes return super()._missing_(value) 59*e1fe3e4aSElliott Hughes 60*e1fe3e4aSElliott Hughes def __str__(self): 61*e1fe3e4aSElliott Hughes return f"{self.major}.{self.minor}" 62*e1fe3e4aSElliott Hughes 63*e1fe3e4aSElliott Hughes @classmethod 64*e1fe3e4aSElliott Hughes def default(cls): 65*e1fe3e4aSElliott Hughes # get the latest defined version (i.e. the max of all versions) 66*e1fe3e4aSElliott Hughes return max(cls.__members__.values()) 67*e1fe3e4aSElliott Hughes 68*e1fe3e4aSElliott Hughes @classmethod 69*e1fe3e4aSElliott Hughes def supported_versions(cls): 70*e1fe3e4aSElliott Hughes return frozenset(cls.__members__.values()) 71*e1fe3e4aSElliott Hughes 72*e1fe3e4aSElliott Hughes 73*e1fe3e4aSElliott Hughesif __name__ == "__main__": 74*e1fe3e4aSElliott Hughes import doctest 75*e1fe3e4aSElliott Hughes 76*e1fe3e4aSElliott Hughes doctest.testmod() 77