<commit_before># Absolute import needed to import ~/.mopidy/settings.py and not ourselves
from __future__ import absolute_import
from copy import copy
import getpass
import logging
import os
from pprint import pformat
import sys

from mopidy import SettingsError
from mopidy.utils.log import indent

logger = logging.getLogger('mopidy.utils.settings')

class SettingsProxy(object):
    def __init__(self, default_settings_module):
        self.default = self._get_settings_dict_from_module(
            default_settings_module)
        self.local = self._get_local_settings()
        self.runtime = {}

    def _read_missing_settings_from_stdin(self, default, local):
        for setting, value in default.iteritems():
            if isinstance(value, basestring) and len(value) == 0:
                local[setting] = self._read_from_stdin(setting + u': ')

    def _read_from_stdin(self, prompt):
        if u'_PASSWORD' in prompt:
            return (getpass.getpass(prompt)
                .decode(getpass.sys.stdin.encoding, 'ignore'))
        else:
            sys.stdout.write(prompt)
            return (sys.stdin.readline().strip()
                .decode(sys.stdin.encoding, 'ignore'))

    def _get_local_settings(self):
        dotdir = os.path.expanduser(u'~/.mopidy/')
        settings_file = os.path.join(dotdir, u'settings.py')
        if not os.path.isfile(settings_file):
            return {}
        sys.path.insert(0, dotdir)
        # pylint: disable = F0401
        import settings as local_settings_module
        # pylint: enable = F0401
        return self._get_settings_dict_from_module(local_settings_module)

    def _get_settings_dict_from_module(self, module):
        settings = filter(lambda (key, value): self._is_setting(key),
            module.__dict__.iteritems())
        return dict(settings)

    def _is_setting(self, name):
        return name.isupper()

    @property
    def current(self):
        current = copy(self.default)
        current.update(self.local)
        current.update(self.runtime)
        return current

    def __getattr__(self, attr):
        if not self._is_setting(attr):
            return
        if attr not in self.current:
            raise SettingsError(u'Setting "%s" is not set.' % attr)
        value = self.current[attr]
        if isinstance(value, basestring) and len(value) == 0:
            raise SettingsError(u'Setting "%s" is empty.' % attr)
        if attr.endswith('_PATH') or attr.endswith('_FILE'):
            value = os.path.expanduser(value)
            value = os.path.abspath(value)
        return value

    def __setattr__(self, attr, value):
        if self._is_setting(attr):
            self.runtime[attr] = value
        else:
            super(SettingsProxy, self).__setattr__(attr, value)

    def validate(self, interactive):
        if interactive:
            self._read_missing_settings_from_stdin(self.default, self.local)
        if self.get_errors():
            logger.error(u'Settings validation errors: %s',
                indent(self.get_errors_as_string()))
            raise SettingsError(u'Settings validation failed.')

    def get_errors(self):
        return validate_settings(self.default, self.local)

    def get_errors_as_string(self):
        lines = []
        for (setting, error) in self.get_errors().iteritems():
            lines.append(u'%s: %s' % (setting, error))
        return '\n'.join(lines)

<commit_msg>Move private methods to be closer it's caller<commit_after># Absolute import needed to import ~/.mopidy/settings.py and not ourselves
from __future__ import absolute_import
from copy import copy
import getpass
import logging
import os
from pprint import pformat
import sys

from mopidy import SettingsError
from mopidy.utils.log import indent

logger = logging.getLogger('mopidy.utils.settings')

class SettingsProxy(object):
    def __init__(self, default_settings_module):
        self.default = self._get_settings_dict_from_module(
            default_settings_module)
        self.local = self._get_local_settings()
        self.runtime = {}

    def _get_local_settings(self):
        dotdir = os.path.expanduser(u'~/.mopidy/')
        settings_file = os.path.join(dotdir, u'settings.py')
        if not os.path.isfile(settings_file):
            return {}
        sys.path.insert(0, dotdir)
        # pylint: disable = F0401
        import settings as local_settings_module
        # pylint: enable = F0401
        return self._get_settings_dict_from_module(local_settings_module)

    def _get_settings_dict_from_module(self, module):
        settings = filter(lambda (key, value): self._is_setting(key),
            module.__dict__.iteritems())
        return dict(settings)

    def _is_setting(self, name):
        return name.isupper()

    @property
    def current(self):
        current = copy(self.default)
        current.update(self.local)
        current.update(self.runtime)
        return current

    def __getattr__(self, attr):
        if not self._is_setting(attr):
            return
        if attr not in self.current:
            raise SettingsError(u'Setting "%s" is not set.' % attr)
        value = self.current[attr]
        if isinstance(value, basestring) and len(value) == 0:
            raise SettingsError(u'Setting "%s" is empty.' % attr)
        if attr.endswith('_PATH') or attr.endswith('_FILE'):
            value = os.path.expanduser(value)
            value = os.path.abspath(value)
        return value

    def __setattr__(self, attr, value):
        if self._is_setting(attr):
            self.runtime[attr] = value
        else:
            super(SettingsProxy, self).__setattr__(attr, value)

    def validate(self, interactive):
        if interactive:
            self._read_missing_settings_from_stdin(self.default, self.local)
        if self.get_errors():
            logger.error(u'Settings validation errors: %s',
                indent(self.get_errors_as_string()))
            raise SettingsError(u'Settings validation failed.')

    def _read_missing_settings_from_stdin(self, default, local):
        for setting, value in default.iteritems():
            if isinstance(value, basestring) and len(value) == 0:
                local[setting] = self._read_from_stdin(setting + u': ')

    def _read_from_stdin(self, prompt):
        if u'_PASSWORD' in prompt:
            return (getpass.getpass(prompt)
                .decode(getpass.sys.stdin.encoding, 'ignore'))
        else:
            sys.stdout.write(prompt)
            return (sys.stdin.readline().strip()
                .decode(sys.stdin.encoding, 'ignore'))

    def get_errors(self):
        return validate_settings(self.default, self.local)

    def get_errors_as_string(self):
        lines = []
        for (setting, error) in self.get_errors().iteritems():
            lines.append(u'%s: %s' % (setting, error))
        return '\n'.join(lines)


{'fraction_non_alphanumeric': 0.10312409603702632, 'fraction_numerical': 0.003181949667341626, 'mean_word_length': 2.579192546583851, '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': '3794453', 'n_tokens_mistral': 2034, 'n_tokens_neox': 1975, 'n_words': 463}