<commit_before>from __future__ import print_function
import contextlib
import sys
import threading


"""Global and thread-local configuration of Chainer.

TODO(beam2d): After adding more entries, move this document to sphinx rst and
add references to the related features.

Chainer provides some global settings that affect the behavior of some

There are two objects that users mainly deal with: :data:`chainer.config` and
:data:`chainer.global_config`. The ``config`` object configures the thread-
local configuration, while the ``global_config`` object configures the global
configuration shared among all threads.

Each entry of the global configuration is initialized by its default value,
which can be overridden by a value set to the corresponding environment
variable. There is a naming rule of the environment variable: an entry of the
name ``foo_var`` can be configured by the environment variable
``CHAINER_FOO_VAR``.

"""


class GlobalConfig(object):

    """The plain object that represents the global configuration of Chainer."""

    def show(self, file=sys.stdout):
        """Prints the global config entries.

        The entries are sorted in the lexicographical order of the entry name.

        Args:
            file: Output file-like object.

        """
        keys = sorted(self.__dict__)
        _print_attrs(self, keys, file)


class LocalConfig(object):

    """Thread-local configuration of Chainer.

    This class implements the local configuration. When a value is set to this
    object, the configuration is only updated in the current thread. When a
    user tries to access an attribute and there is no local value, it
    automatically retrieves a value from the global configuration.

    """

    def __init__(self, global_config):
        super(LocalConfig, self).__setattr__('_global', global_config)
        super(LocalConfig, self).__setattr__('_local', threading.local())

    def __delattr__(self, name):
        delattr(self._local, name)

    def __getattr__(self, name):
        if hasattr(self._local, name):
            return getattr(self._local, name)
        return getattr(self._global, name)

    def __setattr__(self, name, value):
        setattr(self._local, name, value)

    def show(self, file=sys.stdout):
        """Prints the config entries.

        The entries are sorted in the lexicographical order of the entry names.

        Args:
            file: Output file-like object.

        """
        keys = sorted(set(self._global.__dict__) | set(self._local.__dict__))
        _print_attrs(self, keys, file)


def _print_attrs(obj, keys, file):
    for key in keys:
        print(u'{}:\t{}'.format(key, getattr(obj, key)), file=file)


global_config = GlobalConfig()
config = LocalConfig(global_config)


@contextlib.contextmanager
def using_config(name, value, config=config):
    """Context manager to temporarily change the thread-local configuration.

    Args:
        name (str): Name of the configuration to change.
        value: Temporary value of the configuration entry.
        config (~chainer.config.LocalConfig): Configuration object. Chainer's
            thread-local configuration is used by default.
<commit_msg>Improve the readability of config.show<commit_after>from __future__ import print_function
import contextlib
import sys
import threading


"""Global and thread-local configuration of Chainer.

TODO(beam2d): After adding more entries, move this document to sphinx rst and
add references to the related features.

Chainer provides some global settings that affect the behavior of some

There are two objects that users mainly deal with: :data:`chainer.config` and
:data:`chainer.global_config`. The ``config`` object configures the thread-
local configuration, while the ``global_config`` object configures the global
configuration shared among all threads.

Each entry of the global configuration is initialized by its default value,
which can be overridden by a value set to the corresponding environment
variable. There is a naming rule of the environment variable: an entry of the
name ``foo_var`` can be configured by the environment variable
``CHAINER_FOO_VAR``.

"""


class GlobalConfig(object):

    """The plain object that represents the global configuration of Chainer."""

    def show(self, file=sys.stdout):
        """Prints the global config entries.

        The entries are sorted in the lexicographical order of the entry name.

        Args:
            file: Output file-like object.

        """
        keys = sorted(self.__dict__)
        _print_attrs(self, keys, file)


class LocalConfig(object):

    """Thread-local configuration of Chainer.

    This class implements the local configuration. When a value is set to this
    object, the configuration is only updated in the current thread. When a
    user tries to access an attribute and there is no local value, it
    automatically retrieves a value from the global configuration.

    """

    def __init__(self, global_config):
        super(LocalConfig, self).__setattr__('_global', global_config)
        super(LocalConfig, self).__setattr__('_local', threading.local())

    def __delattr__(self, name):
        delattr(self._local, name)

    def __getattr__(self, name):
        if hasattr(self._local, name):
            return getattr(self._local, name)
        return getattr(self._global, name)

    def __setattr__(self, name, value):
        setattr(self._local, name, value)

    def show(self, file=sys.stdout):
        """Prints the config entries.

        The entries are sorted in the lexicographical order of the entry names.

        Args:
            file: Output file-like object.

        """
        keys = sorted(set(self._global.__dict__) | set(self._local.__dict__))
        _print_attrs(self, keys, file)


def _print_attrs(obj, keys, file):
    max_len = max(len(key) for key in keys)
    for key in keys:
        spacer = ' ' * (max_len - len(key))
        print(u'{} {}{}'.format(key, spacer, getattr(obj, key)), file=file)


global_config = GlobalConfig()
config = LocalConfig(global_config)


@contextlib.contextmanager
def using_config(name, value, config=config):
    """Context manager to temporarily change the thread-local configuration.

    Args:
        name (str): Name of the configuration to change.
        value: Temporary value of the configuration entry.
        config (~chainer.config.LocalConfig): Configuration object. Chainer's
            thread-local configuration is used by default.

{'fraction_non_alphanumeric': 0.08158257935899402, 'fraction_numerical': 0.00030670142616163164, 'mean_word_length': 3.4216949152542373, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, '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': '3360639', 'n_tokens_mistral': 1733, 'n_tokens_neox': 1676, 'n_words': 691}