<commit_before># coding: utf-8
from datetime import date
from types import GeneratorType
import json
import os

from yadic.util import merge


def serialize_to_json(obj):
    if isinstance(obj, (map, set, GeneratorType)):
        return tuple(obj)
    elif isinstance(obj, date):
        return date.strftime(obj, '%m/%d/%Y')
    else:
        raise TypeError('Type "{0}" not supported'.format(obj))


def load_configs(fnames, parser=json.load):
    """
    Загружает список конфигурационных файлов,
    разделённых символом ";" и возвращает итоговую конфигурацию.
    Последняя получается слиянием конфигураций из файлов,
    через ообновление с заменой в порядке следования имен файлов.
    """
    config = {}
    for fname in fnames.split(';'):
        with open(os.path.expandvars(fname)) as f:
            patch = parser(f)
            config = merge(
                config, patch,
                # словари сливаются вплоть до второго уровня вложенности
                # те же, что расположены глубже, заменяются старый новым
                lambda v1, v2, m, path: (
                    merge(v1, v2, m, path)
                    if (
                        isinstance(v1, dict) and isinstance(v2, dict)
                        and
                        len(path) <= 2
                    ) else
                    v2
                )
            )
    return config
<commit_msg>deep envvars resolving for utl.load_configs<commit_after># coding: utf-8
from datetime import date
from types import GeneratorType
import json
import os

from yadic.util import merge


def serialize_to_json(obj):
    if isinstance(obj, (map, set, GeneratorType)):
        return tuple(obj)
    elif isinstance(obj, date):
        return date.strftime(obj, '%m/%d/%Y')
    else:
        raise TypeError('Type "{0}" not supported'.format(obj))


def load_configs(fnames, parser=json.load):
    """
    Загружает список конфигурационных файлов,
    разделённых символом ";" и возвращает итоговую конфигурацию.
    Последняя получается слиянием конфигураций из файлов,
    через ообновление с заменой в порядке следования имен файлов.
    """
    config = {}
    for fname in os.path.expandvars(fnames).split(';'):
        with open(os.path.expandvars(fname)) as f:
            patch = parser(f)
            config = merge(
                config, patch,
                # словари сливаются вплоть до второго уровня вложенности
                # те же, что расположены глубже, заменяются старый новым
                lambda v1, v2, m, path: (
                    merge(v1, v2, m, path)
                    if (
                        isinstance(v1, dict) and isinstance(v2, dict)
                        and
                        len(path) <= 2
                    ) else
                    v2
                )
            )
    return config

{'fraction_non_alphanumeric': 0.08491895701198027, 'fraction_numerical': 0.007047216349541931, 'mean_word_length': 1.816468253968254, 'pattern_counts': {'":': 0, '<': 5, '<?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': '2532794', 'n_tokens_mistral': 898, 'n_tokens_neox': 948, 'n_words': 244}