diff options
-rw-r--r-- | setuptools/config.py | 78 | ||||
-rw-r--r-- | setuptools/dist.py | 5 | ||||
-rw-r--r-- | setuptools/tests/test_config.py | 20 |
3 files changed, 99 insertions, 4 deletions
diff --git a/setuptools/config.py b/setuptools/config.py index 2dd42893..6459e1de 100644 --- a/setuptools/config.py +++ b/setuptools/config.py @@ -2,6 +2,7 @@ from __future__ import absolute_import, unicode_literals import io import os import sys +from collections import defaultdict from functools import partial from distutils.errors import DistutilsOptionError @@ -9,6 +10,80 @@ from setuptools.py26compat import import_module from setuptools.extern.six import string_types +def read_configuration(filepath, find_others=False): + """Read given configuration file and returns options from it as a dict. + + :param str|unicode filepath: Path to configuration file + to get options from. + + :param bool find_others: Whether to search for other configuration files + which could be on in various places. + + :rtype: dict + """ + from setuptools.dist import Distribution, _Distribution + + dist = Distribution() + + filenames = dist.find_config_files() if find_others else [] + if filepath not in filenames: + filenames.append(filepath) + + _Distribution.parse_config_files(dist, filenames=filenames) + + handlers = parse_configuration(dist, dist.command_options) + + return configuration_to_dict(handlers) + + +def configuration_to_dict(handlers): + """Returns configuration data gathered by given handlers as a dict. + + :param list[ConfigHandler] handlers: Handlers list, + usually from parse_configuration() + + :rtype: dict + """ + config_dict = defaultdict(dict) + + for handler in handlers: + + obj_alias = handler.section_prefix + target_obj = handler.target_obj + + for option in handler.set_options: + getter = getattr(target_obj, 'get_%s' % option, None) + + if getter is None: + value = getattr(target_obj, option) + + else: + value = getter() + + config_dict[obj_alias][option] = value + + return config_dict + + +def parse_configuration(distribution, command_options): + """Performs additional parsing of configuration options + for a distribution. + + Returns a list of used option handlers. + + :param Distribution distribution: + :param dict command_options: + :rtype: list + """ + meta = ConfigMetadataHandler(distribution.metadata, command_options) + meta.parse() + + options = ConfigOptionsHandler(distribution, command_options) + options.parse() + + return [meta, options] + + class ConfigHandler(object): """Handles metadata supplied in configuration files.""" @@ -44,6 +119,7 @@ class ConfigHandler(object): self.target_obj = target_obj self.sections = sections + self.set_options = [] @property def parsers(self): @@ -77,6 +153,8 @@ class ConfigHandler(object): else: setter(value) + self.set_options.append(option_name) + @classmethod def _parse_list(cls, value, separator=','): """Represents value as a list. diff --git a/setuptools/dist.py b/setuptools/dist.py index c975abe0..c04e6426 100644 --- a/setuptools/dist.py +++ b/setuptools/dist.py @@ -19,7 +19,7 @@ from pkg_resources.extern import packaging from setuptools.depends import Require from setuptools import windows_support from setuptools.monkey import get_unpatched -from setuptools.config import ConfigMetadataHandler, ConfigOptionsHandler +from setuptools.config import parse_configuration import pkg_resources @@ -350,8 +350,7 @@ class Distribution(_Distribution): """ _Distribution.parse_config_files(self, filenames=filenames) - ConfigMetadataHandler(self.metadata, self.command_options).parse() - ConfigOptionsHandler(self, self.command_options).parse() + parse_configuration(self, self.command_options) def parse_command_line(self): """Process features after parsing command line options""" diff --git a/setuptools/tests/test_config.py b/setuptools/tests/test_config.py index 259a396a..cd646dba 100644 --- a/setuptools/tests/test_config.py +++ b/setuptools/tests/test_config.py @@ -2,7 +2,7 @@ import contextlib import pytest from distutils.errors import DistutilsOptionError from setuptools.dist import Distribution -from setuptools.config import ConfigHandler +from setuptools.config import ConfigHandler, read_configuration class ErrConfigHandler(ConfigHandler): @@ -52,6 +52,24 @@ def test_parsers_implemented(): handler.parsers +class TestConfigurationReader: + + def test_basic(self, tmpdir): + fake_env( + tmpdir, + '[metadata]\n' + 'version = 10.1.1\n' + 'keywords = one, two\n' + '\n' + '[options]\n' + 'scripts = bin/a.py, bin/b.py\n' + ) + config_dict = read_configuration('%s' % tmpdir.join('setup.cfg')) + assert config_dict['metadata']['version'] == '10.1.1' + assert config_dict['metadata']['keywords'] == ['one', 'two'] + assert config_dict['options']['scripts'] == ['bin/a.py', 'bin/b.py'] + + class TestMetadata: def test_basic(self, tmpdir): |