Skip to content

Booleans specified with -e / --extra-settings do not evaluate to False #2938

Description

@r4victor
  • I have read the Filing Issues and subsequent “How to Get Help” sections of the documentation.
  • I have searched the issues (including closed ones) and believe that this is not a duplicate.

Issue

  1. Pick any boolean settings parameter that is set to True by default or in pelicanconf.py.
  2. Try to override it to False with -e / --extra-settings.
  3. Observe that parameter is still True.

For example, I set DELETE_OUTPUT_DIRECTORY = True in pelicanconf.py and then run:

pelican --debug -e DELETE_OUTPUT_DIRECTORY=false

I see how the old files in the output directory are deleted. Here's the debug log: https://github.com/r4victor/pelican/blob/boolean_overrides_demo/website/debug.txt

Setting -e param=False or -e param=0 doesn't work as well. The only way is to set the parameter to an empty string like -e param=. This is definitely not what users are supposed to do according to the docs (https://docs.getpelican.com/en/latest/settings.html#settings).

It seems the problem was introduced when fixing issue #2789 and originates in the coerce_overrides() function in settings.py:

def coerce_overrides(overrides):
    if overrides is None:
        return {}
    coerced = {}
    types_to_cast = {int, str, bool}
    for k, v in overrides.items():
        if k not in DEFAULT_CONFIG:
            logger.warning('Override for unknown setting %s, ignoring', k)
            continue
        setting_type = type(DEFAULT_CONFIG[k])
        if setting_type not in types_to_cast:
            coerced[k] = json.loads(v)
        else:
            try:
                coerced[k] = setting_type(v)
            except ValueError:
                logger.debug('ValueError for %s override with %s, try to '
                             'load as json', k, v)
                coerced[k] = json.loads(v)
    return coerced

So, when types_to_cast is bool, setting -e k=v results in coerced[k] = bool(v), but in Python bool(v) is True for any string except for the empty string. bool("false") is True.

The solution would be to evaluate "false", "False", "0", "" (something else?) to False, and everything else to True.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions