diff --git a/cookiecutter/config.py b/cookiecutter/config.py index a07aa1a8b..09e9adc62 100644 --- a/cookiecutter/config.py +++ b/cookiecutter/config.py @@ -4,7 +4,7 @@ import logging import os -import poyo +import yaml from cookiecutter.exceptions import ConfigDoesNotExistException, InvalidConfiguration @@ -62,11 +62,11 @@ def get_config(config_path): logger.debug('config_path is %s', config_path) with open(config_path, encoding='utf-8') as file_handle: try: - yaml_dict = poyo.parse_string(file_handle.read()) - except poyo.exceptions.PoyoException as e: + yaml_dict = yaml.safe_load(file_handle) + except yaml.YAMLError as e: raise InvalidConfiguration( - 'Unable to parse YAML file {}. Error: {}'.format(config_path, e) - ) + 'Unable to parse YAML file {}.'.format(config_path) + ) from e config_dict = merge_configs(DEFAULT_CONFIG, yaml_dict) diff --git a/setup.py b/setup.py index 6ab7e9abd..e3c006e16 100644 --- a/setup.py +++ b/setup.py @@ -11,7 +11,7 @@ 'binaryornot>=0.4.4', 'Jinja2<3.0.0', 'click>=7.0', - 'poyo>=0.5.0', + 'pyyaml>=5.3.1', 'jinja2-time>=0.2.0', 'python-slugify>=4.0.0', 'requests>=2.23.0', diff --git a/tests/conftest.py b/tests/conftest.py index ee3eab6d7..57964f903 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,5 +1,4 @@ """pytest fixtures which are globally available throughout the suite.""" -import logging import os import shutil @@ -9,9 +8,13 @@ USER_CONFIG = """ -cookiecutters_dir: "{cookiecutters_dir}" -replay_dir: "{replay_dir}" +cookiecutters_dir: '{cookiecutters_dir}' +replay_dir: '{replay_dir}' """ +# In YAML, double quotes mean to use escape sequences. +# Single quotes mean we will have unescaped backslahes. +# http://blogs.perl.org/users/tinita/2018/03/ +# strings-in-yaml---to-quote-or-not-to-quote.html def backup_dir(original_dir, backup_dir): @@ -175,9 +178,3 @@ def user_config_file(user_dir, user_config_data): config_text = USER_CONFIG.format(**user_config_data) config_file.write(config_text) return str(config_file) - - -@pytest.fixture(autouse=True) -def disable_poyo_logging(): - """Fixture that disables poyo logging.""" - logging.getLogger('poyo').setLevel(logging.WARNING) diff --git a/tests/test_cli.py b/tests/test_cli.py index 4a1e11471..8da5d7607 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -494,7 +494,11 @@ def test_debug_list_installed_templates(cli_runner, debug_file, user_config_path fake_template_dir = os.path.dirname(os.path.abspath('fake-project')) os.makedirs(os.path.dirname(user_config_path)) with open(user_config_path, 'w') as config_file: - config_file.write('cookiecutters_dir: "%s"' % fake_template_dir) + # In YAML, double quotes mean to use escape sequences. + # Single quotes mean we will have unescaped backslahes. + # http://blogs.perl.org/users/tinita/2018/03/ + # strings-in-yaml---to-quote-or-not-to-quote.html + config_file.write("cookiecutters_dir: '%s'" % fake_template_dir) open(os.path.join('fake-project', 'cookiecutter.json'), 'w').write('{}') result = cli_runner( diff --git a/tests/test_get_config.py b/tests/test_get_config.py index 9466dc382..55aecd5b9 100644 --- a/tests/test_get_config.py +++ b/tests/test_get_config.py @@ -2,6 +2,7 @@ import os import pytest +import yaml from cookiecutter import config from cookiecutter.exceptions import ConfigDoesNotExistException, InvalidConfiguration @@ -82,13 +83,13 @@ def test_get_config_does_not_exist(): def test_invalid_config(): """An invalid config file should raise an `InvalidConfiguration` \ exception.""" - with pytest.raises(InvalidConfiguration) as exc_info: - config.get_config('tests/test-config/invalid-config.yaml') - expected_error_msg = ( - 'Unable to parse YAML file tests/test-config/invalid-config.yaml. Error: ' + 'Unable to parse YAML file tests/test-config/invalid-config.yaml.' ) - assert expected_error_msg in str(exc_info.value) + with pytest.raises(InvalidConfiguration) as exc_info: + config.get_config('tests/test-config/invalid-config.yaml') + assert expected_error_msg in str(exc_info.value) + assert isinstance(exc_info.value.__cause__, yaml.YAMLError) def test_get_config_with_defaults():