Source code for pyjob.misc

# MIT License
#
# Copyright (c) 2017-18 Felix Simkovic
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

__author__ = 'Felix Simkovic'
__version__ = '1.0'

import chardet.universaldetector
import os
import sys
import tempfile
import warnings

from pyjob.exception import PyJobError


[docs]def decode(byte_s): """Decode a string by guessing the encoding Parameters ---------- byte_s : bytes The :obj:`bytes` to decode Returns ------- :obj:`str` `byte_s` decoded Raises ------ :exc:`PyJobError` Unable to infer string encoding """ detector = chardet.universaldetector.UniversalDetector() for line in byte_s.splitlines(): detector.feed(line) if detector.done: break detector.close() if detector.result['confidence'] < 0.98: raise PyJobError('Unable to infer string encoding') return byte_s.decode(detector.result['encoding'])
[docs]def deprecate(version, msg=None): """Decorator to deprecate Python classes and functions Parameters ---------- version : str A string containing the version with which the callable is removed msg : str, optional An additional message that will be displayed alongside the default message Examples -------- Enable :obj:`~DeprecationWarning` messages to be displayed. >>> import warnings >>> warnings.simplefilter('default') Decorate a simple Python function without additional message >>> @deprecate('0.0.0') ... def sum(a, b): ... return a + b >>> sum(1, 2) deprecated.py:34: DeprecationWarning: sum has been deprecated and will be removed in version 0.0.0! warnings.warn(message, DeprecationWarning) 3 Decorate a simple Python function with additional message >>> @deprecate('0.0.1', msg='Use XXX instead!') ... def sum(a, b): ... return a + b >>> sum(2, 2) deprecated.py:34: DeprecationWarning: sum has been deprecated and will be removed in version 0.0.0! warnings.warn(message, DeprecationWarning) 4 Decorate an entire Python class >>> @deprecate('0.0.2') ... class Obj(object): ... pass >>> Obj() deprecated.py:34: DeprecationWarning: Obj has been deprecated and will be removed in version 0.0.2! warnings.warn(message, DeprecationWarning) <__main__.Obj object at 0x7f8ee0f1ead0> Decorate a Python class method >>> class Obj(object): ... def __init__(self, v): ... self.v = v ... @deprecate('0.0.3') ... def mul(self, other): ... return self.v * other.v >>> Obj(2).mul(Obj(3)) deprecated.py:34: DeprecationWarning: mul has been deprecated and will be removed in version 0.0.3! warnings.warn(message, DeprecationWarning) 6 Decorate a Python class staticmethod >>> class Obj(object): ... @staticmethod ... @deprecate('0.0.4') ... def sub(a, b): ... return a - b ... >>> Obj.sub(2, 1) deprecated.py:34: DeprecationWarning: sub has been deprecated and will be removed in version 0.0.4! warnings.warn(message, DeprecationWarning) 1 Decorate a Python class classmethod >>> class Obj(object): ... CONST = 5 ... @classmethod ... @deprecate('0.0.5') ... def sub(cls, a): ... return a - cls.CONST ... >>> Obj().sub(5) deprecated.py:34: DeprecationWarning: sub has been deprecated and will be removed in version 0.0.5! warnings.warn(message, DeprecationWarning) 0 """ def deprecate_decorator(callable_): def warn(*args, **kwargs): message = "%s has been deprecated and will be removed in version %s!" % (callable_.__name__, version) if msg: message += " - %s" % msg warnings.warn(message, DeprecationWarning) return callable_(*args, **kwargs) return warn return deprecate_decorator
[docs]def typecast(value): """Recursively typecast an input Parameters ---------- value : int, float, str, tuple, list """ if isinstance(value, (dict, list)): iterator = range(len(value)) if isinstance(value, list) else value for i in iterator: value[i] = typecast(value[i]) elif value == 'None': return None elif value in ('False', 'True'): return True if value == 'True' else False else: for type_fn in (int, float, str): try: return type_fn(value) except ValueError: pass return value