Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pass arguments to ConfigParser #7

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,12 @@ The command implementation reads the configuraion file(s) by using the
``ConfigFileProcessor.read_config()`` method and stores it in the
``default_map`` of the ``context_settings``.

If you need to refine the behaviour of the underlying ConfigParser then pass
named arguments to ``read_config``, these will be passed on to the
ConfigParser constructor. e.g.

``ConfigFileProcessor.read_config(interpolation=ExtendedInterpolation())``

That is only the first part of the problem. We have now a solution that allows
us to read configuration files (and override the command options defaults)
before the command-line parsing begins.
Expand Down
4 changes: 2 additions & 2 deletions click_configfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -382,10 +382,10 @@ def hello(ctx, name):
# -- GENERIC PART:
# Uses declarative specification from above (config_files, config_sections, ...)
@classmethod
def read_config(cls):
def read_config(cls, **args):
configfile_names = list(
generate_configfile_names(cls.config_files, cls.config_searchpath))
parser = configparser.ConfigParser()
parser = configparser.ConfigParser(**args)
parser.optionxform = str
parser.read(configfile_names)

Expand Down
31 changes: 30 additions & 1 deletion tests/functional/test_basics.py
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ class ConfigFileProcessorWithUnboundSection(ConfigFileProcessor2):
# -- POINT: CONTEXT_SETTINGS = dict(default_map=...)
ConfigFileProcessorWithUnboundSection.read_config()

expected = "LookupError: No schema found for: section=unbound.section"
expected = "No schema found for: section=unbound.section"
assert expected in str(e)


Expand Down Expand Up @@ -378,3 +378,32 @@ def test_config_searchpath__param_from_primary_file_overrides_secondary(self,
config = ConfigFileProcessor3.read_config()
assert config == dict(name="Alice")
assert config["name"] == "Alice" # -- FROM: config_file1 (prefered)

# an example of passing extra parameters to the underlying ConfigParser
def test_inline_comments(self, cli_runner_isolated):
assert ConfigFileProcessor1.config_files[0] == "hello.ini"
CONFIG_FILE_CONTENTS1 = """
[default]
dummy = nothing
; this is a comment
[hello]
name = Alice ; this is an inline comment
"""
write_configfile_with_contents("hello.ini", CONFIG_FILE_CONTENTS1)
assert os.path.exists("hello.ini")
assert not os.path.exists("hello.cfg")

CONTEXT_SETTINGS = dict(
default_map=ConfigFileProcessor1.read_config(
inline_comment_prefixes=[";", "#"]
)
)

@click.command(context_settings=CONTEXT_SETTINGS)
@click.pass_context
def hello(ctx):
click.echo("Hello %s" % ctx.default_map["name"])

result = cli_runner_isolated.invoke(hello, [])
assert result.output == "Hello Alice\n"
assert result.exit_code == 0
2 changes: 1 addition & 1 deletion tests/unit/test_schema_description.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,5 +162,5 @@ def test_matches_section__with_bad_arg(self, bad_section_name):
class Hello(SectionSchema):
pass

expected = "ValueError: %r (expected: string, strings)" % bad_section_name
expected = "%r (expected: string, strings)" % bad_section_name
assert expected in str(e)