<jupyter_start><jupyter_text>(concepts:configurations) ConfigurationsHere we mention a few details that were not part of the {ref}`concepts:overview`.  Help stringsDescriptions are provided in two places: for the script itself, and for each parameter.Note that the parameter help strings are not parsed when the class is not constructed from a `.py`file, which is the case here (as this uses a Jupyter notebook). So we show the syntax below butdo not demonstrate its use.Note that providing a docstring for the class is always recommended, as it seems{func}`dataclasses.dataclass` fills one up if missing.<jupyter_code>from configpile import *
from typing import ClassVar
from typing_extensions import Annotated # or `from typing import Annotated` if Python >= 3.9
from dataclasses import dataclass

@dataclass(frozen=True)
class TestConfig(Config):
    """
    Docstring describing the program 
    """

    #: Sphinx autodoc-style comment (starting with #:) describing the parameter immediately below.
    x: Annotated[int, Param.store(parsers.int_parser)]<jupyter_output><empty_output><jupyter_text>Members of a {class}`~configpile.config.Config` subclassThere are different kinds of members in a configuration: ParametersThey correspond to annotated field declarations, with the general syntax:```python   PARAM_NAME: Annotated[PARAM_TYPE, Param.PARAM_STATIC_METHOD(PARSER, EXTRA_OPTIONS)]```where- `PARAM_NAME` is the parameter name, cannot end with an underscore `_`,-  `PARAM_TYPE` is the Python type of the parameter,- `PARSER` is a parser instance (see {ref}`concepts:parsers`),- `EXTRA_OPTIONS` modify how `configpile` handles the processing.See {ref}concepts:params` for further details. ArgumentsArgument declarations provide information to `configpile` about how to handle command line flagsthat do not correspond to parameters.For example, an {class}`configpile.arg.Expander` provides a key/value pair. They often go alongwith a proper parameter.Because the arguments are not fields that will be part of the dataclass (they do not store valuesthemselves, but modify the processing), they need to be declared as class attributes using{data}`typing.ClassVar`. Here is a short example.<jupyter_code>@dataclass(frozen=True)
class ConfigWithBool(Config):

    smoothing: Annotated[bool, Param.store(parsers.bool_parser)]

    perform_smoothing: ClassVar[Expander] = Expander.make("--smoothing", "true")
    skip_smoothing: ClassVar[Expander] = Expander.make("--smoothing", "false")
ConfigWithBool.from_command_line_(args=["--perform-smoothing"])
ConfigWithBool.from_command_line_(args=["--skip-smoothing"])<jupyter_output><empty_output><jupyter_text>INI handlingSections in an INI file are parsed according to two modes:- the relaxed mode ignore keys that do not match known parameters,- the strict mode reports an error when a key is present that does not match a parameter.Only the section names that are specified in the {class}`~configpile.config.Config` instancethrough the {attr}`~configpile.config.Config.`By default, `configpile` parses the section named `common`, `COMMON` or `Common` in the relaxedmode.  ExampleWe present an example where the two behaviors are shown.<jupyter_code>@dataclass(frozen=True)
class ConfigWithCustomINI(Config):
    ini_relaxed_sections_ = ['all']
    ini_strict_sections_ = ['specific']

    number: Annotated[int, Param.store(parsers.int_parser)]
    word: Annotated[str, Param.store(parsers.stripped_str_parser)]

ConfigWithCustomINI.parse_ini_contents_("""
[all]
number = 123
extra_stuff = will_be_ignored

[specific]
word = hello
""")
ConfigWithCustomINI.parse_ini_contents_("""
[all]
number = 123

[specific]
word = hello
extra_stuff = not_ignored

""")<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.08884131656408883, 'fraction_numerical': 0.0021407546160021407, 'mean_word_length': 6.174664107485604, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 14, '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}}
{'chain_length': '3', 'dir': 'jupyter-structured-clean-dedup', 'id': '589050', 'license': 'MIT', 'n_tokens_mistral': 1107, 'n_tokens_neox': 1065, 'n_words': 378, 'path': 'docs/source/concepts/config.ipynb', 'repo_name': 'denisrosset/configpile', 'size': '3737'}