view configmix/py.py @ 728:450223a8cff2 v0.22

+++++ v0.22
author Franz Glasner <fzglas.hg@dom66.de>
date Thu, 17 Aug 2023 09:07:00 +0200
parents f454889e41fa
children
line wrap: on
line source

# -*- coding: utf-8 -*-
# :-
# :Copyright: (c) 2015-2022, Franz Glasner. All rights reserved.
# :License:   BSD-3-Clause. See LICENSE.txt for details.
# :-
"""Read configuration settings from Python files.

"""

from __future__ import division, absolute_import, print_function


__all__ = ["load"]


try:
    from collections import OrderedDict as DictImpl
except ImportError:
    try:
        from ordereddict import OrderedDict as DictImpl
    except ImportError:
        DictImpl = dict

from .compat import PY2, u2fs


def load(filename, extract=None):
    """Load Python-style configuration files.

    Files are loaded and **executed** with :func:`exec` using an empty
    dict as global and local context.#

    :param filename: the path to the configuration file
    :param extract: an optional list of variable names (keys) to extract
                    into the resulting configuration dictionary
    :returns: the configuration as dictionary
    :rtype: collections.OrderedDict or ordereddict.OrderedDict or dict

    """
    if extract is not None:
        if not isinstance(extract, (type([]), type(tuple()), type(set()), )):
            raise TypeError("`extract' must be a sequence")
    gcontext = DictImpl()
    lcontext = DictImpl()
    if PY2:
        execfile(u2fs(filename, True), gcontext, lcontext)      # noqa: F821
    else:
        # "rb" mode allows Python to derive the encoding automatically
        with open(filename, "rb") as vf:
            code = compile(vf.read(), filename, "exec")
            exec(code, gcontext, lcontext)
    if extract is None:
        if "__all__" in lcontext:
            extract = lcontext["__all__"]
        else:
            extract = [k for k in lcontext if not k.startswith('_')]
    #
    # Don't bail on non-existing keys and (implicitly) convert to an
    # ordered list
    #
    extract = [v for v in extract if v in lcontext]
    return DictImpl(zip(extract, [lcontext[v] for v in extract]))