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

Cookiecutter fails to get config if the .cookiecutterrc is an empty file #1994

Open
apirogov opened this issue Dec 6, 2023 · 1 comment
Open

Comments

@apirogov
Copy link

apirogov commented Dec 6, 2023

  • Cookiecutter version: 2.5.0
  • Python version: 3.8
  • Operating System: Linux

Description:

When using get_user_config(), the method fails with an exception instead of returning default values, if the .cookiecutterrc file exists, but is empty.

Stacktrace:

>>> get_user_config()
Traceback (most recent call last):
  File "/local/home/a.pirogov/.cache/pypoetry/virtualenvs/fair-python-cookiecutter-Y_dY9N1_-py3.8/lib/python3.8/site-packages/cookiecutter/config.py", line 115, in get_user_config
    env_config_file = os.environ['COOKIECUTTER_CONFIG']
  File "/local/home/a.pirogov/.pyenv/versions/3.8.17/lib/python3.8/os.py", line 675, in __getitem__
    raise KeyError(key) from None
KeyError: 'COOKIECUTTER_CONFIG'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/local/home/a.pirogov/.cache/pypoetry/virtualenvs/fair-python-cookiecutter-Y_dY9N1_-py3.8/lib/python3.8/site-packages/cookiecutter/config.py", line 121, in get_user_config
    return get_config(USER_CONFIG_PATH)
  File "/local/home/a.pirogov/.cache/pypoetry/virtualenvs/fair-python-cookiecutter-Y_dY9N1_-py3.8/lib/python3.8/site-packages/cookiecutter/config.py", line 69, in get_config
    config_dict = merge_configs(DEFAULT_CONFIG, yaml_dict)
  File "/local/home/a.pirogov/.cache/pypoetry/virtualenvs/fair-python-cookiecutter-Y_dY9N1_-py3.8/lib/python3.8/site-packages/cookiecutter/config.py", line 44, in merge_configs
    for k, v in overwrite.items():
AttributeError: 'NoneType' object has no attribute 'items'

What I've run:

Just have an empty .cookiecutterrc and run get_user_config().

Expected behavior:

This exception should not happen, a missing .cookiecutterrc should be treated the same as an empty one.

@alanverresen
Copy link
Contributor

alanverresen commented Dec 7, 2023

I've been able to reproduce this error, and have observed the following:

  1. pyyaml.safe_load(stream) returns None if the YAML stream is empty [1]; an empty YAML stream is a stream that contains no YAML documents [2], and an empty file contains no YAML documents
  2. the implementation of cookiecutter.config.get_config(config_path) does not check if None is returned, and instead, passes the result along to cookiecutter.config.merge_configs(default, overwrite) without checking
  3. in addition, the current implementation assumes that the top level of the YAML config file is an object (which would be transformed to a dict), but it could also be an array (which would be transformed to a list), which would also result in an Exception

pyyaml works as described in (1), and the mistake has been made in the cookiecutter package. To address (2) and (3), I would like to propose to add the following checks to cookiecutter.config.get_config(config_path):

  • if the result returned by pyyaml.safe_load(stream) is None, then the result is replaced by an empty dictionary
  • if the result returned by pyyaml.safe_load(stream) is not a dict (or None), then raise an InvalidConfiguration exception to inform the user that something is wrong with their configuration file, even though it's a valid YAML file

I'll make a pull request for a fix and the necessary tests.

[1] https://pyyaml.org/wiki/PyYAMLDocumentation#reference
[2] https://pyyaml.org/wiki/PyYAMLDocumentation#documents

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

No branches or pull requests

2 participants