Commit 163f3644 authored by idle sign's avatar idle sign

Added API functions.

parent acaece80
......@@ -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.
......
......@@ -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"""
......
......@@ -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):
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment