Source code for chemdataextractor.utils

# -*- coding: utf-8 -*-
"""
Miscellaneous utility functions.

"""

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
import errno
import functools
import logging
import os

import six


log = logging.getLogger(__name__)


[docs]def memoized_property(fget): """Decorator to create memoized properties.""" attr_name = '_{}'.format(fget.__name__) @functools.wraps(fget) def fget_memoized(self): if not hasattr(self, attr_name): setattr(self, attr_name, fget(self)) return getattr(self, attr_name) return property(fget_memoized)
[docs]def memoize(obj): """Decorator to create memoized functions, methods or classes.""" cache = obj.cache = {} @functools.wraps(obj) def memoizer(*args, **kwargs): if args not in cache: cache[args] = obj(*args, **kwargs) return cache[args] return memoizer
[docs]def python_2_unicode_compatible(klass): """Fix __str__, __unicode__ and __repr__ methods under Python 2.""" if six.PY2: if '__str__' not in klass.__dict__: raise ValueError("Define __str__() on %s to use @python_2_unicode_compatible" % klass.__name__) if '__repr__' not in klass.__dict__: raise ValueError("Define __repr__() on %s to use @python_2_unicode_compatible" % klass.__name__) klass.__unicode__ = klass.__str__ klass._unicode_repr = klass.__repr__ klass.__str__ = lambda self: self.__unicode__().encode('utf-8') klass.__repr__ = lambda self: self._unicode_repr().encode('ascii', errors='backslashreplace') return klass
[docs]class Singleton(type): """Singleton metaclass.""" _instances = {} def __call__(cls, *args, **kwargs): if cls not in cls._instances: cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs) return cls._instances[cls]
[docs]def flatten(x): """Return a single flat list containing elements from nested lists.""" result = [] for el in x: if hasattr(el, '__iter__') and not isinstance(el, six.string_types): result.extend(flatten(el)) else: result.append(el) return result
[docs]def first(el): if len(el) > 0: return el[0] else: return None
[docs]def ensure_dir(path): """Ensure a directory exists.""" try: os.makedirs(path) except OSError as e: if e.errno != errno.EEXIST: raise