<commit_before># -*- coding: utf-8 -*-
"""
Contexter is a full replacement of the contextlib standard library
module. It comes with more features, a nicer API and full support for
Python 2.5 up to 3.x from a single source file.
"""

__author__ = '<NAME>'
__version__ = '0.1.2'
__license__ = 'MIT'

import sys
import contextlib
import functools

__all__ = ['Contexter']
__all__ += ['contextmanager', 'nested', 'closing', 'ContextDecorator',
            'ExitStack']



if sys.version_info < (3,):
    def reraise(exc):
        raise exc[0], exc[1], exc[2]
else:
    def reraise(exc):
        raise exc[1].with_traceback(exc[2])



_not_a_context = TypeError(
    "Only context managers (implementing `__enter__` and `__exit__`)"
    " or objects with a `close` method are supported.")


class Contexter(object):
    __slots__ = '_prepared', '_context_stack'

    def __init__(self, *contexts):
        self._prepared = list(contexts)
        self._context_stack = []

    def __call__(self, *contexts):
        for context in contexts:
            self << context
        return self

    def values(self, stack=-1):
        return [value for context, value in self._context_stack[stack]]

    def value(self, index, stack=-1):
        if isinstance(index, slice):
            return [x[1] for x in self._context_stack[stack][index]]
        else:
            return self._context_stack[stack][index][1]

    __getitem__ = value

    def __len__(self):
        return len(self._context_stack[-1])

    def append(self, context):
        if hasattr(context, '__enter__') and hasattr(context, '__exit__'):
            value = context.__enter__()
            self._context_stack[-1].append((context, value))
            return value
        elif hasattr(context, 'close'):
            self._context_stack[-1].append((context, context))
            return context
        else:
            raise _not_a_context

    __lshift__ = append

    def __enter__(self):
        self._context_stack.append([])
        if self._context_stack == [[]]:
            for context in self._prepared:
                self << context
        return self

    def __exit__(self, *exc):
        contexts = self._context_stack.pop()
        for context, value in contexts[::-1]:
            try:
                if hasattr(context, '__exit__'):
                    if(context.__exit__(*exc)):
                        exc = (None, None, None)
                elif hasattr(context, 'close'):
                    context.close()
                else:
                    raise _not_a_context
            except:
                exc = sys.exc_info()

        if exc != (None, None, None):
            reraise(exc)

    def close(self):
        self.__exit__(None, None, None)


class _ExitDummy(object):
    def __init__(self, exit):
        self.exit = exit

    def __enter__(self):
        return self

    def __exit__(self, *ext):
        return self.exit(*exc)


class _CloseDummy(object):
    def __init__(self, callback, args, kwds):
        self.callback = callback
        self.args = args
        self.kwds = kwds

    def __call__(self, *args, **kwds):
        return self.callback(*args, **kwds)<commit_msg>fix typo<commit_after># -*- coding: utf-8 -*-
"""
Contexter is a full replacement of the contextlib standard library
module. It comes with more features, a nicer API and full support for
Python 2.5 up to 3.x from a single source file.
"""

__author__ = '<NAME>'
__version__ = '0.1.2'
__license__ = 'MIT'

import sys
import contextlib
import functools

__all__ = ['Contexter']
__all__ += ['contextmanager', 'nested', 'closing', 'ContextDecorator',
            'ExitStack']



if sys.version_info < (3,):
    def reraise(exc):
        raise exc[0], exc[1], exc[2]
else:
    def reraise(exc):
        raise exc[1].with_traceback(exc[2])



_not_a_context = TypeError(
    "Only context managers (implementing `__enter__` and `__exit__`)"
    " or objects with a `close` method are supported.")


class Contexter(object):
    __slots__ = '_prepared', '_context_stack'

    def __init__(self, *contexts):
        self._prepared = list(contexts)
        self._context_stack = []

    def __call__(self, *contexts):
        for context in contexts:
            self << context
        return self

    def values(self, stack=-1):
        return [value for context, value in self._context_stack[stack]]

    def value(self, index, stack=-1):
        if isinstance(index, slice):
            return [x[1] for x in self._context_stack[stack][index]]
        else:
            return self._context_stack[stack][index][1]

    __getitem__ = value

    def __len__(self):
        return len(self._context_stack[-1])

    def append(self, context):
        if hasattr(context, '__enter__') and hasattr(context, '__exit__'):
            value = context.__enter__()
            self._context_stack[-1].append((context, value))
            return value
        elif hasattr(context, 'close'):
            self._context_stack[-1].append((context, context))
            return context
        else:
            raise _not_a_context

    __lshift__ = append

    def __enter__(self):
        self._context_stack.append([])
        if self._context_stack == [[]]:
            for context in self._prepared:
                self << context
        return self

    def __exit__(self, *exc):
        contexts = self._context_stack.pop()
        for context, value in contexts[::-1]:
            try:
                if hasattr(context, '__exit__'):
                    if(context.__exit__(*exc)):
                        exc = (None, None, None)
                elif hasattr(context, 'close'):
                    context.close()
                else:
                    raise _not_a_context
            except:
                exc = sys.exc_info()

        if exc != (None, None, None):
            reraise(exc)

    def close(self):
        self.__exit__(None, None, None)


class _ExitDummy(object):
    def __init__(self, exit):
        self.exit = exit

    def __enter__(self):
        return self

    def __exit__(self, *exc):
        return self.exit(*exc)


class _CloseDummy(object):
    def __init__(self, callback, args, kwds):
        self.callback = callback
        self.args = args
        self.kwds = kwds

    def __call__(self, *args, **kwds):
        return self.callback(*args, **kwds)
{'fraction_non_alphanumeric': 0.11607843137254902, 'fraction_numerical': 0.006588235294117647, 'mean_word_length': 2.197592778335005, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2518874', 'n_tokens_mistral': 1923, 'n_tokens_neox': 1835, 'n_words': 514}