Skip to content

ConfigItems overwrites all data with last entry in the list of config items #2909

@pjbull

Description

@pjbull

ConfigItems does not work as expected and results in a list of items that contains only the same values.

Reproduciton

plugin.py

class TestPlugin(BasePlugin):
    config_scheme = (
        (
            "items", mkdocs.config.config_options.ConfigItems(
                ("value", mkdocs.config.config_options.Type(str)),
            ),
        ),
    )

    def on_config(self, config):
        print(self.config)

mkdocs.yml

site_name: Test Site

plugins:
    - test:
        items:
            - value: a
            - value: b

This results in:

INFO     -  Building documentation...
{'items': [{'value': 'b'}, {'value': 'b'}]}
INFO     -  Cleaning site directory
INFO     -  Documentation built in 0.05 seconds
INFO     -  [12:21:39] Watching paths for changes: 'docs', 'mkdocs.yml'
INFO     -  [12:21:39] Serving on http://127.0.0.1:8000/

Note that both "value" values are b rather than the first one being a.

Cause

ConfigItems creates a single SubConfig instance when it is instantiated:

self.item_config = SubConfig(*config_options)

It then uses this instance to do validation:

return [self.item_config.validate(item) for item in value]

The SubConfig instance uses load_dict to populate self.data before validation.

self.load_dict(value)

The load_dict function uses update to make changes to self.data on the SubConfig instance:

self.data.update(patch)

Since there is only one SubConfig instance, when this dictionary gets updated it gets updated across all references to it.

Fix

A number of popular plugins already create their own ConfigItems to address this by making item_config a property that returns a separate SubConfig instance each time it is used. This seems like a reasonable approach.

https://github.com/pieterdavid/mkdocs-doxygen-plugin/blob/49b841b649acf58b668c0b805ab27f9e454920f4/mkdocsdoxygen/configitems.py#L24-L26

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions