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