Skip to content

Conversation

@NielsPichon
Copy link

Goal

This PR aims at making config inheritance possible. To do so it makes to contributions:

  • allow specifying a list of config files for a single argument with the is_config_file=True option
  • allow specifying a config file list inside a config file which will be recursively parsed.

Motivations

This is useful for instance when using a piece of software for many different configurations which can be divided into some sort of parent and children classes.

Details

As an example we could have something like

general_conf_for cars
             |
           /   \
         /       \
       /           \  
sports_car_conf    consumer_cars_conf    Brand
                            \                /
                              \            /
                                \        /
                                   \   /
                                     |
                                    Model

With the PR we can now specify specify something like -my-config consumer_cars brand for the model to have both the config or the brand and the consumer_cars_conf. The order matters as the last specified config file will take precedence of the previous ones. Alternatively you can specify it in a config file of its own:

model.ini

my-config=[consumer_cars, brand]
model_name=model

This will pull out and parse the config for brand and that for consumer cars. The consumer_cars_conf itself could be something like:

consumer_cars_conf.ini

my-config=general_conf_for cars
top-speed=130

As such this allows the user to build a full inheritance system.

Parsing order and circular dependencies

In terms of evaluation order for the arguments we have the following:

  1. command_line args
  2. model.ini args (e.g. top-speed)
  3. brand.ini args
  4. consumer_car_conf.ini args
  5. general_conf_for_cars
  6. default_values

In the general case, for each recursion level, the existing command_line args take precedence, then all the config files are parsed in the reversed order of appearance on the command line, and their args are added to the command line if not there already, and then we start a new recursion round with the newly parsed confs.

Note that we have put some guards to avoid circular dependencies (eg config1 pointing to config2 which points to config 1, creating an endless loop), but the first pass (the config files specified in the original command line arguments) are not registered as already parsed. This is not really an issue as the arguments from the first config file will already be in the command_line_args if it get parsed again and will thus not be updated.

Testing

I have also added some unittest to make sure everytthing is parsed as expected and there are no infinite loop if the config files define circular dependencies.

@bw2
Copy link
Owner

bw2 commented Jan 26, 2022

Sorry I think this functionality is too complicated for the main configargparse repo.

@tbooth
Copy link
Collaborator

tbooth commented Apr 14, 2025

I feel like this functionality could be encapsulated within a custom ConfigFileParser instance, without introducing all these changes to the fundamentals of the main code. Any user of the module can create such a subclass, or extend one of the concrete parser instances, and then pass it as the config_file_parser_class.

If there is some small change to the main module that would help with using such a class then I'm sure that could be considered for inclusion.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants