Skip to content

back to Claude Sonnet 3.5 - Base summary

Claude Sonnet 3.5 - Base: cookiecutter

Pytest Summary for test tests

status count
failed 270
passed 97
skipped 4
total 371
collected 371

Failed pytests:

test_dump.py::test_type_error_if_no_template_name

test_dump.py::test_type_error_if_no_template_name
replay_test_dir = 'tests/test-replay/'
context = {'cookiecutter': {'email': 'raphael@hackebrot.de', 'full_name': 'Raphael Pierzina', 'github_username': 'hackebrot', 'version': '0.1.0'}}

    def test_type_error_if_no_template_name(replay_test_dir, context):
        """Test that replay.dump raises if the template_name is not a valid str."""
>       with pytest.raises(TypeError):
E       Failed: DID NOT RAISE 

tests/replay/test_dump.py:37: Failed

test_dump.py::test_type_error_if_not_dict_context

test_dump.py::test_type_error_if_not_dict_context
replay_test_dir = 'tests/test-replay/', template_name = 'cookiedozer'

    def test_type_error_if_not_dict_context(replay_test_dir, template_name):
        """Test that replay.dump raises if the context is not of type dict."""
>       with pytest.raises(TypeError):
E       Failed: DID NOT RAISE 

tests/replay/test_dump.py:43: Failed

test_dump.py::test_value_error_if_key_missing_in_context

test_dump.py::test_value_error_if_key_missing_in_context
replay_test_dir = 'tests/test-replay/', template_name = 'cookiedozer'

    def test_value_error_if_key_missing_in_context(replay_test_dir, template_name):
        """Test that replay.dump raises if the context does not contain a key \
        named 'cookiecutter'."""
>       with pytest.raises(ValueError):
E       Failed: DID NOT RAISE 

tests/replay/test_dump.py:50: Failed

test_load.py::test_type_error_if_no_template_name

test_load.py::test_type_error_if_no_template_name
replay_test_dir = 'tests/test-replay/'

    def test_type_error_if_no_template_name(replay_test_dir):
        """Test that replay.load raises if the template_name is not a valid str."""
>       with pytest.raises(TypeError):
E       Failed: DID NOT RAISE 

tests/replay/test_load.py:26: Failed

test_load.py::test_value_error_if_key_missing_in_context

test_load.py::test_value_error_if_key_missing_in_context
mocker = 
replay_test_dir = 'tests/test-replay/'

    def test_value_error_if_key_missing_in_context(mocker, replay_test_dir):
        """Test that replay.load raises if the loaded context does not contain \
        'cookiecutter'."""
>       with pytest.raises(ValueError):
E       Failed: DID NOT RAISE 

tests/replay/test_load.py:33: Failed

test_replay.py::test_get_replay_file_name[bar.json]

test_replay.py::test_get_replay_file_name[bar.json]
replay_file_name = 'bar.json'

    @pytest.mark.parametrize("replay_file_name", ['bar', 'bar.json'])
    def test_get_replay_file_name(replay_file_name):
        """Make sure that replay.get_file_name generates a valid json file path."""
        exp_replay_file_path = os.path.join('foo', 'bar.json')
        replay_file_path = replay.get_file_name('foo', replay_file_name)
>       assert replay_file_path == exp_replay_file_path
E       AssertionError: assert 'foo/bar.json.json' == 'foo/bar.json'
E         
E         - foo/bar.json
E         + foo/bar.json.json
E         ?             +++++

tests/replay/test_replay.py:15: AssertionError

test_replay.py::test_raise_on_invalid_mode[invalid_kwargs0]

test_replay.py::test_raise_on_invalid_mode[invalid_kwargs0]
invalid_kwargs = {'no_input': True}

    @pytest.mark.parametrize(
        'invalid_kwargs',
        (
            {'no_input': True},
            {'extra_context': {}},
            {'no_input': True, 'extra_context': {}},
        ),
    )
    def test_raise_on_invalid_mode(invalid_kwargs):
        """Test `cookiecutter` raise exception on unacceptable `replay` request."""
        with pytest.raises(exceptions.InvalidModeException):
>           main.cookiecutter('foo', replay=True, **invalid_kwargs)

tests/replay/test_replay.py:29: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

template = 'foo', checkout = None, no_input = True, extra_context = None
replay = True, overwrite_if_exists = False, output_dir = '.', config_file = None
default_config = False, password = None, directory = None
skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False

    def cookiecutter(template, checkout=None, no_input=False, extra_context=
        None, replay=None, overwrite_if_exists=False, output_dir='.',
        config_file=None, default_config=False, password=None, directory=None,
        skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False
        ):
        """
        Run Cookiecutter just as if using it from the command line.

        :param template: A directory containing a project template directory,
            or a URL to a git repository.
        :param checkout: The branch, tag or commit ID to checkout after clone.
        :param no_input: Do not prompt for user input.
            Use default values for template parameters taken from `cookiecutter.json`, user
            config and `extra_dict`. Force a refresh of cached resources.
        :param extra_context: A dictionary of context that overrides default
            and user configuration.
        :param replay: Do not prompt for input, instead read from saved json. If
            ``True`` read from the ``replay_dir``.
            if it exists
        :param overwrite_if_exists: Overwrite the contents of the output directory
            if it exists.
        :param output_dir: Where to output the generated project dir into.
        :param config_file: User configuration file path.
        :param default_config: Use default values rather than a config file.
        :param password: The password to use when extracting the repository.
        :param directory: Relative path to a cookiecutter template in a repository.
        :param skip_if_file_exists: Skip the files in the corresponding directories
            if they already exist.
        :param accept_hooks: Accept pre and post hooks if set to `True`.
        :param keep_project_on_failure: If `True` keep generated project directory even when
            generation fails
        """
        # Get user configuration
        config_dict = get_user_config(config_file=config_file, default_config=default_config)

        # Determine the template directory
>       repo_dir, cleanup = determine_repo_dir(
            template=template,
            checkout=checkout,
            clone_to_dir=config_dict['cookiecutters_dir'],
            no_input=no_input,
            password=password,
            directory=directory
        )
E       TypeError: determine_repo_dir() missing 1 required positional argument: 'abbreviations'

cookiecutter/main.py:59: TypeError

test_replay.py::test_raise_on_invalid_mode[invalid_kwargs1]

test_replay.py::test_raise_on_invalid_mode[invalid_kwargs1]
invalid_kwargs = {'extra_context': {}}

    @pytest.mark.parametrize(
        'invalid_kwargs',
        (
            {'no_input': True},
            {'extra_context': {}},
            {'no_input': True, 'extra_context': {}},
        ),
    )
    def test_raise_on_invalid_mode(invalid_kwargs):
        """Test `cookiecutter` raise exception on unacceptable `replay` request."""
        with pytest.raises(exceptions.InvalidModeException):
>           main.cookiecutter('foo', replay=True, **invalid_kwargs)

tests/replay/test_replay.py:29: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

template = 'foo', checkout = None, no_input = False, extra_context = {}
replay = True, overwrite_if_exists = False, output_dir = '.', config_file = None
default_config = False, password = None, directory = None
skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False

    def cookiecutter(template, checkout=None, no_input=False, extra_context=
        None, replay=None, overwrite_if_exists=False, output_dir='.',
        config_file=None, default_config=False, password=None, directory=None,
        skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False
        ):
        """
        Run Cookiecutter just as if using it from the command line.

        :param template: A directory containing a project template directory,
            or a URL to a git repository.
        :param checkout: The branch, tag or commit ID to checkout after clone.
        :param no_input: Do not prompt for user input.
            Use default values for template parameters taken from `cookiecutter.json`, user
            config and `extra_dict`. Force a refresh of cached resources.
        :param extra_context: A dictionary of context that overrides default
            and user configuration.
        :param replay: Do not prompt for input, instead read from saved json. If
            ``True`` read from the ``replay_dir``.
            if it exists
        :param overwrite_if_exists: Overwrite the contents of the output directory
            if it exists.
        :param output_dir: Where to output the generated project dir into.
        :param config_file: User configuration file path.
        :param default_config: Use default values rather than a config file.
        :param password: The password to use when extracting the repository.
        :param directory: Relative path to a cookiecutter template in a repository.
        :param skip_if_file_exists: Skip the files in the corresponding directories
            if they already exist.
        :param accept_hooks: Accept pre and post hooks if set to `True`.
        :param keep_project_on_failure: If `True` keep generated project directory even when
            generation fails
        """
        # Get user configuration
        config_dict = get_user_config(config_file=config_file, default_config=default_config)

        # Determine the template directory
>       repo_dir, cleanup = determine_repo_dir(
            template=template,
            checkout=checkout,
            clone_to_dir=config_dict['cookiecutters_dir'],
            no_input=no_input,
            password=password,
            directory=directory
        )
E       TypeError: determine_repo_dir() missing 1 required positional argument: 'abbreviations'

cookiecutter/main.py:59: TypeError

test_replay.py::test_raise_on_invalid_mode[invalid_kwargs2]

test_replay.py::test_raise_on_invalid_mode[invalid_kwargs2]
invalid_kwargs = {'extra_context': {}, 'no_input': True}

    @pytest.mark.parametrize(
        'invalid_kwargs',
        (
            {'no_input': True},
            {'extra_context': {}},
            {'no_input': True, 'extra_context': {}},
        ),
    )
    def test_raise_on_invalid_mode(invalid_kwargs):
        """Test `cookiecutter` raise exception on unacceptable `replay` request."""
        with pytest.raises(exceptions.InvalidModeException):
>           main.cookiecutter('foo', replay=True, **invalid_kwargs)

tests/replay/test_replay.py:29: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

template = 'foo', checkout = None, no_input = True, extra_context = {}
replay = True, overwrite_if_exists = False, output_dir = '.', config_file = None
default_config = False, password = None, directory = None
skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False

    def cookiecutter(template, checkout=None, no_input=False, extra_context=
        None, replay=None, overwrite_if_exists=False, output_dir='.',
        config_file=None, default_config=False, password=None, directory=None,
        skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False
        ):
        """
        Run Cookiecutter just as if using it from the command line.

        :param template: A directory containing a project template directory,
            or a URL to a git repository.
        :param checkout: The branch, tag or commit ID to checkout after clone.
        :param no_input: Do not prompt for user input.
            Use default values for template parameters taken from `cookiecutter.json`, user
            config and `extra_dict`. Force a refresh of cached resources.
        :param extra_context: A dictionary of context that overrides default
            and user configuration.
        :param replay: Do not prompt for input, instead read from saved json. If
            ``True`` read from the ``replay_dir``.
            if it exists
        :param overwrite_if_exists: Overwrite the contents of the output directory
            if it exists.
        :param output_dir: Where to output the generated project dir into.
        :param config_file: User configuration file path.
        :param default_config: Use default values rather than a config file.
        :param password: The password to use when extracting the repository.
        :param directory: Relative path to a cookiecutter template in a repository.
        :param skip_if_file_exists: Skip the files in the corresponding directories
            if they already exist.
        :param accept_hooks: Accept pre and post hooks if set to `True`.
        :param keep_project_on_failure: If `True` keep generated project directory even when
            generation fails
        """
        # Get user configuration
        config_dict = get_user_config(config_file=config_file, default_config=default_config)

        # Determine the template directory
>       repo_dir, cleanup = determine_repo_dir(
            template=template,
            checkout=checkout,
            clone_to_dir=config_dict['cookiecutters_dir'],
            no_input=no_input,
            password=password,
            directory=directory
        )
E       TypeError: determine_repo_dir() missing 1 required positional argument: 'abbreviations'

cookiecutter/main.py:59: TypeError

test_replay.py::test_main_does_not_invoke_dump_but_load

test_replay.py::test_main_does_not_invoke_dump_but_load
mocker = 

    def test_main_does_not_invoke_dump_but_load(mocker):
        """Test `cookiecutter` calling correct functions on `replay`."""
        mock_prompt = mocker.patch('cookiecutter.main.prompt_for_config')
        mock_gen_context = mocker.patch('cookiecutter.main.generate_context')
        mock_gen_files = mocker.patch('cookiecutter.main.generate_files')
        mock_replay_dump = mocker.patch('cookiecutter.main.dump')
        mock_replay_load = mocker.patch('cookiecutter.main.load')

>       main.cookiecutter('tests/fake-repo-tmpl/', replay=True)

tests/replay/test_replay.py:40: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

template = 'tests/fake-repo-tmpl/', checkout = None, no_input = False
extra_context = None, replay = True, overwrite_if_exists = False
output_dir = '.', config_file = None, default_config = False, password = None
directory = None, skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False

    def cookiecutter(template, checkout=None, no_input=False, extra_context=
        None, replay=None, overwrite_if_exists=False, output_dir='.',
        config_file=None, default_config=False, password=None, directory=None,
        skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False
        ):
        """
        Run Cookiecutter just as if using it from the command line.

        :param template: A directory containing a project template directory,
            or a URL to a git repository.
        :param checkout: The branch, tag or commit ID to checkout after clone.
        :param no_input: Do not prompt for user input.
            Use default values for template parameters taken from `cookiecutter.json`, user
            config and `extra_dict`. Force a refresh of cached resources.
        :param extra_context: A dictionary of context that overrides default
            and user configuration.
        :param replay: Do not prompt for input, instead read from saved json. If
            ``True`` read from the ``replay_dir``.
            if it exists
        :param overwrite_if_exists: Overwrite the contents of the output directory
            if it exists.
        :param output_dir: Where to output the generated project dir into.
        :param config_file: User configuration file path.
        :param default_config: Use default values rather than a config file.
        :param password: The password to use when extracting the repository.
        :param directory: Relative path to a cookiecutter template in a repository.
        :param skip_if_file_exists: Skip the files in the corresponding directories
            if they already exist.
        :param accept_hooks: Accept pre and post hooks if set to `True`.
        :param keep_project_on_failure: If `True` keep generated project directory even when
            generation fails
        """
        # Get user configuration
        config_dict = get_user_config(config_file=config_file, default_config=default_config)

        # Determine the template directory
>       repo_dir, cleanup = determine_repo_dir(
            template=template,
            checkout=checkout,
            clone_to_dir=config_dict['cookiecutters_dir'],
            no_input=no_input,
            password=password,
            directory=directory
        )
E       TypeError: determine_repo_dir() missing 1 required positional argument: 'abbreviations'

cookiecutter/main.py:59: TypeError

test_replay.py::test_main_does_not_invoke_load_but_dump

test_replay.py::test_main_does_not_invoke_load_but_dump
mocker = 

    def test_main_does_not_invoke_load_but_dump(mocker):
        """Test `cookiecutter` calling correct functions on non-replay launch."""
        mock_prompt = mocker.patch('cookiecutter.main.prompt_for_config')
        mock_gen_context = mocker.patch('cookiecutter.main.generate_context')
        mock_gen_files = mocker.patch('cookiecutter.main.generate_files')
        mock_replay_dump = mocker.patch('cookiecutter.main.dump')
        mock_replay_load = mocker.patch('cookiecutter.main.load')

>       main.cookiecutter('tests/fake-repo-tmpl/', replay=False)

tests/replay/test_replay.py:57: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

template = 'tests/fake-repo-tmpl/', checkout = None, no_input = False
extra_context = None, replay = False, overwrite_if_exists = False
output_dir = '.', config_file = None, default_config = False, password = None
directory = None, skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False

    def cookiecutter(template, checkout=None, no_input=False, extra_context=
        None, replay=None, overwrite_if_exists=False, output_dir='.',
        config_file=None, default_config=False, password=None, directory=None,
        skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False
        ):
        """
        Run Cookiecutter just as if using it from the command line.

        :param template: A directory containing a project template directory,
            or a URL to a git repository.
        :param checkout: The branch, tag or commit ID to checkout after clone.
        :param no_input: Do not prompt for user input.
            Use default values for template parameters taken from `cookiecutter.json`, user
            config and `extra_dict`. Force a refresh of cached resources.
        :param extra_context: A dictionary of context that overrides default
            and user configuration.
        :param replay: Do not prompt for input, instead read from saved json. If
            ``True`` read from the ``replay_dir``.
            if it exists
        :param overwrite_if_exists: Overwrite the contents of the output directory
            if it exists.
        :param output_dir: Where to output the generated project dir into.
        :param config_file: User configuration file path.
        :param default_config: Use default values rather than a config file.
        :param password: The password to use when extracting the repository.
        :param directory: Relative path to a cookiecutter template in a repository.
        :param skip_if_file_exists: Skip the files in the corresponding directories
            if they already exist.
        :param accept_hooks: Accept pre and post hooks if set to `True`.
        :param keep_project_on_failure: If `True` keep generated project directory even when
            generation fails
        """
        # Get user configuration
        config_dict = get_user_config(config_file=config_file, default_config=default_config)

        # Determine the template directory
>       repo_dir, cleanup = determine_repo_dir(
            template=template,
            checkout=checkout,
            clone_to_dir=config_dict['cookiecutters_dir'],
            no_input=no_input,
            password=password,
            directory=directory
        )
E       TypeError: determine_repo_dir() missing 1 required positional argument: 'abbreviations'

cookiecutter/main.py:59: TypeError

test_abbreviation_expansion.py::test_abbreviation_expansion[Expansion prefix]

test_abbreviation_expansion.py::test_abbreviation_expansion[Expansion prefix]
template = 'xx:a', abbreviations = {'xx': '<{0}>'}, expected_result = ''

    @pytest.mark.parametrize(
        ('template', 'abbreviations', 'expected_result'),
        [
            ('foo', {'foo': 'bar'}, 'bar'),
            ('baz', {'foo': 'bar'}, 'baz'),
            ('xx:a', {'xx': '<{0}>'}, ''),
            ('gh:a', {'gh': '<{0}>'}, ''),
            ('xx:a', {'xx': '<>'}, '<>'),
            (
                'gh:pydanny/cookiecutter-django',
                BUILTIN_ABBREVIATIONS,
                'https://github.com/pydanny/cookiecutter-django.git',
            ),
            (
                'gl:pydanny/cookiecutter-django',
                BUILTIN_ABBREVIATIONS,
                'https://gitlab.com/pydanny/cookiecutter-django.git',
            ),
            (
                'bb:pydanny/cookiecutter-django',
                BUILTIN_ABBREVIATIONS,
                'https://bitbucket.org/pydanny/cookiecutter-django',
            ),
        ],
        ids=(
            'Simple expansion',
            'Skip expansion (expansion not an abbreviation)',
            'Expansion prefix',
            'expansion_override_builtin',
            'expansion_prefix_ignores_suffix',
            'Correct expansion for builtin abbreviations (github)',
            'Correct expansion for builtin abbreviations (gitlab)',
            'Correct expansion for builtin abbreviations (bitbucket)',
        ),
    )
    def test_abbreviation_expansion(template, abbreviations, expected_result):
        """Verify abbreviation unpacking."""
        expanded = expand_abbreviations(template, abbreviations)
>       assert expanded == expected_result
E       AssertionError: assert 'xx:a' == ''
E         
E         - 
E         + xx:a

tests/repository/test_abbreviation_expansion.py:47: AssertionError

test_abbreviation_expansion.py::test_abbreviation_expansion[expansion_override_builtin]

test_abbreviation_expansion.py::test_abbreviation_expansion[expansion_override_builtin]
template = 'gh:a', abbreviations = {'gh': '<{0}>'}, expected_result = ''

    @pytest.mark.parametrize(
        ('template', 'abbreviations', 'expected_result'),
        [
            ('foo', {'foo': 'bar'}, 'bar'),
            ('baz', {'foo': 'bar'}, 'baz'),
            ('xx:a', {'xx': '<{0}>'}, ''),
            ('gh:a', {'gh': '<{0}>'}, ''),
            ('xx:a', {'xx': '<>'}, '<>'),
            (
                'gh:pydanny/cookiecutter-django',
                BUILTIN_ABBREVIATIONS,
                'https://github.com/pydanny/cookiecutter-django.git',
            ),
            (
                'gl:pydanny/cookiecutter-django',
                BUILTIN_ABBREVIATIONS,
                'https://gitlab.com/pydanny/cookiecutter-django.git',
            ),
            (
                'bb:pydanny/cookiecutter-django',
                BUILTIN_ABBREVIATIONS,
                'https://bitbucket.org/pydanny/cookiecutter-django',
            ),
        ],
        ids=(
            'Simple expansion',
            'Skip expansion (expansion not an abbreviation)',
            'Expansion prefix',
            'expansion_override_builtin',
            'expansion_prefix_ignores_suffix',
            'Correct expansion for builtin abbreviations (github)',
            'Correct expansion for builtin abbreviations (gitlab)',
            'Correct expansion for builtin abbreviations (bitbucket)',
        ),
    )
    def test_abbreviation_expansion(template, abbreviations, expected_result):
        """Verify abbreviation unpacking."""
        expanded = expand_abbreviations(template, abbreviations)
>       assert expanded == expected_result
E       AssertionError: assert 'gh:a' == ''
E         
E         - 
E         + gh:a

tests/repository/test_abbreviation_expansion.py:47: AssertionError

test_abbreviation_expansion.py::test_abbreviation_expansion[expansion_prefix_ignores_suffix]

test_abbreviation_expansion.py::test_abbreviation_expansion[expansion_prefix_ignores_suffix]
template = 'xx:a', abbreviations = {'xx': '<>'}, expected_result = '<>'

    @pytest.mark.parametrize(
        ('template', 'abbreviations', 'expected_result'),
        [
            ('foo', {'foo': 'bar'}, 'bar'),
            ('baz', {'foo': 'bar'}, 'baz'),
            ('xx:a', {'xx': '<{0}>'}, ''),
            ('gh:a', {'gh': '<{0}>'}, ''),
            ('xx:a', {'xx': '<>'}, '<>'),
            (
                'gh:pydanny/cookiecutter-django',
                BUILTIN_ABBREVIATIONS,
                'https://github.com/pydanny/cookiecutter-django.git',
            ),
            (
                'gl:pydanny/cookiecutter-django',
                BUILTIN_ABBREVIATIONS,
                'https://gitlab.com/pydanny/cookiecutter-django.git',
            ),
            (
                'bb:pydanny/cookiecutter-django',
                BUILTIN_ABBREVIATIONS,
                'https://bitbucket.org/pydanny/cookiecutter-django',
            ),
        ],
        ids=(
            'Simple expansion',
            'Skip expansion (expansion not an abbreviation)',
            'Expansion prefix',
            'expansion_override_builtin',
            'expansion_prefix_ignores_suffix',
            'Correct expansion for builtin abbreviations (github)',
            'Correct expansion for builtin abbreviations (gitlab)',
            'Correct expansion for builtin abbreviations (bitbucket)',
        ),
    )
    def test_abbreviation_expansion(template, abbreviations, expected_result):
        """Verify abbreviation unpacking."""
        expanded = expand_abbreviations(template, abbreviations)
>       assert expanded == expected_result
E       AssertionError: assert 'xx:a' == '<>'
E         
E         - <>
E         + xx:a

tests/repository/test_abbreviation_expansion.py:47: AssertionError

test_abbreviation_expansion.py::test_abbreviation_expansion[Correct expansion for builtin abbreviations (github)]

test_abbreviation_expansion.py::test_abbreviation_expansion[Correct expansion for builtin abbreviations (github)]
template = 'gh:pydanny/cookiecutter-django'
abbreviations = {'bb': 'https://bitbucket.org/{0}', 'gh': 'https://github.com/{0}.git', 'gl': 'https://gitlab.com/{0}.git'}
expected_result = 'https://github.com/pydanny/cookiecutter-django.git'

    @pytest.mark.parametrize(
        ('template', 'abbreviations', 'expected_result'),
        [
            ('foo', {'foo': 'bar'}, 'bar'),
            ('baz', {'foo': 'bar'}, 'baz'),
            ('xx:a', {'xx': '<{0}>'}, ''),
            ('gh:a', {'gh': '<{0}>'}, ''),
            ('xx:a', {'xx': '<>'}, '<>'),
            (
                'gh:pydanny/cookiecutter-django',
                BUILTIN_ABBREVIATIONS,
                'https://github.com/pydanny/cookiecutter-django.git',
            ),
            (
                'gl:pydanny/cookiecutter-django',
                BUILTIN_ABBREVIATIONS,
                'https://gitlab.com/pydanny/cookiecutter-django.git',
            ),
            (
                'bb:pydanny/cookiecutter-django',
                BUILTIN_ABBREVIATIONS,
                'https://bitbucket.org/pydanny/cookiecutter-django',
            ),
        ],
        ids=(
            'Simple expansion',
            'Skip expansion (expansion not an abbreviation)',
            'Expansion prefix',
            'expansion_override_builtin',
            'expansion_prefix_ignores_suffix',
            'Correct expansion for builtin abbreviations (github)',
            'Correct expansion for builtin abbreviations (gitlab)',
            'Correct expansion for builtin abbreviations (bitbucket)',
        ),
    )
    def test_abbreviation_expansion(template, abbreviations, expected_result):
        """Verify abbreviation unpacking."""
        expanded = expand_abbreviations(template, abbreviations)
>       assert expanded == expected_result
E       AssertionError: assert 'gh:pydanny/cookiecutter-django' == 'https://github.com/pydanny/cookiecutter-django.git'
E         
E         - https://github.com/pydanny/cookiecutter-django.git
E         + gh:pydanny/cookiecutter-django

tests/repository/test_abbreviation_expansion.py:47: AssertionError

test_abbreviation_expansion.py::test_abbreviation_expansion[Correct expansion for builtin abbreviations (gitlab)]

test_abbreviation_expansion.py::test_abbreviation_expansion[Correct expansion for builtin abbreviations (gitlab)]
template = 'gl:pydanny/cookiecutter-django'
abbreviations = {'bb': 'https://bitbucket.org/{0}', 'gh': 'https://github.com/{0}.git', 'gl': 'https://gitlab.com/{0}.git'}
expected_result = 'https://gitlab.com/pydanny/cookiecutter-django.git'

    @pytest.mark.parametrize(
        ('template', 'abbreviations', 'expected_result'),
        [
            ('foo', {'foo': 'bar'}, 'bar'),
            ('baz', {'foo': 'bar'}, 'baz'),
            ('xx:a', {'xx': '<{0}>'}, ''),
            ('gh:a', {'gh': '<{0}>'}, ''),
            ('xx:a', {'xx': '<>'}, '<>'),
            (
                'gh:pydanny/cookiecutter-django',
                BUILTIN_ABBREVIATIONS,
                'https://github.com/pydanny/cookiecutter-django.git',
            ),
            (
                'gl:pydanny/cookiecutter-django',
                BUILTIN_ABBREVIATIONS,
                'https://gitlab.com/pydanny/cookiecutter-django.git',
            ),
            (
                'bb:pydanny/cookiecutter-django',
                BUILTIN_ABBREVIATIONS,
                'https://bitbucket.org/pydanny/cookiecutter-django',
            ),
        ],
        ids=(
            'Simple expansion',
            'Skip expansion (expansion not an abbreviation)',
            'Expansion prefix',
            'expansion_override_builtin',
            'expansion_prefix_ignores_suffix',
            'Correct expansion for builtin abbreviations (github)',
            'Correct expansion for builtin abbreviations (gitlab)',
            'Correct expansion for builtin abbreviations (bitbucket)',
        ),
    )
    def test_abbreviation_expansion(template, abbreviations, expected_result):
        """Verify abbreviation unpacking."""
        expanded = expand_abbreviations(template, abbreviations)
>       assert expanded == expected_result
E       AssertionError: assert 'gl:pydanny/cookiecutter-django' == 'https://gitlab.com/pydanny/cookiecutter-django.git'
E         
E         - https://gitlab.com/pydanny/cookiecutter-django.git
E         + gl:pydanny/cookiecutter-django

tests/repository/test_abbreviation_expansion.py:47: AssertionError

test_abbreviation_expansion.py::test_abbreviation_expansion[Correct expansion for builtin abbreviations (bitbucket)]

test_abbreviation_expansion.py::test_abbreviation_expansion[Correct expansion for builtin abbreviations (bitbucket)]
template = 'bb:pydanny/cookiecutter-django'
abbreviations = {'bb': 'https://bitbucket.org/{0}', 'gh': 'https://github.com/{0}.git', 'gl': 'https://gitlab.com/{0}.git'}
expected_result = 'https://bitbucket.org/pydanny/cookiecutter-django'

    @pytest.mark.parametrize(
        ('template', 'abbreviations', 'expected_result'),
        [
            ('foo', {'foo': 'bar'}, 'bar'),
            ('baz', {'foo': 'bar'}, 'baz'),
            ('xx:a', {'xx': '<{0}>'}, ''),
            ('gh:a', {'gh': '<{0}>'}, ''),
            ('xx:a', {'xx': '<>'}, '<>'),
            (
                'gh:pydanny/cookiecutter-django',
                BUILTIN_ABBREVIATIONS,
                'https://github.com/pydanny/cookiecutter-django.git',
            ),
            (
                'gl:pydanny/cookiecutter-django',
                BUILTIN_ABBREVIATIONS,
                'https://gitlab.com/pydanny/cookiecutter-django.git',
            ),
            (
                'bb:pydanny/cookiecutter-django',
                BUILTIN_ABBREVIATIONS,
                'https://bitbucket.org/pydanny/cookiecutter-django',
            ),
        ],
        ids=(
            'Simple expansion',
            'Skip expansion (expansion not an abbreviation)',
            'Expansion prefix',
            'expansion_override_builtin',
            'expansion_prefix_ignores_suffix',
            'Correct expansion for builtin abbreviations (github)',
            'Correct expansion for builtin abbreviations (gitlab)',
            'Correct expansion for builtin abbreviations (bitbucket)',
        ),
    )
    def test_abbreviation_expansion(template, abbreviations, expected_result):
        """Verify abbreviation unpacking."""
        expanded = expand_abbreviations(template, abbreviations)
>       assert expanded == expected_result
E       AssertionError: assert 'bb:pydanny/cookiecutter-django' == 'https://bitbucket.org/pydanny/cookiecutter-django'
E         
E         - https://bitbucket.org/pydanny/cookiecutter-django
E         + bb:pydanny/cookiecutter-django

tests/repository/test_abbreviation_expansion.py:47: AssertionError

test_abbreviation_expansion.py::test_abbreviation_expansion_prefix_not_0_in_braces

test_abbreviation_expansion.py::test_abbreviation_expansion_prefix_not_0_in_braces
def test_abbreviation_expansion_prefix_not_0_in_braces():
        """Verify abbreviation unpacking raises error on incorrect index."""
>       with pytest.raises(IndexError):
E       Failed: DID NOT RAISE 

tests/repository/test_abbreviation_expansion.py:52: Failed

zipfile.zip-True]

zipfile.zip-True]
mocker = 
template = 'https://example.com/path/to/zipfile.zip', is_url = True
user_config_data = {'cookiecutters_dir': '/tmp/pytest-of-root/pytest-0/user_dir0/cookiecutters', 'replay_dir': '/tmp/pytest-of-root/pytest-0/user_dir0/cookiecutter_replay'}

    @pytest.mark.parametrize(
        'template, is_url',
        [
            ('/path/to/zipfile.zip', False),
            ('https://example.com/path/to/zipfile.zip', True),
            ('http://example.com/path/to/zipfile.zip', True),
        ],
    )
    def test_zipfile_unzip(mocker, template, is_url, user_config_data):
        """Verify zip files correctly handled for different source locations.

        `unzip()` should be called with correct args when `determine_repo_dir()`
        is passed a zipfile, or a URL to a zipfile.
        """
        mock_clone = mocker.patch(
            'cookiecutter.repository.unzip',
            return_value='tests/fake-repo-tmpl',
            autospec=True,
        )

>       project_dir, cleanup = repository.determine_repo_dir(
            template,
            abbreviations={},
            clone_to_dir=user_config_data['cookiecutters_dir'],
            checkout=None,
            no_input=True,
            password=None,
        )

tests/repository/test_determine_repo_dir_clones_repo.py:30: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
cookiecutter/repository.py:78: in determine_repo_dir
    repo_dir = clone(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

repo_url = 'https://example.com/path/to/zipfile.zip', checkout = None
clone_to_dir = '/tmp/pytest-of-root/pytest-0/user_dir0/cookiecutters'
no_input = True

    def clone(repo_url: str, checkout: Optional[str]=None, clone_to_dir:
        'os.PathLike[str]'='.', no_input: bool=False):
        """Clone a repo to the current directory.

        :param repo_url: Repo URL of unknown type.
        :param checkout: The branch, tag or commit ID to checkout after clone.
        :param clone_to_dir: The directory to clone to.
                             Defaults to the current directory.
        :param no_input: Do not prompt for user input and eventually force a refresh of
            cached resources.
        :returns: str with path to the new directory of the repository.
        """
>       repo_type, repo_url = identify_repo(repo_url)
E       TypeError: cannot unpack non-iterable NoneType object

cookiecutter/vcs.py:61: TypeError

zipfile.zip-True]

zipfile.zip-True]
mocker = 
template = 'http://example.com/path/to/zipfile.zip', is_url = True
user_config_data = {'cookiecutters_dir': '/tmp/pytest-of-root/pytest-0/user_dir0/cookiecutters', 'replay_dir': '/tmp/pytest-of-root/pytest-0/user_dir0/cookiecutter_replay'}

    @pytest.mark.parametrize(
        'template, is_url',
        [
            ('/path/to/zipfile.zip', False),
            ('https://example.com/path/to/zipfile.zip', True),
            ('http://example.com/path/to/zipfile.zip', True),
        ],
    )
    def test_zipfile_unzip(mocker, template, is_url, user_config_data):
        """Verify zip files correctly handled for different source locations.

        `unzip()` should be called with correct args when `determine_repo_dir()`
        is passed a zipfile, or a URL to a zipfile.
        """
        mock_clone = mocker.patch(
            'cookiecutter.repository.unzip',
            return_value='tests/fake-repo-tmpl',
            autospec=True,
        )

>       project_dir, cleanup = repository.determine_repo_dir(
            template,
            abbreviations={},
            clone_to_dir=user_config_data['cookiecutters_dir'],
            checkout=None,
            no_input=True,
            password=None,
        )

tests/repository/test_determine_repo_dir_clones_repo.py:30: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
cookiecutter/repository.py:78: in determine_repo_dir
    repo_dir = clone(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

repo_url = 'http://example.com/path/to/zipfile.zip', checkout = None
clone_to_dir = '/tmp/pytest-of-root/pytest-0/user_dir0/cookiecutters'
no_input = True

    def clone(repo_url: str, checkout: Optional[str]=None, clone_to_dir:
        'os.PathLike[str]'='.', no_input: bool=False):
        """Clone a repo to the current directory.

        :param repo_url: Repo URL of unknown type.
        :param checkout: The branch, tag or commit ID to checkout after clone.
        :param clone_to_dir: The directory to clone to.
                             Defaults to the current directory.
        :param no_input: Do not prompt for user input and eventually force a refresh of
            cached resources.
        :returns: str with path to the new directory of the repository.
        """
>       repo_type, repo_url = identify_repo(repo_url)
E       TypeError: cannot unpack non-iterable NoneType object

cookiecutter/vcs.py:61: TypeError

test_determine_repo_dir_clones_repo.py::test_repository_url_should_clone

test_determine_repo_dir_clones_repo.py::test_repository_url_should_clone
mocker = 
template_url = 'https://github.com/pytest-dev/cookiecutter-pytest-plugin.git'
user_config_data = {'cookiecutters_dir': '/tmp/pytest-of-root/pytest-0/user_dir0/cookiecutters', 'replay_dir': '/tmp/pytest-of-root/pytest-0/user_dir0/cookiecutter_replay'}

    def test_repository_url_should_clone(mocker, template_url, user_config_data):
        """Verify repository url triggers clone function.

        `clone()` should be called with correct args when `determine_repo_dir()` is
        passed a repository template url.
        """
        mock_clone = mocker.patch(
            'cookiecutter.repository.clone',
            return_value='tests/fake-repo-tmpl',
            autospec=True,
        )

        project_dir, cleanup = repository.determine_repo_dir(
            template_url,
            abbreviations={},
            clone_to_dir=user_config_data['cookiecutters_dir'],
            checkout=None,
            no_input=True,
        )

        mock_clone.assert_called_once_with(
            repo_url=template_url,
            checkout=None,
            clone_to_dir=user_config_data['cookiecutters_dir'],
            no_input=True,
        )

        assert os.path.isdir(project_dir)
>       assert not cleanup
E       assert not True

tests/repository/test_determine_repo_dir_clones_repo.py:89: AssertionError

test_determine_repo_dir_clones_repo.py::test_repository_url_with_no_context_file

test_determine_repo_dir_clones_repo.py::test_repository_url_with_no_context_file
mocker = 
template_url = 'https://github.com/pytest-dev/cookiecutter-pytest-plugin.git'
user_config_data = {'cookiecutters_dir': '/tmp/pytest-of-root/pytest-0/user_dir0/cookiecutters', 'replay_dir': '/tmp/pytest-of-root/pytest-0/user_dir0/cookiecutter_replay'}

    def test_repository_url_with_no_context_file(mocker, template_url, user_config_data):
        """Verify cloned repository without `cookiecutter.json` file raises error."""
        mocker.patch(
            'cookiecutter.repository.clone',
            return_value='tests/fake-repo-bad',
            autospec=True,
        )

        with pytest.raises(exceptions.RepositoryNotFound) as err:
            repository.determine_repo_dir(
                template_url,
                abbreviations={},
                clone_to_dir=None,
                checkout=None,
                no_input=True,
            )

>       assert str(err.value) == (
            'A valid repository for "{}" could not be found in the following '
            'locations:\n{}'.format(template_url, 'tests/fake-repo-bad')
        )
E       assert 'The repository tests/fake-repo-bad does not contain a cookiecutter.json file' == 'A valid repository for "https://github.com/pytest-dev/cookiecutter-pytest-plugin.git" could not be found in the following locations:\ntests/fake-repo-bad'
E         
E         + The repository tests/fake-repo-bad does not contain a cookiecutter.json file
E         - A valid repository for "https://github.com/pytest-dev/cookiecutter-pytest-plugin.git" could not be found in the following locations:
E         - tests/fake-repo-bad

tests/repository/test_determine_repo_dir_clones_repo.py:110: AssertionError

test_determine_repo_dir_finds_existing_cookiecutter.py::test_should_find_existing_cookiecutter

test_determine_repo_dir_finds_existing_cookiecutter.py::test_should_find_existing_cookiecutter
template = 'cookiecutter-pytest-plugin'
user_config_data = {'cookiecutters_dir': '/tmp/pytest-of-root/pytest-0/user_dir0/cookiecutters', 'replay_dir': '/tmp/pytest-of-root/pytest-0/user_dir0/cookiecutter_replay'}
cloned_cookiecutter_path = '/tmp/pytest-of-root/pytest-0/user_dir0/cookiecutters/cookiecutter-pytest-plugin'

    def test_should_find_existing_cookiecutter(
        template, user_config_data, cloned_cookiecutter_path
    ):
        """
        Should find folder created by `cloned_cookiecutter_path` and return it.

        This folder is considered like previously cloned project directory.
        """
>       project_dir, cleanup = repository.determine_repo_dir(
            template=template,
            abbreviations={},
            clone_to_dir=user_config_data['cookiecutters_dir'],
            checkout=None,
            no_input=True,
        )

tests/repository/test_determine_repo_dir_finds_existing_cookiecutter.py:38: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

template = 'cookiecutter-pytest-plugin', abbreviations = {}
clone_to_dir = '/tmp/pytest-of-root/pytest-0/user_dir0/cookiecutters'
checkout = None, no_input = True, password = None, directory = None

    def determine_repo_dir(template, abbreviations, clone_to_dir, checkout,
        no_input, password=None, directory=None):
        """
        Locate the repository directory from a template reference.

        Applies repository abbreviations to the template reference.
        If the template refers to a repository URL, clone it.
        If the template is a path to a local repository, use it.

        :param template: A directory containing a project template directory,
            or a URL to a git repository.
        :param abbreviations: A dictionary of repository abbreviation
            definitions.
        :param clone_to_dir: The directory to clone the repository into.
        :param checkout: The branch, tag or commit ID to checkout after clone.
        :param no_input: Do not prompt for user input and eventually force a refresh of
            cached resources.
        :param password: The password to use when extracting the repository.
        :param directory: Directory within repo where cookiecutter.json lives.
        :return: A tuple containing the cookiecutter template directory, and
            a boolean describing whether that directory should be cleaned up
            after the template has been instantiated.
        :raises: `RepositoryNotFound` if a repository directory could not be found.
        """
        template = expand_abbreviations(template, abbreviations)

        if is_repo_url(template):
            repo_dir = clone(
                repo_url=template,
                checkout=checkout,
                clone_to_dir=clone_to_dir,
                no_input=no_input
            )
            cleanup = True
        elif is_zip_file(template):
            repo_dir = unzip(
                zip_uri=template,
                is_url=is_repo_url(template),
                clone_to_dir=clone_to_dir,
                no_input=no_input,
                password=password
            )
            cleanup = True
        else:
            repo_dir = template
            cleanup = False

        if directory:
            repo_dir = os.path.join(repo_dir, directory)

        if not repository_has_cookiecutter_json(repo_dir):
>           raise RepositoryNotFound(
                'The repository {} does not contain a cookiecutter.json file'.format(repo_dir)
            )
E           cookiecutter.exceptions.RepositoryNotFound: The repository cookiecutter-pytest-plugin does not contain a cookiecutter.json file

cookiecutter/repository.py:102: RepositoryNotFound

test_determine_repo_dir_finds_subdirectories.py::test_should_find_existing_cookiecutter

test_determine_repo_dir_finds_subdirectories.py::test_should_find_existing_cookiecutter
template = 'cookiecutter-pytest-plugin'
user_config_data = {'cookiecutters_dir': '/tmp/pytest-of-root/pytest-0/user_dir0/cookiecutters', 'replay_dir': '/tmp/pytest-of-root/pytest-0/user_dir0/cookiecutter_replay'}
cloned_cookiecutter_path = '/tmp/pytest-of-root/pytest-0/user_dir0/cookiecutters/cookiecutter-pytest-plugin/my-dir'

    def test_should_find_existing_cookiecutter(
        template, user_config_data, cloned_cookiecutter_path
    ):
        """Find `cookiecutter.json` in sub folder created by `cloned_cookiecutter_path`."""
>       project_dir, cleanup = repository.determine_repo_dir(
            template=template,
            abbreviations={},
            clone_to_dir=user_config_data['cookiecutters_dir'],
            checkout=None,
            no_input=True,
            directory='my-dir',
        )

tests/repository/test_determine_repo_dir_finds_subdirectories.py:38: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

template = 'cookiecutter-pytest-plugin', abbreviations = {}
clone_to_dir = '/tmp/pytest-of-root/pytest-0/user_dir0/cookiecutters'
checkout = None, no_input = True, password = None, directory = 'my-dir'

    def determine_repo_dir(template, abbreviations, clone_to_dir, checkout,
        no_input, password=None, directory=None):
        """
        Locate the repository directory from a template reference.

        Applies repository abbreviations to the template reference.
        If the template refers to a repository URL, clone it.
        If the template is a path to a local repository, use it.

        :param template: A directory containing a project template directory,
            or a URL to a git repository.
        :param abbreviations: A dictionary of repository abbreviation
            definitions.
        :param clone_to_dir: The directory to clone the repository into.
        :param checkout: The branch, tag or commit ID to checkout after clone.
        :param no_input: Do not prompt for user input and eventually force a refresh of
            cached resources.
        :param password: The password to use when extracting the repository.
        :param directory: Directory within repo where cookiecutter.json lives.
        :return: A tuple containing the cookiecutter template directory, and
            a boolean describing whether that directory should be cleaned up
            after the template has been instantiated.
        :raises: `RepositoryNotFound` if a repository directory could not be found.
        """
        template = expand_abbreviations(template, abbreviations)

        if is_repo_url(template):
            repo_dir = clone(
                repo_url=template,
                checkout=checkout,
                clone_to_dir=clone_to_dir,
                no_input=no_input
            )
            cleanup = True
        elif is_zip_file(template):
            repo_dir = unzip(
                zip_uri=template,
                is_url=is_repo_url(template),
                clone_to_dir=clone_to_dir,
                no_input=no_input,
                password=password
            )
            cleanup = True
        else:
            repo_dir = template
            cleanup = False

        if directory:
            repo_dir = os.path.join(repo_dir, directory)

        if not repository_has_cookiecutter_json(repo_dir):
>           raise RepositoryNotFound(
                'The repository {} does not contain a cookiecutter.json file'.format(repo_dir)
            )
E           cookiecutter.exceptions.RepositoryNotFound: The repository cookiecutter-pytest-plugin/my-dir does not contain a cookiecutter.json file

cookiecutter/repository.py:102: RepositoryNotFound

test_determine_repo_dir_finds_subdirectories.py::test_local_repo_typo

test_determine_repo_dir_finds_subdirectories.py::test_local_repo_typo
template = 'cookiecutter-pytest-plugin'
user_config_data = {'cookiecutters_dir': '/tmp/pytest-of-root/pytest-0/user_dir0/cookiecutters', 'replay_dir': '/tmp/pytest-of-root/pytest-0/user_dir0/cookiecutter_replay'}
cloned_cookiecutter_path = '/tmp/pytest-of-root/pytest-0/user_dir0/cookiecutters/cookiecutter-pytest-plugin/my-dir'

    def test_local_repo_typo(template, user_config_data, cloned_cookiecutter_path):
        """Wrong pointing to `cookiecutter.json` sub-directory should raise."""
        with pytest.raises(exceptions.RepositoryNotFound) as err:
            repository.determine_repo_dir(
                template=template,
                abbreviations={},
                clone_to_dir=user_config_data['cookiecutters_dir'],
                checkout=None,
                no_input=True,
                directory='wrong-dir',
            )

        wrong_full_cookiecutter_path = os.path.join(
            os.path.dirname(cloned_cookiecutter_path), 'wrong-dir'
        )
>       assert str(err.value) == (
            'A valid repository for "{}" could not be found in the following '
            'locations:\n{}'.format(
                template,
                '\n'.join(
                    [os.path.join(template, 'wrong-dir'), wrong_full_cookiecutter_path]
                ),
            )
        )
E       assert 'The repository cookiecutter-pytest-plugin/wrong-dir does not contain a cookiecutter.json file' == 'A valid repository for "cookiecutter-pytest-plugin" could not be found in the following locations:\ncookiecutter-pytest-plugin/wrong-dir\n/tmp/pytest-of-root/pytest-0/user_dir0/cookiecutters/cookiecutter-pytest-plugin/wrong-dir'
E         
E         + The repository cookiecutter-pytest-plugin/wrong-dir does not contain a cookiecutter.json file
E         - A valid repository for "cookiecutter-pytest-plugin" could not be found in the following locations:
E         - cookiecutter-pytest-plugin/wrong-dir
E         - /tmp/pytest-of-root/pytest-0/user_dir0/cookiecutters/cookiecutter-pytest-plugin/wrong-dir

tests/repository/test_determine_repo_dir_finds_subdirectories.py:66: AssertionError

test_determine_repository_should_use_local_repo.py::test_local_repo_with_no_context_raises

test_determine_repository_should_use_local_repo.py::test_local_repo_with_no_context_raises
tmp_path = PosixPath('/tmp/pytest-of-root/pytest-0/test_local_repo_with_no_contex0')

    def test_local_repo_with_no_context_raises(tmp_path):
        """A local repository without a cookiecutter.json should raise a \
        `RepositoryNotFound` exception."""
        template_path = str(Path('tests', 'fake-repo-bad'))
        with pytest.raises(exceptions.RepositoryNotFound) as err:
            repository.determine_repo_dir(
                template_path,
                abbreviations={},
                clone_to_dir=str(tmp_path),
                checkout=None,
                no_input=True,
            )

>       assert str(err.value) == (
            'A valid repository for "{}" could not be found in the following '
            'locations:\n{}'.format(
                template_path,
                '\n'.join(
                    [template_path, str(tmp_path.joinpath('tests', 'fake-repo-bad'))]
                ),
            )
        )
E       assert 'The repository tests/fake-repo-bad does not contain a cookiecutter.json file' == 'A valid repository for "tests/fake-repo-bad" could not be found in the following locations:\ntests/fake-repo-bad\n/tmp/pytest-of-root/pytest-0/test_local_repo_with_no_contex0/tests/fake-repo-bad'
E         
E         + The repository tests/fake-repo-bad does not contain a cookiecutter.json file
E         - A valid repository for "tests/fake-repo-bad" could not be found in the following locations:
E         - tests/fake-repo-bad
E         - /tmp/pytest-of-root/pytest-0/test_local_repo_with_no_contex0/tests/fake-repo-bad

tests/repository/test_determine_repository_should_use_local_repo.py:37: AssertionError

test_determine_repository_should_use_local_repo.py::test_local_repo_typo

test_determine_repository_should_use_local_repo.py::test_local_repo_typo
tmp_path = PosixPath('/tmp/pytest-of-root/pytest-0/test_local_repo_typo1')

    def test_local_repo_typo(tmp_path):
        """An unknown local repository should raise a `RepositoryNotFound` \
        exception."""
        template_path = str(Path('tests', 'unknown-repo'))
        with pytest.raises(exceptions.RepositoryNotFound) as err:
            repository.determine_repo_dir(
                template_path,
                abbreviations={},
                clone_to_dir=str(tmp_path),
                checkout=None,
                no_input=True,
            )

>       assert str(err.value) == (
            'A valid repository for "{}" could not be found in the following '
            'locations:\n{}'.format(
                template_path,
                '\n'.join([template_path, str(tmp_path.joinpath('tests', 'unknown-repo'))]),
            )
        )
E       assert 'The repository tests/unknown-repo does not contain a cookiecutter.json file' == 'A valid repository for "tests/unknown-repo" could not be found in the following locations:\ntests/unknown-repo\n/tmp/pytest-of-root/pytest-0/test_local_repo_typo1/tests/unknown-repo'
E         
E         + The repository tests/unknown-repo does not contain a cookiecutter.json file
E         - A valid repository for "tests/unknown-repo" could not be found in the following locations:
E         - tests/unknown-repo
E         - /tmp/pytest-of-root/pytest-0/test_local_repo_typo1/tests/unknown-repo

tests/repository/test_determine_repository_should_use_local_repo.py:61: AssertionError

test_is_repo_url.py::test_expand_abbreviations

test_is_repo_url.py::test_expand_abbreviations
def test_expand_abbreviations():
        """Validate `repository.expand_abbreviations` correctly translate url."""
        template = 'gh:audreyfeldroy/cookiecutter-pypackage'

        # This is not a valid repo url just yet!
        # First `repository.expand_abbreviations` needs to translate it
        assert is_repo_url(template) is False

        expanded_template = expand_abbreviations(template, BUILTIN_ABBREVIATIONS)
>       assert is_repo_url(expanded_template) is True
E       AssertionError: assert False is True
E        +  where False = is_repo_url('gh:audreyfeldroy/cookiecutter-pypackage')

tests/repository/test_is_repo_url.py:76: AssertionError

test_abort_generate_on_hook_error.py::test_hooks_raises_errors[pre_gen_hook_raises_error]

test_abort_generate_on_hook_error.py::test_hooks_raises_errors[pre_gen_hook_raises_error]
tmp_path = PosixPath('/tmp/pytest-of-root/pytest-0/test_hooks_raises_errors_pre_g0')
abort_pre_gen = 'yes', abort_post_gen = 'no'

    @pytest.mark.parametrize(
        ("abort_pre_gen", "abort_post_gen"),
        (("yes", "no"), ("no", "yes")),
        ids=("pre_gen_hook_raises_error", "post_gen_hook_raises_error"),
    )
    @pytest.mark.usefixtures("clean_system")
    def test_hooks_raises_errors(tmp_path, abort_pre_gen, abort_post_gen):
        """Verify pre- and pos-gen errors raises correct error code from script.

        This allows developers to make different error codes in their code,
        for different errors.
        """
        context = {
            "cookiecutter": {
                "repo_dir": "foobar",
                "abort_pre_gen": abort_pre_gen,
                "abort_post_gen": abort_post_gen,
            }
        }

        with pytest.raises(exceptions.FailedHookException) as error:
>           generate.generate_files(
                repo_dir="tests/hooks-abort-render",
                context=context,
                output_dir=str(tmp_path),
            )

tests/test_abort_generate_on_hook_error.py:34: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

repo_dir = 'tests/hooks-abort-render'
context = {'cookiecutter': {'abort_post_gen': 'no', 'abort_pre_gen': 'yes', 'repo_dir': 'foobar'}}
output_dir = '/tmp/pytest-of-root/pytest-0/test_hooks_raises_errors_pre_g0'
overwrite_if_exists = False, skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False

    def generate_files(repo_dir, context=None, output_dir='.',
        overwrite_if_exists=False, skip_if_file_exists=False, accept_hooks=True,
        keep_project_on_failure=False):
        """Render the templates and saves them to files.

        :param repo_dir: Project template input directory.
        :param context: Dict for populating the template's variables.
        :param output_dir: Where to output the generated project dir into.
        :param overwrite_if_exists: Overwrite the contents of the output directory
            if it exists.
        :param skip_if_file_exists: Skip the files in the corresponding directories
            if they already exist
        :param accept_hooks: Accept pre and post hooks if set to `True`.
        :param keep_project_on_failure: If `True` keep generated project directory even when
            generation fails
        """
>       template_dir = find_template(repo_dir)
E       TypeError: find_template() missing 1 required positional argument: 'env'

cookiecutter/generate.py:225: TypeError

test_abort_generate_on_hook_error.py::test_hooks_raises_errors[post_gen_hook_raises_error]

test_abort_generate_on_hook_error.py::test_hooks_raises_errors[post_gen_hook_raises_error]
tmp_path = PosixPath('/tmp/pytest-of-root/pytest-0/test_hooks_raises_errors_post_0')
abort_pre_gen = 'no', abort_post_gen = 'yes'

    @pytest.mark.parametrize(
        ("abort_pre_gen", "abort_post_gen"),
        (("yes", "no"), ("no", "yes")),
        ids=("pre_gen_hook_raises_error", "post_gen_hook_raises_error"),
    )
    @pytest.mark.usefixtures("clean_system")
    def test_hooks_raises_errors(tmp_path, abort_pre_gen, abort_post_gen):
        """Verify pre- and pos-gen errors raises correct error code from script.

        This allows developers to make different error codes in their code,
        for different errors.
        """
        context = {
            "cookiecutter": {
                "repo_dir": "foobar",
                "abort_pre_gen": abort_pre_gen,
                "abort_post_gen": abort_post_gen,
            }
        }

        with pytest.raises(exceptions.FailedHookException) as error:
>           generate.generate_files(
                repo_dir="tests/hooks-abort-render",
                context=context,
                output_dir=str(tmp_path),
            )

tests/test_abort_generate_on_hook_error.py:34: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

repo_dir = 'tests/hooks-abort-render'
context = {'cookiecutter': {'abort_post_gen': 'yes', 'abort_pre_gen': 'no', 'repo_dir': 'foobar'}}
output_dir = '/tmp/pytest-of-root/pytest-0/test_hooks_raises_errors_post_0'
overwrite_if_exists = False, skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False

    def generate_files(repo_dir, context=None, output_dir='.',
        overwrite_if_exists=False, skip_if_file_exists=False, accept_hooks=True,
        keep_project_on_failure=False):
        """Render the templates and saves them to files.

        :param repo_dir: Project template input directory.
        :param context: Dict for populating the template's variables.
        :param output_dir: Where to output the generated project dir into.
        :param overwrite_if_exists: Overwrite the contents of the output directory
            if it exists.
        :param skip_if_file_exists: Skip the files in the corresponding directories
            if they already exist
        :param accept_hooks: Accept pre and post hooks if set to `True`.
        :param keep_project_on_failure: If `True` keep generated project directory even when
            generation fails
        """
>       template_dir = find_template(repo_dir)
E       TypeError: find_template() missing 1 required positional argument: 'env'

cookiecutter/generate.py:225: TypeError

test_cli.py::test_cli_error_on_existing_output_directory

test_cli.py::test_cli_error_on_existing_output_directory
cli_runner = .cli_main at 0x7fcb9265e680>

    @pytest.mark.usefixtures('make_fake_project_dir', 'remove_fake_project_dir')
    def test_cli_error_on_existing_output_directory(cli_runner):
        """Test cli invocation without `overwrite-if-exists` fail if dir exist."""
        result = cli_runner('tests/fake-repo-pre/', '--no-input')
        assert result.exit_code != 0
        expected_error_msg = 'Error: "fake-project" directory already exists\n'
>       assert result.output == expected_error_msg
E       assert '' == 'Error: "fake-project" directory already exists\n'
E         
E         - Error: "fake-project" directory already exists

tests/test_cli.py:81: AssertionError

test_cli.py::test_cli

test_cli.py::test_cli
cli_runner = .cli_main at 0x7fcb9265e680>

    @pytest.mark.usefixtures('remove_fake_project_dir')
    def test_cli(cli_runner):
        """Test cli invocation work without flags if directory not exist."""
        result = cli_runner('tests/fake-repo-pre/', '--no-input')
>       assert result.exit_code == 0
E       assert 1 == 0
E        +  where 1 = .exit_code

tests/test_cli.py:88: AssertionError

test_cli.py::test_cli_verbose

test_cli.py::test_cli_verbose
cli_runner = .cli_main at 0x7fcb9265e680>

    @pytest.mark.usefixtures('remove_fake_project_dir')
    def test_cli_verbose(cli_runner):
        """Test cli invocation display log if called with `verbose` flag."""
        result = cli_runner('tests/fake-repo-pre/', '--no-input', '-v')
>       assert result.exit_code == 0
E       assert 1 == 0
E        +  where 1 = .exit_code

tests/test_cli.py:98: AssertionError

test_cli.py::test_cli_replay

test_cli.py::test_cli_replay
self = 
args = ('tests/fake-repo-pre/', None, False)
kwargs = {'accept_hooks': True, 'config_file': None, 'default_config': False, 'directory': None, ...}
expected = call('tests/fake-repo-pre/', None, False, replay=True, overwrite_if_exists=False, skip_if_file_exists=False, output_dir='.', config_file=None, default_config=False, extra_context=None, password=None, directory=None, accept_hooks=True, keep_project_on_failure=False)
actual = call('tests/fake-repo-pre/', checkout=None, no_input=False, extra_context=OrderedDict(), replay=True, overwrite_if_exists=False, output_dir='.', config_file=None, default_config=False, password=None, directory=None, skip_if_file_exists=False, accept_hooks='yes', keep_project_on_failure=False)
_error_message = ._error_message at 0x7fcb92725090>
cause = None

    def assert_called_with(self, /, *args, **kwargs):
        """assert that the last call was made with the specified arguments.

        Raises an AssertionError if the args and keyword args passed in are
        different to the last call to the mock."""
        if self.call_args is None:
            expected = self._format_mock_call_signature(args, kwargs)
            actual = 'not called.'
            error_message = ('expected call not found.\nExpected: %s\nActual: %s'
                    % (expected, actual))
            raise AssertionError(error_message)

        def _error_message():
            msg = self._format_mock_failure_message(args, kwargs)
            return msg
        expected = self._call_matcher(_Call((args, kwargs), two=True))
        actual = self._call_matcher(self.call_args)
        if actual != expected:
            cause = expected if isinstance(expected, Exception) else None
>           raise AssertionError(_error_message()) from cause
E           AssertionError: expected call not found.
E           Expected: cookiecutter('tests/fake-repo-pre/', None, False, replay=True, overwrite_if_exists=False, skip_if_file_exists=False, output_dir='.', config_file=None, default_config=False, extra_context=None, password=None, directory=None, accept_hooks=True, keep_project_on_failure=False)
E           Actual: cookiecutter('tests/fake-repo-pre/', checkout=None, no_input=False, extra_context=OrderedDict(), replay=True, overwrite_if_exists=False, output_dir='.', config_file=None, default_config=False, password=None, directory=None, skip_if_file_exists=False, accept_hooks='yes', keep_project_on_failure=False)

/usr/lib/python3.10/unittest/mock.py:929: AssertionError

During handling of the above exception, another exception occurred:

self = 
args = ('tests/fake-repo-pre/', None, False)
kwargs = {'accept_hooks': True, 'config_file': None, 'default_config': False, 'directory': None, ...}

    def assert_called_once_with(self, /, *args, **kwargs):
        """assert that the mock was called exactly once and that that call was
        with the specified arguments."""
        if not self.call_count == 1:
            msg = ("Expected '%s' to be called once. Called %s times.%s"
                   % (self._mock_name or 'mock',
                      self.call_count,
                      self._calls_repr()))
            raise AssertionError(msg)
>       return self.assert_called_with(*args, **kwargs)
E       AssertionError: expected call not found.
E       Expected: cookiecutter('tests/fake-repo-pre/', None, False, replay=True, overwrite_if_exists=False, skip_if_file_exists=False, output_dir='.', config_file=None, default_config=False, extra_context=None, password=None, directory=None, accept_hooks=True, keep_project_on_failure=False)
E       Actual: cookiecutter('tests/fake-repo-pre/', checkout=None, no_input=False, extra_context=OrderedDict(), replay=True, overwrite_if_exists=False, output_dir='.', config_file=None, default_config=False, password=None, directory=None, skip_if_file_exists=False, accept_hooks='yes', keep_project_on_failure=False)
E       
E       pytest introspection follows:
E       
E       Args:
E       assert ('tests/fake-repo-pre/',) == ('tests/fake-repo-pre/', None, False)
E         
E         Right contains 2 more items, first extra item: None
E         
E         Full diff:
E           (
E               'tests/fake-repo-pre/',
E         -     None,
E         -     False,
E           )
E       Kwargs:
E       assert {'checkout': None, 'no_input': False, 'extra_context': OrderedDict(), 'replay': True, 'overwrite_if_exists': False, 'output_dir': '.', 'config_file': None, 'default_config': False, 'password': None, 'directory': None, 'skip_if_file_exists': False, 'accept_hooks': 'yes', 'keep_project_on_failure': False} == {'replay': True, 'overwrite_if_exists': False, 'skip_if_file_exists': False, 'output_dir': '.', 'config_file': None, 'default_config': False, 'extra_context': None, 'password': None, 'directory': None, 'accept_hooks': True, 'keep_project_on_failure': False}
E         
E         Common items:
E         {'config_file': None,
E          'default_config': False,
E          'directory': None,
E          'keep_project_on_failure': False,
E          'output_dir': '.',
E          'overwrite_if_exists': False,
E          'password': None,
E          'replay': True,
E          'skip_if_file_exists': False}
E         Differing items:
E         {'extra_context': OrderedDict()} != {'extra_context': None}
E         {'accept_hooks': 'yes'} != {'accept_hooks': True}
E         Left contains 2 more items:
E         {'checkout': None, 'no_input': False}
E         
E         Full diff:
E           {
E         -     'accept_hooks': True,
E         ?                     ^^^
E         +     'accept_hooks': 'yes',
E         ?                     ^^ ++
E         +     'checkout': None,
E               'config_file': None,
E               'default_config': False,
E               'directory': None,
E         -     'extra_context': None,
E         ?                      ^^^
E         +     'extra_context': OrderedDict(),
E         ?                      ^^^ +++++++++
E               'keep_project_on_failure': False,
E         +     'no_input': False,
E               'output_dir': '.',
E               'overwrite_if_exists': False,
E               'password': None,
E               'replay': True,
E               'skip_if_file_exists': False,
E           }

/usr/lib/python3.10/unittest/mock.py:941: AssertionError

During handling of the above exception, another exception occurred:

mocker = 
cli_runner = .cli_main at 0x7fcb9265e680>

    @pytest.mark.usefixtures('remove_fake_project_dir')
    def test_cli_replay(mocker, cli_runner):
        """Test cli invocation display log with `verbose` and `replay` flags."""
        mock_cookiecutter = mocker.patch('cookiecutter.cli.cookiecutter')

        template_path = 'tests/fake-repo-pre/'
        result = cli_runner(template_path, '--replay', '-v')

        assert result.exit_code == 0
>       mock_cookiecutter.assert_called_once_with(
            template_path,
            None,
            False,
            replay=True,
            overwrite_if_exists=False,
            skip_if_file_exists=False,
            output_dir='.',
            config_file=None,
            default_config=False,
            extra_context=None,
            password=None,
            directory=None,
            accept_hooks=True,
            keep_project_on_failure=False,
        )
E       AssertionError: expected call not found.
E       Expected: cookiecutter('tests/fake-repo-pre/', None, False, replay=True, overwrite_if_exists=False, skip_if_file_exists=False, output_dir='.', config_file=None, default_config=False, extra_context=None, password=None, directory=None, accept_hooks=True, keep_project_on_failure=False)
E       Actual: cookiecutter('tests/fake-repo-pre/', checkout=None, no_input=False, extra_context=OrderedDict(), replay=True, overwrite_if_exists=False, output_dir='.', config_file=None, default_config=False, password=None, directory=None, skip_if_file_exists=False, accept_hooks='yes', keep_project_on_failure=False)
E       
E       pytest introspection follows:
E       
E       Args:
E       assert ('tests/fake-repo-pre/',) == ('tests/fake-repo-pre/', None, False)
E         
E         Right contains 2 more items, first extra item: None
E         
E         Full diff:
E           (
E               'tests/fake-repo-pre/',
E         -     None,
E         -     False,
E           )
E       Kwargs:
E       assert {'checkout': None, 'no_input': False, 'extra_context': OrderedDict(), 'replay': True, 'overwrite_if_exists': False, 'output_dir': '.', 'config_file': None, 'default_config': False, 'password': None, 'directory': None, 'skip_if_file_exists': False, 'accept_hooks': 'yes', 'keep_project_on_failure': False} == {'replay': True, 'overwrite_if_exists': False, 'skip_if_file_exists': False, 'output_dir': '.', 'config_file': None, 'default_config': False, 'extra_context': None, 'password': None, 'directory': None, 'accept_hooks': True, 'keep_project_on_failure': False}
E         
E         Common items:
E         {'config_file': None,
E          'default_config': False,
E          'directory': None,
E          'keep_project_on_failure': False,
E          'output_dir': '.',
E          'overwrite_if_exists': False,
E          'password': None,
E          'replay': True,
E          'skip_if_file_exists': False}
E         Differing items:
E         {'extra_context': OrderedDict()} != {'extra_context': None}
E         {'accept_hooks': 'yes'} != {'accept_hooks': True}
E         Left contains 2 more items:
E         {'checkout': None, 'no_input': False}
E         
E         Full diff:
E           {
E         -     'accept_hooks': True,
E         ?                     ^^^
E         +     'accept_hooks': 'yes',
E         ?                     ^^ ++
E         +     'checkout': None,
E               'config_file': None,
E               'default_config': False,
E               'directory': None,
E         -     'extra_context': None,
E         ?                      ^^^
E         +     'extra_context': OrderedDict(),
E         ?                      ^^^ +++++++++
E               'keep_project_on_failure': False,
E         +     'no_input': False,
E               'output_dir': '.',
E               'overwrite_if_exists': False,
E               'password': None,
E               'replay': True,
E               'skip_if_file_exists': False,
E           }

tests/test_cli.py:113: AssertionError

test_cli.py::test_cli_replay_file

test_cli.py::test_cli_replay_file
self = 
args = ('tests/fake-repo-pre/', None, False)
kwargs = {'accept_hooks': True, 'config_file': None, 'default_config': False, 'directory': None, ...}
expected = call('tests/fake-repo-pre/', None, False, replay='~/custom-replay-file', overwrite_if_exists=False, skip_if_file_exists=False, output_dir='.', config_file=None, default_config=False, extra_context=None, password=None, directory=None, accept_hooks=True, keep_project_on_failure=False)
actual = call('tests/fake-repo-pre/', checkout=None, no_input=False, extra_context=OrderedDict(), replay=False, overwrite_if_exists=False, output_dir='.', config_file=None, default_config=False, password=None, directory=None, skip_if_file_exists=False, accept_hooks='yes', keep_project_on_failure=False)
_error_message = ._error_message at 0x7fcb92604af0>
cause = None

    def assert_called_with(self, /, *args, **kwargs):
        """assert that the last call was made with the specified arguments.

        Raises an AssertionError if the args and keyword args passed in are
        different to the last call to the mock."""
        if self.call_args is None:
            expected = self._format_mock_call_signature(args, kwargs)
            actual = 'not called.'
            error_message = ('expected call not found.\nExpected: %s\nActual: %s'
                    % (expected, actual))
            raise AssertionError(error_message)

        def _error_message():
            msg = self._format_mock_failure_message(args, kwargs)
            return msg
        expected = self._call_matcher(_Call((args, kwargs), two=True))
        actual = self._call_matcher(self.call_args)
        if actual != expected:
            cause = expected if isinstance(expected, Exception) else None
>           raise AssertionError(_error_message()) from cause
E           AssertionError: expected call not found.
E           Expected: cookiecutter('tests/fake-repo-pre/', None, False, replay='~/custom-replay-file', overwrite_if_exists=False, skip_if_file_exists=False, output_dir='.', config_file=None, default_config=False, extra_context=None, password=None, directory=None, accept_hooks=True, keep_project_on_failure=False)
E           Actual: cookiecutter('tests/fake-repo-pre/', checkout=None, no_input=False, extra_context=OrderedDict(), replay=False, overwrite_if_exists=False, output_dir='.', config_file=None, default_config=False, password=None, directory=None, skip_if_file_exists=False, accept_hooks='yes', keep_project_on_failure=False)

/usr/lib/python3.10/unittest/mock.py:929: AssertionError

During handling of the above exception, another exception occurred:

self = 
args = ('tests/fake-repo-pre/', None, False)
kwargs = {'accept_hooks': True, 'config_file': None, 'default_config': False, 'directory': None, ...}

    def assert_called_once_with(self, /, *args, **kwargs):
        """assert that the mock was called exactly once and that that call was
        with the specified arguments."""
        if not self.call_count == 1:
            msg = ("Expected '%s' to be called once. Called %s times.%s"
                   % (self._mock_name or 'mock',
                      self.call_count,
                      self._calls_repr()))
            raise AssertionError(msg)
>       return self.assert_called_with(*args, **kwargs)
E       AssertionError: expected call not found.
E       Expected: cookiecutter('tests/fake-repo-pre/', None, False, replay='~/custom-replay-file', overwrite_if_exists=False, skip_if_file_exists=False, output_dir='.', config_file=None, default_config=False, extra_context=None, password=None, directory=None, accept_hooks=True, keep_project_on_failure=False)
E       Actual: cookiecutter('tests/fake-repo-pre/', checkout=None, no_input=False, extra_context=OrderedDict(), replay=False, overwrite_if_exists=False, output_dir='.', config_file=None, default_config=False, password=None, directory=None, skip_if_file_exists=False, accept_hooks='yes', keep_project_on_failure=False)
E       
E       pytest introspection follows:
E       
E       Args:
E       assert ('tests/fake-repo-pre/',) == ('tests/fake-repo-pre/', None, False)
E         
E         Right contains 2 more items, first extra item: None
E         
E         Full diff:
E           (
E               'tests/fake-repo-pre/',
E         -     None,
E         -     False,
E           )
E       Kwargs:
E       assert {'checkout': None, 'no_input': False, 'extra_context': OrderedDict(), 'replay': False, 'overwrite_if_exists': False, 'output_dir': '.', 'config_file': None, 'default_config': False, 'password': None, 'directory': None, 'skip_if_file_exists': False, 'accept_hooks': 'yes', 'keep_project_on_failure': False} == {'replay': '~/custom-replay-file', 'overwrite_if_exists': False, 'skip_if_file_exists': False, 'output_dir': '.', 'config_file': None, 'default_config': False, 'extra_context': None, 'password': None, 'directory': None, 'accept_hooks': True, 'keep_project_on_failure': False}
E         
E         Common items:
E         {'config_file': None,
E          'default_config': False,
E          'directory': None,
E          'keep_project_on_failure': False,
E          'output_dir': '.',
E          'overwrite_if_exists': False,
E          'password': None,
E          'skip_if_file_exists': False}
E         Differing items:
E         {'extra_context': OrderedDict()} != {'extra_context': None}
E         {'replay': False} != {'replay': '~/custom-replay-file'}
E         {'accept_hooks': 'yes'} != {'accept_hooks': True}
E         Left contains 2 more items:
E         {'checkout': None, 'no_input': False}
E         
E         Full diff:
E           {
E         -     'accept_hooks': True,
E         ?                     ^^^
E         +     'accept_hooks': 'yes',
E         ?                     ^^ ++
E         +     'checkout': None,
E               'config_file': None,
E               'default_config': False,
E               'directory': None,
E         -     'extra_context': None,
E         ?                      ^^^
E         +     'extra_context': OrderedDict(),
E         ?                      ^^^ +++++++++
E               'keep_project_on_failure': False,
E         +     'no_input': False,
E               'output_dir': '.',
E               'overwrite_if_exists': False,
E               'password': None,
E         -     'replay': '~/custom-replay-file',
E         +     'replay': False,
E               'skip_if_file_exists': False,
E           }

/usr/lib/python3.10/unittest/mock.py:941: AssertionError

During handling of the above exception, another exception occurred:

mocker = 
cli_runner = .cli_main at 0x7fcb9265e680>

    @pytest.mark.usefixtures('remove_fake_project_dir')
    def test_cli_replay_file(mocker, cli_runner):
        """Test cli invocation correctly pass --replay-file option."""
        mock_cookiecutter = mocker.patch('cookiecutter.cli.cookiecutter')

        template_path = 'tests/fake-repo-pre/'
        result = cli_runner(template_path, '--replay-file', '~/custom-replay-file', '-v')

        assert result.exit_code == 0
>       mock_cookiecutter.assert_called_once_with(
            template_path,
            None,
            False,
            replay='~/custom-replay-file',
            overwrite_if_exists=False,
            skip_if_file_exists=False,
            output_dir='.',
            config_file=None,
            default_config=False,
            extra_context=None,
            password=None,
            directory=None,
            accept_hooks=True,
            keep_project_on_failure=False,
        )
E       AssertionError: expected call not found.
E       Expected: cookiecutter('tests/fake-repo-pre/', None, False, replay='~/custom-replay-file', overwrite_if_exists=False, skip_if_file_exists=False, output_dir='.', config_file=None, default_config=False, extra_context=None, password=None, directory=None, accept_hooks=True, keep_project_on_failure=False)
E       Actual: cookiecutter('tests/fake-repo-pre/', checkout=None, no_input=False, extra_context=OrderedDict(), replay=False, overwrite_if_exists=False, output_dir='.', config_file=None, default_config=False, password=None, directory=None, skip_if_file_exists=False, accept_hooks='yes', keep_project_on_failure=False)
E       
E       pytest introspection follows:
E       
E       Args:
E       assert ('tests/fake-repo-pre/',) == ('tests/fake-repo-pre/', None, False)
E         
E         Right contains 2 more items, first extra item: None
E         
E         Full diff:
E           (
E               'tests/fake-repo-pre/',
E         -     None,
E         -     False,
E           )
E       Kwargs:
E       assert {'checkout': None, 'no_input': False, 'extra_context': OrderedDict(), 'replay': False, 'overwrite_if_exists': False, 'output_dir': '.', 'config_file': None, 'default_config': False, 'password': None, 'directory': None, 'skip_if_file_exists': False, 'accept_hooks': 'yes', 'keep_project_on_failure': False} == {'replay': '~/custom-replay-file', 'overwrite_if_exists': False, 'skip_if_file_exists': False, 'output_dir': '.', 'config_file': None, 'default_config': False, 'extra_context': None, 'password': None, 'directory': None, 'accept_hooks': True, 'keep_project_on_failure': False}
E         
E         Common items:
E         {'config_file': None,
E          'default_config': False,
E          'directory': None,
E          'keep_project_on_failure': False,
E          'output_dir': '.',
E          'overwrite_if_exists': False,
E          'password': None,
E          'skip_if_file_exists': False}
E         Differing items:
E         {'extra_context': OrderedDict()} != {'extra_context': None}
E         {'replay': False} != {'replay': '~/custom-replay-file'}
E         {'accept_hooks': 'yes'} != {'accept_hooks': True}
E         Left contains 2 more items:
E         {'checkout': None, 'no_input': False}
E         
E         Full diff:
E           {
E         -     'accept_hooks': True,
E         ?                     ^^^
E         +     'accept_hooks': 'yes',
E         ?                     ^^ ++
E         +     'checkout': None,
E               'config_file': None,
E               'default_config': False,
E               'directory': None,
E         -     'extra_context': None,
E         ?                      ^^^
E         +     'extra_context': OrderedDict(),
E         ?                      ^^^ +++++++++
E               'keep_project_on_failure': False,
E         +     'no_input': False,
E               'output_dir': '.',
E               'overwrite_if_exists': False,
E               'password': None,
E         -     'replay': '~/custom-replay-file',
E         +     'replay': False,
E               'skip_if_file_exists': False,
E           }

tests/test_cli.py:140: AssertionError

test_cli.py::test_cli_replay_generated

test_cli.py::test_cli_replay_generated
mocker = 
cli_runner = .cli_main at 0x7fcb9265e680>

    @pytest.mark.usefixtures('remove_tmp_dir')
    def test_cli_replay_generated(mocker, cli_runner):
        """Test cli invocation correctly generates a project with replay."""
        template_path = 'tests/fake-repo-replay/'
        result = cli_runner(
            template_path,
            '--replay-file',
            'tests/test-replay/valid_replay.json',
            '-o',
            'tests/tmp/',
            '-v',
        )
>       assert result.exit_code == 0
E       assert 1 == 0
E        +  where 1 = .exit_code

tests/test_cli.py:170: AssertionError

test_cli.py::test_cli_exit_on_noinput_and_replay

test_cli.py::test_cli_exit_on_noinput_and_replay
mocker = 
cli_runner = .cli_main at 0x7fcb9265e680>

    @pytest.mark.usefixtures('remove_fake_project_dir')
    def test_cli_exit_on_noinput_and_replay(mocker, cli_runner):
        """Test cli invocation fail if both `no-input` and `replay` flags passed."""
        mock_cookiecutter = mocker.patch(
            'cookiecutter.cli.cookiecutter', side_effect=cookiecutter
        )

        template_path = 'tests/fake-repo-pre/'
        result = cli_runner(template_path, '--no-input', '--replay', '-v')

        assert result.exit_code == 1

        expected_error_msg = (
            "You can not use both replay and no_input or extra_context at the same time."
        )

>       assert expected_error_msg in result.output
E       assert 'You can not use both replay and no_input or extra_context at the same time.' in ''
E        +  where '' = .output

tests/test_cli.py:190: AssertionError

test_cli.py::test_run_cookiecutter_on_overwrite_if_exists_and_replay[-f]

test_cli.py::test_run_cookiecutter_on_overwrite_if_exists_and_replay[-f]
self = 
args = ('tests/fake-repo-pre/', None, False)
kwargs = {'accept_hooks': True, 'config_file': None, 'default_config': False, 'directory': None, ...}
expected = call('tests/fake-repo-pre/', None, False, replay=True, overwrite_if_exists=True, skip_if_file_exists=False, output_dir='.', config_file=None, default_config=False, extra_context=None, password=None, directory=None, accept_hooks=True, keep_project_on_failure=False)
actual = call('tests/fake-repo-pre/', checkout=None, no_input=False, extra_context=OrderedDict(), replay=True, overwrite_if_exists=True, output_dir='.', config_file=None, default_config=False, password=None, directory=None, skip_if_file_exists=False, accept_hooks='yes', keep_project_on_failure=False)
_error_message = ._error_message at 0x7fcb927bb880>
cause = None

    def assert_called_with(self, /, *args, **kwargs):
        """assert that the last call was made with the specified arguments.

        Raises an AssertionError if the args and keyword args passed in are
        different to the last call to the mock."""
        if self.call_args is None:
            expected = self._format_mock_call_signature(args, kwargs)
            actual = 'not called.'
            error_message = ('expected call not found.\nExpected: %s\nActual: %s'
                    % (expected, actual))
            raise AssertionError(error_message)

        def _error_message():
            msg = self._format_mock_failure_message(args, kwargs)
            return msg
        expected = self._call_matcher(_Call((args, kwargs), two=True))
        actual = self._call_matcher(self.call_args)
        if actual != expected:
            cause = expected if isinstance(expected, Exception) else None
>           raise AssertionError(_error_message()) from cause
E           AssertionError: expected call not found.
E           Expected: cookiecutter('tests/fake-repo-pre/', None, False, replay=True, overwrite_if_exists=True, skip_if_file_exists=False, output_dir='.', config_file=None, default_config=False, extra_context=None, password=None, directory=None, accept_hooks=True, keep_project_on_failure=False)
E           Actual: cookiecutter('tests/fake-repo-pre/', checkout=None, no_input=False, extra_context=OrderedDict(), replay=True, overwrite_if_exists=True, output_dir='.', config_file=None, default_config=False, password=None, directory=None, skip_if_file_exists=False, accept_hooks='yes', keep_project_on_failure=False)

/usr/lib/python3.10/unittest/mock.py:929: AssertionError

During handling of the above exception, another exception occurred:

self = 
args = ('tests/fake-repo-pre/', None, False)
kwargs = {'accept_hooks': True, 'config_file': None, 'default_config': False, 'directory': None, ...}

    def assert_called_once_with(self, /, *args, **kwargs):
        """assert that the mock was called exactly once and that that call was
        with the specified arguments."""
        if not self.call_count == 1:
            msg = ("Expected '%s' to be called once. Called %s times.%s"
                   % (self._mock_name or 'mock',
                      self.call_count,
                      self._calls_repr()))
            raise AssertionError(msg)
>       return self.assert_called_with(*args, **kwargs)
E       AssertionError: expected call not found.
E       Expected: cookiecutter('tests/fake-repo-pre/', None, False, replay=True, overwrite_if_exists=True, skip_if_file_exists=False, output_dir='.', config_file=None, default_config=False, extra_context=None, password=None, directory=None, accept_hooks=True, keep_project_on_failure=False)
E       Actual: cookiecutter('tests/fake-repo-pre/', checkout=None, no_input=False, extra_context=OrderedDict(), replay=True, overwrite_if_exists=True, output_dir='.', config_file=None, default_config=False, password=None, directory=None, skip_if_file_exists=False, accept_hooks='yes', keep_project_on_failure=False)
E       
E       pytest introspection follows:
E       
E       Args:
E       assert ('tests/fake-repo-pre/',) == ('tests/fake-repo-pre/', None, False)
E         
E         Right contains 2 more items, first extra item: None
E         
E         Full diff:
E           (
E               'tests/fake-repo-pre/',
E         -     None,
E         -     False,
E           )
E       Kwargs:
E       assert {'checkout': None, 'no_input': False, 'extra_context': OrderedDict(), 'replay': True, 'overwrite_if_exists': True, 'output_dir': '.', 'config_file': None, 'default_config': False, 'password': None, 'directory': None, 'skip_if_file_exists': False, 'accept_hooks': 'yes', 'keep_project_on_failure': False} == {'replay': True, 'overwrite_if_exists': True, 'skip_if_file_exists': False, 'output_dir': '.', 'config_file': None, 'default_config': False, 'extra_context': None, 'password': None, 'directory': None, 'accept_hooks': True, 'keep_project_on_failure': False}
E         
E         Common items:
E         {'config_file': None,
E          'default_config': False,
E          'directory': None,
E          'keep_project_on_failure': False,
E          'output_dir': '.',
E          'overwrite_if_exists': True,
E          'password': None,
E          'replay': True,
E          'skip_if_file_exists': False}
E         Differing items:
E         {'extra_context': OrderedDict()} != {'extra_context': None}
E         {'accept_hooks': 'yes'} != {'accept_hooks': True}
E         Left contains 2 more items:
E         {'checkout': None, 'no_input': False}
E         
E         Full diff:
E           {
E         -     'accept_hooks': True,
E         ?                     ^^^
E         +     'accept_hooks': 'yes',
E         ?                     ^^ ++
E         +     'checkout': None,
E               'config_file': None,
E               'default_config': False,
E               'directory': None,
E         -     'extra_context': None,
E         ?                      ^^^
E         +     'extra_context': OrderedDict(),
E         ?                      ^^^ +++++++++
E               'keep_project_on_failure': False,
E         +     'no_input': False,
E               'output_dir': '.',
E               'overwrite_if_exists': True,
E               'password': None,
E               'replay': True,
E               'skip_if_file_exists': False,
E           }

/usr/lib/python3.10/unittest/mock.py:941: AssertionError

During handling of the above exception, another exception occurred:

mocker = 
cli_runner = .cli_main at 0x7fcb9265e680>
overwrite_cli_flag = '-f'

    @pytest.mark.usefixtures('remove_fake_project_dir')
    def test_run_cookiecutter_on_overwrite_if_exists_and_replay(
        mocker, cli_runner, overwrite_cli_flag
    ):
        """Test cli invocation with `overwrite-if-exists` and `replay` flags."""
        mock_cookiecutter = mocker.patch('cookiecutter.cli.cookiecutter')

        template_path = 'tests/fake-repo-pre/'
        result = cli_runner(template_path, '--replay', '-v', overwrite_cli_flag)

        assert result.exit_code == 0

>       mock_cookiecutter.assert_called_once_with(
            template_path,
            None,
            False,
            replay=True,
            overwrite_if_exists=True,
            skip_if_file_exists=False,
            output_dir='.',
            config_file=None,
            default_config=False,
            extra_context=None,
            password=None,
            directory=None,
            accept_hooks=True,
            keep_project_on_failure=False,
        )
E       AssertionError: expected call not found.
E       Expected: cookiecutter('tests/fake-repo-pre/', None, False, replay=True, overwrite_if_exists=True, skip_if_file_exists=False, output_dir='.', config_file=None, default_config=False, extra_context=None, password=None, directory=None, accept_hooks=True, keep_project_on_failure=False)
E       Actual: cookiecutter('tests/fake-repo-pre/', checkout=None, no_input=False, extra_context=OrderedDict(), replay=True, overwrite_if_exists=True, output_dir='.', config_file=None, default_config=False, password=None, directory=None, skip_if_file_exists=False, accept_hooks='yes', keep_project_on_failure=False)
E       
E       pytest introspection follows:
E       
E       Args:
E       assert ('tests/fake-repo-pre/',) == ('tests/fake-repo-pre/', None, False)
E         
E         Right contains 2 more items, first extra item: None
E         
E         Full diff:
E           (
E               'tests/fake-repo-pre/',
E         -     None,
E         -     False,
E           )
E       Kwargs:
E       assert {'checkout': None, 'no_input': False, 'extra_context': OrderedDict(), 'replay': True, 'overwrite_if_exists': True, 'output_dir': '.', 'config_file': None, 'default_config': False, 'password': None, 'directory': None, 'skip_if_file_exists': False, 'accept_hooks': 'yes', 'keep_project_on_failure': False} == {'replay': True, 'overwrite_if_exists': True, 'skip_if_file_exists': False, 'output_dir': '.', 'config_file': None, 'default_config': False, 'extra_context': None, 'password': None, 'directory': None, 'accept_hooks': True, 'keep_project_on_failure': False}
E         
E         Common items:
E         {'config_file': None,
E          'default_config': False,
E          'directory': None,
E          'keep_project_on_failure': False,
E          'output_dir': '.',
E          'overwrite_if_exists': True,
E          'password': None,
E          'replay': True,
E          'skip_if_file_exists': False}
E         Differing items:
E         {'extra_context': OrderedDict()} != {'extra_context': None}
E         {'accept_hooks': 'yes'} != {'accept_hooks': True}
E         Left contains 2 more items:
E         {'checkout': None, 'no_input': False}
E         
E         Full diff:
E           {
E         -     'accept_hooks': True,
E         ?                     ^^^
E         +     'accept_hooks': 'yes',
E         ?                     ^^ ++
E         +     'checkout': None,
E               'config_file': None,
E               'default_config': False,
E               'directory': None,
E         -     'extra_context': None,
E         ?                      ^^^
E         +     'extra_context': OrderedDict(),
E         ?                      ^^^ +++++++++
E               'keep_project_on_failure': False,
E         +     'no_input': False,
E               'output_dir': '.',
E               'overwrite_if_exists': True,
E               'password': None,
E               'replay': True,
E               'skip_if_file_exists': False,
E           }

tests/test_cli.py:228: AssertionError

test_cli.py::test_run_cookiecutter_on_overwrite_if_exists_and_replay[--overwrite-if-exists]

test_cli.py::test_run_cookiecutter_on_overwrite_if_exists_and_replay[--overwrite-if-exists]
self = 
args = ('tests/fake-repo-pre/', None, False)
kwargs = {'accept_hooks': True, 'config_file': None, 'default_config': False, 'directory': None, ...}
expected = call('tests/fake-repo-pre/', None, False, replay=True, overwrite_if_exists=True, skip_if_file_exists=False, output_dir='.', config_file=None, default_config=False, extra_context=None, password=None, directory=None, accept_hooks=True, keep_project_on_failure=False)
actual = call('tests/fake-repo-pre/', checkout=None, no_input=False, extra_context=OrderedDict(), replay=True, overwrite_if_exists=True, output_dir='.', config_file=None, default_config=False, password=None, directory=None, skip_if_file_exists=False, accept_hooks='yes', keep_project_on_failure=False)
_error_message = ._error_message at 0x7fcb9265ea70>
cause = None

    def assert_called_with(self, /, *args, **kwargs):
        """assert that the last call was made with the specified arguments.

        Raises an AssertionError if the args and keyword args passed in are
        different to the last call to the mock."""
        if self.call_args is None:
            expected = self._format_mock_call_signature(args, kwargs)
            actual = 'not called.'
            error_message = ('expected call not found.\nExpected: %s\nActual: %s'
                    % (expected, actual))
            raise AssertionError(error_message)

        def _error_message():
            msg = self._format_mock_failure_message(args, kwargs)
            return msg
        expected = self._call_matcher(_Call((args, kwargs), two=True))
        actual = self._call_matcher(self.call_args)
        if actual != expected:
            cause = expected if isinstance(expected, Exception) else None
>           raise AssertionError(_error_message()) from cause
E           AssertionError: expected call not found.
E           Expected: cookiecutter('tests/fake-repo-pre/', None, False, replay=True, overwrite_if_exists=True, skip_if_file_exists=False, output_dir='.', config_file=None, default_config=False, extra_context=None, password=None, directory=None, accept_hooks=True, keep_project_on_failure=False)
E           Actual: cookiecutter('tests/fake-repo-pre/', checkout=None, no_input=False, extra_context=OrderedDict(), replay=True, overwrite_if_exists=True, output_dir='.', config_file=None, default_config=False, password=None, directory=None, skip_if_file_exists=False, accept_hooks='yes', keep_project_on_failure=False)

/usr/lib/python3.10/unittest/mock.py:929: AssertionError

During handling of the above exception, another exception occurred:

self = 
args = ('tests/fake-repo-pre/', None, False)
kwargs = {'accept_hooks': True, 'config_file': None, 'default_config': False, 'directory': None, ...}

    def assert_called_once_with(self, /, *args, **kwargs):
        """assert that the mock was called exactly once and that that call was
        with the specified arguments."""
        if not self.call_count == 1:
            msg = ("Expected '%s' to be called once. Called %s times.%s"
                   % (self._mock_name or 'mock',
                      self.call_count,
                      self._calls_repr()))
            raise AssertionError(msg)
>       return self.assert_called_with(*args, **kwargs)
E       AssertionError: expected call not found.
E       Expected: cookiecutter('tests/fake-repo-pre/', None, False, replay=True, overwrite_if_exists=True, skip_if_file_exists=False, output_dir='.', config_file=None, default_config=False, extra_context=None, password=None, directory=None, accept_hooks=True, keep_project_on_failure=False)
E       Actual: cookiecutter('tests/fake-repo-pre/', checkout=None, no_input=False, extra_context=OrderedDict(), replay=True, overwrite_if_exists=True, output_dir='.', config_file=None, default_config=False, password=None, directory=None, skip_if_file_exists=False, accept_hooks='yes', keep_project_on_failure=False)
E       
E       pytest introspection follows:
E       
E       Args:
E       assert ('tests/fake-repo-pre/',) == ('tests/fake-repo-pre/', None, False)
E         
E         Right contains 2 more items, first extra item: None
E         
E         Full diff:
E           (
E               'tests/fake-repo-pre/',
E         -     None,
E         -     False,
E           )
E       Kwargs:
E       assert {'checkout': None, 'no_input': False, 'extra_context': OrderedDict(), 'replay': True, 'overwrite_if_exists': True, 'output_dir': '.', 'config_file': None, 'default_config': False, 'password': None, 'directory': None, 'skip_if_file_exists': False, 'accept_hooks': 'yes', 'keep_project_on_failure': False} == {'replay': True, 'overwrite_if_exists': True, 'skip_if_file_exists': False, 'output_dir': '.', 'config_file': None, 'default_config': False, 'extra_context': None, 'password': None, 'directory': None, 'accept_hooks': True, 'keep_project_on_failure': False}
E         
E         Common items:
E         {'config_file': None,
E          'default_config': False,
E          'directory': None,
E          'keep_project_on_failure': False,
E          'output_dir': '.',
E          'overwrite_if_exists': True,
E          'password': None,
E          'replay': True,
E          'skip_if_file_exists': False}
E         Differing items:
E         {'extra_context': OrderedDict()} != {'extra_context': None}
E         {'accept_hooks': 'yes'} != {'accept_hooks': True}
E         Left contains 2 more items:
E         {'checkout': None, 'no_input': False}
E         
E         Full diff:
E           {
E         -     'accept_hooks': True,
E         ?                     ^^^
E         +     'accept_hooks': 'yes',
E         ?                     ^^ ++
E         +     'checkout': None,
E               'config_file': None,
E               'default_config': False,
E               'directory': None,
E         -     'extra_context': None,
E         ?                      ^^^
E         +     'extra_context': OrderedDict(),
E         ?                      ^^^ +++++++++
E               'keep_project_on_failure': False,
E         +     'no_input': False,
E               'output_dir': '.',
E               'overwrite_if_exists': True,
E               'password': None,
E               'replay': True,
E               'skip_if_file_exists': False,
E           }

/usr/lib/python3.10/unittest/mock.py:941: AssertionError

During handling of the above exception, another exception occurred:

mocker = 
cli_runner = .cli_main at 0x7fcb9265e680>
overwrite_cli_flag = '--overwrite-if-exists'

    @pytest.mark.usefixtures('remove_fake_project_dir')
    def test_run_cookiecutter_on_overwrite_if_exists_and_replay(
        mocker, cli_runner, overwrite_cli_flag
    ):
        """Test cli invocation with `overwrite-if-exists` and `replay` flags."""
        mock_cookiecutter = mocker.patch('cookiecutter.cli.cookiecutter')

        template_path = 'tests/fake-repo-pre/'
        result = cli_runner(template_path, '--replay', '-v', overwrite_cli_flag)

        assert result.exit_code == 0

>       mock_cookiecutter.assert_called_once_with(
            template_path,
            None,
            False,
            replay=True,
            overwrite_if_exists=True,
            skip_if_file_exists=False,
            output_dir='.',
            config_file=None,
            default_config=False,
            extra_context=None,
            password=None,
            directory=None,
            accept_hooks=True,
            keep_project_on_failure=False,
        )
E       AssertionError: expected call not found.
E       Expected: cookiecutter('tests/fake-repo-pre/', None, False, replay=True, overwrite_if_exists=True, skip_if_file_exists=False, output_dir='.', config_file=None, default_config=False, extra_context=None, password=None, directory=None, accept_hooks=True, keep_project_on_failure=False)
E       Actual: cookiecutter('tests/fake-repo-pre/', checkout=None, no_input=False, extra_context=OrderedDict(), replay=True, overwrite_if_exists=True, output_dir='.', config_file=None, default_config=False, password=None, directory=None, skip_if_file_exists=False, accept_hooks='yes', keep_project_on_failure=False)
E       
E       pytest introspection follows:
E       
E       Args:
E       assert ('tests/fake-repo-pre/',) == ('tests/fake-repo-pre/', None, False)
E         
E         Right contains 2 more items, first extra item: None
E         
E         Full diff:
E           (
E               'tests/fake-repo-pre/',
E         -     None,
E         -     False,
E           )
E       Kwargs:
E       assert {'checkout': None, 'no_input': False, 'extra_context': OrderedDict(), 'replay': True, 'overwrite_if_exists': True, 'output_dir': '.', 'config_file': None, 'default_config': False, 'password': None, 'directory': None, 'skip_if_file_exists': False, 'accept_hooks': 'yes', 'keep_project_on_failure': False} == {'replay': True, 'overwrite_if_exists': True, 'skip_if_file_exists': False, 'output_dir': '.', 'config_file': None, 'default_config': False, 'extra_context': None, 'password': None, 'directory': None, 'accept_hooks': True, 'keep_project_on_failure': False}
E         
E         Common items:
E         {'config_file': None,
E          'default_config': False,
E          'directory': None,
E          'keep_project_on_failure': False,
E          'output_dir': '.',
E          'overwrite_if_exists': True,
E          'password': None,
E          'replay': True,
E          'skip_if_file_exists': False}
E         Differing items:
E         {'extra_context': OrderedDict()} != {'extra_context': None}
E         {'accept_hooks': 'yes'} != {'accept_hooks': True}
E         Left contains 2 more items:
E         {'checkout': None, 'no_input': False}
E         
E         Full diff:
E           {
E         -     'accept_hooks': True,
E         ?                     ^^^
E         +     'accept_hooks': 'yes',
E         ?                     ^^ ++
E         +     'checkout': None,
E               'config_file': None,
E               'default_config': False,
E               'directory': None,
E         -     'extra_context': None,
E         ?                      ^^^
E         +     'extra_context': OrderedDict(),
E         ?                      ^^^ +++++++++
E               'keep_project_on_failure': False,
E         +     'no_input': False,
E               'output_dir': '.',
E               'overwrite_if_exists': True,
E               'password': None,
E               'replay': True,
E               'skip_if_file_exists': False,
E           }

tests/test_cli.py:228: AssertionError

test_cli.py::test_cli_overwrite_if_exists_when_output_dir_does_not_exist[-f]

test_cli.py::test_cli_overwrite_if_exists_when_output_dir_does_not_exist[-f]
cli_runner = .cli_main at 0x7fcb9265e680>
overwrite_cli_flag = '-f'

    @pytest.mark.usefixtures('remove_fake_project_dir')
    def test_cli_overwrite_if_exists_when_output_dir_does_not_exist(
        cli_runner, overwrite_cli_flag
    ):
        """Test cli invocation with `overwrite-if-exists` and `no-input` flags.

        Case when output dir not exist.
        """
        result = cli_runner('tests/fake-repo-pre/', '--no-input', overwrite_cli_flag)

>       assert result.exit_code == 0
E       assert 1 == 0
E        +  where 1 = .exit_code

tests/test_cli.py:256: AssertionError

test_cli.py::test_cli_overwrite_if_exists_when_output_dir_does_not_exist[--overwrite-if-exists]

test_cli.py::test_cli_overwrite_if_exists_when_output_dir_does_not_exist[--overwrite-if-exists]
cli_runner = .cli_main at 0x7fcb9265e680>
overwrite_cli_flag = '--overwrite-if-exists'

    @pytest.mark.usefixtures('remove_fake_project_dir')
    def test_cli_overwrite_if_exists_when_output_dir_does_not_exist(
        cli_runner, overwrite_cli_flag
    ):
        """Test cli invocation with `overwrite-if-exists` and `no-input` flags.

        Case when output dir not exist.
        """
        result = cli_runner('tests/fake-repo-pre/', '--no-input', overwrite_cli_flag)

>       assert result.exit_code == 0
E       assert 1 == 0
E        +  where 1 = .exit_code

tests/test_cli.py:256: AssertionError

test_cli.py::test_cli_overwrite_if_exists_when_output_dir_exists[-f]

test_cli.py::test_cli_overwrite_if_exists_when_output_dir_exists[-f]
cli_runner = .cli_main at 0x7fcb9265e680>
overwrite_cli_flag = '-f'

    @pytest.mark.usefixtures('make_fake_project_dir', 'remove_fake_project_dir')
    def test_cli_overwrite_if_exists_when_output_dir_exists(cli_runner, overwrite_cli_flag):
        """Test cli invocation with `overwrite-if-exists` and `no-input` flags.

        Case when output dir already exist.
        """
        result = cli_runner('tests/fake-repo-pre/', '--no-input', overwrite_cli_flag)
>       assert result.exit_code == 0
E       assert 1 == 0
E        +  where 1 = .exit_code

tests/test_cli.py:267: AssertionError

test_cli.py::test_cli_overwrite_if_exists_when_output_dir_exists[--overwrite-if-exists]

test_cli.py::test_cli_overwrite_if_exists_when_output_dir_exists[--overwrite-if-exists]
cli_runner = .cli_main at 0x7fcb9265e680>
overwrite_cli_flag = '--overwrite-if-exists'

    @pytest.mark.usefixtures('make_fake_project_dir', 'remove_fake_project_dir')
    def test_cli_overwrite_if_exists_when_output_dir_exists(cli_runner, overwrite_cli_flag):
        """Test cli invocation with `overwrite-if-exists` and `no-input` flags.

        Case when output dir already exist.
        """
        result = cli_runner('tests/fake-repo-pre/', '--no-input', overwrite_cli_flag)
>       assert result.exit_code == 0
E       assert 1 == 0
E        +  where 1 = .exit_code

tests/test_cli.py:267: AssertionError

test_cli.py::test_cli_output_dir[-o]

test_cli.py::test_cli_output_dir[-o]
self = 
args = ('tests/fake-repo-pre/', None, False)
kwargs = {'accept_hooks': True, 'config_file': None, 'default_config': False, 'directory': None, ...}
expected = call('tests/fake-repo-pre/', None, False, replay=False, overwrite_if_exists=False, skip_if_file_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_output_dir__o_0/output', config_file=None, default_config=False, extra_context=None, password=None, directory=None, accept_hooks=True, keep_project_on_failure=False)
actual = call('tests/fake-repo-pre/', checkout=None, no_input=False, extra_context=OrderedDict(), replay=False, overwrite_if_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_output_dir__o_0/output', config_file=None, default_config=False, password=None, directory=None, skip_if_file_exists=False, accept_hooks='yes', keep_project_on_failure=False)
_error_message = ._error_message at 0x7fcb92606050>
cause = None

    def assert_called_with(self, /, *args, **kwargs):
        """assert that the last call was made with the specified arguments.

        Raises an AssertionError if the args and keyword args passed in are
        different to the last call to the mock."""
        if self.call_args is None:
            expected = self._format_mock_call_signature(args, kwargs)
            actual = 'not called.'
            error_message = ('expected call not found.\nExpected: %s\nActual: %s'
                    % (expected, actual))
            raise AssertionError(error_message)

        def _error_message():
            msg = self._format_mock_failure_message(args, kwargs)
            return msg
        expected = self._call_matcher(_Call((args, kwargs), two=True))
        actual = self._call_matcher(self.call_args)
        if actual != expected:
            cause = expected if isinstance(expected, Exception) else None
>           raise AssertionError(_error_message()) from cause
E           AssertionError: expected call not found.
E           Expected: cookiecutter('tests/fake-repo-pre/', None, False, replay=False, overwrite_if_exists=False, skip_if_file_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_output_dir__o_0/output', config_file=None, default_config=False, extra_context=None, password=None, directory=None, accept_hooks=True, keep_project_on_failure=False)
E           Actual: cookiecutter('tests/fake-repo-pre/', checkout=None, no_input=False, extra_context=OrderedDict(), replay=False, overwrite_if_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_output_dir__o_0/output', config_file=None, default_config=False, password=None, directory=None, skip_if_file_exists=False, accept_hooks='yes', keep_project_on_failure=False)

/usr/lib/python3.10/unittest/mock.py:929: AssertionError

During handling of the above exception, another exception occurred:

self = 
args = ('tests/fake-repo-pre/', None, False)
kwargs = {'accept_hooks': True, 'config_file': None, 'default_config': False, 'directory': None, ...}

    def assert_called_once_with(self, /, *args, **kwargs):
        """assert that the mock was called exactly once and that that call was
        with the specified arguments."""
        if not self.call_count == 1:
            msg = ("Expected '%s' to be called once. Called %s times.%s"
                   % (self._mock_name or 'mock',
                      self.call_count,
                      self._calls_repr()))
            raise AssertionError(msg)
>       return self.assert_called_with(*args, **kwargs)
E       AssertionError: expected call not found.
E       Expected: cookiecutter('tests/fake-repo-pre/', None, False, replay=False, overwrite_if_exists=False, skip_if_file_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_output_dir__o_0/output', config_file=None, default_config=False, extra_context=None, password=None, directory=None, accept_hooks=True, keep_project_on_failure=False)
E       Actual: cookiecutter('tests/fake-repo-pre/', checkout=None, no_input=False, extra_context=OrderedDict(), replay=False, overwrite_if_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_output_dir__o_0/output', config_file=None, default_config=False, password=None, directory=None, skip_if_file_exists=False, accept_hooks='yes', keep_project_on_failure=False)
E       
E       pytest introspection follows:
E       
E       Args:
E       assert ('tests/fake-repo-pre/',) == ('tests/fake-repo-pre/', None, False)
E         
E         Right contains 2 more items, first extra item: None
E         
E         Full diff:
E           (
E               'tests/fake-repo-pre/',
E         -     None,
E         -     False,
E           )
E       Kwargs:
E       assert {'checkout': None, 'no_input': False, 'extra_context': OrderedDict(), 'replay': False, 'overwrite_if_exists': False, 'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_output_dir__o_0/output', 'config_file': None, 'default_config': False, 'password': None, 'directory': None, 'skip_if_file_exists': False, 'accept_hooks': 'yes', 'keep_project_on_failure': False} == {'replay': False, 'overwrite_if_exists': False, 'skip_if_file_exists': False, 'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_output_dir__o_0/output', 'config_file': None, 'default_config': False, 'extra_context': None, 'password': None, 'directory': None, 'accept_hooks': True, 'keep_project_on_failure': False}
E         
E         Common items:
E         {'config_file': None,
E          'default_config': False,
E          'directory': None,
E          'keep_project_on_failure': False,
E          'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_output_dir__o_0/output',
E          'overwrite_if_exists': False,
E          'password': None,
E          'replay': False,
E          'skip_if_file_exists': False}
E         Differing items:
E         {'extra_context': OrderedDict()} != {'extra_context': None}
E         {'accept_hooks': 'yes'} != {'accept_hooks': True}
E         Left contains 2 more items:
E         {'checkout': None, 'no_input': False}
E         
E         Full diff:
E           {
E         -     'accept_hooks': True,
E         ?                     ^^^
E         +     'accept_hooks': 'yes',
E         ?                     ^^ ++
E         +     'checkout': None,
E               'config_file': None,
E               'default_config': False,
E               'directory': None,
E         -     'extra_context': None,
E         ?                      ^^^
E         +     'extra_context': OrderedDict(),
E         ?                      ^^^ +++++++++
E               'keep_project_on_failure': False,
E         +     'no_input': False,
E               'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_output_dir__o_0/output',
E               'overwrite_if_exists': False,
E               'password': None,
E               'replay': False,
E               'skip_if_file_exists': False,
E           }

/usr/lib/python3.10/unittest/mock.py:941: AssertionError

During handling of the above exception, another exception occurred:

mocker = 
cli_runner = .cli_main at 0x7fcb9265e680>
output_dir_flag = '-o'
output_dir = '/tmp/pytest-of-root/pytest-0/test_cli_output_dir__o_0/output'

    def test_cli_output_dir(mocker, cli_runner, output_dir_flag, output_dir):
        """Test cli invocation with `output-dir` flag changes output directory."""
        mock_cookiecutter = mocker.patch('cookiecutter.cli.cookiecutter')

        template_path = 'tests/fake-repo-pre/'
        result = cli_runner(template_path, output_dir_flag, output_dir)

        assert result.exit_code == 0
>       mock_cookiecutter.assert_called_once_with(
            template_path,
            None,
            False,
            replay=False,
            overwrite_if_exists=False,
            skip_if_file_exists=False,
            output_dir=output_dir,
            config_file=None,
            default_config=False,
            extra_context=None,
            password=None,
            directory=None,
            accept_hooks=True,
            keep_project_on_failure=False,
        )
E       AssertionError: expected call not found.
E       Expected: cookiecutter('tests/fake-repo-pre/', None, False, replay=False, overwrite_if_exists=False, skip_if_file_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_output_dir__o_0/output', config_file=None, default_config=False, extra_context=None, password=None, directory=None, accept_hooks=True, keep_project_on_failure=False)
E       Actual: cookiecutter('tests/fake-repo-pre/', checkout=None, no_input=False, extra_context=OrderedDict(), replay=False, overwrite_if_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_output_dir__o_0/output', config_file=None, default_config=False, password=None, directory=None, skip_if_file_exists=False, accept_hooks='yes', keep_project_on_failure=False)
E       
E       pytest introspection follows:
E       
E       Args:
E       assert ('tests/fake-repo-pre/',) == ('tests/fake-repo-pre/', None, False)
E         
E         Right contains 2 more items, first extra item: None
E         
E         Full diff:
E           (
E               'tests/fake-repo-pre/',
E         -     None,
E         -     False,
E           )
E       Kwargs:
E       assert {'checkout': None, 'no_input': False, 'extra_context': OrderedDict(), 'replay': False, 'overwrite_if_exists': False, 'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_output_dir__o_0/output', 'config_file': None, 'default_config': False, 'password': None, 'directory': None, 'skip_if_file_exists': False, 'accept_hooks': 'yes', 'keep_project_on_failure': False} == {'replay': False, 'overwrite_if_exists': False, 'skip_if_file_exists': False, 'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_output_dir__o_0/output', 'config_file': None, 'default_config': False, 'extra_context': None, 'password': None, 'directory': None, 'accept_hooks': True, 'keep_project_on_failure': False}
E         
E         Common items:
E         {'config_file': None,
E          'default_config': False,
E          'directory': None,
E          'keep_project_on_failure': False,
E          'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_output_dir__o_0/output',
E          'overwrite_if_exists': False,
E          'password': None,
E          'replay': False,
E          'skip_if_file_exists': False}
E         Differing items:
E         {'extra_context': OrderedDict()} != {'extra_context': None}
E         {'accept_hooks': 'yes'} != {'accept_hooks': True}
E         Left contains 2 more items:
E         {'checkout': None, 'no_input': False}
E         
E         Full diff:
E           {
E         -     'accept_hooks': True,
E         ?                     ^^^
E         +     'accept_hooks': 'yes',
E         ?                     ^^ ++
E         +     'checkout': None,
E               'config_file': None,
E               'default_config': False,
E               'directory': None,
E         -     'extra_context': None,
E         ?                      ^^^
E         +     'extra_context': OrderedDict(),
E         ?                      ^^^ +++++++++
E               'keep_project_on_failure': False,
E         +     'no_input': False,
E               'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_output_dir__o_0/output',
E               'overwrite_if_exists': False,
E               'password': None,
E               'replay': False,
E               'skip_if_file_exists': False,
E           }

tests/test_cli.py:285: AssertionError

test_cli.py::test_cli_output_dir[--output-dir]

test_cli.py::test_cli_output_dir[--output-dir]
self = 
args = ('tests/fake-repo-pre/', None, False)
kwargs = {'accept_hooks': True, 'config_file': None, 'default_config': False, 'directory': None, ...}
expected = call('tests/fake-repo-pre/', None, False, replay=False, overwrite_if_exists=False, skip_if_file_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_output_dir___output_d0/output', config_file=None, default_config=False, extra_context=None, password=None, directory=None, accept_hooks=True, keep_project_on_failure=False)
actual = call('tests/fake-repo-pre/', checkout=None, no_input=False, extra_context=OrderedDict(), replay=False, overwrite_if_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_output_dir___output_d0/output', config_file=None, default_config=False, password=None, directory=None, skip_if_file_exists=False, accept_hooks='yes', keep_project_on_failure=False)
_error_message = ._error_message at 0x7fcb9265fac0>
cause = None

    def assert_called_with(self, /, *args, **kwargs):
        """assert that the last call was made with the specified arguments.

        Raises an AssertionError if the args and keyword args passed in are
        different to the last call to the mock."""
        if self.call_args is None:
            expected = self._format_mock_call_signature(args, kwargs)
            actual = 'not called.'
            error_message = ('expected call not found.\nExpected: %s\nActual: %s'
                    % (expected, actual))
            raise AssertionError(error_message)

        def _error_message():
            msg = self._format_mock_failure_message(args, kwargs)
            return msg
        expected = self._call_matcher(_Call((args, kwargs), two=True))
        actual = self._call_matcher(self.call_args)
        if actual != expected:
            cause = expected if isinstance(expected, Exception) else None
>           raise AssertionError(_error_message()) from cause
E           AssertionError: expected call not found.
E           Expected: cookiecutter('tests/fake-repo-pre/', None, False, replay=False, overwrite_if_exists=False, skip_if_file_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_output_dir___output_d0/output', config_file=None, default_config=False, extra_context=None, password=None, directory=None, accept_hooks=True, keep_project_on_failure=False)
E           Actual: cookiecutter('tests/fake-repo-pre/', checkout=None, no_input=False, extra_context=OrderedDict(), replay=False, overwrite_if_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_output_dir___output_d0/output', config_file=None, default_config=False, password=None, directory=None, skip_if_file_exists=False, accept_hooks='yes', keep_project_on_failure=False)

/usr/lib/python3.10/unittest/mock.py:929: AssertionError

During handling of the above exception, another exception occurred:

self = 
args = ('tests/fake-repo-pre/', None, False)
kwargs = {'accept_hooks': True, 'config_file': None, 'default_config': False, 'directory': None, ...}

    def assert_called_once_with(self, /, *args, **kwargs):
        """assert that the mock was called exactly once and that that call was
        with the specified arguments."""
        if not self.call_count == 1:
            msg = ("Expected '%s' to be called once. Called %s times.%s"
                   % (self._mock_name or 'mock',
                      self.call_count,
                      self._calls_repr()))
            raise AssertionError(msg)
>       return self.assert_called_with(*args, **kwargs)
E       AssertionError: expected call not found.
E       Expected: cookiecutter('tests/fake-repo-pre/', None, False, replay=False, overwrite_if_exists=False, skip_if_file_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_output_dir___output_d0/output', config_file=None, default_config=False, extra_context=None, password=None, directory=None, accept_hooks=True, keep_project_on_failure=False)
E       Actual: cookiecutter('tests/fake-repo-pre/', checkout=None, no_input=False, extra_context=OrderedDict(), replay=False, overwrite_if_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_output_dir___output_d0/output', config_file=None, default_config=False, password=None, directory=None, skip_if_file_exists=False, accept_hooks='yes', keep_project_on_failure=False)
E       
E       pytest introspection follows:
E       
E       Args:
E       assert ('tests/fake-repo-pre/',) == ('tests/fake-repo-pre/', None, False)
E         
E         Right contains 2 more items, first extra item: None
E         
E         Full diff:
E           (
E               'tests/fake-repo-pre/',
E         -     None,
E         -     False,
E           )
E       Kwargs:
E       assert {'checkout': None, 'no_input': False, 'extra_context': OrderedDict(), 'replay': False, 'overwrite_if_exists': False, 'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_output_dir___output_d0/output', 'config_file': None, 'default_config': False, 'password': None, 'directory': None, 'skip_if_file_exists': False, 'accept_hooks': 'yes', 'keep_project_on_failure': False} == {'replay': False, 'overwrite_if_exists': False, 'skip_if_file_exists': False, 'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_output_dir___output_d0/output', 'config_file': None, 'default_config': False, 'extra_context': None, 'password': None, 'directory': None, 'accept_hooks': True, 'keep_project_on_failure': False}
E         
E         Common items:
E         {'config_file': None,
E          'default_config': False,
E          'directory': None,
E          'keep_project_on_failure': False,
E          'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_output_dir___output_d0/output',
E          'overwrite_if_exists': False,
E          'password': None,
E          'replay': False,
E          'skip_if_file_exists': False}
E         Differing items:
E         {'extra_context': OrderedDict()} != {'extra_context': None}
E         {'accept_hooks': 'yes'} != {'accept_hooks': True}
E         Left contains 2 more items:
E         {'checkout': None, 'no_input': False}
E         
E         Full diff:
E           {
E         -     'accept_hooks': True,
E         ?                     ^^^
E         +     'accept_hooks': 'yes',
E         ?                     ^^ ++
E         +     'checkout': None,
E               'config_file': None,
E               'default_config': False,
E               'directory': None,
E         -     'extra_context': None,
E         ?                      ^^^
E         +     'extra_context': OrderedDict(),
E         ?                      ^^^ +++++++++
E               'keep_project_on_failure': False,
E         +     'no_input': False,
E               'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_output_dir___output_d0/output',
E               'overwrite_if_exists': False,
E               'password': None,
E               'replay': False,
E               'skip_if_file_exists': False,
E           }

/usr/lib/python3.10/unittest/mock.py:941: AssertionError

During handling of the above exception, another exception occurred:

mocker = 
cli_runner = .cli_main at 0x7fcb9265e680>
output_dir_flag = '--output-dir'
output_dir = '/tmp/pytest-of-root/pytest-0/test_cli_output_dir___output_d0/output'

    def test_cli_output_dir(mocker, cli_runner, output_dir_flag, output_dir):
        """Test cli invocation with `output-dir` flag changes output directory."""
        mock_cookiecutter = mocker.patch('cookiecutter.cli.cookiecutter')

        template_path = 'tests/fake-repo-pre/'
        result = cli_runner(template_path, output_dir_flag, output_dir)

        assert result.exit_code == 0
>       mock_cookiecutter.assert_called_once_with(
            template_path,
            None,
            False,
            replay=False,
            overwrite_if_exists=False,
            skip_if_file_exists=False,
            output_dir=output_dir,
            config_file=None,
            default_config=False,
            extra_context=None,
            password=None,
            directory=None,
            accept_hooks=True,
            keep_project_on_failure=False,
        )
E       AssertionError: expected call not found.
E       Expected: cookiecutter('tests/fake-repo-pre/', None, False, replay=False, overwrite_if_exists=False, skip_if_file_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_output_dir___output_d0/output', config_file=None, default_config=False, extra_context=None, password=None, directory=None, accept_hooks=True, keep_project_on_failure=False)
E       Actual: cookiecutter('tests/fake-repo-pre/', checkout=None, no_input=False, extra_context=OrderedDict(), replay=False, overwrite_if_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_output_dir___output_d0/output', config_file=None, default_config=False, password=None, directory=None, skip_if_file_exists=False, accept_hooks='yes', keep_project_on_failure=False)
E       
E       pytest introspection follows:
E       
E       Args:
E       assert ('tests/fake-repo-pre/',) == ('tests/fake-repo-pre/', None, False)
E         
E         Right contains 2 more items, first extra item: None
E         
E         Full diff:
E           (
E               'tests/fake-repo-pre/',
E         -     None,
E         -     False,
E           )
E       Kwargs:
E       assert {'checkout': None, 'no_input': False, 'extra_context': OrderedDict(), 'replay': False, 'overwrite_if_exists': False, 'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_output_dir___output_d0/output', 'config_file': None, 'default_config': False, 'password': None, 'directory': None, 'skip_if_file_exists': False, 'accept_hooks': 'yes', 'keep_project_on_failure': False} == {'replay': False, 'overwrite_if_exists': False, 'skip_if_file_exists': False, 'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_output_dir___output_d0/output', 'config_file': None, 'default_config': False, 'extra_context': None, 'password': None, 'directory': None, 'accept_hooks': True, 'keep_project_on_failure': False}
E         
E         Common items:
E         {'config_file': None,
E          'default_config': False,
E          'directory': None,
E          'keep_project_on_failure': False,
E          'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_output_dir___output_d0/output',
E          'overwrite_if_exists': False,
E          'password': None,
E          'replay': False,
E          'skip_if_file_exists': False}
E         Differing items:
E         {'extra_context': OrderedDict()} != {'extra_context': None}
E         {'accept_hooks': 'yes'} != {'accept_hooks': True}
E         Left contains 2 more items:
E         {'checkout': None, 'no_input': False}
E         
E         Full diff:
E           {
E         -     'accept_hooks': True,
E         ?                     ^^^
E         +     'accept_hooks': 'yes',
E         ?                     ^^ ++
E         +     'checkout': None,
E               'config_file': None,
E               'default_config': False,
E               'directory': None,
E         -     'extra_context': None,
E         ?                      ^^^
E         +     'extra_context': OrderedDict(),
E         ?                      ^^^ +++++++++
E               'keep_project_on_failure': False,
E         +     'no_input': False,
E               'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_output_dir___output_d0/output',
E               'overwrite_if_exists': False,
E               'password': None,
E               'replay': False,
E               'skip_if_file_exists': False,
E           }

tests/test_cli.py:285: AssertionError

test_cli.py::test_cli_help[help]

test_cli.py::test_cli_help[help]
cli_runner = .cli_main at 0x7fcb9265e680>
help_cli_flag = 'help'

    def test_cli_help(cli_runner, help_cli_flag):
        """Test cli invocation display help message with `help` flag."""
        result = cli_runner(help_cli_flag)
>       assert result.exit_code == 0
E       assert 1 == 0
E        +  where 1 = .exit_code

tests/test_cli.py:312: AssertionError

test_cli.py::test_user_config

test_cli.py::test_user_config
self = 
args = ('tests/fake-repo-pre/', None, False)
kwargs = {'accept_hooks': True, 'config_file': '/tmp/pytest-of-root/pytest-0/test_user_config0/tests/config.yaml', 'default_config': False, 'directory': None, ...}
expected = call('tests/fake-repo-pre/', None, False, replay=False, overwrite_if_exists=False, skip_if_file_exists=False, output_dir='.', config_file='/tmp/pytest-of-root/pytest-0/test_user_config0/tests/config.yaml', default_config=False, extra_context=None, password=None, directory=None, accept_hooks=True, keep_project_on_failure=False)
actual = call('tests/fake-repo-pre/', checkout=None, no_input=False, extra_context=OrderedDict(), replay=False, overwrite_if_exists=False, output_dir='.', config_file='/tmp/pytest-of-root/pytest-0/test_user_config0/tests/config.yaml', default_config=False, password=None, directory=None, skip_if_file_exists=False, accept_hooks='yes', keep_project_on_failure=False)
_error_message = ._error_message at 0x7fcb92604c10>
cause = None

    def assert_called_with(self, /, *args, **kwargs):
        """assert that the last call was made with the specified arguments.

        Raises an AssertionError if the args and keyword args passed in are
        different to the last call to the mock."""
        if self.call_args is None:
            expected = self._format_mock_call_signature(args, kwargs)
            actual = 'not called.'
            error_message = ('expected call not found.\nExpected: %s\nActual: %s'
                    % (expected, actual))
            raise AssertionError(error_message)

        def _error_message():
            msg = self._format_mock_failure_message(args, kwargs)
            return msg
        expected = self._call_matcher(_Call((args, kwargs), two=True))
        actual = self._call_matcher(self.call_args)
        if actual != expected:
            cause = expected if isinstance(expected, Exception) else None
>           raise AssertionError(_error_message()) from cause
E           AssertionError: expected call not found.
E           Expected: cookiecutter('tests/fake-repo-pre/', None, False, replay=False, overwrite_if_exists=False, skip_if_file_exists=False, output_dir='.', config_file='/tmp/pytest-of-root/pytest-0/test_user_config0/tests/config.yaml', default_config=False, extra_context=None, password=None, directory=None, accept_hooks=True, keep_project_on_failure=False)
E           Actual: cookiecutter('tests/fake-repo-pre/', checkout=None, no_input=False, extra_context=OrderedDict(), replay=False, overwrite_if_exists=False, output_dir='.', config_file='/tmp/pytest-of-root/pytest-0/test_user_config0/tests/config.yaml', default_config=False, password=None, directory=None, skip_if_file_exists=False, accept_hooks='yes', keep_project_on_failure=False)

/usr/lib/python3.10/unittest/mock.py:929: AssertionError

During handling of the above exception, another exception occurred:

self = 
args = ('tests/fake-repo-pre/', None, False)
kwargs = {'accept_hooks': True, 'config_file': '/tmp/pytest-of-root/pytest-0/test_user_config0/tests/config.yaml', 'default_config': False, 'directory': None, ...}

    def assert_called_once_with(self, /, *args, **kwargs):
        """assert that the mock was called exactly once and that that call was
        with the specified arguments."""
        if not self.call_count == 1:
            msg = ("Expected '%s' to be called once. Called %s times.%s"
                   % (self._mock_name or 'mock',
                      self.call_count,
                      self._calls_repr()))
            raise AssertionError(msg)
>       return self.assert_called_with(*args, **kwargs)
E       AssertionError: expected call not found.
E       Expected: cookiecutter('tests/fake-repo-pre/', None, False, replay=False, overwrite_if_exists=False, skip_if_file_exists=False, output_dir='.', config_file='/tmp/pytest-of-root/pytest-0/test_user_config0/tests/config.yaml', default_config=False, extra_context=None, password=None, directory=None, accept_hooks=True, keep_project_on_failure=False)
E       Actual: cookiecutter('tests/fake-repo-pre/', checkout=None, no_input=False, extra_context=OrderedDict(), replay=False, overwrite_if_exists=False, output_dir='.', config_file='/tmp/pytest-of-root/pytest-0/test_user_config0/tests/config.yaml', default_config=False, password=None, directory=None, skip_if_file_exists=False, accept_hooks='yes', keep_project_on_failure=False)
E       
E       pytest introspection follows:
E       
E       Args:
E       assert ('tests/fake-repo-pre/',) == ('tests/fake-repo-pre/', None, False)
E         
E         Right contains 2 more items, first extra item: None
E         
E         Full diff:
E           (
E               'tests/fake-repo-pre/',
E         -     None,
E         -     False,
E           )
E       Kwargs:
E       assert {'checkout': None, 'no_input': False, 'extra_context': OrderedDict(), 'replay': False, 'overwrite_if_exists': False, 'output_dir': '.', 'config_file': '/tmp/pytest-of-root/pytest-0/test_user_config0/tests/config.yaml', 'default_config': False, 'password': None, 'directory': None, 'skip_if_file_exists': False, 'accept_hooks': 'yes', 'keep_project_on_failure': False} == {'replay': False, 'overwrite_if_exists': False, 'skip_if_file_exists': False, 'output_dir': '.', 'config_file': '/tmp/pytest-of-root/pytest-0/test_user_config0/tests/config.yaml', 'default_config': False, 'extra_context': None, 'password': None, 'directory': None, 'accept_hooks': True, 'keep_project_on_failure': False}
E         
E         Common items:
E         {'config_file': '/tmp/pytest-of-root/pytest-0/test_user_config0/tests/config.yaml',
E          'default_config': False,
E          'directory': None,
E          'keep_project_on_failure': False,
E          'output_dir': '.',
E          'overwrite_if_exists': False,
E          'password': None,
E          'replay': False,
E          'skip_if_file_exists': False}
E         Differing items:
E         {'extra_context': OrderedDict()} != {'extra_context': None}
E         {'accept_hooks': 'yes'} != {'accept_hooks': True}
E         Left contains 2 more items:
E         {'checkout': None, 'no_input': False}
E         
E         Full diff:
E           {
E         -     'accept_hooks': True,
E         ?                     ^^^
E         +     'accept_hooks': 'yes',
E         ?                     ^^ ++
E         +     'checkout': None,
E               'config_file': '/tmp/pytest-of-root/pytest-0/test_user_config0/tests/config.yaml',
E               'default_config': False,
E               'directory': None,
E         -     'extra_context': None,
E         ?                      ^^^
E         +     'extra_context': OrderedDict(),
E         ?                      ^^^ +++++++++
E               'keep_project_on_failure': False,
E         +     'no_input': False,
E               'output_dir': '.',
E               'overwrite_if_exists': False,
E               'password': None,
E               'replay': False,
E               'skip_if_file_exists': False,
E           }

/usr/lib/python3.10/unittest/mock.py:941: AssertionError

During handling of the above exception, another exception occurred:

mocker = 
cli_runner = .cli_main at 0x7fcb9265e680>
user_config_path = '/tmp/pytest-of-root/pytest-0/test_user_config0/tests/config.yaml'

    def test_user_config(mocker, cli_runner, user_config_path):
        """Test cli invocation works with `config-file` option."""
        mock_cookiecutter = mocker.patch('cookiecutter.cli.cookiecutter')

        template_path = 'tests/fake-repo-pre/'
        result = cli_runner(template_path, '--config-file', user_config_path)

        assert result.exit_code == 0
>       mock_cookiecutter.assert_called_once_with(
            template_path,
            None,
            False,
            replay=False,
            overwrite_if_exists=False,
            skip_if_file_exists=False,
            output_dir='.',
            config_file=user_config_path,
            default_config=False,
            extra_context=None,
            password=None,
            directory=None,
            accept_hooks=True,
            keep_project_on_failure=False,
        )
E       AssertionError: expected call not found.
E       Expected: cookiecutter('tests/fake-repo-pre/', None, False, replay=False, overwrite_if_exists=False, skip_if_file_exists=False, output_dir='.', config_file='/tmp/pytest-of-root/pytest-0/test_user_config0/tests/config.yaml', default_config=False, extra_context=None, password=None, directory=None, accept_hooks=True, keep_project_on_failure=False)
E       Actual: cookiecutter('tests/fake-repo-pre/', checkout=None, no_input=False, extra_context=OrderedDict(), replay=False, overwrite_if_exists=False, output_dir='.', config_file='/tmp/pytest-of-root/pytest-0/test_user_config0/tests/config.yaml', default_config=False, password=None, directory=None, skip_if_file_exists=False, accept_hooks='yes', keep_project_on_failure=False)
E       
E       pytest introspection follows:
E       
E       Args:
E       assert ('tests/fake-repo-pre/',) == ('tests/fake-repo-pre/', None, False)
E         
E         Right contains 2 more items, first extra item: None
E         
E         Full diff:
E           (
E               'tests/fake-repo-pre/',
E         -     None,
E         -     False,
E           )
E       Kwargs:
E       assert {'checkout': None, 'no_input': False, 'extra_context': OrderedDict(), 'replay': False, 'overwrite_if_exists': False, 'output_dir': '.', 'config_file': '/tmp/pytest-of-root/pytest-0/test_user_config0/tests/config.yaml', 'default_config': False, 'password': None, 'directory': None, 'skip_if_file_exists': False, 'accept_hooks': 'yes', 'keep_project_on_failure': False} == {'replay': False, 'overwrite_if_exists': False, 'skip_if_file_exists': False, 'output_dir': '.', 'config_file': '/tmp/pytest-of-root/pytest-0/test_user_config0/tests/config.yaml', 'default_config': False, 'extra_context': None, 'password': None, 'directory': None, 'accept_hooks': True, 'keep_project_on_failure': False}
E         
E         Common items:
E         {'config_file': '/tmp/pytest-of-root/pytest-0/test_user_config0/tests/config.yaml',
E          'default_config': False,
E          'directory': None,
E          'keep_project_on_failure': False,
E          'output_dir': '.',
E          'overwrite_if_exists': False,
E          'password': None,
E          'replay': False,
E          'skip_if_file_exists': False}
E         Differing items:
E         {'extra_context': OrderedDict()} != {'extra_context': None}
E         {'accept_hooks': 'yes'} != {'accept_hooks': True}
E         Left contains 2 more items:
E         {'checkout': None, 'no_input': False}
E         
E         Full diff:
E           {
E         -     'accept_hooks': True,
E         ?                     ^^^
E         +     'accept_hooks': 'yes',
E         ?                     ^^ ++
E         +     'checkout': None,
E               'config_file': '/tmp/pytest-of-root/pytest-0/test_user_config0/tests/config.yaml',
E               'default_config': False,
E               'directory': None,
E         -     'extra_context': None,
E         ?                      ^^^
E         +     'extra_context': OrderedDict(),
E         ?                      ^^^ +++++++++
E               'keep_project_on_failure': False,
E         +     'no_input': False,
E               'output_dir': '.',
E               'overwrite_if_exists': False,
E               'password': None,
E               'replay': False,
E               'skip_if_file_exists': False,
E           }

tests/test_cli.py:330: AssertionError

test_cli.py::test_default_user_config_overwrite

test_cli.py::test_default_user_config_overwrite
self = 
args = ('tests/fake-repo-pre/', None, False)
kwargs = {'accept_hooks': True, 'config_file': '/tmp/pytest-of-root/pytest-0/test_default_user_config_overw0/tests/config.yaml', 'default_config': True, 'directory': None, ...}
expected = call('tests/fake-repo-pre/', None, False, replay=False, overwrite_if_exists=False, skip_if_file_exists=False, output_dir='.', config_file='/tmp/pytest-of-root/pytest-0/test_default_user_config_overw0/tests/config.yaml', default_config=True, extra_context=None, password=None, directory=None, accept_hooks=True, keep_project_on_failure=False)
actual = call('tests/fake-repo-pre/', checkout=None, no_input=False, extra_context=OrderedDict(), replay=False, overwrite_if_exists=False, output_dir='.', config_file='/tmp/pytest-of-root/pytest-0/test_default_user_config_overw0/tests/config.yaml', default_config=True, password=None, directory=None, skip_if_file_exists=False, accept_hooks='yes', keep_project_on_failure=False)
_error_message = ._error_message at 0x7fcb92605630>
cause = None

    def assert_called_with(self, /, *args, **kwargs):
        """assert that the last call was made with the specified arguments.

        Raises an AssertionError if the args and keyword args passed in are
        different to the last call to the mock."""
        if self.call_args is None:
            expected = self._format_mock_call_signature(args, kwargs)
            actual = 'not called.'
            error_message = ('expected call not found.\nExpected: %s\nActual: %s'
                    % (expected, actual))
            raise AssertionError(error_message)

        def _error_message():
            msg = self._format_mock_failure_message(args, kwargs)
            return msg
        expected = self._call_matcher(_Call((args, kwargs), two=True))
        actual = self._call_matcher(self.call_args)
        if actual != expected:
            cause = expected if isinstance(expected, Exception) else None
>           raise AssertionError(_error_message()) from cause
E           AssertionError: expected call not found.
E           Expected: cookiecutter('tests/fake-repo-pre/', None, False, replay=False, overwrite_if_exists=False, skip_if_file_exists=False, output_dir='.', config_file='/tmp/pytest-of-root/pytest-0/test_default_user_config_overw0/tests/config.yaml', default_config=True, extra_context=None, password=None, directory=None, accept_hooks=True, keep_project_on_failure=False)
E           Actual: cookiecutter('tests/fake-repo-pre/', checkout=None, no_input=False, extra_context=OrderedDict(), replay=False, overwrite_if_exists=False, output_dir='.', config_file='/tmp/pytest-of-root/pytest-0/test_default_user_config_overw0/tests/config.yaml', default_config=True, password=None, directory=None, skip_if_file_exists=False, accept_hooks='yes', keep_project_on_failure=False)

/usr/lib/python3.10/unittest/mock.py:929: AssertionError

During handling of the above exception, another exception occurred:

self = 
args = ('tests/fake-repo-pre/', None, False)
kwargs = {'accept_hooks': True, 'config_file': '/tmp/pytest-of-root/pytest-0/test_default_user_config_overw0/tests/config.yaml', 'default_config': True, 'directory': None, ...}

    def assert_called_once_with(self, /, *args, **kwargs):
        """assert that the mock was called exactly once and that that call was
        with the specified arguments."""
        if not self.call_count == 1:
            msg = ("Expected '%s' to be called once. Called %s times.%s"
                   % (self._mock_name or 'mock',
                      self.call_count,
                      self._calls_repr()))
            raise AssertionError(msg)
>       return self.assert_called_with(*args, **kwargs)
E       AssertionError: expected call not found.
E       Expected: cookiecutter('tests/fake-repo-pre/', None, False, replay=False, overwrite_if_exists=False, skip_if_file_exists=False, output_dir='.', config_file='/tmp/pytest-of-root/pytest-0/test_default_user_config_overw0/tests/config.yaml', default_config=True, extra_context=None, password=None, directory=None, accept_hooks=True, keep_project_on_failure=False)
E       Actual: cookiecutter('tests/fake-repo-pre/', checkout=None, no_input=False, extra_context=OrderedDict(), replay=False, overwrite_if_exists=False, output_dir='.', config_file='/tmp/pytest-of-root/pytest-0/test_default_user_config_overw0/tests/config.yaml', default_config=True, password=None, directory=None, skip_if_file_exists=False, accept_hooks='yes', keep_project_on_failure=False)
E       
E       pytest introspection follows:
E       
E       Args:
E       assert ('tests/fake-repo-pre/',) == ('tests/fake-repo-pre/', None, False)
E         
E         Right contains 2 more items, first extra item: None
E         
E         Full diff:
E           (
E               'tests/fake-repo-pre/',
E         -     None,
E         -     False,
E           )
E       Kwargs:
E       assert {'checkout': None, 'no_input': False, 'extra_context': OrderedDict(), 'replay': False, 'overwrite_if_exists': False, 'output_dir': '.', 'config_file': '/tmp/pytest-of-root/pytest-0/test_default_user_config_overw0/tests/config.yaml', 'default_config': True, 'password': None, 'directory': None, 'skip_if_file_exists': False, 'accept_hooks': 'yes', 'keep_project_on_failure': False} == {'replay': False, 'overwrite_if_exists': False, 'skip_if_file_exists': False, 'output_dir': '.', 'config_file': '/tmp/pytest-of-root/pytest-0/test_default_user_config_overw0/tests/config.yaml', 'default_config': True, 'extra_context': None, 'password': None, 'directory': None, 'accept_hooks': True, 'keep_project_on_failure': False}
E         
E         Common items:
E         {'config_file': '/tmp/pytest-of-root/pytest-0/test_default_user_config_overw0/tests/config.yaml',
E          'default_config': True,
E          'directory': None,
E          'keep_project_on_failure': False,
E          'output_dir': '.',
E          'overwrite_if_exists': False,
E          'password': None,
E          'replay': False,
E          'skip_if_file_exists': False}
E         Differing items:
E         {'extra_context': OrderedDict()} != {'extra_context': None}
E         {'accept_hooks': 'yes'} != {'accept_hooks': True}
E         Left contains 2 more items:
E         {'checkout': None, 'no_input': False}
E         
E         Full diff:
E           {
E         -     'accept_hooks': True,
E         ?                     ^^^
E         +     'accept_hooks': 'yes',
E         ?                     ^^ ++
E         +     'checkout': None,
E               'config_file': '/tmp/pytest-of-root/pytest-0/test_default_user_config_overw0/tests/config.yaml',
E               'default_config': True,
E               'directory': None,
E         -     'extra_context': None,
E         ?                      ^^^
E         +     'extra_context': OrderedDict(),
E         ?                      ^^^ +++++++++
E               'keep_project_on_failure': False,
E         +     'no_input': False,
E               'output_dir': '.',
E               'overwrite_if_exists': False,
E               'password': None,
E               'replay': False,
E               'skip_if_file_exists': False,
E           }

/usr/lib/python3.10/unittest/mock.py:941: AssertionError

During handling of the above exception, another exception occurred:

mocker = 
cli_runner = .cli_main at 0x7fcb9265e680>
user_config_path = '/tmp/pytest-of-root/pytest-0/test_default_user_config_overw0/tests/config.yaml'

    def test_default_user_config_overwrite(mocker, cli_runner, user_config_path):
        """Test cli invocation ignores `config-file` if `default-config` passed."""
        mock_cookiecutter = mocker.patch('cookiecutter.cli.cookiecutter')

        template_path = 'tests/fake-repo-pre/'
        result = cli_runner(
            template_path,
            '--config-file',
            user_config_path,
            '--default-config',
        )

        assert result.exit_code == 0
>       mock_cookiecutter.assert_called_once_with(
            template_path,
            None,
            False,
            replay=False,
            overwrite_if_exists=False,
            skip_if_file_exists=False,
            output_dir='.',
            config_file=user_config_path,
            default_config=True,
            extra_context=None,
            password=None,
            directory=None,
            accept_hooks=True,
            keep_project_on_failure=False,
        )
E       AssertionError: expected call not found.
E       Expected: cookiecutter('tests/fake-repo-pre/', None, False, replay=False, overwrite_if_exists=False, skip_if_file_exists=False, output_dir='.', config_file='/tmp/pytest-of-root/pytest-0/test_default_user_config_overw0/tests/config.yaml', default_config=True, extra_context=None, password=None, directory=None, accept_hooks=True, keep_project_on_failure=False)
E       Actual: cookiecutter('tests/fake-repo-pre/', checkout=None, no_input=False, extra_context=OrderedDict(), replay=False, overwrite_if_exists=False, output_dir='.', config_file='/tmp/pytest-of-root/pytest-0/test_default_user_config_overw0/tests/config.yaml', default_config=True, password=None, directory=None, skip_if_file_exists=False, accept_hooks='yes', keep_project_on_failure=False)
E       
E       pytest introspection follows:
E       
E       Args:
E       assert ('tests/fake-repo-pre/',) == ('tests/fake-repo-pre/', None, False)
E         
E         Right contains 2 more items, first extra item: None
E         
E         Full diff:
E           (
E               'tests/fake-repo-pre/',
E         -     None,
E         -     False,
E           )
E       Kwargs:
E       assert {'checkout': None, 'no_input': False, 'extra_context': OrderedDict(), 'replay': False, 'overwrite_if_exists': False, 'output_dir': '.', 'config_file': '/tmp/pytest-of-root/pytest-0/test_default_user_config_overw0/tests/config.yaml', 'default_config': True, 'password': None, 'directory': None, 'skip_if_file_exists': False, 'accept_hooks': 'yes', 'keep_project_on_failure': False} == {'replay': False, 'overwrite_if_exists': False, 'skip_if_file_exists': False, 'output_dir': '.', 'config_file': '/tmp/pytest-of-root/pytest-0/test_default_user_config_overw0/tests/config.yaml', 'default_config': True, 'extra_context': None, 'password': None, 'directory': None, 'accept_hooks': True, 'keep_project_on_failure': False}
E         
E         Common items:
E         {'config_file': '/tmp/pytest-of-root/pytest-0/test_default_user_config_overw0/tests/config.yaml',
E          'default_config': True,
E          'directory': None,
E          'keep_project_on_failure': False,
E          'output_dir': '.',
E          'overwrite_if_exists': False,
E          'password': None,
E          'replay': False,
E          'skip_if_file_exists': False}
E         Differing items:
E         {'extra_context': OrderedDict()} != {'extra_context': None}
E         {'accept_hooks': 'yes'} != {'accept_hooks': True}
E         Left contains 2 more items:
E         {'checkout': None, 'no_input': False}
E         
E         Full diff:
E           {
E         -     'accept_hooks': True,
E         ?                     ^^^
E         +     'accept_hooks': 'yes',
E         ?                     ^^ ++
E         +     'checkout': None,
E               'config_file': '/tmp/pytest-of-root/pytest-0/test_default_user_config_overw0/tests/config.yaml',
E               'default_config': True,
E               'directory': None,
E         -     'extra_context': None,
E         ?                      ^^^
E         +     'extra_context': OrderedDict(),
E         ?                      ^^^ +++++++++
E               'keep_project_on_failure': False,
E         +     'no_input': False,
E               'output_dir': '.',
E               'overwrite_if_exists': False,
E               'password': None,
E               'replay': False,
E               'skip_if_file_exists': False,
E           }

tests/test_cli.py:361: AssertionError

test_cli.py::test_default_user_config

test_cli.py::test_default_user_config
self = 
args = ('tests/fake-repo-pre/', None, False)
kwargs = {'accept_hooks': True, 'config_file': None, 'default_config': True, 'directory': None, ...}
expected = call('tests/fake-repo-pre/', None, False, replay=False, overwrite_if_exists=False, skip_if_file_exists=False, output_dir='.', config_file=None, default_config=True, extra_context=None, password=None, directory=None, accept_hooks=True, keep_project_on_failure=False)
actual = call('tests/fake-repo-pre/', checkout=None, no_input=False, extra_context=OrderedDict(), replay=False, overwrite_if_exists=False, output_dir='.', config_file=None, default_config=True, password=None, directory=None, skip_if_file_exists=False, accept_hooks='yes', keep_project_on_failure=False)
_error_message = ._error_message at 0x7fcb926077f0>
cause = None

    def assert_called_with(self, /, *args, **kwargs):
        """assert that the last call was made with the specified arguments.

        Raises an AssertionError if the args and keyword args passed in are
        different to the last call to the mock."""
        if self.call_args is None:
            expected = self._format_mock_call_signature(args, kwargs)
            actual = 'not called.'
            error_message = ('expected call not found.\nExpected: %s\nActual: %s'
                    % (expected, actual))
            raise AssertionError(error_message)

        def _error_message():
            msg = self._format_mock_failure_message(args, kwargs)
            return msg
        expected = self._call_matcher(_Call((args, kwargs), two=True))
        actual = self._call_matcher(self.call_args)
        if actual != expected:
            cause = expected if isinstance(expected, Exception) else None
>           raise AssertionError(_error_message()) from cause
E           AssertionError: expected call not found.
E           Expected: cookiecutter('tests/fake-repo-pre/', None, False, replay=False, overwrite_if_exists=False, skip_if_file_exists=False, output_dir='.', config_file=None, default_config=True, extra_context=None, password=None, directory=None, accept_hooks=True, keep_project_on_failure=False)
E           Actual: cookiecutter('tests/fake-repo-pre/', checkout=None, no_input=False, extra_context=OrderedDict(), replay=False, overwrite_if_exists=False, output_dir='.', config_file=None, default_config=True, password=None, directory=None, skip_if_file_exists=False, accept_hooks='yes', keep_project_on_failure=False)

/usr/lib/python3.10/unittest/mock.py:929: AssertionError

During handling of the above exception, another exception occurred:

self = 
args = ('tests/fake-repo-pre/', None, False)
kwargs = {'accept_hooks': True, 'config_file': None, 'default_config': True, 'directory': None, ...}

    def assert_called_once_with(self, /, *args, **kwargs):
        """assert that the mock was called exactly once and that that call was
        with the specified arguments."""
        if not self.call_count == 1:
            msg = ("Expected '%s' to be called once. Called %s times.%s"
                   % (self._mock_name or 'mock',
                      self.call_count,
                      self._calls_repr()))
            raise AssertionError(msg)
>       return self.assert_called_with(*args, **kwargs)
E       AssertionError: expected call not found.
E       Expected: cookiecutter('tests/fake-repo-pre/', None, False, replay=False, overwrite_if_exists=False, skip_if_file_exists=False, output_dir='.', config_file=None, default_config=True, extra_context=None, password=None, directory=None, accept_hooks=True, keep_project_on_failure=False)
E       Actual: cookiecutter('tests/fake-repo-pre/', checkout=None, no_input=False, extra_context=OrderedDict(), replay=False, overwrite_if_exists=False, output_dir='.', config_file=None, default_config=True, password=None, directory=None, skip_if_file_exists=False, accept_hooks='yes', keep_project_on_failure=False)
E       
E       pytest introspection follows:
E       
E       Args:
E       assert ('tests/fake-repo-pre/',) == ('tests/fake-repo-pre/', None, False)
E         
E         Right contains 2 more items, first extra item: None
E         
E         Full diff:
E           (
E               'tests/fake-repo-pre/',
E         -     None,
E         -     False,
E           )
E       Kwargs:
E       assert {'checkout': None, 'no_input': False, 'extra_context': OrderedDict(), 'replay': False, 'overwrite_if_exists': False, 'output_dir': '.', 'config_file': None, 'default_config': True, 'password': None, 'directory': None, 'skip_if_file_exists': False, 'accept_hooks': 'yes', 'keep_project_on_failure': False} == {'replay': False, 'overwrite_if_exists': False, 'skip_if_file_exists': False, 'output_dir': '.', 'config_file': None, 'default_config': True, 'extra_context': None, 'password': None, 'directory': None, 'accept_hooks': True, 'keep_project_on_failure': False}
E         
E         Common items:
E         {'config_file': None,
E          'default_config': True,
E          'directory': None,
E          'keep_project_on_failure': False,
E          'output_dir': '.',
E          'overwrite_if_exists': False,
E          'password': None,
E          'replay': False,
E          'skip_if_file_exists': False}
E         Differing items:
E         {'extra_context': OrderedDict()} != {'extra_context': None}
E         {'accept_hooks': 'yes'} != {'accept_hooks': True}
E         Left contains 2 more items:
E         {'checkout': None, 'no_input': False}
E         
E         Full diff:
E           {
E         -     'accept_hooks': True,
E         ?                     ^^^
E         +     'accept_hooks': 'yes',
E         ?                     ^^ ++
E         +     'checkout': None,
E               'config_file': None,
E               'default_config': True,
E               'directory': None,
E         -     'extra_context': None,
E         ?                      ^^^
E         +     'extra_context': OrderedDict(),
E         ?                      ^^^ +++++++++
E               'keep_project_on_failure': False,
E         +     'no_input': False,
E               'output_dir': '.',
E               'overwrite_if_exists': False,
E               'password': None,
E               'replay': False,
E               'skip_if_file_exists': False,
E           }

/usr/lib/python3.10/unittest/mock.py:941: AssertionError

During handling of the above exception, another exception occurred:

mocker = 
cli_runner = .cli_main at 0x7fcb9265e680>

    def test_default_user_config(mocker, cli_runner):
        """Test cli invocation accepts `default-config` flag correctly."""
        mock_cookiecutter = mocker.patch('cookiecutter.cli.cookiecutter')

        template_path = 'tests/fake-repo-pre/'
        result = cli_runner(template_path, '--default-config')

        assert result.exit_code == 0
>       mock_cookiecutter.assert_called_once_with(
            template_path,
            None,
            False,
            replay=False,
            overwrite_if_exists=False,
            skip_if_file_exists=False,
            output_dir='.',
            config_file=None,
            default_config=True,
            extra_context=None,
            password=None,
            directory=None,
            accept_hooks=True,
            keep_project_on_failure=False,
        )
E       AssertionError: expected call not found.
E       Expected: cookiecutter('tests/fake-repo-pre/', None, False, replay=False, overwrite_if_exists=False, skip_if_file_exists=False, output_dir='.', config_file=None, default_config=True, extra_context=None, password=None, directory=None, accept_hooks=True, keep_project_on_failure=False)
E       Actual: cookiecutter('tests/fake-repo-pre/', checkout=None, no_input=False, extra_context=OrderedDict(), replay=False, overwrite_if_exists=False, output_dir='.', config_file=None, default_config=True, password=None, directory=None, skip_if_file_exists=False, accept_hooks='yes', keep_project_on_failure=False)
E       
E       pytest introspection follows:
E       
E       Args:
E       assert ('tests/fake-repo-pre/',) == ('tests/fake-repo-pre/', None, False)
E         
E         Right contains 2 more items, first extra item: None
E         
E         Full diff:
E           (
E               'tests/fake-repo-pre/',
E         -     None,
E         -     False,
E           )
E       Kwargs:
E       assert {'checkout': None, 'no_input': False, 'extra_context': OrderedDict(), 'replay': False, 'overwrite_if_exists': False, 'output_dir': '.', 'config_file': None, 'default_config': True, 'password': None, 'directory': None, 'skip_if_file_exists': False, 'accept_hooks': 'yes', 'keep_project_on_failure': False} == {'replay': False, 'overwrite_if_exists': False, 'skip_if_file_exists': False, 'output_dir': '.', 'config_file': None, 'default_config': True, 'extra_context': None, 'password': None, 'directory': None, 'accept_hooks': True, 'keep_project_on_failure': False}
E         
E         Common items:
E         {'config_file': None,
E          'default_config': True,
E          'directory': None,
E          'keep_project_on_failure': False,
E          'output_dir': '.',
E          'overwrite_if_exists': False,
E          'password': None,
E          'replay': False,
E          'skip_if_file_exists': False}
E         Differing items:
E         {'extra_context': OrderedDict()} != {'extra_context': None}
E         {'accept_hooks': 'yes'} != {'accept_hooks': True}
E         Left contains 2 more items:
E         {'checkout': None, 'no_input': False}
E         
E         Full diff:
E           {
E         -     'accept_hooks': True,
E         ?                     ^^^
E         +     'accept_hooks': 'yes',
E         ?                     ^^ ++
E         +     'checkout': None,
E               'config_file': None,
E               'default_config': True,
E               'directory': None,
E         -     'extra_context': None,
E         ?                      ^^^
E         +     'extra_context': OrderedDict(),
E         ?                      ^^^ +++++++++
E               'keep_project_on_failure': False,
E         +     'no_input': False,
E               'output_dir': '.',
E               'overwrite_if_exists': False,
E               'password': None,
E               'replay': False,
E               'skip_if_file_exists': False,
E           }

tests/test_cli.py:387: AssertionError

test_cli.py::test_echo_undefined_variable_error

test_cli.py::test_echo_undefined_variable_error
output_dir = '/tmp/pytest-of-root/pytest-0/test_echo_undefined_variable_e0/output'
cli_runner = .cli_main at 0x7fcb9265e680>

    def test_echo_undefined_variable_error(output_dir, cli_runner):
        """Cli invocation return error if variable undefined in template."""
        template_path = 'tests/undefined-variable/file-name/'

        result = cli_runner(
            '--no-input',
            '--default-config',
            '--output-dir',
            output_dir,
            template_path,
        )

        assert result.exit_code == 1

        error = "Unable to create file '{{cookiecutter.foobar}}'"
>       assert error in result.output
E       assert "Unable to create file '{{cookiecutter.foobar}}'" in ''
E        +  where '' = .output

tests/test_cli.py:420: AssertionError

test_cli.py::test_echo_unknown_extension_error

test_cli.py::test_echo_unknown_extension_error
output_dir = '/tmp/pytest-of-root/pytest-0/test_echo_unknown_extension_er0/output'
cli_runner = .cli_main at 0x7fcb9265e680>

    def test_echo_unknown_extension_error(output_dir, cli_runner):
        """Cli return error if extension incorrectly defined in template."""
        template_path = 'tests/test-extensions/unknown/'

        result = cli_runner(
            '--no-input',
            '--default-config',
            '--output-dir',
            output_dir,
            template_path,
        )

        assert result.exit_code == 1

>       assert 'Unable to load extension: ' in result.output
E       assert 'Unable to load extension: ' in ''
E        +  where '' = .output

tests/test_cli.py:459: AssertionError

test_cli.py::test_local_extension

test_cli.py::test_local_extension
tmpdir = local('/tmp/pytest-of-root/pytest-0/test_local_extension0')
cli_runner = .cli_main at 0x7fcb9265e680>

    def test_local_extension(tmpdir, cli_runner):
        """Test to verify correct work of extension, included in template."""
        output_dir = str(tmpdir.mkdir('output'))
        template_path = 'tests/test-extensions/local_extension/'

        result = cli_runner(
            '--no-input',
            '--default-config',
            '--output-dir',
            output_dir,
            template_path,
        )
>       assert result.exit_code == 0
E       assert 1 == 0
E        +  where 1 = .exit_code

tests/test_cli.py:474: AssertionError

test_cli.py::test_cli_extra_context

test_cli.py::test_cli_extra_context
cli_runner = .cli_main at 0x7fcb9265e680>

    @pytest.mark.usefixtures('remove_fake_project_dir')
    def test_cli_extra_context(cli_runner):
        """Cli invocation replace content if called with replacement pairs."""
        result = cli_runner(
            'tests/fake-repo-pre/',
            '--no-input',
            '-v',
            'project_name=Awesomez',
        )
>       assert result.exit_code == 0
E       assert 1 == 0
E        +  where 1 = .exit_code

tests/test_cli.py:499: AssertionError

test_cli.py::test_cli_extra_context_invalid_format

test_cli.py::test_cli_extra_context_invalid_format
cli_runner = .cli_main at 0x7fcb9265e680>

    @pytest.mark.usefixtures('remove_fake_project_dir')
    def test_cli_extra_context_invalid_format(cli_runner):
        """Cli invocation raise error if called with unknown argument."""
        result = cli_runner(
            'tests/fake-repo-pre/',
            '--no-input',
            '-v',
            'ExtraContextWithNoEqualsSoInvalid',
        )
        assert result.exit_code == 2
        assert "Error: Invalid value for '[EXTRA_CONTEXT]...'" in result.output
>       assert 'should contain items of the form key=value' in result.output
E       assert 'should contain items of the form key=value' in 'Usage: main [OPTIONS] [TEMPLATE] [EXTRA_CONTEXT]...\nTry \'main -h\' for help.\n\nError: Invalid value for \'[EXTRA_CONTEXT]...\': "ExtraContextWithNoEqualsSoInvalid" is not a valid key/value pair. Use the format key=value.\n'
E        +  where 'Usage: main [OPTIONS] [TEMPLATE] [EXTRA_CONTEXT]...\nTry \'main -h\' for help.\n\nError: Invalid value for \'[EXTRA_CONTEXT]...\': "ExtraContextWithNoEqualsSoInvalid" is not a valid key/value pair. Use the format key=value.\n' = .output

tests/test_cli.py:516: AssertionError

test_cli.py::test_debug_file_non_verbose

test_cli.py::test_debug_file_non_verbose
cli_runner = .cli_main at 0x7fcb9265e680>
debug_file = PosixPath('/tmp/pytest-of-root/pytest-0/test_debug_file_non_verbose0/fake-repo.log')

    @pytest.mark.usefixtures('remove_fake_project_dir')
    def test_debug_file_non_verbose(cli_runner, debug_file):
        """Test cli invocation writes log to `debug-file` if flag enabled.

        Case for normal log output.
        """
        assert not debug_file.exists()

        result = cli_runner(
            '--no-input',
            '--debug-file',
            str(debug_file),
            'tests/fake-repo-pre/',
        )
>       assert result.exit_code == 0
E       assert 1 == 0
E        +  where 1 = .exit_code

tests/test_cli.py:539: AssertionError

test_cli.py::test_debug_file_verbose

test_cli.py::test_debug_file_verbose
cli_runner = .cli_main at 0x7fcb9265e680>
debug_file = PosixPath('/tmp/pytest-of-root/pytest-0/test_debug_file_verbose0/fake-repo.log')

    @pytest.mark.usefixtures('remove_fake_project_dir')
    def test_debug_file_verbose(cli_runner, debug_file):
        """Test cli invocation writes log to `debug-file` if flag enabled.

        Case for verbose log output.
        """
        assert not debug_file.exists()

        result = cli_runner(
            '--verbose',
            '--no-input',
            '--debug-file',
            str(debug_file),
            'tests/fake-repo-pre/',
        )
>       assert result.exit_code == 0
E       assert 1 == 0
E        +  where 1 = .exit_code

tests/test_cli.py:566: AssertionError

test_cli.py::test_debug_list_installed_templates

test_cli.py::test_debug_list_installed_templates
cli_runner = .cli_main at 0x7fcb9265e680>
debug_file = PosixPath('/tmp/pytest-of-root/pytest-0/test_debug_list_installed_temp0/fake-repo.log')
user_config_path = '/tmp/pytest-of-root/pytest-0/test_debug_list_installed_temp0/tests/config.yaml'

    @pytest.mark.usefixtures('make_fake_project_dir', 'remove_fake_project_dir')
    def test_debug_list_installed_templates(cli_runner, debug_file, user_config_path):
        """Verify --list-installed command correct invocation."""
        fake_template_dir = os.path.dirname(os.path.abspath('fake-project'))
        os.makedirs(os.path.dirname(user_config_path))
        # Single quotes in YAML will not parse escape codes (\).
        Path(user_config_path).write_text(f"cookiecutters_dir: '{fake_template_dir}'")
        Path("fake-project", "cookiecutter.json").write_text('{}')

        result = cli_runner(
            '--list-installed',
            '--config-file',
            user_config_path,
            str(debug_file),
        )

>       assert "1 installed templates:" in result.output
E       AssertionError: assert '1 installed templates:' in 'Installed templates:\n  .venv\n  docs\n  tests\n  .git\n  cookiecutter\n  logo\n  .github\n  cookiecutter.egg-info\n  fake-project\n'
E        +  where 'Installed templates:\n  .venv\n  docs\n  tests\n  .git\n  cookiecutter\n  logo\n  .github\n  cookiecutter.egg-info\n  fake-project\n' = .output

tests/test_cli.py:594: AssertionError

test_cli.py::test_debug_list_installed_templates_failure

test_cli.py::test_debug_list_installed_templates_failure
cli_runner = .cli_main at 0x7fcb9265e680>
debug_file = PosixPath('/tmp/pytest-of-root/pytest-0/test_debug_list_installed_temp1/fake-repo.log')
user_config_path = '/tmp/pytest-of-root/pytest-0/test_debug_list_installed_temp1/tests/config.yaml'

    def test_debug_list_installed_templates_failure(
        cli_runner, debug_file, user_config_path
    ):
        """Verify --list-installed command error on invocation."""
        os.makedirs(os.path.dirname(user_config_path))
        Path(user_config_path).write_text('cookiecutters_dir: "/notarealplace/"')

        result = cli_runner(
            '--list-installed', '--config-file', user_config_path, str(debug_file)
        )

>       assert "Error: Cannot list installed templates." in result.output
E       AssertionError: assert 'Error: Cannot list installed templates.' in 'No templates found in /notarealplace/\n'
E        +  where 'No templates found in /notarealplace/\n' = .output

tests/test_cli.py:609: AssertionError

test_cli.py::test_directory_repo

test_cli.py::test_directory_repo
cli_runner = .cli_main at 0x7fcb9265e680>

    @pytest.mark.usefixtures('remove_fake_project_dir')
    def test_directory_repo(cli_runner):
        """Test cli invocation works with `directory` option."""
        result = cli_runner(
            'tests/fake-repo-dir/',
            '--no-input',
            '-v',
            '--directory=my-dir',
        )
>       assert result.exit_code == 0
E       assert 1 == 0
E        +  where 1 = .exit_code

tests/test_cli.py:622: AssertionError

test_cli.py::test_cli_accept_hooks[-o---accept-hooks=yes-None-True]

test_cli.py::test_cli_accept_hooks[-o---accept-hooks=yes-None-True]
self = 
args = ('tests/fake-repo-pre/', None, False)
kwargs = {'accept_hooks': True, 'config_file': None, 'default_config': False, 'directory': None, ...}
expected = call('tests/fake-repo-pre/', None, False, replay=False, overwrite_if_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks__o___acc0/output', config_file=None, default_config=False, extra_context=None, password=None, directory=None, skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False)
actual = call('tests/fake-repo-pre/', checkout=None, no_input=False, extra_context=OrderedDict(), replay=False, overwrite_if_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks__o___acc0/output', config_file=None, default_config=False, password=None, directory=None, skip_if_file_exists=False, accept_hooks='yes', keep_project_on_failure=False)
_error_message = ._error_message at 0x7fcb92192a70>
cause = None

    def assert_called_with(self, /, *args, **kwargs):
        """assert that the last call was made with the specified arguments.

        Raises an AssertionError if the args and keyword args passed in are
        different to the last call to the mock."""
        if self.call_args is None:
            expected = self._format_mock_call_signature(args, kwargs)
            actual = 'not called.'
            error_message = ('expected call not found.\nExpected: %s\nActual: %s'
                    % (expected, actual))
            raise AssertionError(error_message)

        def _error_message():
            msg = self._format_mock_failure_message(args, kwargs)
            return msg
        expected = self._call_matcher(_Call((args, kwargs), two=True))
        actual = self._call_matcher(self.call_args)
        if actual != expected:
            cause = expected if isinstance(expected, Exception) else None
>           raise AssertionError(_error_message()) from cause
E           AssertionError: expected call not found.
E           Expected: cookiecutter('tests/fake-repo-pre/', None, False, replay=False, overwrite_if_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks__o___acc0/output', config_file=None, default_config=False, extra_context=None, password=None, directory=None, skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False)
E           Actual: cookiecutter('tests/fake-repo-pre/', checkout=None, no_input=False, extra_context=OrderedDict(), replay=False, overwrite_if_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks__o___acc0/output', config_file=None, default_config=False, password=None, directory=None, skip_if_file_exists=False, accept_hooks='yes', keep_project_on_failure=False)

/usr/lib/python3.10/unittest/mock.py:929: AssertionError

During handling of the above exception, another exception occurred:

self = 
args = ('tests/fake-repo-pre/', None, False)
kwargs = {'accept_hooks': True, 'config_file': None, 'default_config': False, 'directory': None, ...}

    def assert_called_once_with(self, /, *args, **kwargs):
        """assert that the mock was called exactly once and that that call was
        with the specified arguments."""
        if not self.call_count == 1:
            msg = ("Expected '%s' to be called once. Called %s times.%s"
                   % (self._mock_name or 'mock',
                      self.call_count,
                      self._calls_repr()))
            raise AssertionError(msg)
>       return self.assert_called_with(*args, **kwargs)
E       AssertionError: expected call not found.
E       Expected: cookiecutter('tests/fake-repo-pre/', None, False, replay=False, overwrite_if_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks__o___acc0/output', config_file=None, default_config=False, extra_context=None, password=None, directory=None, skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False)
E       Actual: cookiecutter('tests/fake-repo-pre/', checkout=None, no_input=False, extra_context=OrderedDict(), replay=False, overwrite_if_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks__o___acc0/output', config_file=None, default_config=False, password=None, directory=None, skip_if_file_exists=False, accept_hooks='yes', keep_project_on_failure=False)
E       
E       pytest introspection follows:
E       
E       Args:
E       assert ('tests/fake-repo-pre/',) == ('tests/fake-repo-pre/', None, False)
E         
E         Right contains 2 more items, first extra item: None
E         
E         Full diff:
E           (
E               'tests/fake-repo-pre/',
E         -     None,
E         -     False,
E           )
E       Kwargs:
E       assert {'checkout': None, 'no_input': False, 'extra_context': OrderedDict(), 'replay': False, 'overwrite_if_exists': False, 'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks__o___acc0/output', 'config_file': None, 'default_config': False, 'password': None, 'directory': None, 'skip_if_file_exists': False, 'accept_hooks': 'yes', 'keep_project_on_failure': False} == {'replay': False, 'overwrite_if_exists': False, 'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks__o___acc0/output', 'config_file': None, 'default_config': False, 'extra_context': None, 'password': None, 'directory': None, 'skip_if_file_exists': False, 'accept_hooks': True, 'keep_project_on_failure': False}
E         
E         Common items:
E         {'config_file': None,
E          'default_config': False,
E          'directory': None,
E          'keep_project_on_failure': False,
E          'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks__o___acc0/output',
E          'overwrite_if_exists': False,
E          'password': None,
E          'replay': False,
E          'skip_if_file_exists': False}
E         Differing items:
E         {'extra_context': OrderedDict()} != {'extra_context': None}
E         {'accept_hooks': 'yes'} != {'accept_hooks': True}
E         Left contains 2 more items:
E         {'checkout': None, 'no_input': False}
E         
E         Full diff:
E           {
E         -     'accept_hooks': True,
E         ?                     ^^^
E         +     'accept_hooks': 'yes',
E         ?                     ^^ ++
E         +     'checkout': None,
E               'config_file': None,
E               'default_config': False,
E               'directory': None,
E         -     'extra_context': None,
E         ?                      ^^^
E         +     'extra_context': OrderedDict(),
E         ?                      ^^^ +++++++++
E               'keep_project_on_failure': False,
E         +     'no_input': False,
E               'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks__o___acc0/output',
E               'overwrite_if_exists': False,
E               'password': None,
E               'replay': False,
E               'skip_if_file_exists': False,
E           }

/usr/lib/python3.10/unittest/mock.py:941: AssertionError

During handling of the above exception, another exception occurred:

mocker = 
cli_runner = .cli_main at 0x7fcb9265e680>
output_dir_flag = '-o'
output_dir = '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks__o___acc0/output'
accept_hooks_arg = '--accept-hooks=yes', user_input = None, expected = True

    @pytest.mark.parametrize(
        "accept_hooks_arg,user_input,expected", cli_accept_hook_arg_testdata
    )
    def test_cli_accept_hooks(
        mocker,
        cli_runner,
        output_dir_flag,
        output_dir,
        accept_hooks_arg,
        user_input,
        expected,
    ):
        """Test cli invocation works with `accept-hooks` option."""
        mock_cookiecutter = mocker.patch("cookiecutter.cli.cookiecutter")

        template_path = "tests/fake-repo-pre/"
        result = cli_runner(
            template_path, output_dir_flag, output_dir, accept_hooks_arg, input=user_input
        )

        assert result.exit_code == 0
>       mock_cookiecutter.assert_called_once_with(
            template_path,
            None,
            False,
            replay=False,
            overwrite_if_exists=False,
            output_dir=output_dir,
            config_file=None,
            default_config=False,
            extra_context=None,
            password=None,
            directory=None,
            skip_if_file_exists=False,
            accept_hooks=expected,
            keep_project_on_failure=False,
        )
E       AssertionError: expected call not found.
E       Expected: cookiecutter('tests/fake-repo-pre/', None, False, replay=False, overwrite_if_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks__o___acc0/output', config_file=None, default_config=False, extra_context=None, password=None, directory=None, skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False)
E       Actual: cookiecutter('tests/fake-repo-pre/', checkout=None, no_input=False, extra_context=OrderedDict(), replay=False, overwrite_if_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks__o___acc0/output', config_file=None, default_config=False, password=None, directory=None, skip_if_file_exists=False, accept_hooks='yes', keep_project_on_failure=False)
E       
E       pytest introspection follows:
E       
E       Args:
E       assert ('tests/fake-repo-pre/',) == ('tests/fake-repo-pre/', None, False)
E         
E         Right contains 2 more items, first extra item: None
E         
E         Full diff:
E           (
E               'tests/fake-repo-pre/',
E         -     None,
E         -     False,
E           )
E       Kwargs:
E       assert {'checkout': None, 'no_input': False, 'extra_context': OrderedDict(), 'replay': False, 'overwrite_if_exists': False, 'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks__o___acc0/output', 'config_file': None, 'default_config': False, 'password': None, 'directory': None, 'skip_if_file_exists': False, 'accept_hooks': 'yes', 'keep_project_on_failure': False} == {'replay': False, 'overwrite_if_exists': False, 'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks__o___acc0/output', 'config_file': None, 'default_config': False, 'extra_context': None, 'password': None, 'directory': None, 'skip_if_file_exists': False, 'accept_hooks': True, 'keep_project_on_failure': False}
E         
E         Common items:
E         {'config_file': None,
E          'default_config': False,
E          'directory': None,
E          'keep_project_on_failure': False,
E          'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks__o___acc0/output',
E          'overwrite_if_exists': False,
E          'password': None,
E          'replay': False,
E          'skip_if_file_exists': False}
E         Differing items:
E         {'extra_context': OrderedDict()} != {'extra_context': None}
E         {'accept_hooks': 'yes'} != {'accept_hooks': True}
E         Left contains 2 more items:
E         {'checkout': None, 'no_input': False}
E         
E         Full diff:
E           {
E         -     'accept_hooks': True,
E         ?                     ^^^
E         +     'accept_hooks': 'yes',
E         ?                     ^^ ++
E         +     'checkout': None,
E               'config_file': None,
E               'default_config': False,
E               'directory': None,
E         -     'extra_context': None,
E         ?                      ^^^
E         +     'extra_context': OrderedDict(),
E         ?                      ^^^ +++++++++
E               'keep_project_on_failure': False,
E         +     'no_input': False,
E               'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks__o___acc0/output',
E               'overwrite_if_exists': False,
E               'password': None,
E               'replay': False,
E               'skip_if_file_exists': False,
E           }

tests/test_cli.py:657: AssertionError

test_cli.py::test_cli_accept_hooks[-o---accept-hooks=no-None-False]

test_cli.py::test_cli_accept_hooks[-o---accept-hooks=no-None-False]
self = 
args = ('tests/fake-repo-pre/', None, False)
kwargs = {'accept_hooks': False, 'config_file': None, 'default_config': False, 'directory': None, ...}
expected = call('tests/fake-repo-pre/', None, False, replay=False, overwrite_if_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks__o___acc1/output', config_file=None, default_config=False, extra_context=None, password=None, directory=None, skip_if_file_exists=False, accept_hooks=False, keep_project_on_failure=False)
actual = call('tests/fake-repo-pre/', checkout=None, no_input=False, extra_context=OrderedDict(), replay=False, overwrite_if_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks__o___acc1/output', config_file=None, default_config=False, password=None, directory=None, skip_if_file_exists=False, accept_hooks='no', keep_project_on_failure=False)
_error_message = ._error_message at 0x7fcb921bcdc0>
cause = None

    def assert_called_with(self, /, *args, **kwargs):
        """assert that the last call was made with the specified arguments.

        Raises an AssertionError if the args and keyword args passed in are
        different to the last call to the mock."""
        if self.call_args is None:
            expected = self._format_mock_call_signature(args, kwargs)
            actual = 'not called.'
            error_message = ('expected call not found.\nExpected: %s\nActual: %s'
                    % (expected, actual))
            raise AssertionError(error_message)

        def _error_message():
            msg = self._format_mock_failure_message(args, kwargs)
            return msg
        expected = self._call_matcher(_Call((args, kwargs), two=True))
        actual = self._call_matcher(self.call_args)
        if actual != expected:
            cause = expected if isinstance(expected, Exception) else None
>           raise AssertionError(_error_message()) from cause
E           AssertionError: expected call not found.
E           Expected: cookiecutter('tests/fake-repo-pre/', None, False, replay=False, overwrite_if_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks__o___acc1/output', config_file=None, default_config=False, extra_context=None, password=None, directory=None, skip_if_file_exists=False, accept_hooks=False, keep_project_on_failure=False)
E           Actual: cookiecutter('tests/fake-repo-pre/', checkout=None, no_input=False, extra_context=OrderedDict(), replay=False, overwrite_if_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks__o___acc1/output', config_file=None, default_config=False, password=None, directory=None, skip_if_file_exists=False, accept_hooks='no', keep_project_on_failure=False)

/usr/lib/python3.10/unittest/mock.py:929: AssertionError

During handling of the above exception, another exception occurred:

self = 
args = ('tests/fake-repo-pre/', None, False)
kwargs = {'accept_hooks': False, 'config_file': None, 'default_config': False, 'directory': None, ...}

    def assert_called_once_with(self, /, *args, **kwargs):
        """assert that the mock was called exactly once and that that call was
        with the specified arguments."""
        if not self.call_count == 1:
            msg = ("Expected '%s' to be called once. Called %s times.%s"
                   % (self._mock_name or 'mock',
                      self.call_count,
                      self._calls_repr()))
            raise AssertionError(msg)
>       return self.assert_called_with(*args, **kwargs)
E       AssertionError: expected call not found.
E       Expected: cookiecutter('tests/fake-repo-pre/', None, False, replay=False, overwrite_if_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks__o___acc1/output', config_file=None, default_config=False, extra_context=None, password=None, directory=None, skip_if_file_exists=False, accept_hooks=False, keep_project_on_failure=False)
E       Actual: cookiecutter('tests/fake-repo-pre/', checkout=None, no_input=False, extra_context=OrderedDict(), replay=False, overwrite_if_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks__o___acc1/output', config_file=None, default_config=False, password=None, directory=None, skip_if_file_exists=False, accept_hooks='no', keep_project_on_failure=False)
E       
E       pytest introspection follows:
E       
E       Args:
E       assert ('tests/fake-repo-pre/',) == ('tests/fake-repo-pre/', None, False)
E         
E         Right contains 2 more items, first extra item: None
E         
E         Full diff:
E           (
E               'tests/fake-repo-pre/',
E         -     None,
E         -     False,
E           )
E       Kwargs:
E       assert {'checkout': None, 'no_input': False, 'extra_context': OrderedDict(), 'replay': False, 'overwrite_if_exists': False, 'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks__o___acc1/output', 'config_file': None, 'default_config': False, 'password': None, 'directory': None, 'skip_if_file_exists': False, 'accept_hooks': 'no', 'keep_project_on_failure': False} == {'replay': False, 'overwrite_if_exists': False, 'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks__o___acc1/output', 'config_file': None, 'default_config': False, 'extra_context': None, 'password': None, 'directory': None, 'skip_if_file_exists': False, 'accept_hooks': False, 'keep_project_on_failure': False}
E         
E         Common items:
E         {'config_file': None,
E          'default_config': False,
E          'directory': None,
E          'keep_project_on_failure': False,
E          'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks__o___acc1/output',
E          'overwrite_if_exists': False,
E          'password': None,
E          'replay': False,
E          'skip_if_file_exists': False}
E         Differing items:
E         {'extra_context': OrderedDict()} != {'extra_context': None}
E         {'accept_hooks': 'no'} != {'accept_hooks': False}
E         Left contains 2 more items:
E         {'checkout': None, 'no_input': False}
E         
E         Full diff:
E           {
E         -     'accept_hooks': False,
E         ?                     ^^^^^
E         +     'accept_hooks': 'no',
E         ?                     ^^^^
E         +     'checkout': None,
E               'config_file': None,
E               'default_config': False,
E               'directory': None,
E         -     'extra_context': None,
E         ?                      ^^^
E         +     'extra_context': OrderedDict(),
E         ?                      ^^^ +++++++++
E               'keep_project_on_failure': False,
E         +     'no_input': False,
E               'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks__o___acc1/output',
E               'overwrite_if_exists': False,
E               'password': None,
E               'replay': False,
E               'skip_if_file_exists': False,
E           }

/usr/lib/python3.10/unittest/mock.py:941: AssertionError

During handling of the above exception, another exception occurred:

mocker = 
cli_runner = .cli_main at 0x7fcb9265e680>
output_dir_flag = '-o'
output_dir = '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks__o___acc1/output'
accept_hooks_arg = '--accept-hooks=no', user_input = None, expected = False

    @pytest.mark.parametrize(
        "accept_hooks_arg,user_input,expected", cli_accept_hook_arg_testdata
    )
    def test_cli_accept_hooks(
        mocker,
        cli_runner,
        output_dir_flag,
        output_dir,
        accept_hooks_arg,
        user_input,
        expected,
    ):
        """Test cli invocation works with `accept-hooks` option."""
        mock_cookiecutter = mocker.patch("cookiecutter.cli.cookiecutter")

        template_path = "tests/fake-repo-pre/"
        result = cli_runner(
            template_path, output_dir_flag, output_dir, accept_hooks_arg, input=user_input
        )

        assert result.exit_code == 0
>       mock_cookiecutter.assert_called_once_with(
            template_path,
            None,
            False,
            replay=False,
            overwrite_if_exists=False,
            output_dir=output_dir,
            config_file=None,
            default_config=False,
            extra_context=None,
            password=None,
            directory=None,
            skip_if_file_exists=False,
            accept_hooks=expected,
            keep_project_on_failure=False,
        )
E       AssertionError: expected call not found.
E       Expected: cookiecutter('tests/fake-repo-pre/', None, False, replay=False, overwrite_if_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks__o___acc1/output', config_file=None, default_config=False, extra_context=None, password=None, directory=None, skip_if_file_exists=False, accept_hooks=False, keep_project_on_failure=False)
E       Actual: cookiecutter('tests/fake-repo-pre/', checkout=None, no_input=False, extra_context=OrderedDict(), replay=False, overwrite_if_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks__o___acc1/output', config_file=None, default_config=False, password=None, directory=None, skip_if_file_exists=False, accept_hooks='no', keep_project_on_failure=False)
E       
E       pytest introspection follows:
E       
E       Args:
E       assert ('tests/fake-repo-pre/',) == ('tests/fake-repo-pre/', None, False)
E         
E         Right contains 2 more items, first extra item: None
E         
E         Full diff:
E           (
E               'tests/fake-repo-pre/',
E         -     None,
E         -     False,
E           )
E       Kwargs:
E       assert {'checkout': None, 'no_input': False, 'extra_context': OrderedDict(), 'replay': False, 'overwrite_if_exists': False, 'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks__o___acc1/output', 'config_file': None, 'default_config': False, 'password': None, 'directory': None, 'skip_if_file_exists': False, 'accept_hooks': 'no', 'keep_project_on_failure': False} == {'replay': False, 'overwrite_if_exists': False, 'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks__o___acc1/output', 'config_file': None, 'default_config': False, 'extra_context': None, 'password': None, 'directory': None, 'skip_if_file_exists': False, 'accept_hooks': False, 'keep_project_on_failure': False}
E         
E         Common items:
E         {'config_file': None,
E          'default_config': False,
E          'directory': None,
E          'keep_project_on_failure': False,
E          'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks__o___acc1/output',
E          'overwrite_if_exists': False,
E          'password': None,
E          'replay': False,
E          'skip_if_file_exists': False}
E         Differing items:
E         {'extra_context': OrderedDict()} != {'extra_context': None}
E         {'accept_hooks': 'no'} != {'accept_hooks': False}
E         Left contains 2 more items:
E         {'checkout': None, 'no_input': False}
E         
E         Full diff:
E           {
E         -     'accept_hooks': False,
E         ?                     ^^^^^
E         +     'accept_hooks': 'no',
E         ?                     ^^^^
E         +     'checkout': None,
E               'config_file': None,
E               'default_config': False,
E               'directory': None,
E         -     'extra_context': None,
E         ?                      ^^^
E         +     'extra_context': OrderedDict(),
E         ?                      ^^^ +++++++++
E               'keep_project_on_failure': False,
E         +     'no_input': False,
E               'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks__o___acc1/output',
E               'overwrite_if_exists': False,
E               'password': None,
E               'replay': False,
E               'skip_if_file_exists': False,
E           }

tests/test_cli.py:657: AssertionError

test_cli.py::test_cli_accept_hooks[-o---accept-hooks=ask-yes-True]

test_cli.py::test_cli_accept_hooks[-o---accept-hooks=ask-yes-True]
self = 
args = ('tests/fake-repo-pre/', None, False)
kwargs = {'accept_hooks': True, 'config_file': None, 'default_config': False, 'directory': None, ...}
expected = call('tests/fake-repo-pre/', None, False, replay=False, overwrite_if_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks__o___acc2/output', config_file=None, default_config=False, extra_context=None, password=None, directory=None, skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False)
actual = call('tests/fake-repo-pre/', checkout=None, no_input=False, extra_context=OrderedDict(), replay=False, overwrite_if_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks__o___acc2/output', config_file=None, default_config=False, password=None, directory=None, skip_if_file_exists=False, accept_hooks='ask', keep_project_on_failure=False)
_error_message = ._error_message at 0x7fcb921bcee0>
cause = None

    def assert_called_with(self, /, *args, **kwargs):
        """assert that the last call was made with the specified arguments.

        Raises an AssertionError if the args and keyword args passed in are
        different to the last call to the mock."""
        if self.call_args is None:
            expected = self._format_mock_call_signature(args, kwargs)
            actual = 'not called.'
            error_message = ('expected call not found.\nExpected: %s\nActual: %s'
                    % (expected, actual))
            raise AssertionError(error_message)

        def _error_message():
            msg = self._format_mock_failure_message(args, kwargs)
            return msg
        expected = self._call_matcher(_Call((args, kwargs), two=True))
        actual = self._call_matcher(self.call_args)
        if actual != expected:
            cause = expected if isinstance(expected, Exception) else None
>           raise AssertionError(_error_message()) from cause
E           AssertionError: expected call not found.
E           Expected: cookiecutter('tests/fake-repo-pre/', None, False, replay=False, overwrite_if_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks__o___acc2/output', config_file=None, default_config=False, extra_context=None, password=None, directory=None, skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False)
E           Actual: cookiecutter('tests/fake-repo-pre/', checkout=None, no_input=False, extra_context=OrderedDict(), replay=False, overwrite_if_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks__o___acc2/output', config_file=None, default_config=False, password=None, directory=None, skip_if_file_exists=False, accept_hooks='ask', keep_project_on_failure=False)

/usr/lib/python3.10/unittest/mock.py:929: AssertionError

During handling of the above exception, another exception occurred:

self = 
args = ('tests/fake-repo-pre/', None, False)
kwargs = {'accept_hooks': True, 'config_file': None, 'default_config': False, 'directory': None, ...}

    def assert_called_once_with(self, /, *args, **kwargs):
        """assert that the mock was called exactly once and that that call was
        with the specified arguments."""
        if not self.call_count == 1:
            msg = ("Expected '%s' to be called once. Called %s times.%s"
                   % (self._mock_name or 'mock',
                      self.call_count,
                      self._calls_repr()))
            raise AssertionError(msg)
>       return self.assert_called_with(*args, **kwargs)
E       AssertionError: expected call not found.
E       Expected: cookiecutter('tests/fake-repo-pre/', None, False, replay=False, overwrite_if_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks__o___acc2/output', config_file=None, default_config=False, extra_context=None, password=None, directory=None, skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False)
E       Actual: cookiecutter('tests/fake-repo-pre/', checkout=None, no_input=False, extra_context=OrderedDict(), replay=False, overwrite_if_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks__o___acc2/output', config_file=None, default_config=False, password=None, directory=None, skip_if_file_exists=False, accept_hooks='ask', keep_project_on_failure=False)
E       
E       pytest introspection follows:
E       
E       Args:
E       assert ('tests/fake-repo-pre/',) == ('tests/fake-repo-pre/', None, False)
E         
E         Right contains 2 more items, first extra item: None
E         
E         Full diff:
E           (
E               'tests/fake-repo-pre/',
E         -     None,
E         -     False,
E           )
E       Kwargs:
E       assert {'checkout': None, 'no_input': False, 'extra_context': OrderedDict(), 'replay': False, 'overwrite_if_exists': False, 'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks__o___acc2/output', 'config_file': None, 'default_config': False, 'password': None, 'directory': None, 'skip_if_file_exists': False, 'accept_hooks': 'ask', 'keep_project_on_failure': False} == {'replay': False, 'overwrite_if_exists': False, 'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks__o___acc2/output', 'config_file': None, 'default_config': False, 'extra_context': None, 'password': None, 'directory': None, 'skip_if_file_exists': False, 'accept_hooks': True, 'keep_project_on_failure': False}
E         
E         Common items:
E         {'config_file': None,
E          'default_config': False,
E          'directory': None,
E          'keep_project_on_failure': False,
E          'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks__o___acc2/output',
E          'overwrite_if_exists': False,
E          'password': None,
E          'replay': False,
E          'skip_if_file_exists': False}
E         Differing items:
E         {'extra_context': OrderedDict()} != {'extra_context': None}
E         {'accept_hooks': 'ask'} != {'accept_hooks': True}
E         Left contains 2 more items:
E         {'checkout': None, 'no_input': False}
E         
E         Full diff:
E           {
E         -     'accept_hooks': True,
E         ?                     ^^^^
E         +     'accept_hooks': 'ask',
E         ?                     ^^^^^
E         +     'checkout': None,
E               'config_file': None,
E               'default_config': False,
E               'directory': None,
E         -     'extra_context': None,
E         ?                      ^^^
E         +     'extra_context': OrderedDict(),
E         ?                      ^^^ +++++++++
E               'keep_project_on_failure': False,
E         +     'no_input': False,
E               'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks__o___acc2/output',
E               'overwrite_if_exists': False,
E               'password': None,
E               'replay': False,
E               'skip_if_file_exists': False,
E           }

/usr/lib/python3.10/unittest/mock.py:941: AssertionError

During handling of the above exception, another exception occurred:

mocker = 
cli_runner = .cli_main at 0x7fcb9265e680>
output_dir_flag = '-o'
output_dir = '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks__o___acc2/output'
accept_hooks_arg = '--accept-hooks=ask', user_input = 'yes', expected = True

    @pytest.mark.parametrize(
        "accept_hooks_arg,user_input,expected", cli_accept_hook_arg_testdata
    )
    def test_cli_accept_hooks(
        mocker,
        cli_runner,
        output_dir_flag,
        output_dir,
        accept_hooks_arg,
        user_input,
        expected,
    ):
        """Test cli invocation works with `accept-hooks` option."""
        mock_cookiecutter = mocker.patch("cookiecutter.cli.cookiecutter")

        template_path = "tests/fake-repo-pre/"
        result = cli_runner(
            template_path, output_dir_flag, output_dir, accept_hooks_arg, input=user_input
        )

        assert result.exit_code == 0
>       mock_cookiecutter.assert_called_once_with(
            template_path,
            None,
            False,
            replay=False,
            overwrite_if_exists=False,
            output_dir=output_dir,
            config_file=None,
            default_config=False,
            extra_context=None,
            password=None,
            directory=None,
            skip_if_file_exists=False,
            accept_hooks=expected,
            keep_project_on_failure=False,
        )
E       AssertionError: expected call not found.
E       Expected: cookiecutter('tests/fake-repo-pre/', None, False, replay=False, overwrite_if_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks__o___acc2/output', config_file=None, default_config=False, extra_context=None, password=None, directory=None, skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False)
E       Actual: cookiecutter('tests/fake-repo-pre/', checkout=None, no_input=False, extra_context=OrderedDict(), replay=False, overwrite_if_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks__o___acc2/output', config_file=None, default_config=False, password=None, directory=None, skip_if_file_exists=False, accept_hooks='ask', keep_project_on_failure=False)
E       
E       pytest introspection follows:
E       
E       Args:
E       assert ('tests/fake-repo-pre/',) == ('tests/fake-repo-pre/', None, False)
E         
E         Right contains 2 more items, first extra item: None
E         
E         Full diff:
E           (
E               'tests/fake-repo-pre/',
E         -     None,
E         -     False,
E           )
E       Kwargs:
E       assert {'checkout': None, 'no_input': False, 'extra_context': OrderedDict(), 'replay': False, 'overwrite_if_exists': False, 'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks__o___acc2/output', 'config_file': None, 'default_config': False, 'password': None, 'directory': None, 'skip_if_file_exists': False, 'accept_hooks': 'ask', 'keep_project_on_failure': False} == {'replay': False, 'overwrite_if_exists': False, 'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks__o___acc2/output', 'config_file': None, 'default_config': False, 'extra_context': None, 'password': None, 'directory': None, 'skip_if_file_exists': False, 'accept_hooks': True, 'keep_project_on_failure': False}
E         
E         Common items:
E         {'config_file': None,
E          'default_config': False,
E          'directory': None,
E          'keep_project_on_failure': False,
E          'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks__o___acc2/output',
E          'overwrite_if_exists': False,
E          'password': None,
E          'replay': False,
E          'skip_if_file_exists': False}
E         Differing items:
E         {'extra_context': OrderedDict()} != {'extra_context': None}
E         {'accept_hooks': 'ask'} != {'accept_hooks': True}
E         Left contains 2 more items:
E         {'checkout': None, 'no_input': False}
E         
E         Full diff:
E           {
E         -     'accept_hooks': True,
E         ?                     ^^^^
E         +     'accept_hooks': 'ask',
E         ?                     ^^^^^
E         +     'checkout': None,
E               'config_file': None,
E               'default_config': False,
E               'directory': None,
E         -     'extra_context': None,
E         ?                      ^^^
E         +     'extra_context': OrderedDict(),
E         ?                      ^^^ +++++++++
E               'keep_project_on_failure': False,
E         +     'no_input': False,
E               'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks__o___acc2/output',
E               'overwrite_if_exists': False,
E               'password': None,
E               'replay': False,
E               'skip_if_file_exists': False,
E           }

tests/test_cli.py:657: AssertionError

test_cli.py::test_cli_accept_hooks[-o---accept-hooks=ask-no-False]

test_cli.py::test_cli_accept_hooks[-o---accept-hooks=ask-no-False]
self = 
args = ('tests/fake-repo-pre/', None, False)
kwargs = {'accept_hooks': False, 'config_file': None, 'default_config': False, 'directory': None, ...}
expected = call('tests/fake-repo-pre/', None, False, replay=False, overwrite_if_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks__o___acc3/output', config_file=None, default_config=False, extra_context=None, password=None, directory=None, skip_if_file_exists=False, accept_hooks=False, keep_project_on_failure=False)
actual = call('tests/fake-repo-pre/', checkout=None, no_input=False, extra_context=OrderedDict(), replay=False, overwrite_if_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks__o___acc3/output', config_file=None, default_config=False, password=None, directory=None, skip_if_file_exists=False, accept_hooks='ask', keep_project_on_failure=False)
_error_message = ._error_message at 0x7fcb921bd6c0>
cause = None

    def assert_called_with(self, /, *args, **kwargs):
        """assert that the last call was made with the specified arguments.

        Raises an AssertionError if the args and keyword args passed in are
        different to the last call to the mock."""
        if self.call_args is None:
            expected = self._format_mock_call_signature(args, kwargs)
            actual = 'not called.'
            error_message = ('expected call not found.\nExpected: %s\nActual: %s'
                    % (expected, actual))
            raise AssertionError(error_message)

        def _error_message():
            msg = self._format_mock_failure_message(args, kwargs)
            return msg
        expected = self._call_matcher(_Call((args, kwargs), two=True))
        actual = self._call_matcher(self.call_args)
        if actual != expected:
            cause = expected if isinstance(expected, Exception) else None
>           raise AssertionError(_error_message()) from cause
E           AssertionError: expected call not found.
E           Expected: cookiecutter('tests/fake-repo-pre/', None, False, replay=False, overwrite_if_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks__o___acc3/output', config_file=None, default_config=False, extra_context=None, password=None, directory=None, skip_if_file_exists=False, accept_hooks=False, keep_project_on_failure=False)
E           Actual: cookiecutter('tests/fake-repo-pre/', checkout=None, no_input=False, extra_context=OrderedDict(), replay=False, overwrite_if_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks__o___acc3/output', config_file=None, default_config=False, password=None, directory=None, skip_if_file_exists=False, accept_hooks='ask', keep_project_on_failure=False)

/usr/lib/python3.10/unittest/mock.py:929: AssertionError

During handling of the above exception, another exception occurred:

self = 
args = ('tests/fake-repo-pre/', None, False)
kwargs = {'accept_hooks': False, 'config_file': None, 'default_config': False, 'directory': None, ...}

    def assert_called_once_with(self, /, *args, **kwargs):
        """assert that the mock was called exactly once and that that call was
        with the specified arguments."""
        if not self.call_count == 1:
            msg = ("Expected '%s' to be called once. Called %s times.%s"
                   % (self._mock_name or 'mock',
                      self.call_count,
                      self._calls_repr()))
            raise AssertionError(msg)
>       return self.assert_called_with(*args, **kwargs)
E       AssertionError: expected call not found.
E       Expected: cookiecutter('tests/fake-repo-pre/', None, False, replay=False, overwrite_if_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks__o___acc3/output', config_file=None, default_config=False, extra_context=None, password=None, directory=None, skip_if_file_exists=False, accept_hooks=False, keep_project_on_failure=False)
E       Actual: cookiecutter('tests/fake-repo-pre/', checkout=None, no_input=False, extra_context=OrderedDict(), replay=False, overwrite_if_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks__o___acc3/output', config_file=None, default_config=False, password=None, directory=None, skip_if_file_exists=False, accept_hooks='ask', keep_project_on_failure=False)
E       
E       pytest introspection follows:
E       
E       Args:
E       assert ('tests/fake-repo-pre/',) == ('tests/fake-repo-pre/', None, False)
E         
E         Right contains 2 more items, first extra item: None
E         
E         Full diff:
E           (
E               'tests/fake-repo-pre/',
E         -     None,
E         -     False,
E           )
E       Kwargs:
E       assert {'checkout': None, 'no_input': False, 'extra_context': OrderedDict(), 'replay': False, 'overwrite_if_exists': False, 'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks__o___acc3/output', 'config_file': None, 'default_config': False, 'password': None, 'directory': None, 'skip_if_file_exists': False, 'accept_hooks': 'ask', 'keep_project_on_failure': False} == {'replay': False, 'overwrite_if_exists': False, 'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks__o___acc3/output', 'config_file': None, 'default_config': False, 'extra_context': None, 'password': None, 'directory': None, 'skip_if_file_exists': False, 'accept_hooks': False, 'keep_project_on_failure': False}
E         
E         Common items:
E         {'config_file': None,
E          'default_config': False,
E          'directory': None,
E          'keep_project_on_failure': False,
E          'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks__o___acc3/output',
E          'overwrite_if_exists': False,
E          'password': None,
E          'replay': False,
E          'skip_if_file_exists': False}
E         Differing items:
E         {'extra_context': OrderedDict()} != {'extra_context': None}
E         {'accept_hooks': 'ask'} != {'accept_hooks': False}
E         Left contains 2 more items:
E         {'checkout': None, 'no_input': False}
E         
E         Full diff:
E           {
E         -     'accept_hooks': False,
E         ?                     ^ - ^
E         +     'accept_hooks': 'ask',
E         ?                     ^  ^^
E         +     'checkout': None,
E               'config_file': None,
E               'default_config': False,
E               'directory': None,
E         -     'extra_context': None,
E         ?                      ^^^
E         +     'extra_context': OrderedDict(),
E         ?                      ^^^ +++++++++
E               'keep_project_on_failure': False,
E         +     'no_input': False,
E               'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks__o___acc3/output',
E               'overwrite_if_exists': False,
E               'password': None,
E               'replay': False,
E               'skip_if_file_exists': False,
E           }

/usr/lib/python3.10/unittest/mock.py:941: AssertionError

During handling of the above exception, another exception occurred:

mocker = 
cli_runner = .cli_main at 0x7fcb9265e680>
output_dir_flag = '-o'
output_dir = '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks__o___acc3/output'
accept_hooks_arg = '--accept-hooks=ask', user_input = 'no', expected = False

    @pytest.mark.parametrize(
        "accept_hooks_arg,user_input,expected", cli_accept_hook_arg_testdata
    )
    def test_cli_accept_hooks(
        mocker,
        cli_runner,
        output_dir_flag,
        output_dir,
        accept_hooks_arg,
        user_input,
        expected,
    ):
        """Test cli invocation works with `accept-hooks` option."""
        mock_cookiecutter = mocker.patch("cookiecutter.cli.cookiecutter")

        template_path = "tests/fake-repo-pre/"
        result = cli_runner(
            template_path, output_dir_flag, output_dir, accept_hooks_arg, input=user_input
        )

        assert result.exit_code == 0
>       mock_cookiecutter.assert_called_once_with(
            template_path,
            None,
            False,
            replay=False,
            overwrite_if_exists=False,
            output_dir=output_dir,
            config_file=None,
            default_config=False,
            extra_context=None,
            password=None,
            directory=None,
            skip_if_file_exists=False,
            accept_hooks=expected,
            keep_project_on_failure=False,
        )
E       AssertionError: expected call not found.
E       Expected: cookiecutter('tests/fake-repo-pre/', None, False, replay=False, overwrite_if_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks__o___acc3/output', config_file=None, default_config=False, extra_context=None, password=None, directory=None, skip_if_file_exists=False, accept_hooks=False, keep_project_on_failure=False)
E       Actual: cookiecutter('tests/fake-repo-pre/', checkout=None, no_input=False, extra_context=OrderedDict(), replay=False, overwrite_if_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks__o___acc3/output', config_file=None, default_config=False, password=None, directory=None, skip_if_file_exists=False, accept_hooks='ask', keep_project_on_failure=False)
E       
E       pytest introspection follows:
E       
E       Args:
E       assert ('tests/fake-repo-pre/',) == ('tests/fake-repo-pre/', None, False)
E         
E         Right contains 2 more items, first extra item: None
E         
E         Full diff:
E           (
E               'tests/fake-repo-pre/',
E         -     None,
E         -     False,
E           )
E       Kwargs:
E       assert {'checkout': None, 'no_input': False, 'extra_context': OrderedDict(), 'replay': False, 'overwrite_if_exists': False, 'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks__o___acc3/output', 'config_file': None, 'default_config': False, 'password': None, 'directory': None, 'skip_if_file_exists': False, 'accept_hooks': 'ask', 'keep_project_on_failure': False} == {'replay': False, 'overwrite_if_exists': False, 'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks__o___acc3/output', 'config_file': None, 'default_config': False, 'extra_context': None, 'password': None, 'directory': None, 'skip_if_file_exists': False, 'accept_hooks': False, 'keep_project_on_failure': False}
E         
E         Common items:
E         {'config_file': None,
E          'default_config': False,
E          'directory': None,
E          'keep_project_on_failure': False,
E          'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks__o___acc3/output',
E          'overwrite_if_exists': False,
E          'password': None,
E          'replay': False,
E          'skip_if_file_exists': False}
E         Differing items:
E         {'extra_context': OrderedDict()} != {'extra_context': None}
E         {'accept_hooks': 'ask'} != {'accept_hooks': False}
E         Left contains 2 more items:
E         {'checkout': None, 'no_input': False}
E         
E         Full diff:
E           {
E         -     'accept_hooks': False,
E         ?                     ^ - ^
E         +     'accept_hooks': 'ask',
E         ?                     ^  ^^
E         +     'checkout': None,
E               'config_file': None,
E               'default_config': False,
E               'directory': None,
E         -     'extra_context': None,
E         ?                      ^^^
E         +     'extra_context': OrderedDict(),
E         ?                      ^^^ +++++++++
E               'keep_project_on_failure': False,
E         +     'no_input': False,
E               'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks__o___acc3/output',
E               'overwrite_if_exists': False,
E               'password': None,
E               'replay': False,
E               'skip_if_file_exists': False,
E           }

tests/test_cli.py:657: AssertionError

test_cli.py::test_cli_accept_hooks[--output-dir---accept-hooks=yes-None-True]

test_cli.py::test_cli_accept_hooks[--output-dir---accept-hooks=yes-None-True]
self = 
args = ('tests/fake-repo-pre/', None, False)
kwargs = {'accept_hooks': True, 'config_file': None, 'default_config': False, 'directory': None, ...}
expected = call('tests/fake-repo-pre/', None, False, replay=False, overwrite_if_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks___output0/output', config_file=None, default_config=False, extra_context=None, password=None, directory=None, skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False)
actual = call('tests/fake-repo-pre/', checkout=None, no_input=False, extra_context=OrderedDict(), replay=False, overwrite_if_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks___output0/output', config_file=None, default_config=False, password=None, directory=None, skip_if_file_exists=False, accept_hooks='yes', keep_project_on_failure=False)
_error_message = ._error_message at 0x7fcb921bd510>
cause = None

    def assert_called_with(self, /, *args, **kwargs):
        """assert that the last call was made with the specified arguments.

        Raises an AssertionError if the args and keyword args passed in are
        different to the last call to the mock."""
        if self.call_args is None:
            expected = self._format_mock_call_signature(args, kwargs)
            actual = 'not called.'
            error_message = ('expected call not found.\nExpected: %s\nActual: %s'
                    % (expected, actual))
            raise AssertionError(error_message)

        def _error_message():
            msg = self._format_mock_failure_message(args, kwargs)
            return msg
        expected = self._call_matcher(_Call((args, kwargs), two=True))
        actual = self._call_matcher(self.call_args)
        if actual != expected:
            cause = expected if isinstance(expected, Exception) else None
>           raise AssertionError(_error_message()) from cause
E           AssertionError: expected call not found.
E           Expected: cookiecutter('tests/fake-repo-pre/', None, False, replay=False, overwrite_if_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks___output0/output', config_file=None, default_config=False, extra_context=None, password=None, directory=None, skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False)
E           Actual: cookiecutter('tests/fake-repo-pre/', checkout=None, no_input=False, extra_context=OrderedDict(), replay=False, overwrite_if_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks___output0/output', config_file=None, default_config=False, password=None, directory=None, skip_if_file_exists=False, accept_hooks='yes', keep_project_on_failure=False)

/usr/lib/python3.10/unittest/mock.py:929: AssertionError

During handling of the above exception, another exception occurred:

self = 
args = ('tests/fake-repo-pre/', None, False)
kwargs = {'accept_hooks': True, 'config_file': None, 'default_config': False, 'directory': None, ...}

    def assert_called_once_with(self, /, *args, **kwargs):
        """assert that the mock was called exactly once and that that call was
        with the specified arguments."""
        if not self.call_count == 1:
            msg = ("Expected '%s' to be called once. Called %s times.%s"
                   % (self._mock_name or 'mock',
                      self.call_count,
                      self._calls_repr()))
            raise AssertionError(msg)
>       return self.assert_called_with(*args, **kwargs)
E       AssertionError: expected call not found.
E       Expected: cookiecutter('tests/fake-repo-pre/', None, False, replay=False, overwrite_if_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks___output0/output', config_file=None, default_config=False, extra_context=None, password=None, directory=None, skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False)
E       Actual: cookiecutter('tests/fake-repo-pre/', checkout=None, no_input=False, extra_context=OrderedDict(), replay=False, overwrite_if_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks___output0/output', config_file=None, default_config=False, password=None, directory=None, skip_if_file_exists=False, accept_hooks='yes', keep_project_on_failure=False)
E       
E       pytest introspection follows:
E       
E       Args:
E       assert ('tests/fake-repo-pre/',) == ('tests/fake-repo-pre/', None, False)
E         
E         Right contains 2 more items, first extra item: None
E         
E         Full diff:
E           (
E               'tests/fake-repo-pre/',
E         -     None,
E         -     False,
E           )
E       Kwargs:
E       assert {'checkout': None, 'no_input': False, 'extra_context': OrderedDict(), 'replay': False, 'overwrite_if_exists': False, 'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks___output0/output', 'config_file': None, 'default_config': False, 'password': None, 'directory': None, 'skip_if_file_exists': False, 'accept_hooks': 'yes', 'keep_project_on_failure': False} == {'replay': False, 'overwrite_if_exists': False, 'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks___output0/output', 'config_file': None, 'default_config': False, 'extra_context': None, 'password': None, 'directory': None, 'skip_if_file_exists': False, 'accept_hooks': True, 'keep_project_on_failure': False}
E         
E         Common items:
E         {'config_file': None,
E          'default_config': False,
E          'directory': None,
E          'keep_project_on_failure': False,
E          'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks___output0/output',
E          'overwrite_if_exists': False,
E          'password': None,
E          'replay': False,
E          'skip_if_file_exists': False}
E         Differing items:
E         {'extra_context': OrderedDict()} != {'extra_context': None}
E         {'accept_hooks': 'yes'} != {'accept_hooks': True}
E         Left contains 2 more items:
E         {'checkout': None, 'no_input': False}
E         
E         Full diff:
E           {
E         -     'accept_hooks': True,
E         ?                     ^^^
E         +     'accept_hooks': 'yes',
E         ?                     ^^ ++
E         +     'checkout': None,
E               'config_file': None,
E               'default_config': False,
E               'directory': None,
E         -     'extra_context': None,
E         ?                      ^^^
E         +     'extra_context': OrderedDict(),
E         ?                      ^^^ +++++++++
E               'keep_project_on_failure': False,
E         +     'no_input': False,
E               'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks___output0/output',
E               'overwrite_if_exists': False,
E               'password': None,
E               'replay': False,
E               'skip_if_file_exists': False,
E           }

/usr/lib/python3.10/unittest/mock.py:941: AssertionError

During handling of the above exception, another exception occurred:

mocker = 
cli_runner = .cli_main at 0x7fcb9265e680>
output_dir_flag = '--output-dir'
output_dir = '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks___output0/output'
accept_hooks_arg = '--accept-hooks=yes', user_input = None, expected = True

    @pytest.mark.parametrize(
        "accept_hooks_arg,user_input,expected", cli_accept_hook_arg_testdata
    )
    def test_cli_accept_hooks(
        mocker,
        cli_runner,
        output_dir_flag,
        output_dir,
        accept_hooks_arg,
        user_input,
        expected,
    ):
        """Test cli invocation works with `accept-hooks` option."""
        mock_cookiecutter = mocker.patch("cookiecutter.cli.cookiecutter")

        template_path = "tests/fake-repo-pre/"
        result = cli_runner(
            template_path, output_dir_flag, output_dir, accept_hooks_arg, input=user_input
        )

        assert result.exit_code == 0
>       mock_cookiecutter.assert_called_once_with(
            template_path,
            None,
            False,
            replay=False,
            overwrite_if_exists=False,
            output_dir=output_dir,
            config_file=None,
            default_config=False,
            extra_context=None,
            password=None,
            directory=None,
            skip_if_file_exists=False,
            accept_hooks=expected,
            keep_project_on_failure=False,
        )
E       AssertionError: expected call not found.
E       Expected: cookiecutter('tests/fake-repo-pre/', None, False, replay=False, overwrite_if_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks___output0/output', config_file=None, default_config=False, extra_context=None, password=None, directory=None, skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False)
E       Actual: cookiecutter('tests/fake-repo-pre/', checkout=None, no_input=False, extra_context=OrderedDict(), replay=False, overwrite_if_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks___output0/output', config_file=None, default_config=False, password=None, directory=None, skip_if_file_exists=False, accept_hooks='yes', keep_project_on_failure=False)
E       
E       pytest introspection follows:
E       
E       Args:
E       assert ('tests/fake-repo-pre/',) == ('tests/fake-repo-pre/', None, False)
E         
E         Right contains 2 more items, first extra item: None
E         
E         Full diff:
E           (
E               'tests/fake-repo-pre/',
E         -     None,
E         -     False,
E           )
E       Kwargs:
E       assert {'checkout': None, 'no_input': False, 'extra_context': OrderedDict(), 'replay': False, 'overwrite_if_exists': False, 'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks___output0/output', 'config_file': None, 'default_config': False, 'password': None, 'directory': None, 'skip_if_file_exists': False, 'accept_hooks': 'yes', 'keep_project_on_failure': False} == {'replay': False, 'overwrite_if_exists': False, 'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks___output0/output', 'config_file': None, 'default_config': False, 'extra_context': None, 'password': None, 'directory': None, 'skip_if_file_exists': False, 'accept_hooks': True, 'keep_project_on_failure': False}
E         
E         Common items:
E         {'config_file': None,
E          'default_config': False,
E          'directory': None,
E          'keep_project_on_failure': False,
E          'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks___output0/output',
E          'overwrite_if_exists': False,
E          'password': None,
E          'replay': False,
E          'skip_if_file_exists': False}
E         Differing items:
E         {'extra_context': OrderedDict()} != {'extra_context': None}
E         {'accept_hooks': 'yes'} != {'accept_hooks': True}
E         Left contains 2 more items:
E         {'checkout': None, 'no_input': False}
E         
E         Full diff:
E           {
E         -     'accept_hooks': True,
E         ?                     ^^^
E         +     'accept_hooks': 'yes',
E         ?                     ^^ ++
E         +     'checkout': None,
E               'config_file': None,
E               'default_config': False,
E               'directory': None,
E         -     'extra_context': None,
E         ?                      ^^^
E         +     'extra_context': OrderedDict(),
E         ?                      ^^^ +++++++++
E               'keep_project_on_failure': False,
E         +     'no_input': False,
E               'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks___output0/output',
E               'overwrite_if_exists': False,
E               'password': None,
E               'replay': False,
E               'skip_if_file_exists': False,
E           }

tests/test_cli.py:657: AssertionError

test_cli.py::test_cli_accept_hooks[--output-dir---accept-hooks=no-None-False]

test_cli.py::test_cli_accept_hooks[--output-dir---accept-hooks=no-None-False]
self = 
args = ('tests/fake-repo-pre/', None, False)
kwargs = {'accept_hooks': False, 'config_file': None, 'default_config': False, 'directory': None, ...}
expected = call('tests/fake-repo-pre/', None, False, replay=False, overwrite_if_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks___output1/output', config_file=None, default_config=False, extra_context=None, password=None, directory=None, skip_if_file_exists=False, accept_hooks=False, keep_project_on_failure=False)
actual = call('tests/fake-repo-pre/', checkout=None, no_input=False, extra_context=OrderedDict(), replay=False, overwrite_if_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks___output1/output', config_file=None, default_config=False, password=None, directory=None, skip_if_file_exists=False, accept_hooks='no', keep_project_on_failure=False)
_error_message = ._error_message at 0x7fcb921bdb40>
cause = None

    def assert_called_with(self, /, *args, **kwargs):
        """assert that the last call was made with the specified arguments.

        Raises an AssertionError if the args and keyword args passed in are
        different to the last call to the mock."""
        if self.call_args is None:
            expected = self._format_mock_call_signature(args, kwargs)
            actual = 'not called.'
            error_message = ('expected call not found.\nExpected: %s\nActual: %s'
                    % (expected, actual))
            raise AssertionError(error_message)

        def _error_message():
            msg = self._format_mock_failure_message(args, kwargs)
            return msg
        expected = self._call_matcher(_Call((args, kwargs), two=True))
        actual = self._call_matcher(self.call_args)
        if actual != expected:
            cause = expected if isinstance(expected, Exception) else None
>           raise AssertionError(_error_message()) from cause
E           AssertionError: expected call not found.
E           Expected: cookiecutter('tests/fake-repo-pre/', None, False, replay=False, overwrite_if_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks___output1/output', config_file=None, default_config=False, extra_context=None, password=None, directory=None, skip_if_file_exists=False, accept_hooks=False, keep_project_on_failure=False)
E           Actual: cookiecutter('tests/fake-repo-pre/', checkout=None, no_input=False, extra_context=OrderedDict(), replay=False, overwrite_if_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks___output1/output', config_file=None, default_config=False, password=None, directory=None, skip_if_file_exists=False, accept_hooks='no', keep_project_on_failure=False)

/usr/lib/python3.10/unittest/mock.py:929: AssertionError

During handling of the above exception, another exception occurred:

self = 
args = ('tests/fake-repo-pre/', None, False)
kwargs = {'accept_hooks': False, 'config_file': None, 'default_config': False, 'directory': None, ...}

    def assert_called_once_with(self, /, *args, **kwargs):
        """assert that the mock was called exactly once and that that call was
        with the specified arguments."""
        if not self.call_count == 1:
            msg = ("Expected '%s' to be called once. Called %s times.%s"
                   % (self._mock_name or 'mock',
                      self.call_count,
                      self._calls_repr()))
            raise AssertionError(msg)
>       return self.assert_called_with(*args, **kwargs)
E       AssertionError: expected call not found.
E       Expected: cookiecutter('tests/fake-repo-pre/', None, False, replay=False, overwrite_if_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks___output1/output', config_file=None, default_config=False, extra_context=None, password=None, directory=None, skip_if_file_exists=False, accept_hooks=False, keep_project_on_failure=False)
E       Actual: cookiecutter('tests/fake-repo-pre/', checkout=None, no_input=False, extra_context=OrderedDict(), replay=False, overwrite_if_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks___output1/output', config_file=None, default_config=False, password=None, directory=None, skip_if_file_exists=False, accept_hooks='no', keep_project_on_failure=False)
E       
E       pytest introspection follows:
E       
E       Args:
E       assert ('tests/fake-repo-pre/',) == ('tests/fake-repo-pre/', None, False)
E         
E         Right contains 2 more items, first extra item: None
E         
E         Full diff:
E           (
E               'tests/fake-repo-pre/',
E         -     None,
E         -     False,
E           )
E       Kwargs:
E       assert {'checkout': None, 'no_input': False, 'extra_context': OrderedDict(), 'replay': False, 'overwrite_if_exists': False, 'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks___output1/output', 'config_file': None, 'default_config': False, 'password': None, 'directory': None, 'skip_if_file_exists': False, 'accept_hooks': 'no', 'keep_project_on_failure': False} == {'replay': False, 'overwrite_if_exists': False, 'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks___output1/output', 'config_file': None, 'default_config': False, 'extra_context': None, 'password': None, 'directory': None, 'skip_if_file_exists': False, 'accept_hooks': False, 'keep_project_on_failure': False}
E         
E         Common items:
E         {'config_file': None,
E          'default_config': False,
E          'directory': None,
E          'keep_project_on_failure': False,
E          'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks___output1/output',
E          'overwrite_if_exists': False,
E          'password': None,
E          'replay': False,
E          'skip_if_file_exists': False}
E         Differing items:
E         {'extra_context': OrderedDict()} != {'extra_context': None}
E         {'accept_hooks': 'no'} != {'accept_hooks': False}
E         Left contains 2 more items:
E         {'checkout': None, 'no_input': False}
E         
E         Full diff:
E           {
E         -     'accept_hooks': False,
E         ?                     ^^^^^
E         +     'accept_hooks': 'no',
E         ?                     ^^^^
E         +     'checkout': None,
E               'config_file': None,
E               'default_config': False,
E               'directory': None,
E         -     'extra_context': None,
E         ?                      ^^^
E         +     'extra_context': OrderedDict(),
E         ?                      ^^^ +++++++++
E               'keep_project_on_failure': False,
E         +     'no_input': False,
E               'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks___output1/output',
E               'overwrite_if_exists': False,
E               'password': None,
E               'replay': False,
E               'skip_if_file_exists': False,
E           }

/usr/lib/python3.10/unittest/mock.py:941: AssertionError

During handling of the above exception, another exception occurred:

mocker = 
cli_runner = .cli_main at 0x7fcb9265e680>
output_dir_flag = '--output-dir'
output_dir = '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks___output1/output'
accept_hooks_arg = '--accept-hooks=no', user_input = None, expected = False

    @pytest.mark.parametrize(
        "accept_hooks_arg,user_input,expected", cli_accept_hook_arg_testdata
    )
    def test_cli_accept_hooks(
        mocker,
        cli_runner,
        output_dir_flag,
        output_dir,
        accept_hooks_arg,
        user_input,
        expected,
    ):
        """Test cli invocation works with `accept-hooks` option."""
        mock_cookiecutter = mocker.patch("cookiecutter.cli.cookiecutter")

        template_path = "tests/fake-repo-pre/"
        result = cli_runner(
            template_path, output_dir_flag, output_dir, accept_hooks_arg, input=user_input
        )

        assert result.exit_code == 0
>       mock_cookiecutter.assert_called_once_with(
            template_path,
            None,
            False,
            replay=False,
            overwrite_if_exists=False,
            output_dir=output_dir,
            config_file=None,
            default_config=False,
            extra_context=None,
            password=None,
            directory=None,
            skip_if_file_exists=False,
            accept_hooks=expected,
            keep_project_on_failure=False,
        )
E       AssertionError: expected call not found.
E       Expected: cookiecutter('tests/fake-repo-pre/', None, False, replay=False, overwrite_if_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks___output1/output', config_file=None, default_config=False, extra_context=None, password=None, directory=None, skip_if_file_exists=False, accept_hooks=False, keep_project_on_failure=False)
E       Actual: cookiecutter('tests/fake-repo-pre/', checkout=None, no_input=False, extra_context=OrderedDict(), replay=False, overwrite_if_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks___output1/output', config_file=None, default_config=False, password=None, directory=None, skip_if_file_exists=False, accept_hooks='no', keep_project_on_failure=False)
E       
E       pytest introspection follows:
E       
E       Args:
E       assert ('tests/fake-repo-pre/',) == ('tests/fake-repo-pre/', None, False)
E         
E         Right contains 2 more items, first extra item: None
E         
E         Full diff:
E           (
E               'tests/fake-repo-pre/',
E         -     None,
E         -     False,
E           )
E       Kwargs:
E       assert {'checkout': None, 'no_input': False, 'extra_context': OrderedDict(), 'replay': False, 'overwrite_if_exists': False, 'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks___output1/output', 'config_file': None, 'default_config': False, 'password': None, 'directory': None, 'skip_if_file_exists': False, 'accept_hooks': 'no', 'keep_project_on_failure': False} == {'replay': False, 'overwrite_if_exists': False, 'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks___output1/output', 'config_file': None, 'default_config': False, 'extra_context': None, 'password': None, 'directory': None, 'skip_if_file_exists': False, 'accept_hooks': False, 'keep_project_on_failure': False}
E         
E         Common items:
E         {'config_file': None,
E          'default_config': False,
E          'directory': None,
E          'keep_project_on_failure': False,
E          'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks___output1/output',
E          'overwrite_if_exists': False,
E          'password': None,
E          'replay': False,
E          'skip_if_file_exists': False}
E         Differing items:
E         {'extra_context': OrderedDict()} != {'extra_context': None}
E         {'accept_hooks': 'no'} != {'accept_hooks': False}
E         Left contains 2 more items:
E         {'checkout': None, 'no_input': False}
E         
E         Full diff:
E           {
E         -     'accept_hooks': False,
E         ?                     ^^^^^
E         +     'accept_hooks': 'no',
E         ?                     ^^^^
E         +     'checkout': None,
E               'config_file': None,
E               'default_config': False,
E               'directory': None,
E         -     'extra_context': None,
E         ?                      ^^^
E         +     'extra_context': OrderedDict(),
E         ?                      ^^^ +++++++++
E               'keep_project_on_failure': False,
E         +     'no_input': False,
E               'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks___output1/output',
E               'overwrite_if_exists': False,
E               'password': None,
E               'replay': False,
E               'skip_if_file_exists': False,
E           }

tests/test_cli.py:657: AssertionError

test_cli.py::test_cli_accept_hooks[--output-dir---accept-hooks=ask-yes-True]

test_cli.py::test_cli_accept_hooks[--output-dir---accept-hooks=ask-yes-True]
self = 
args = ('tests/fake-repo-pre/', None, False)
kwargs = {'accept_hooks': True, 'config_file': None, 'default_config': False, 'directory': None, ...}
expected = call('tests/fake-repo-pre/', None, False, replay=False, overwrite_if_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks___output2/output', config_file=None, default_config=False, extra_context=None, password=None, directory=None, skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False)
actual = call('tests/fake-repo-pre/', checkout=None, no_input=False, extra_context=OrderedDict(), replay=False, overwrite_if_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks___output2/output', config_file=None, default_config=False, password=None, directory=None, skip_if_file_exists=False, accept_hooks='ask', keep_project_on_failure=False)
_error_message = ._error_message at 0x7fcb921bcc10>
cause = None

    def assert_called_with(self, /, *args, **kwargs):
        """assert that the last call was made with the specified arguments.

        Raises an AssertionError if the args and keyword args passed in are
        different to the last call to the mock."""
        if self.call_args is None:
            expected = self._format_mock_call_signature(args, kwargs)
            actual = 'not called.'
            error_message = ('expected call not found.\nExpected: %s\nActual: %s'
                    % (expected, actual))
            raise AssertionError(error_message)

        def _error_message():
            msg = self._format_mock_failure_message(args, kwargs)
            return msg
        expected = self._call_matcher(_Call((args, kwargs), two=True))
        actual = self._call_matcher(self.call_args)
        if actual != expected:
            cause = expected if isinstance(expected, Exception) else None
>           raise AssertionError(_error_message()) from cause
E           AssertionError: expected call not found.
E           Expected: cookiecutter('tests/fake-repo-pre/', None, False, replay=False, overwrite_if_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks___output2/output', config_file=None, default_config=False, extra_context=None, password=None, directory=None, skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False)
E           Actual: cookiecutter('tests/fake-repo-pre/', checkout=None, no_input=False, extra_context=OrderedDict(), replay=False, overwrite_if_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks___output2/output', config_file=None, default_config=False, password=None, directory=None, skip_if_file_exists=False, accept_hooks='ask', keep_project_on_failure=False)

/usr/lib/python3.10/unittest/mock.py:929: AssertionError

During handling of the above exception, another exception occurred:

self = 
args = ('tests/fake-repo-pre/', None, False)
kwargs = {'accept_hooks': True, 'config_file': None, 'default_config': False, 'directory': None, ...}

    def assert_called_once_with(self, /, *args, **kwargs):
        """assert that the mock was called exactly once and that that call was
        with the specified arguments."""
        if not self.call_count == 1:
            msg = ("Expected '%s' to be called once. Called %s times.%s"
                   % (self._mock_name or 'mock',
                      self.call_count,
                      self._calls_repr()))
            raise AssertionError(msg)
>       return self.assert_called_with(*args, **kwargs)
E       AssertionError: expected call not found.
E       Expected: cookiecutter('tests/fake-repo-pre/', None, False, replay=False, overwrite_if_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks___output2/output', config_file=None, default_config=False, extra_context=None, password=None, directory=None, skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False)
E       Actual: cookiecutter('tests/fake-repo-pre/', checkout=None, no_input=False, extra_context=OrderedDict(), replay=False, overwrite_if_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks___output2/output', config_file=None, default_config=False, password=None, directory=None, skip_if_file_exists=False, accept_hooks='ask', keep_project_on_failure=False)
E       
E       pytest introspection follows:
E       
E       Args:
E       assert ('tests/fake-repo-pre/',) == ('tests/fake-repo-pre/', None, False)
E         
E         Right contains 2 more items, first extra item: None
E         
E         Full diff:
E           (
E               'tests/fake-repo-pre/',
E         -     None,
E         -     False,
E           )
E       Kwargs:
E       assert {'checkout': None, 'no_input': False, 'extra_context': OrderedDict(), 'replay': False, 'overwrite_if_exists': False, 'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks___output2/output', 'config_file': None, 'default_config': False, 'password': None, 'directory': None, 'skip_if_file_exists': False, 'accept_hooks': 'ask', 'keep_project_on_failure': False} == {'replay': False, 'overwrite_if_exists': False, 'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks___output2/output', 'config_file': None, 'default_config': False, 'extra_context': None, 'password': None, 'directory': None, 'skip_if_file_exists': False, 'accept_hooks': True, 'keep_project_on_failure': False}
E         
E         Common items:
E         {'config_file': None,
E          'default_config': False,
E          'directory': None,
E          'keep_project_on_failure': False,
E          'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks___output2/output',
E          'overwrite_if_exists': False,
E          'password': None,
E          'replay': False,
E          'skip_if_file_exists': False}
E         Differing items:
E         {'extra_context': OrderedDict()} != {'extra_context': None}
E         {'accept_hooks': 'ask'} != {'accept_hooks': True}
E         Left contains 2 more items:
E         {'checkout': None, 'no_input': False}
E         
E         Full diff:
E           {
E         -     'accept_hooks': True,
E         ?                     ^^^^
E         +     'accept_hooks': 'ask',
E         ?                     ^^^^^
E         +     'checkout': None,
E               'config_file': None,
E               'default_config': False,
E               'directory': None,
E         -     'extra_context': None,
E         ?                      ^^^
E         +     'extra_context': OrderedDict(),
E         ?                      ^^^ +++++++++
E               'keep_project_on_failure': False,
E         +     'no_input': False,
E               'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks___output2/output',
E               'overwrite_if_exists': False,
E               'password': None,
E               'replay': False,
E               'skip_if_file_exists': False,
E           }

/usr/lib/python3.10/unittest/mock.py:941: AssertionError

During handling of the above exception, another exception occurred:

mocker = 
cli_runner = .cli_main at 0x7fcb9265e680>
output_dir_flag = '--output-dir'
output_dir = '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks___output2/output'
accept_hooks_arg = '--accept-hooks=ask', user_input = 'yes', expected = True

    @pytest.mark.parametrize(
        "accept_hooks_arg,user_input,expected", cli_accept_hook_arg_testdata
    )
    def test_cli_accept_hooks(
        mocker,
        cli_runner,
        output_dir_flag,
        output_dir,
        accept_hooks_arg,
        user_input,
        expected,
    ):
        """Test cli invocation works with `accept-hooks` option."""
        mock_cookiecutter = mocker.patch("cookiecutter.cli.cookiecutter")

        template_path = "tests/fake-repo-pre/"
        result = cli_runner(
            template_path, output_dir_flag, output_dir, accept_hooks_arg, input=user_input
        )

        assert result.exit_code == 0
>       mock_cookiecutter.assert_called_once_with(
            template_path,
            None,
            False,
            replay=False,
            overwrite_if_exists=False,
            output_dir=output_dir,
            config_file=None,
            default_config=False,
            extra_context=None,
            password=None,
            directory=None,
            skip_if_file_exists=False,
            accept_hooks=expected,
            keep_project_on_failure=False,
        )
E       AssertionError: expected call not found.
E       Expected: cookiecutter('tests/fake-repo-pre/', None, False, replay=False, overwrite_if_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks___output2/output', config_file=None, default_config=False, extra_context=None, password=None, directory=None, skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False)
E       Actual: cookiecutter('tests/fake-repo-pre/', checkout=None, no_input=False, extra_context=OrderedDict(), replay=False, overwrite_if_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks___output2/output', config_file=None, default_config=False, password=None, directory=None, skip_if_file_exists=False, accept_hooks='ask', keep_project_on_failure=False)
E       
E       pytest introspection follows:
E       
E       Args:
E       assert ('tests/fake-repo-pre/',) == ('tests/fake-repo-pre/', None, False)
E         
E         Right contains 2 more items, first extra item: None
E         
E         Full diff:
E           (
E               'tests/fake-repo-pre/',
E         -     None,
E         -     False,
E           )
E       Kwargs:
E       assert {'checkout': None, 'no_input': False, 'extra_context': OrderedDict(), 'replay': False, 'overwrite_if_exists': False, 'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks___output2/output', 'config_file': None, 'default_config': False, 'password': None, 'directory': None, 'skip_if_file_exists': False, 'accept_hooks': 'ask', 'keep_project_on_failure': False} == {'replay': False, 'overwrite_if_exists': False, 'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks___output2/output', 'config_file': None, 'default_config': False, 'extra_context': None, 'password': None, 'directory': None, 'skip_if_file_exists': False, 'accept_hooks': True, 'keep_project_on_failure': False}
E         
E         Common items:
E         {'config_file': None,
E          'default_config': False,
E          'directory': None,
E          'keep_project_on_failure': False,
E          'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks___output2/output',
E          'overwrite_if_exists': False,
E          'password': None,
E          'replay': False,
E          'skip_if_file_exists': False}
E         Differing items:
E         {'extra_context': OrderedDict()} != {'extra_context': None}
E         {'accept_hooks': 'ask'} != {'accept_hooks': True}
E         Left contains 2 more items:
E         {'checkout': None, 'no_input': False}
E         
E         Full diff:
E           {
E         -     'accept_hooks': True,
E         ?                     ^^^^
E         +     'accept_hooks': 'ask',
E         ?                     ^^^^^
E         +     'checkout': None,
E               'config_file': None,
E               'default_config': False,
E               'directory': None,
E         -     'extra_context': None,
E         ?                      ^^^
E         +     'extra_context': OrderedDict(),
E         ?                      ^^^ +++++++++
E               'keep_project_on_failure': False,
E         +     'no_input': False,
E               'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks___output2/output',
E               'overwrite_if_exists': False,
E               'password': None,
E               'replay': False,
E               'skip_if_file_exists': False,
E           }

tests/test_cli.py:657: AssertionError

test_cli.py::test_cli_accept_hooks[--output-dir---accept-hooks=ask-no-False]

test_cli.py::test_cli_accept_hooks[--output-dir---accept-hooks=ask-no-False]
self = 
args = ('tests/fake-repo-pre/', None, False)
kwargs = {'accept_hooks': False, 'config_file': None, 'default_config': False, 'directory': None, ...}
expected = call('tests/fake-repo-pre/', None, False, replay=False, overwrite_if_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks___output3/output', config_file=None, default_config=False, extra_context=None, password=None, directory=None, skip_if_file_exists=False, accept_hooks=False, keep_project_on_failure=False)
actual = call('tests/fake-repo-pre/', checkout=None, no_input=False, extra_context=OrderedDict(), replay=False, overwrite_if_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks___output3/output', config_file=None, default_config=False, password=None, directory=None, skip_if_file_exists=False, accept_hooks='ask', keep_project_on_failure=False)
_error_message = ._error_message at 0x7fcb921beef0>
cause = None

    def assert_called_with(self, /, *args, **kwargs):
        """assert that the last call was made with the specified arguments.

        Raises an AssertionError if the args and keyword args passed in are
        different to the last call to the mock."""
        if self.call_args is None:
            expected = self._format_mock_call_signature(args, kwargs)
            actual = 'not called.'
            error_message = ('expected call not found.\nExpected: %s\nActual: %s'
                    % (expected, actual))
            raise AssertionError(error_message)

        def _error_message():
            msg = self._format_mock_failure_message(args, kwargs)
            return msg
        expected = self._call_matcher(_Call((args, kwargs), two=True))
        actual = self._call_matcher(self.call_args)
        if actual != expected:
            cause = expected if isinstance(expected, Exception) else None
>           raise AssertionError(_error_message()) from cause
E           AssertionError: expected call not found.
E           Expected: cookiecutter('tests/fake-repo-pre/', None, False, replay=False, overwrite_if_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks___output3/output', config_file=None, default_config=False, extra_context=None, password=None, directory=None, skip_if_file_exists=False, accept_hooks=False, keep_project_on_failure=False)
E           Actual: cookiecutter('tests/fake-repo-pre/', checkout=None, no_input=False, extra_context=OrderedDict(), replay=False, overwrite_if_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks___output3/output', config_file=None, default_config=False, password=None, directory=None, skip_if_file_exists=False, accept_hooks='ask', keep_project_on_failure=False)

/usr/lib/python3.10/unittest/mock.py:929: AssertionError

During handling of the above exception, another exception occurred:

self = 
args = ('tests/fake-repo-pre/', None, False)
kwargs = {'accept_hooks': False, 'config_file': None, 'default_config': False, 'directory': None, ...}

    def assert_called_once_with(self, /, *args, **kwargs):
        """assert that the mock was called exactly once and that that call was
        with the specified arguments."""
        if not self.call_count == 1:
            msg = ("Expected '%s' to be called once. Called %s times.%s"
                   % (self._mock_name or 'mock',
                      self.call_count,
                      self._calls_repr()))
            raise AssertionError(msg)
>       return self.assert_called_with(*args, **kwargs)
E       AssertionError: expected call not found.
E       Expected: cookiecutter('tests/fake-repo-pre/', None, False, replay=False, overwrite_if_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks___output3/output', config_file=None, default_config=False, extra_context=None, password=None, directory=None, skip_if_file_exists=False, accept_hooks=False, keep_project_on_failure=False)
E       Actual: cookiecutter('tests/fake-repo-pre/', checkout=None, no_input=False, extra_context=OrderedDict(), replay=False, overwrite_if_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks___output3/output', config_file=None, default_config=False, password=None, directory=None, skip_if_file_exists=False, accept_hooks='ask', keep_project_on_failure=False)
E       
E       pytest introspection follows:
E       
E       Args:
E       assert ('tests/fake-repo-pre/',) == ('tests/fake-repo-pre/', None, False)
E         
E         Right contains 2 more items, first extra item: None
E         
E         Full diff:
E           (
E               'tests/fake-repo-pre/',
E         -     None,
E         -     False,
E           )
E       Kwargs:
E       assert {'checkout': None, 'no_input': False, 'extra_context': OrderedDict(), 'replay': False, 'overwrite_if_exists': False, 'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks___output3/output', 'config_file': None, 'default_config': False, 'password': None, 'directory': None, 'skip_if_file_exists': False, 'accept_hooks': 'ask', 'keep_project_on_failure': False} == {'replay': False, 'overwrite_if_exists': False, 'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks___output3/output', 'config_file': None, 'default_config': False, 'extra_context': None, 'password': None, 'directory': None, 'skip_if_file_exists': False, 'accept_hooks': False, 'keep_project_on_failure': False}
E         
E         Common items:
E         {'config_file': None,
E          'default_config': False,
E          'directory': None,
E          'keep_project_on_failure': False,
E          'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks___output3/output',
E          'overwrite_if_exists': False,
E          'password': None,
E          'replay': False,
E          'skip_if_file_exists': False}
E         Differing items:
E         {'extra_context': OrderedDict()} != {'extra_context': None}
E         {'accept_hooks': 'ask'} != {'accept_hooks': False}
E         Left contains 2 more items:
E         {'checkout': None, 'no_input': False}
E         
E         Full diff:
E           {
E         -     'accept_hooks': False,
E         ?                     ^ - ^
E         +     'accept_hooks': 'ask',
E         ?                     ^  ^^
E         +     'checkout': None,
E               'config_file': None,
E               'default_config': False,
E               'directory': None,
E         -     'extra_context': None,
E         ?                      ^^^
E         +     'extra_context': OrderedDict(),
E         ?                      ^^^ +++++++++
E               'keep_project_on_failure': False,
E         +     'no_input': False,
E               'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks___output3/output',
E               'overwrite_if_exists': False,
E               'password': None,
E               'replay': False,
E               'skip_if_file_exists': False,
E           }

/usr/lib/python3.10/unittest/mock.py:941: AssertionError

During handling of the above exception, another exception occurred:

mocker = 
cli_runner = .cli_main at 0x7fcb9265e680>
output_dir_flag = '--output-dir'
output_dir = '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks___output3/output'
accept_hooks_arg = '--accept-hooks=ask', user_input = 'no', expected = False

    @pytest.mark.parametrize(
        "accept_hooks_arg,user_input,expected", cli_accept_hook_arg_testdata
    )
    def test_cli_accept_hooks(
        mocker,
        cli_runner,
        output_dir_flag,
        output_dir,
        accept_hooks_arg,
        user_input,
        expected,
    ):
        """Test cli invocation works with `accept-hooks` option."""
        mock_cookiecutter = mocker.patch("cookiecutter.cli.cookiecutter")

        template_path = "tests/fake-repo-pre/"
        result = cli_runner(
            template_path, output_dir_flag, output_dir, accept_hooks_arg, input=user_input
        )

        assert result.exit_code == 0
>       mock_cookiecutter.assert_called_once_with(
            template_path,
            None,
            False,
            replay=False,
            overwrite_if_exists=False,
            output_dir=output_dir,
            config_file=None,
            default_config=False,
            extra_context=None,
            password=None,
            directory=None,
            skip_if_file_exists=False,
            accept_hooks=expected,
            keep_project_on_failure=False,
        )
E       AssertionError: expected call not found.
E       Expected: cookiecutter('tests/fake-repo-pre/', None, False, replay=False, overwrite_if_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks___output3/output', config_file=None, default_config=False, extra_context=None, password=None, directory=None, skip_if_file_exists=False, accept_hooks=False, keep_project_on_failure=False)
E       Actual: cookiecutter('tests/fake-repo-pre/', checkout=None, no_input=False, extra_context=OrderedDict(), replay=False, overwrite_if_exists=False, output_dir='/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks___output3/output', config_file=None, default_config=False, password=None, directory=None, skip_if_file_exists=False, accept_hooks='ask', keep_project_on_failure=False)
E       
E       pytest introspection follows:
E       
E       Args:
E       assert ('tests/fake-repo-pre/',) == ('tests/fake-repo-pre/', None, False)
E         
E         Right contains 2 more items, first extra item: None
E         
E         Full diff:
E           (
E               'tests/fake-repo-pre/',
E         -     None,
E         -     False,
E           )
E       Kwargs:
E       assert {'checkout': None, 'no_input': False, 'extra_context': OrderedDict(), 'replay': False, 'overwrite_if_exists': False, 'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks___output3/output', 'config_file': None, 'default_config': False, 'password': None, 'directory': None, 'skip_if_file_exists': False, 'accept_hooks': 'ask', 'keep_project_on_failure': False} == {'replay': False, 'overwrite_if_exists': False, 'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks___output3/output', 'config_file': None, 'default_config': False, 'extra_context': None, 'password': None, 'directory': None, 'skip_if_file_exists': False, 'accept_hooks': False, 'keep_project_on_failure': False}
E         
E         Common items:
E         {'config_file': None,
E          'default_config': False,
E          'directory': None,
E          'keep_project_on_failure': False,
E          'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks___output3/output',
E          'overwrite_if_exists': False,
E          'password': None,
E          'replay': False,
E          'skip_if_file_exists': False}
E         Differing items:
E         {'extra_context': OrderedDict()} != {'extra_context': None}
E         {'accept_hooks': 'ask'} != {'accept_hooks': False}
E         Left contains 2 more items:
E         {'checkout': None, 'no_input': False}
E         
E         Full diff:
E           {
E         -     'accept_hooks': False,
E         ?                     ^ - ^
E         +     'accept_hooks': 'ask',
E         ?                     ^  ^^
E         +     'checkout': None,
E               'config_file': None,
E               'default_config': False,
E               'directory': None,
E         -     'extra_context': None,
E         ?                      ^^^
E         +     'extra_context': OrderedDict(),
E         ?                      ^^^ +++++++++
E               'keep_project_on_failure': False,
E         +     'no_input': False,
E               'output_dir': '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks___output3/output',
E               'overwrite_if_exists': False,
E               'password': None,
E               'replay': False,
E               'skip_if_file_exists': False,
E           }

tests/test_cli.py:657: AssertionError

test_cli.py::test_cli_with_json_decoding_error

test_cli.py::test_cli_with_json_decoding_error
cli_runner = .cli_main at 0x7fcb9265e680>

    @pytest.mark.usefixtures('remove_fake_project_dir')
    def test_cli_with_json_decoding_error(cli_runner):
        """Test cli invocation with a malformed JSON file."""
        template_path = 'tests/fake-repo-bad-json/'
        result = cli_runner(template_path, '--no-input')
        assert result.exit_code != 0

        # Validate the error message.
        # original message from json module should be included
        pattern = 'Expecting \'{0,1}:\'{0,1} delimiter: line 1 column (19|20) \\(char 19\\)'
>       assert re.search(pattern, result.output)
E       assert None
E        +  where None = ("Expecting '{0,1}:'{0,1} delimiter: line 1 column (19|20) \\(char 19\\)", '')
E        +    where  = re.search
E        +    and   '' = .output

tests/test_cli.py:685: AssertionError

test_cli.py::test_cli_with_pre_prompt_hook

test_cli.py::test_cli_with_pre_prompt_hook
cli_runner = .cli_main at 0x7fcb9265e680>

    @pytest.mark.usefixtures('remove_fake_project_dir')
    def test_cli_with_pre_prompt_hook(cli_runner):
        """Test cli invocation in a template with pre_prompt hook."""
        template_path = 'tests/test-pyhooks/'
        result = cli_runner(template_path, '--no-input')
>       assert result.exit_code == 0
E       assert 1 == 0
E        +  where 1 = .exit_code

tests/test_cli.py:699: AssertionError

test_cookiecutter_invocation.py::test_should_invoke_main

test_cookiecutter_invocation.py::test_should_invoke_main
monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0x7fcb92565ba0>
project_dir = 'fake-project-templated'

    @pytest.mark.usefixtures('clean_system')
    def test_should_invoke_main(monkeypatch, project_dir):
        """Should create a project and exit with 0 code on cli invocation."""
        monkeypatch.setenv('PYTHONPATH', '.')

>       exit_code = subprocess.check_call(
            [sys.executable, '-m', 'cookiecutter.cli', 'tests/fake-repo-tmpl', '--no-input']
        )

tests/test_cookiecutter_invocation.py:31: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

popenargs = (['/testbed/.venv/bin/python3', '-m', 'cookiecutter.cli', 'tests/fake-repo-tmpl', '--no-input'],)
kwargs = {}, retcode = 1
cmd = ['/testbed/.venv/bin/python3', '-m', 'cookiecutter.cli', 'tests/fake-repo-tmpl', '--no-input']

    def check_call(*popenargs, **kwargs):
        """Run command with arguments.  Wait for command to complete.  If
        the exit code was zero then return, otherwise raise
        CalledProcessError.  The CalledProcessError object will have the
        return code in the returncode attribute.

        The arguments are the same as for the call function.  Example:

        check_call(["ls", "-l"])
        """
        retcode = call(*popenargs, **kwargs)
        if retcode:
            cmd = kwargs.get("args")
            if cmd is None:
                cmd = popenargs[0]
>           raise CalledProcessError(retcode, cmd)
E           subprocess.CalledProcessError: Command '['/testbed/.venv/bin/python3', '-m', 'cookiecutter.cli', 'tests/fake-repo-tmpl', '--no-input']' returned non-zero exit status 1.

/usr/lib/python3.10/subprocess.py:369: CalledProcessError

]

]
path = 'tests/fake-repo-pre/'

    @pytest.mark.parametrize('path', ['tests/fake-repo-pre/', 'tests/fake-repo-pre'])
    @pytest.mark.usefixtures('clean_system', 'remove_additional_dirs')
    def test_cookiecutter_no_input_return_project_dir(path):
        """Verify `cookiecutter` create project dir on input with or without slash."""
>       project_dir = main.cookiecutter(path, no_input=True)

tests/test_cookiecutter_local_no_input.py:39: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

template = 'tests/fake-repo-pre/', checkout = None, no_input = True
extra_context = None, replay = None, overwrite_if_exists = False
output_dir = '.', config_file = None, default_config = False, password = None
directory = None, skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False

    def cookiecutter(template, checkout=None, no_input=False, extra_context=
        None, replay=None, overwrite_if_exists=False, output_dir='.',
        config_file=None, default_config=False, password=None, directory=None,
        skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False
        ):
        """
        Run Cookiecutter just as if using it from the command line.

        :param template: A directory containing a project template directory,
            or a URL to a git repository.
        :param checkout: The branch, tag or commit ID to checkout after clone.
        :param no_input: Do not prompt for user input.
            Use default values for template parameters taken from `cookiecutter.json`, user
            config and `extra_dict`. Force a refresh of cached resources.
        :param extra_context: A dictionary of context that overrides default
            and user configuration.
        :param replay: Do not prompt for input, instead read from saved json. If
            ``True`` read from the ``replay_dir``.
            if it exists
        :param overwrite_if_exists: Overwrite the contents of the output directory
            if it exists.
        :param output_dir: Where to output the generated project dir into.
        :param config_file: User configuration file path.
        :param default_config: Use default values rather than a config file.
        :param password: The password to use when extracting the repository.
        :param directory: Relative path to a cookiecutter template in a repository.
        :param skip_if_file_exists: Skip the files in the corresponding directories
            if they already exist.
        :param accept_hooks: Accept pre and post hooks if set to `True`.
        :param keep_project_on_failure: If `True` keep generated project directory even when
            generation fails
        """
        # Get user configuration
        config_dict = get_user_config(config_file=config_file, default_config=default_config)

        # Determine the template directory
>       repo_dir, cleanup = determine_repo_dir(
            template=template,
            checkout=checkout,
            clone_to_dir=config_dict['cookiecutters_dir'],
            no_input=no_input,
            password=password,
            directory=directory
        )
E       TypeError: determine_repo_dir() missing 1 required positional argument: 'abbreviations'

cookiecutter/main.py:59: TypeError

fake-repo-pre]

fake-repo-pre]
path = 'tests/fake-repo-pre'

    @pytest.mark.parametrize('path', ['tests/fake-repo-pre/', 'tests/fake-repo-pre'])
    @pytest.mark.usefixtures('clean_system', 'remove_additional_dirs')
    def test_cookiecutter_no_input_return_project_dir(path):
        """Verify `cookiecutter` create project dir on input with or without slash."""
>       project_dir = main.cookiecutter(path, no_input=True)

tests/test_cookiecutter_local_no_input.py:39: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

template = 'tests/fake-repo-pre', checkout = None, no_input = True
extra_context = None, replay = None, overwrite_if_exists = False
output_dir = '.', config_file = None, default_config = False, password = None
directory = None, skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False

    def cookiecutter(template, checkout=None, no_input=False, extra_context=
        None, replay=None, overwrite_if_exists=False, output_dir='.',
        config_file=None, default_config=False, password=None, directory=None,
        skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False
        ):
        """
        Run Cookiecutter just as if using it from the command line.

        :param template: A directory containing a project template directory,
            or a URL to a git repository.
        :param checkout: The branch, tag or commit ID to checkout after clone.
        :param no_input: Do not prompt for user input.
            Use default values for template parameters taken from `cookiecutter.json`, user
            config and `extra_dict`. Force a refresh of cached resources.
        :param extra_context: A dictionary of context that overrides default
            and user configuration.
        :param replay: Do not prompt for input, instead read from saved json. If
            ``True`` read from the ``replay_dir``.
            if it exists
        :param overwrite_if_exists: Overwrite the contents of the output directory
            if it exists.
        :param output_dir: Where to output the generated project dir into.
        :param config_file: User configuration file path.
        :param default_config: Use default values rather than a config file.
        :param password: The password to use when extracting the repository.
        :param directory: Relative path to a cookiecutter template in a repository.
        :param skip_if_file_exists: Skip the files in the corresponding directories
            if they already exist.
        :param accept_hooks: Accept pre and post hooks if set to `True`.
        :param keep_project_on_failure: If `True` keep generated project directory even when
            generation fails
        """
        # Get user configuration
        config_dict = get_user_config(config_file=config_file, default_config=default_config)

        # Determine the template directory
>       repo_dir, cleanup = determine_repo_dir(
            template=template,
            checkout=checkout,
            clone_to_dir=config_dict['cookiecutters_dir'],
            no_input=no_input,
            password=password,
            directory=directory
        )
E       TypeError: determine_repo_dir() missing 1 required positional argument: 'abbreviations'

cookiecutter/main.py:59: TypeError

test_cookiecutter_local_no_input.py::test_cookiecutter_no_input_extra_context

test_cookiecutter_local_no_input.py::test_cookiecutter_no_input_extra_context
@pytest.mark.usefixtures('clean_system', 'remove_additional_dirs')
    def test_cookiecutter_no_input_extra_context():
        """Verify `cookiecutter` accept `extra_context` argument."""
>       main.cookiecutter(
            'tests/fake-repo-pre',
            no_input=True,
            extra_context={'repo_name': 'fake-project-extra'},
        )

tests/test_cookiecutter_local_no_input.py:50: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

template = 'tests/fake-repo-pre', checkout = None, no_input = True
extra_context = {'repo_name': 'fake-project-extra'}, replay = None
overwrite_if_exists = False, output_dir = '.', config_file = None
default_config = False, password = None, directory = None
skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False

    def cookiecutter(template, checkout=None, no_input=False, extra_context=
        None, replay=None, overwrite_if_exists=False, output_dir='.',
        config_file=None, default_config=False, password=None, directory=None,
        skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False
        ):
        """
        Run Cookiecutter just as if using it from the command line.

        :param template: A directory containing a project template directory,
            or a URL to a git repository.
        :param checkout: The branch, tag or commit ID to checkout after clone.
        :param no_input: Do not prompt for user input.
            Use default values for template parameters taken from `cookiecutter.json`, user
            config and `extra_dict`. Force a refresh of cached resources.
        :param extra_context: A dictionary of context that overrides default
            and user configuration.
        :param replay: Do not prompt for input, instead read from saved json. If
            ``True`` read from the ``replay_dir``.
            if it exists
        :param overwrite_if_exists: Overwrite the contents of the output directory
            if it exists.
        :param output_dir: Where to output the generated project dir into.
        :param config_file: User configuration file path.
        :param default_config: Use default values rather than a config file.
        :param password: The password to use when extracting the repository.
        :param directory: Relative path to a cookiecutter template in a repository.
        :param skip_if_file_exists: Skip the files in the corresponding directories
            if they already exist.
        :param accept_hooks: Accept pre and post hooks if set to `True`.
        :param keep_project_on_failure: If `True` keep generated project directory even when
            generation fails
        """
        # Get user configuration
        config_dict = get_user_config(config_file=config_file, default_config=default_config)

        # Determine the template directory
>       repo_dir, cleanup = determine_repo_dir(
            template=template,
            checkout=checkout,
            clone_to_dir=config_dict['cookiecutters_dir'],
            no_input=no_input,
            password=password,
            directory=directory
        )
E       TypeError: determine_repo_dir() missing 1 required positional argument: 'abbreviations'

cookiecutter/main.py:59: TypeError

test_cookiecutter_local_no_input.py::test_cookiecutter_templated_context

test_cookiecutter_local_no_input.py::test_cookiecutter_templated_context
@pytest.mark.usefixtures('clean_system', 'remove_additional_dirs')
    def test_cookiecutter_templated_context():
        """Verify Jinja2 templating correctly works in `cookiecutter.json` file."""
>       main.cookiecutter('tests/fake-repo-tmpl', no_input=True)

tests/test_cookiecutter_local_no_input.py:61: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

template = 'tests/fake-repo-tmpl', checkout = None, no_input = True
extra_context = None, replay = None, overwrite_if_exists = False
output_dir = '.', config_file = None, default_config = False, password = None
directory = None, skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False

    def cookiecutter(template, checkout=None, no_input=False, extra_context=
        None, replay=None, overwrite_if_exists=False, output_dir='.',
        config_file=None, default_config=False, password=None, directory=None,
        skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False
        ):
        """
        Run Cookiecutter just as if using it from the command line.

        :param template: A directory containing a project template directory,
            or a URL to a git repository.
        :param checkout: The branch, tag or commit ID to checkout after clone.
        :param no_input: Do not prompt for user input.
            Use default values for template parameters taken from `cookiecutter.json`, user
            config and `extra_dict`. Force a refresh of cached resources.
        :param extra_context: A dictionary of context that overrides default
            and user configuration.
        :param replay: Do not prompt for input, instead read from saved json. If
            ``True`` read from the ``replay_dir``.
            if it exists
        :param overwrite_if_exists: Overwrite the contents of the output directory
            if it exists.
        :param output_dir: Where to output the generated project dir into.
        :param config_file: User configuration file path.
        :param default_config: Use default values rather than a config file.
        :param password: The password to use when extracting the repository.
        :param directory: Relative path to a cookiecutter template in a repository.
        :param skip_if_file_exists: Skip the files in the corresponding directories
            if they already exist.
        :param accept_hooks: Accept pre and post hooks if set to `True`.
        :param keep_project_on_failure: If `True` keep generated project directory even when
            generation fails
        """
        # Get user configuration
        config_dict = get_user_config(config_file=config_file, default_config=default_config)

        # Determine the template directory
>       repo_dir, cleanup = determine_repo_dir(
            template=template,
            checkout=checkout,
            clone_to_dir=config_dict['cookiecutters_dir'],
            no_input=no_input,
            password=password,
            directory=directory
        )
E       TypeError: determine_repo_dir() missing 1 required positional argument: 'abbreviations'

cookiecutter/main.py:59: TypeError

test_cookiecutter_local_no_input.py::test_cookiecutter_no_input_return_rendered_file

test_cookiecutter_local_no_input.py::test_cookiecutter_no_input_return_rendered_file
@pytest.mark.usefixtures('clean_system', 'remove_additional_dirs')
    def test_cookiecutter_no_input_return_rendered_file():
        """Verify Jinja2 templating correctly works in `cookiecutter.json` file."""
>       project_dir = main.cookiecutter('tests/fake-repo-pre', no_input=True)

tests/test_cookiecutter_local_no_input.py:68: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

template = 'tests/fake-repo-pre', checkout = None, no_input = True
extra_context = None, replay = None, overwrite_if_exists = False
output_dir = '.', config_file = None, default_config = False, password = None
directory = None, skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False

    def cookiecutter(template, checkout=None, no_input=False, extra_context=
        None, replay=None, overwrite_if_exists=False, output_dir='.',
        config_file=None, default_config=False, password=None, directory=None,
        skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False
        ):
        """
        Run Cookiecutter just as if using it from the command line.

        :param template: A directory containing a project template directory,
            or a URL to a git repository.
        :param checkout: The branch, tag or commit ID to checkout after clone.
        :param no_input: Do not prompt for user input.
            Use default values for template parameters taken from `cookiecutter.json`, user
            config and `extra_dict`. Force a refresh of cached resources.
        :param extra_context: A dictionary of context that overrides default
            and user configuration.
        :param replay: Do not prompt for input, instead read from saved json. If
            ``True`` read from the ``replay_dir``.
            if it exists
        :param overwrite_if_exists: Overwrite the contents of the output directory
            if it exists.
        :param output_dir: Where to output the generated project dir into.
        :param config_file: User configuration file path.
        :param default_config: Use default values rather than a config file.
        :param password: The password to use when extracting the repository.
        :param directory: Relative path to a cookiecutter template in a repository.
        :param skip_if_file_exists: Skip the files in the corresponding directories
            if they already exist.
        :param accept_hooks: Accept pre and post hooks if set to `True`.
        :param keep_project_on_failure: If `True` keep generated project directory even when
            generation fails
        """
        # Get user configuration
        config_dict = get_user_config(config_file=config_file, default_config=default_config)

        # Determine the template directory
>       repo_dir, cleanup = determine_repo_dir(
            template=template,
            checkout=checkout,
            clone_to_dir=config_dict['cookiecutters_dir'],
            no_input=no_input,
            password=password,
            directory=directory
        )
E       TypeError: determine_repo_dir() missing 1 required positional argument: 'abbreviations'

cookiecutter/main.py:59: TypeError

test_cookiecutter_local_no_input.py::test_cookiecutter_dict_values_in_context

test_cookiecutter_local_no_input.py::test_cookiecutter_dict_values_in_context
@pytest.mark.usefixtures('clean_system', 'remove_additional_dirs')
    def test_cookiecutter_dict_values_in_context():
        """Verify configured dictionary from `cookiecutter.json` correctly unpacked."""
>       project_dir = main.cookiecutter('tests/fake-repo-dict', no_input=True)

tests/test_cookiecutter_local_no_input.py:77: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

template = 'tests/fake-repo-dict', checkout = None, no_input = True
extra_context = None, replay = None, overwrite_if_exists = False
output_dir = '.', config_file = None, default_config = False, password = None
directory = None, skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False

    def cookiecutter(template, checkout=None, no_input=False, extra_context=
        None, replay=None, overwrite_if_exists=False, output_dir='.',
        config_file=None, default_config=False, password=None, directory=None,
        skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False
        ):
        """
        Run Cookiecutter just as if using it from the command line.

        :param template: A directory containing a project template directory,
            or a URL to a git repository.
        :param checkout: The branch, tag or commit ID to checkout after clone.
        :param no_input: Do not prompt for user input.
            Use default values for template parameters taken from `cookiecutter.json`, user
            config and `extra_dict`. Force a refresh of cached resources.
        :param extra_context: A dictionary of context that overrides default
            and user configuration.
        :param replay: Do not prompt for input, instead read from saved json. If
            ``True`` read from the ``replay_dir``.
            if it exists
        :param overwrite_if_exists: Overwrite the contents of the output directory
            if it exists.
        :param output_dir: Where to output the generated project dir into.
        :param config_file: User configuration file path.
        :param default_config: Use default values rather than a config file.
        :param password: The password to use when extracting the repository.
        :param directory: Relative path to a cookiecutter template in a repository.
        :param skip_if_file_exists: Skip the files in the corresponding directories
            if they already exist.
        :param accept_hooks: Accept pre and post hooks if set to `True`.
        :param keep_project_on_failure: If `True` keep generated project directory even when
            generation fails
        """
        # Get user configuration
        config_dict = get_user_config(config_file=config_file, default_config=default_config)

        # Determine the template directory
>       repo_dir, cleanup = determine_repo_dir(
            template=template,
            checkout=checkout,
            clone_to_dir=config_dict['cookiecutters_dir'],
            no_input=no_input,
            password=password,
            directory=directory
        )
E       TypeError: determine_repo_dir() missing 1 required positional argument: 'abbreviations'

cookiecutter/main.py:59: TypeError

test_cookiecutter_local_no_input.py::test_cookiecutter_template_cleanup

test_cookiecutter_local_no_input.py::test_cookiecutter_template_cleanup
mocker = 

    @pytest.mark.usefixtures('clean_system', 'remove_additional_dirs')
    def test_cookiecutter_template_cleanup(mocker):
        """Verify temporary folder for zip unpacking dropped."""
        mocker.patch('tempfile.mkdtemp', return_value='fake-tmp', autospec=True)

        mocker.patch(
            'cookiecutter.prompt.prompt_and_delete', return_value=True, autospec=True
        )

>       main.cookiecutter('tests/files/fake-repo-tmpl.zip', no_input=True)

tests/test_cookiecutter_local_no_input.py:133: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

template = 'tests/files/fake-repo-tmpl.zip', checkout = None, no_input = True
extra_context = None, replay = None, overwrite_if_exists = False
output_dir = '.', config_file = None, default_config = False, password = None
directory = None, skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False

    def cookiecutter(template, checkout=None, no_input=False, extra_context=
        None, replay=None, overwrite_if_exists=False, output_dir='.',
        config_file=None, default_config=False, password=None, directory=None,
        skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False
        ):
        """
        Run Cookiecutter just as if using it from the command line.

        :param template: A directory containing a project template directory,
            or a URL to a git repository.
        :param checkout: The branch, tag or commit ID to checkout after clone.
        :param no_input: Do not prompt for user input.
            Use default values for template parameters taken from `cookiecutter.json`, user
            config and `extra_dict`. Force a refresh of cached resources.
        :param extra_context: A dictionary of context that overrides default
            and user configuration.
        :param replay: Do not prompt for input, instead read from saved json. If
            ``True`` read from the ``replay_dir``.
            if it exists
        :param overwrite_if_exists: Overwrite the contents of the output directory
            if it exists.
        :param output_dir: Where to output the generated project dir into.
        :param config_file: User configuration file path.
        :param default_config: Use default values rather than a config file.
        :param password: The password to use when extracting the repository.
        :param directory: Relative path to a cookiecutter template in a repository.
        :param skip_if_file_exists: Skip the files in the corresponding directories
            if they already exist.
        :param accept_hooks: Accept pre and post hooks if set to `True`.
        :param keep_project_on_failure: If `True` keep generated project directory even when
            generation fails
        """
        # Get user configuration
        config_dict = get_user_config(config_file=config_file, default_config=default_config)

        # Determine the template directory
>       repo_dir, cleanup = determine_repo_dir(
            template=template,
            checkout=checkout,
            clone_to_dir=config_dict['cookiecutters_dir'],
            no_input=no_input,
            password=password,
            directory=directory
        )
E       TypeError: determine_repo_dir() missing 1 required positional argument: 'abbreviations'

cookiecutter/main.py:59: TypeError

test_cookiecutter_local_with_input.py::test_cookiecutter_local_with_input

test_cookiecutter_local_with_input.py::test_cookiecutter_local_with_input
monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0x7fcb925a6860>

    @pytest.mark.usefixtures('clean_system', 'remove_additional_dirs')
    def test_cookiecutter_local_with_input(monkeypatch):
        """Verify simple cookiecutter run results, without extra_context provided."""
        monkeypatch.setattr(
            'cookiecutter.prompt.read_user_variable',
            lambda var, default, prompts, prefix: default,
        )
>       main.cookiecutter('tests/fake-repo-pre/', no_input=False)

tests/test_cookiecutter_local_with_input.py:27: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

template = 'tests/fake-repo-pre/', checkout = None, no_input = False
extra_context = None, replay = None, overwrite_if_exists = False
output_dir = '.', config_file = None, default_config = False, password = None
directory = None, skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False

    def cookiecutter(template, checkout=None, no_input=False, extra_context=
        None, replay=None, overwrite_if_exists=False, output_dir='.',
        config_file=None, default_config=False, password=None, directory=None,
        skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False
        ):
        """
        Run Cookiecutter just as if using it from the command line.

        :param template: A directory containing a project template directory,
            or a URL to a git repository.
        :param checkout: The branch, tag or commit ID to checkout after clone.
        :param no_input: Do not prompt for user input.
            Use default values for template parameters taken from `cookiecutter.json`, user
            config and `extra_dict`. Force a refresh of cached resources.
        :param extra_context: A dictionary of context that overrides default
            and user configuration.
        :param replay: Do not prompt for input, instead read from saved json. If
            ``True`` read from the ``replay_dir``.
            if it exists
        :param overwrite_if_exists: Overwrite the contents of the output directory
            if it exists.
        :param output_dir: Where to output the generated project dir into.
        :param config_file: User configuration file path.
        :param default_config: Use default values rather than a config file.
        :param password: The password to use when extracting the repository.
        :param directory: Relative path to a cookiecutter template in a repository.
        :param skip_if_file_exists: Skip the files in the corresponding directories
            if they already exist.
        :param accept_hooks: Accept pre and post hooks if set to `True`.
        :param keep_project_on_failure: If `True` keep generated project directory even when
            generation fails
        """
        # Get user configuration
        config_dict = get_user_config(config_file=config_file, default_config=default_config)

        # Determine the template directory
>       repo_dir, cleanup = determine_repo_dir(
            template=template,
            checkout=checkout,
            clone_to_dir=config_dict['cookiecutters_dir'],
            no_input=no_input,
            password=password,
            directory=directory
        )
E       TypeError: determine_repo_dir() missing 1 required positional argument: 'abbreviations'

cookiecutter/main.py:59: TypeError

test_cookiecutter_local_with_input.py::test_cookiecutter_input_extra_context

test_cookiecutter_local_with_input.py::test_cookiecutter_input_extra_context
monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0x7fcb925d4670>

    @pytest.mark.usefixtures('clean_system', 'remove_additional_dirs')
    def test_cookiecutter_input_extra_context(monkeypatch):
        """Verify simple cookiecutter run results, with extra_context provided."""
        monkeypatch.setattr(
            'cookiecutter.prompt.read_user_variable',
            lambda var, default, prompts, prefix: default,
        )
>       main.cookiecutter(
            'tests/fake-repo-pre',
            no_input=False,
            extra_context={'repo_name': 'fake-project-input-extra'},
        )

tests/test_cookiecutter_local_with_input.py:42: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

template = 'tests/fake-repo-pre', checkout = None, no_input = False
extra_context = {'repo_name': 'fake-project-input-extra'}, replay = None
overwrite_if_exists = False, output_dir = '.', config_file = None
default_config = False, password = None, directory = None
skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False

    def cookiecutter(template, checkout=None, no_input=False, extra_context=
        None, replay=None, overwrite_if_exists=False, output_dir='.',
        config_file=None, default_config=False, password=None, directory=None,
        skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False
        ):
        """
        Run Cookiecutter just as if using it from the command line.

        :param template: A directory containing a project template directory,
            or a URL to a git repository.
        :param checkout: The branch, tag or commit ID to checkout after clone.
        :param no_input: Do not prompt for user input.
            Use default values for template parameters taken from `cookiecutter.json`, user
            config and `extra_dict`. Force a refresh of cached resources.
        :param extra_context: A dictionary of context that overrides default
            and user configuration.
        :param replay: Do not prompt for input, instead read from saved json. If
            ``True`` read from the ``replay_dir``.
            if it exists
        :param overwrite_if_exists: Overwrite the contents of the output directory
            if it exists.
        :param output_dir: Where to output the generated project dir into.
        :param config_file: User configuration file path.
        :param default_config: Use default values rather than a config file.
        :param password: The password to use when extracting the repository.
        :param directory: Relative path to a cookiecutter template in a repository.
        :param skip_if_file_exists: Skip the files in the corresponding directories
            if they already exist.
        :param accept_hooks: Accept pre and post hooks if set to `True`.
        :param keep_project_on_failure: If `True` keep generated project directory even when
            generation fails
        """
        # Get user configuration
        config_dict = get_user_config(config_file=config_file, default_config=default_config)

        # Determine the template directory
>       repo_dir, cleanup = determine_repo_dir(
            template=template,
            checkout=checkout,
            clone_to_dir=config_dict['cookiecutters_dir'],
            no_input=no_input,
            password=password,
            directory=directory
        )
E       TypeError: determine_repo_dir() missing 1 required positional argument: 'abbreviations'

cookiecutter/main.py:59: TypeError

test_cookiecutter_nested_templates.py::test_cookiecutter_nested_templates[fake-nested-templates-fake-project]

test_cookiecutter_nested_templates.py::test_cookiecutter_nested_templates[fake-nested-templates-fake-project]
mocker = 
template_dir = 'fake-nested-templates', output_dir = 'fake-project'

    @pytest.mark.parametrize(
        "template_dir,output_dir",
        [
            ["fake-nested-templates", "fake-project"],
            ["fake-nested-templates-old-style", "fake-package"],
        ],
    )
    def test_cookiecutter_nested_templates(mocker, template_dir: str, output_dir: str):
        """Verify cookiecutter nested configuration files mechanism."""
        mock_generate_files = mocker.patch("cookiecutter.main.generate_files")
        main_dir = (Path("tests") / template_dir).resolve()
>       main.cookiecutter(f"{main_dir}", no_input=True)

tests/test_cookiecutter_nested_templates.py:21: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

template = '/testbed/tests/fake-nested-templates', checkout = None
no_input = True, extra_context = None, replay = None
overwrite_if_exists = False, output_dir = '.', config_file = None
default_config = False, password = None, directory = None
skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False

    def cookiecutter(template, checkout=None, no_input=False, extra_context=
        None, replay=None, overwrite_if_exists=False, output_dir='.',
        config_file=None, default_config=False, password=None, directory=None,
        skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False
        ):
        """
        Run Cookiecutter just as if using it from the command line.

        :param template: A directory containing a project template directory,
            or a URL to a git repository.
        :param checkout: The branch, tag or commit ID to checkout after clone.
        :param no_input: Do not prompt for user input.
            Use default values for template parameters taken from `cookiecutter.json`, user
            config and `extra_dict`. Force a refresh of cached resources.
        :param extra_context: A dictionary of context that overrides default
            and user configuration.
        :param replay: Do not prompt for input, instead read from saved json. If
            ``True`` read from the ``replay_dir``.
            if it exists
        :param overwrite_if_exists: Overwrite the contents of the output directory
            if it exists.
        :param output_dir: Where to output the generated project dir into.
        :param config_file: User configuration file path.
        :param default_config: Use default values rather than a config file.
        :param password: The password to use when extracting the repository.
        :param directory: Relative path to a cookiecutter template in a repository.
        :param skip_if_file_exists: Skip the files in the corresponding directories
            if they already exist.
        :param accept_hooks: Accept pre and post hooks if set to `True`.
        :param keep_project_on_failure: If `True` keep generated project directory even when
            generation fails
        """
        # Get user configuration
        config_dict = get_user_config(config_file=config_file, default_config=default_config)

        # Determine the template directory
>       repo_dir, cleanup = determine_repo_dir(
            template=template,
            checkout=checkout,
            clone_to_dir=config_dict['cookiecutters_dir'],
            no_input=no_input,
            password=password,
            directory=directory
        )
E       TypeError: determine_repo_dir() missing 1 required positional argument: 'abbreviations'

cookiecutter/main.py:59: TypeError

test_cookiecutter_nested_templates.py::test_cookiecutter_nested_templates[fake-nested-templates-old-style-fake-package]

test_cookiecutter_nested_templates.py::test_cookiecutter_nested_templates[fake-nested-templates-old-style-fake-package]
mocker = 
template_dir = 'fake-nested-templates-old-style', output_dir = 'fake-package'

    @pytest.mark.parametrize(
        "template_dir,output_dir",
        [
            ["fake-nested-templates", "fake-project"],
            ["fake-nested-templates-old-style", "fake-package"],
        ],
    )
    def test_cookiecutter_nested_templates(mocker, template_dir: str, output_dir: str):
        """Verify cookiecutter nested configuration files mechanism."""
        mock_generate_files = mocker.patch("cookiecutter.main.generate_files")
        main_dir = (Path("tests") / template_dir).resolve()
>       main.cookiecutter(f"{main_dir}", no_input=True)

tests/test_cookiecutter_nested_templates.py:21: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

template = '/testbed/tests/fake-nested-templates-old-style', checkout = None
no_input = True, extra_context = None, replay = None
overwrite_if_exists = False, output_dir = '.', config_file = None
default_config = False, password = None, directory = None
skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False

    def cookiecutter(template, checkout=None, no_input=False, extra_context=
        None, replay=None, overwrite_if_exists=False, output_dir='.',
        config_file=None, default_config=False, password=None, directory=None,
        skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False
        ):
        """
        Run Cookiecutter just as if using it from the command line.

        :param template: A directory containing a project template directory,
            or a URL to a git repository.
        :param checkout: The branch, tag or commit ID to checkout after clone.
        :param no_input: Do not prompt for user input.
            Use default values for template parameters taken from `cookiecutter.json`, user
            config and `extra_dict`. Force a refresh of cached resources.
        :param extra_context: A dictionary of context that overrides default
            and user configuration.
        :param replay: Do not prompt for input, instead read from saved json. If
            ``True`` read from the ``replay_dir``.
            if it exists
        :param overwrite_if_exists: Overwrite the contents of the output directory
            if it exists.
        :param output_dir: Where to output the generated project dir into.
        :param config_file: User configuration file path.
        :param default_config: Use default values rather than a config file.
        :param password: The password to use when extracting the repository.
        :param directory: Relative path to a cookiecutter template in a repository.
        :param skip_if_file_exists: Skip the files in the corresponding directories
            if they already exist.
        :param accept_hooks: Accept pre and post hooks if set to `True`.
        :param keep_project_on_failure: If `True` keep generated project directory even when
            generation fails
        """
        # Get user configuration
        config_dict = get_user_config(config_file=config_file, default_config=default_config)

        # Determine the template directory
>       repo_dir, cleanup = determine_repo_dir(
            template=template,
            checkout=checkout,
            clone_to_dir=config_dict['cookiecutters_dir'],
            no_input=no_input,
            password=password,
            directory=directory
        )
E       TypeError: determine_repo_dir() missing 1 required positional argument: 'abbreviations'

cookiecutter/main.py:59: TypeError

test_custom_extensions_in_hooks.py::test_hook_with_extension[pre_gen_hook]

test_custom_extensions_in_hooks.py::test_hook_with_extension[pre_gen_hook]
template = 'tests/test-extensions/custom-extension-pre'
output_dir = '/tmp/pytest-of-root/pytest-0/test_hook_with_extension_pre_g0/output'

    def test_hook_with_extension(template, output_dir):
        """Verify custom Jinja2 extension correctly work in hooks and file rendering.

        Each file in hooks has simple tests inside and will raise error if not
        correctly rendered.
        """
>       project_dir = main.cookiecutter(
            template,
            no_input=True,
            output_dir=output_dir,
            extra_context={'project_slug': 'foobar', 'name': 'Cookiemonster'},
        )

tests/test_custom_extensions_in_hooks.py:36: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

template = 'tests/test-extensions/custom-extension-pre', checkout = None
no_input = True
extra_context = {'name': 'Cookiemonster', 'project_slug': 'foobar'}
replay = None, overwrite_if_exists = False
output_dir = '/tmp/pytest-of-root/pytest-0/test_hook_with_extension_pre_g0/output'
config_file = None, default_config = False, password = None, directory = None
skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False

    def cookiecutter(template, checkout=None, no_input=False, extra_context=
        None, replay=None, overwrite_if_exists=False, output_dir='.',
        config_file=None, default_config=False, password=None, directory=None,
        skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False
        ):
        """
        Run Cookiecutter just as if using it from the command line.

        :param template: A directory containing a project template directory,
            or a URL to a git repository.
        :param checkout: The branch, tag or commit ID to checkout after clone.
        :param no_input: Do not prompt for user input.
            Use default values for template parameters taken from `cookiecutter.json`, user
            config and `extra_dict`. Force a refresh of cached resources.
        :param extra_context: A dictionary of context that overrides default
            and user configuration.
        :param replay: Do not prompt for input, instead read from saved json. If
            ``True`` read from the ``replay_dir``.
            if it exists
        :param overwrite_if_exists: Overwrite the contents of the output directory
            if it exists.
        :param output_dir: Where to output the generated project dir into.
        :param config_file: User configuration file path.
        :param default_config: Use default values rather than a config file.
        :param password: The password to use when extracting the repository.
        :param directory: Relative path to a cookiecutter template in a repository.
        :param skip_if_file_exists: Skip the files in the corresponding directories
            if they already exist.
        :param accept_hooks: Accept pre and post hooks if set to `True`.
        :param keep_project_on_failure: If `True` keep generated project directory even when
            generation fails
        """
        # Get user configuration
        config_dict = get_user_config(config_file=config_file, default_config=default_config)

        # Determine the template directory
>       repo_dir, cleanup = determine_repo_dir(
            template=template,
            checkout=checkout,
            clone_to_dir=config_dict['cookiecutters_dir'],
            no_input=no_input,
            password=password,
            directory=directory
        )
E       TypeError: determine_repo_dir() missing 1 required positional argument: 'abbreviations'

cookiecutter/main.py:59: TypeError

test_custom_extensions_in_hooks.py::test_hook_with_extension[post_gen_hook]

test_custom_extensions_in_hooks.py::test_hook_with_extension[post_gen_hook]
template = 'tests/test-extensions/custom-extension-post'
output_dir = '/tmp/pytest-of-root/pytest-0/test_hook_with_extension_post_0/output'

    def test_hook_with_extension(template, output_dir):
        """Verify custom Jinja2 extension correctly work in hooks and file rendering.

        Each file in hooks has simple tests inside and will raise error if not
        correctly rendered.
        """
>       project_dir = main.cookiecutter(
            template,
            no_input=True,
            output_dir=output_dir,
            extra_context={'project_slug': 'foobar', 'name': 'Cookiemonster'},
        )

tests/test_custom_extensions_in_hooks.py:36: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

template = 'tests/test-extensions/custom-extension-post', checkout = None
no_input = True
extra_context = {'name': 'Cookiemonster', 'project_slug': 'foobar'}
replay = None, overwrite_if_exists = False
output_dir = '/tmp/pytest-of-root/pytest-0/test_hook_with_extension_post_0/output'
config_file = None, default_config = False, password = None, directory = None
skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False

    def cookiecutter(template, checkout=None, no_input=False, extra_context=
        None, replay=None, overwrite_if_exists=False, output_dir='.',
        config_file=None, default_config=False, password=None, directory=None,
        skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False
        ):
        """
        Run Cookiecutter just as if using it from the command line.

        :param template: A directory containing a project template directory,
            or a URL to a git repository.
        :param checkout: The branch, tag or commit ID to checkout after clone.
        :param no_input: Do not prompt for user input.
            Use default values for template parameters taken from `cookiecutter.json`, user
            config and `extra_dict`. Force a refresh of cached resources.
        :param extra_context: A dictionary of context that overrides default
            and user configuration.
        :param replay: Do not prompt for input, instead read from saved json. If
            ``True`` read from the ``replay_dir``.
            if it exists
        :param overwrite_if_exists: Overwrite the contents of the output directory
            if it exists.
        :param output_dir: Where to output the generated project dir into.
        :param config_file: User configuration file path.
        :param default_config: Use default values rather than a config file.
        :param password: The password to use when extracting the repository.
        :param directory: Relative path to a cookiecutter template in a repository.
        :param skip_if_file_exists: Skip the files in the corresponding directories
            if they already exist.
        :param accept_hooks: Accept pre and post hooks if set to `True`.
        :param keep_project_on_failure: If `True` keep generated project directory even when
            generation fails
        """
        # Get user configuration
        config_dict = get_user_config(config_file=config_file, default_config=default_config)

        # Determine the template directory
>       repo_dir, cleanup = determine_repo_dir(
            template=template,
            checkout=checkout,
            clone_to_dir=config_dict['cookiecutters_dir'],
            no_input=no_input,
            password=password,
            directory=directory
        )
E       TypeError: determine_repo_dir() missing 1 required positional argument: 'abbreviations'

cookiecutter/main.py:59: TypeError

test_default_extensions.py::test_jinja2_time_extension

test_default_extensions.py::test_jinja2_time_extension
tmp_path = PosixPath('/tmp/pytest-of-root/pytest-0/test_jinja2_time_extension0')

    def test_jinja2_time_extension(tmp_path):
        """Verify Jinja2 time extension work correctly."""
>       project_dir = cookiecutter(
            'tests/test-extensions/default/', no_input=True, output_dir=str(tmp_path)
        )

tests/test_default_extensions.py:24: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

template = 'tests/test-extensions/default/', checkout = None, no_input = True
extra_context = None, replay = None, overwrite_if_exists = False
output_dir = '/tmp/pytest-of-root/pytest-0/test_jinja2_time_extension0'
config_file = None, default_config = False, password = None, directory = None
skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False

    def cookiecutter(template, checkout=None, no_input=False, extra_context=
        None, replay=None, overwrite_if_exists=False, output_dir='.',
        config_file=None, default_config=False, password=None, directory=None,
        skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False
        ):
        """
        Run Cookiecutter just as if using it from the command line.

        :param template: A directory containing a project template directory,
            or a URL to a git repository.
        :param checkout: The branch, tag or commit ID to checkout after clone.
        :param no_input: Do not prompt for user input.
            Use default values for template parameters taken from `cookiecutter.json`, user
            config and `extra_dict`. Force a refresh of cached resources.
        :param extra_context: A dictionary of context that overrides default
            and user configuration.
        :param replay: Do not prompt for input, instead read from saved json. If
            ``True`` read from the ``replay_dir``.
            if it exists
        :param overwrite_if_exists: Overwrite the contents of the output directory
            if it exists.
        :param output_dir: Where to output the generated project dir into.
        :param config_file: User configuration file path.
        :param default_config: Use default values rather than a config file.
        :param password: The password to use when extracting the repository.
        :param directory: Relative path to a cookiecutter template in a repository.
        :param skip_if_file_exists: Skip the files in the corresponding directories
            if they already exist.
        :param accept_hooks: Accept pre and post hooks if set to `True`.
        :param keep_project_on_failure: If `True` keep generated project directory even when
            generation fails
        """
        # Get user configuration
        config_dict = get_user_config(config_file=config_file, default_config=default_config)

        # Determine the template directory
>       repo_dir, cleanup = determine_repo_dir(
            template=template,
            checkout=checkout,
            clone_to_dir=config_dict['cookiecutters_dir'],
            no_input=no_input,
            password=password,
            directory=directory
        )
E       TypeError: determine_repo_dir() missing 1 required positional argument: 'abbreviations'

cookiecutter/main.py:59: TypeError

test_default_extensions.py::test_jinja2_slugify_extension

test_default_extensions.py::test_jinja2_slugify_extension
tmp_path = PosixPath('/tmp/pytest-of-root/pytest-0/test_jinja2_slugify_extension0')

    def test_jinja2_slugify_extension(tmp_path):
        """Verify Jinja2 slugify extension work correctly."""
>       project_dir = cookiecutter(
            'tests/test-extensions/default/', no_input=True, output_dir=str(tmp_path)
        )

tests/test_default_extensions.py:47: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

template = 'tests/test-extensions/default/', checkout = None, no_input = True
extra_context = None, replay = None, overwrite_if_exists = False
output_dir = '/tmp/pytest-of-root/pytest-0/test_jinja2_slugify_extension0'
config_file = None, default_config = False, password = None, directory = None
skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False

    def cookiecutter(template, checkout=None, no_input=False, extra_context=
        None, replay=None, overwrite_if_exists=False, output_dir='.',
        config_file=None, default_config=False, password=None, directory=None,
        skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False
        ):
        """
        Run Cookiecutter just as if using it from the command line.

        :param template: A directory containing a project template directory,
            or a URL to a git repository.
        :param checkout: The branch, tag or commit ID to checkout after clone.
        :param no_input: Do not prompt for user input.
            Use default values for template parameters taken from `cookiecutter.json`, user
            config and `extra_dict`. Force a refresh of cached resources.
        :param extra_context: A dictionary of context that overrides default
            and user configuration.
        :param replay: Do not prompt for input, instead read from saved json. If
            ``True`` read from the ``replay_dir``.
            if it exists
        :param overwrite_if_exists: Overwrite the contents of the output directory
            if it exists.
        :param output_dir: Where to output the generated project dir into.
        :param config_file: User configuration file path.
        :param default_config: Use default values rather than a config file.
        :param password: The password to use when extracting the repository.
        :param directory: Relative path to a cookiecutter template in a repository.
        :param skip_if_file_exists: Skip the files in the corresponding directories
            if they already exist.
        :param accept_hooks: Accept pre and post hooks if set to `True`.
        :param keep_project_on_failure: If `True` keep generated project directory even when
            generation fails
        """
        # Get user configuration
        config_dict = get_user_config(config_file=config_file, default_config=default_config)

        # Determine the template directory
>       repo_dir, cleanup = determine_repo_dir(
            template=template,
            checkout=checkout,
            clone_to_dir=config_dict['cookiecutters_dir'],
            no_input=no_input,
            password=password,
            directory=directory
        )
E       TypeError: determine_repo_dir() missing 1 required positional argument: 'abbreviations'

cookiecutter/main.py:59: TypeError

test_default_extensions.py::test_jinja2_uuid_extension

test_default_extensions.py::test_jinja2_uuid_extension
tmp_path = PosixPath('/tmp/pytest-of-root/pytest-0/test_jinja2_uuid_extension0')

    def test_jinja2_uuid_extension(tmp_path):
        """Verify Jinja2 uuid extension work correctly."""
>       project_dir = cookiecutter(
            'tests/test-extensions/default/', no_input=True, output_dir=str(tmp_path)
        )

tests/test_default_extensions.py:56: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

template = 'tests/test-extensions/default/', checkout = None, no_input = True
extra_context = None, replay = None, overwrite_if_exists = False
output_dir = '/tmp/pytest-of-root/pytest-0/test_jinja2_uuid_extension0'
config_file = None, default_config = False, password = None, directory = None
skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False

    def cookiecutter(template, checkout=None, no_input=False, extra_context=
        None, replay=None, overwrite_if_exists=False, output_dir='.',
        config_file=None, default_config=False, password=None, directory=None,
        skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False
        ):
        """
        Run Cookiecutter just as if using it from the command line.

        :param template: A directory containing a project template directory,
            or a URL to a git repository.
        :param checkout: The branch, tag or commit ID to checkout after clone.
        :param no_input: Do not prompt for user input.
            Use default values for template parameters taken from `cookiecutter.json`, user
            config and `extra_dict`. Force a refresh of cached resources.
        :param extra_context: A dictionary of context that overrides default
            and user configuration.
        :param replay: Do not prompt for input, instead read from saved json. If
            ``True`` read from the ``replay_dir``.
            if it exists
        :param overwrite_if_exists: Overwrite the contents of the output directory
            if it exists.
        :param output_dir: Where to output the generated project dir into.
        :param config_file: User configuration file path.
        :param default_config: Use default values rather than a config file.
        :param password: The password to use when extracting the repository.
        :param directory: Relative path to a cookiecutter template in a repository.
        :param skip_if_file_exists: Skip the files in the corresponding directories
            if they already exist.
        :param accept_hooks: Accept pre and post hooks if set to `True`.
        :param keep_project_on_failure: If `True` keep generated project directory even when
            generation fails
        """
        # Get user configuration
        config_dict = get_user_config(config_file=config_file, default_config=default_config)

        # Determine the template directory
>       repo_dir, cleanup = determine_repo_dir(
            template=template,
            checkout=checkout,
            clone_to_dir=config_dict['cookiecutters_dir'],
            no_input=no_input,
            password=password,
            directory=directory
        )
E       TypeError: determine_repo_dir() missing 1 required positional argument: 'abbreviations'

cookiecutter/main.py:59: TypeError

test_find.py::test_find_template[template with default jinja strings]

test_find.py::test_find_template[template with default jinja strings]
repo_name = 'fake-repo-pre'
env = 
error_expectation = 
expected = '{{cookiecutter.repo_name}}'

    @pytest.mark.parametrize(
        "repo_name,context,error_expectation,expected",
        [
            ("fake-repo-pre", {}, does_not_raise(), '{{cookiecutter.repo_name}}'),
            (
                "fake-repo-pre2",
                {
                    'cookiecutter': {
                        '_jinja2_env_vars': {
                            'variable_start_string': '{%{',
                            'variable_end_string': '}%}',
                        }
                    }
                },
                does_not_raise(),
                '{%{cookiecutter.repo_name}%}',
            ),
            (
                "fake-repo-pre",
                {
                    'cookiecutter': {
                        '_jinja2_env_vars': {
                            'variable_start_string': '{%{',
                            'variable_end_string': '}%}',
                        }
                    }
                },
                pytest.raises(NonTemplatedInputDirException),
                None,
            ),
            ("fake-repo-bad", {}, pytest.raises(NonTemplatedInputDirException), None),
        ],
        ids=[
            'template with default jinja strings',
            'template with custom jinja strings',
            'template with custom jinja strings but folder with default jinja strings',
            'template missing folder',
        ],
    )
    def test_find_template(repo_name, env, error_expectation, expected):
        """Verify correctness of `find.find_template` path detection."""
        repo_dir = Path('tests', repo_name)

        with error_expectation:
            template = find.find_template(repo_dir, env)

            test_dir = Path(repo_dir, expected)
>           assert template == test_dir
E           AssertionError: assert PosixPath('tests/fake-repo-pre') == PosixPath('tests/fake-repo-pre/{{cookiecutter.repo_name}}')

tests/test_find.py:72: AssertionError

test_find.py::test_find_template[template with custom jinja strings]

test_find.py::test_find_template[template with custom jinja strings]
repo_name = 'fake-repo-pre2'
env = 
error_expectation = 
expected = '{%{cookiecutter.repo_name}%}'

    @pytest.mark.parametrize(
        "repo_name,context,error_expectation,expected",
        [
            ("fake-repo-pre", {}, does_not_raise(), '{{cookiecutter.repo_name}}'),
            (
                "fake-repo-pre2",
                {
                    'cookiecutter': {
                        '_jinja2_env_vars': {
                            'variable_start_string': '{%{',
                            'variable_end_string': '}%}',
                        }
                    }
                },
                does_not_raise(),
                '{%{cookiecutter.repo_name}%}',
            ),
            (
                "fake-repo-pre",
                {
                    'cookiecutter': {
                        '_jinja2_env_vars': {
                            'variable_start_string': '{%{',
                            'variable_end_string': '}%}',
                        }
                    }
                },
                pytest.raises(NonTemplatedInputDirException),
                None,
            ),
            ("fake-repo-bad", {}, pytest.raises(NonTemplatedInputDirException), None),
        ],
        ids=[
            'template with default jinja strings',
            'template with custom jinja strings',
            'template with custom jinja strings but folder with default jinja strings',
            'template missing folder',
        ],
    )
    def test_find_template(repo_name, env, error_expectation, expected):
        """Verify correctness of `find.find_template` path detection."""
        repo_dir = Path('tests', repo_name)

        with error_expectation:
            template = find.find_template(repo_dir, env)

            test_dir = Path(repo_dir, expected)
>           assert template == test_dir
E           AssertionError: assert PosixPath('tests/fake-repo-pre2') == PosixPath('tests/fake-repo-pre2/{%{cookiecutter.repo_name}%}')

tests/test_find.py:72: AssertionError

test_find.py::test_find_template[template with custom jinja strings but folder with default jinja strings]

test_find.py::test_find_template[template with custom jinja strings but folder with default jinja strings]
repo_name = 'fake-repo-pre'
env = 
error_expectation = <_pytest.python_api.RaisesContext object at 0x7fcb9315d750>
expected = None

    @pytest.mark.parametrize(
        "repo_name,context,error_expectation,expected",
        [
            ("fake-repo-pre", {}, does_not_raise(), '{{cookiecutter.repo_name}}'),
            (
                "fake-repo-pre2",
                {
                    'cookiecutter': {
                        '_jinja2_env_vars': {
                            'variable_start_string': '{%{',
                            'variable_end_string': '}%}',
                        }
                    }
                },
                does_not_raise(),
                '{%{cookiecutter.repo_name}%}',
            ),
            (
                "fake-repo-pre",
                {
                    'cookiecutter': {
                        '_jinja2_env_vars': {
                            'variable_start_string': '{%{',
                            'variable_end_string': '}%}',
                        }
                    }
                },
                pytest.raises(NonTemplatedInputDirException),
                None,
            ),
            ("fake-repo-bad", {}, pytest.raises(NonTemplatedInputDirException), None),
        ],
        ids=[
            'template with default jinja strings',
            'template with custom jinja strings',
            'template with custom jinja strings but folder with default jinja strings',
            'template missing folder',
        ],
    )
    def test_find_template(repo_name, env, error_expectation, expected):
        """Verify correctness of `find.find_template` path detection."""
        repo_dir = Path('tests', repo_name)

        with error_expectation:
            template = find.find_template(repo_dir, env)

>           test_dir = Path(repo_dir, expected)

tests/test_find.py:71: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
/usr/lib/python3.10/pathlib.py:960: in __new__
    self = cls._from_parts(args)
/usr/lib/python3.10/pathlib.py:594: in _from_parts
    drv, root, parts = self._parse_args(args)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

cls = 
args = (PosixPath('tests/fake-repo-pre'), None)

    @classmethod
    def _parse_args(cls, args):
        # This is useful when you don't want to create an instance, just
        # canonicalize some constructor arguments.
        parts = []
        for a in args:
            if isinstance(a, PurePath):
                parts += a._parts
            else:
>               a = os.fspath(a)
E               TypeError: expected str, bytes or os.PathLike object, not NoneType

/usr/lib/python3.10/pathlib.py:578: TypeError

test_generate_context.py::test_generate_context[input_params0-expected_context0]

test_generate_context.py::test_generate_context[input_params0-expected_context0]
input_params = {'context_file': 'tests/test-generate-context/test.json'}
expected_context = {'test': {'1': 2, 'some_key': 'some_val'}}

    @pytest.mark.usefixtures('clean_system')
    @pytest.mark.parametrize('input_params, expected_context', context_data())
    def test_generate_context(input_params, expected_context):
        """Verify input contexts combinations result in expected content on output."""
>       assert generate.generate_context(**input_params) == expected_context
E       AssertionError: assert OrderedDict([('1', 2), ('some_key', 'some_val')]) == {'test': {'1': 2, 'some_key': 'some_val'}}
E         
E         Left contains 2 more items:
E         {'1': 2, 'some_key': 'some_val'}
E         Right contains 1 more item:
E         {'test': {'1': 2, 'some_key': 'some_val'}}
E         
E         Full diff:
E         + OrderedDict({
E         - {
E         -     'test': {
E         -         '1': 2,
E         ? ----
E         +     '1': 2,
E         -         'some_key': 'some_val',
E         ? ----
E         +     'some_key': 'some_val',
E         + })
E         -     },
E         - }

tests/test_generate_context.py:58: AssertionError

test_generate_context.py::test_generate_context[input_params1-expected_context1]

test_generate_context.py::test_generate_context[input_params1-expected_context1]
input_params = {'context_file': 'tests/test-generate-context/test.json', 'default_context': {'1': 3}}
expected_context = {'test': {'1': 3, 'some_key': 'some_val'}}

    @pytest.mark.usefixtures('clean_system')
    @pytest.mark.parametrize('input_params, expected_context', context_data())
    def test_generate_context(input_params, expected_context):
        """Verify input contexts combinations result in expected content on output."""
>       assert generate.generate_context(**input_params) == expected_context
E       AssertionError: assert OrderedDict([('1', '3'), ('some_key', 'some_val')]) == {'test': {'1': 3, 'some_key': 'some_val'}}
E         
E         Left contains 2 more items:
E         {'1': '3', 'some_key': 'some_val'}
E         Right contains 1 more item:
E         {'test': {'1': 3, 'some_key': 'some_val'}}
E         
E         Full diff:
E         + OrderedDict({
E         - {
E         -     'test': {
E         -         '1': 3,
E         ? ----
E         +     '1': '3',
E         ?          + +
E         -         'some_key': 'some_val',
E         ? ----
E         +     'some_key': 'some_val',
E         + })
E         -     },
E         - }

tests/test_generate_context.py:58: AssertionError

test_generate_context.py::test_generate_context[input_params2-expected_context2]

test_generate_context.py::test_generate_context[input_params2-expected_context2]
input_params = {'context_file': 'tests/test-generate-context/test.json', 'extra_context': {'1': 4}}
expected_context = {'test': {'1': 4, 'some_key': 'some_val'}}

    @pytest.mark.usefixtures('clean_system')
    @pytest.mark.parametrize('input_params, expected_context', context_data())
    def test_generate_context(input_params, expected_context):
        """Verify input contexts combinations result in expected content on output."""
>       assert generate.generate_context(**input_params) == expected_context
E       AssertionError: assert OrderedDict([('1', '4'), ('some_key', 'some_val')]) == {'test': {'1': 4, 'some_key': 'some_val'}}
E         
E         Left contains 2 more items:
E         {'1': '4', 'some_key': 'some_val'}
E         Right contains 1 more item:
E         {'test': {'1': 4, 'some_key': 'some_val'}}
E         
E         Full diff:
E         + OrderedDict({
E         - {
E         -     'test': {
E         -         '1': 4,
E         ? ----
E         +     '1': '4',
E         ?          + +
E         -         'some_key': 'some_val',
E         ? ----
E         +     'some_key': 'some_val',
E         + })
E         -     },
E         - }

tests/test_generate_context.py:58: AssertionError

test_generate_context.py::test_generate_context[input_params3-expected_context3]

test_generate_context.py::test_generate_context[input_params3-expected_context3]
input_params = {'context_file': 'tests/test-generate-context/test.json', 'default_context': {'1': 3}, 'extra_context': {'1': 5}}
expected_context = {'test': {'1': 5, 'some_key': 'some_val'}}

    @pytest.mark.usefixtures('clean_system')
    @pytest.mark.parametrize('input_params, expected_context', context_data())
    def test_generate_context(input_params, expected_context):
        """Verify input contexts combinations result in expected content on output."""
>       assert generate.generate_context(**input_params) == expected_context
E       AssertionError: assert OrderedDict([('1', '5'), ('some_key', 'some_val')]) == {'test': {'1': 5, 'some_key': 'some_val'}}
E         
E         Left contains 2 more items:
E         {'1': '5', 'some_key': 'some_val'}
E         Right contains 1 more item:
E         {'test': {'1': 5, 'some_key': 'some_val'}}
E         
E         Full diff:
E         + OrderedDict({
E         - {
E         -     'test': {
E         -         '1': 5,
E         ? ----
E         +     '1': '5',
E         ?          + +
E         -         'some_key': 'some_val',
E         ? ----
E         +     'some_key': 'some_val',
E         + })
E         -     },
E         - }

tests/test_generate_context.py:58: AssertionError

test_generate_context.py::test_default_context_replacement_in_generate_context

test_generate_context.py::test_default_context_replacement_in_generate_context
def test_default_context_replacement_in_generate_context():
        """Verify default content settings are correctly replaced by template settings.

        Make sure that the default for list variables of `orientation` is based on
        the user config (`choices_template.json`) and not changed to a single value
        from `default_context`.
        """
        expected_context = {
            'choices_template': OrderedDict(
                [
                    ('full_name', 'Raphael Pierzina'),
                    ('github_username', 'hackebrot'),
                    ('project_name', 'Kivy Project'),
                    ('repo_name', '{{cookiecutter.project_name|lower}}'),
                    ('orientation', ['landscape', 'all', 'portrait']),
                ]
            )
        }

        generated_context = generate.generate_context(
            context_file='tests/test-generate-context/choices_template.json',
            default_context={
                'not_in_template': 'foobar',
                'project_name': 'Kivy Project',
                'orientation': 'landscape',
            },
            extra_context={
                'also_not_in_template': 'foobar2',
                'github_username': 'hackebrot',
            },
        )

>       assert generated_context == expected_context
E       AssertionError: assert OrderedDict([('full_name', 'Raphael Pierzina'), ('github_username', 'hackebrot'), ('project_name', 'Kivy Project'), ('repo_name', '{{cookiecutter.project_name|lower}}'), ('orientation', 'landscape'), ('not_in_template', 'foobar'), ('also_not_in_template', 'foobar2')]) == {'choices_template': OrderedDict([('full_name', 'Raphael Pierzina'), ('github_username', 'hackebrot'), ('project_name', 'Kivy Project'), ('repo_name', '{{cookiecutter.project_name|lower}}'), ('orientation', ['landscape', 'all', 'portrait'])])}
E         
E         Left contains 7 more items:
E         {'also_not_in_template': 'foobar2',
E          'full_name': 'Raphael Pierzina',
E          'github_username': 'hackebrot',
E          'not_in_template': 'foobar',
E          'orientation': 'landscape',
E          'project_name': 'Kivy Project',
E          'repo_name': '{{cookiecutter.project_name|lower}}'}
E         Right contains 1 more item:
E         {'choices_template': OrderedDict([('full_name', 'Raphael Pierzina'),
E                                           ('github_username', 'hackebrot'),
E                                           ('project_name', 'Kivy Project'),
E                                           ('repo_name',
E                                            '{{cookiecutter.project_name|lower}}'),
E                                           ('orientation',
E                                            ['landscape', 'all', 'portrait'])])}
E         
E         Full diff:
E         - {
E         -     'choices_template': OrderedDict({
E         + OrderedDict({
E         +     'also_not_in_template': 'foobar2',
E         -         'full_name': 'Raphael Pierzina',
E         ? ----
E         +     'full_name': 'Raphael Pierzina',
E         -         'github_username': 'hackebrot',
E         ? ----
E         +     'github_username': 'hackebrot',
E         +     'not_in_template': 'foobar',
E         +     'orientation': 'landscape',
E         -         'orientation': [
E         -             'landscape',
E         -             'all',
E         -             'portrait',
E         -         ],
E         -         'project_name': 'Kivy Project',
E         ? ----
E         +     'project_name': 'Kivy Project',
E         -         'repo_name': '{{cookiecutter.project_name|lower}}',
E         ? ----
E         +     'repo_name': '{{cookiecutter.project_name|lower}}',
E         + })
E         -     }),
E         - }

tests/test_generate_context.py:109: AssertionError

test_generate_context.py::test_generate_context_decodes_non_ascii_chars

test_generate_context.py::test_generate_context_decodes_non_ascii_chars
def test_generate_context_decodes_non_ascii_chars():
        """Verify `generate_context` correctly decodes non-ascii chars."""
        expected_context = {
            'non_ascii': OrderedDict(
                [
                    ('full_name', 'éèà'),
                ]
            )
        }

        generated_context = generate.generate_context(
            context_file='tests/test-generate-context/non_ascii.json'
        )

>       assert generated_context == expected_context
E       AssertionError: assert OrderedDict([('full_name', 'éèà')]) == {'non_ascii': OrderedDict([('full_name', 'éèà')])}
E         
E         Left contains 1 more item:
E         {'full_name': 'éèà'}
E         Right contains 1 more item:
E         {'non_ascii': OrderedDict([('full_name', 'éèà')])}
E         
E         Full diff:
E         + OrderedDict({
E         - {
E         -     'non_ascii': OrderedDict({
E         -         'full_name': 'éèà',
E         ? ----
E         +     'full_name': 'éèà',
E         + })
E         -     }),
E         - }

tests/test_generate_context.py:126: AssertionError

test_generate_context.py::test_apply_overwrites_does_include_unused_variables

test_generate_context.py::test_apply_overwrites_does_include_unused_variables
template_context = OrderedDict([('full_name', 'Raphael Pierzina'), ('github_username', 'hackebrot'), ('project_name', 'Kivy Project'), ('repo_name', '{{cookiecutter.project_name|lower}}'), ('orientation', ['all', 'landscape', 'portrait']), ('deployment_regions', ['eu', 'us', 'ap']), ('deployments', {'preprod': ['eu', 'us', 'ap'], 'prod': ['eu', 'us', 'ap']}), ('not in template', 'foobar')])

    def test_apply_overwrites_does_include_unused_variables(template_context):
        """Verify `apply_overwrites_to_context` skips variables that are not in context."""
        generate.apply_overwrites_to_context(
            context=template_context, overwrite_context={'not in template': 'foobar'}
        )

>       assert 'not in template' not in template_context
E       AssertionError: assert 'not in template' not in OrderedDict([('full_name', 'Raphael Pierzina'), ('github_username', 'hackebrot'), ('project_name', 'Kivy Project'), ('repo_name', '{{cookiecutter.project_name|lower}}'), ('orientation', ['all', 'landscape', 'portrait']), ('deployment_regions', ['eu', 'us', 'ap']), ('deployments', {'preprod': ['eu', 'us', 'ap'], 'prod': ['eu', 'us', 'ap']}), ('not in template', 'foobar')])

tests/test_generate_context.py:157: AssertionError

test_generate_context.py::test_apply_overwrites_does_not_modify_choices_for_invalid_overwrite

test_generate_context.py::test_apply_overwrites_does_not_modify_choices_for_invalid_overwrite
def test_apply_overwrites_does_not_modify_choices_for_invalid_overwrite():
        """Verify variables overwrite for list if variable not in list ignored."""
        expected_context = {
            'choices_template': OrderedDict(
                [
                    ('full_name', 'Raphael Pierzina'),
                    ('github_username', 'hackebrot'),
                    ('project_name', 'Kivy Project'),
                    ('repo_name', '{{cookiecutter.project_name|lower}}'),
                    ('orientation', ['all', 'landscape', 'portrait']),
                ]
            )
        }

>       with pytest.warns(UserWarning, match="Invalid default received"):
E       Failed: DID NOT WARN. No warnings of type (,) were emitted.
E        Emitted warnings: [].

tests/test_generate_context.py:183: Failed

test_generate_context.py::test_apply_overwrites_invalid_overwrite

test_generate_context.py::test_apply_overwrites_invalid_overwrite
template_context = OrderedDict([('full_name', 'Raphael Pierzina'), ('github_username', 'hackebrot'), ('project_name', 'Kivy Project'), ('repo_name', '{{cookiecutter.project_name|lower}}'), ('orientation', 'foobar'), ('deployment_regions', ['eu', 'us', 'ap']), ('deployments', {'preprod': ['eu', 'us', 'ap'], 'prod': ['eu', 'us', 'ap']})])

    def test_apply_overwrites_invalid_overwrite(template_context):
        """Verify variables overwrite for list if variable not in list not ignored."""
>       with pytest.raises(ValueError):
E       Failed: DID NOT RAISE 

tests/test_generate_context.py:202: Failed

test_generate_context.py::test_apply_overwrites_sets_multichoice_values

test_generate_context.py::test_apply_overwrites_sets_multichoice_values
template_context = OrderedDict([('full_name', 'Raphael Pierzina'), ('github_username', 'hackebrot'), ('project_name', 'Kivy Project'), ('repo_name', '{{cookiecutter.project_name|lower}}'), ('orientation', ['all', 'landscape', 'portrait']), ('deployment_regions', ['eu', 'us', 'ap', 'eu']), ('deployments', {'preprod': ['eu', 'us', 'ap'], 'prod': ['eu', 'us', 'ap']})])

    def test_apply_overwrites_sets_multichoice_values(template_context):
        """Verify variable overwrite for list given multiple valid values."""
        generate.apply_overwrites_to_context(
            context=template_context,
            overwrite_context={'deployment_regions': ['eu']},
        )
>       assert template_context['deployment_regions'] == ['eu']
E       AssertionError: assert ['eu', 'us', 'ap', 'eu'] == ['eu']
E         
E         Left contains 3 more items, first extra item: 'us'
E         
E         Full diff:
E           [
E               'eu',
E         +     'us',
E         +     'ap',
E         +     'eu',
E           ]

tests/test_generate_context.py:214: AssertionError

test_generate_context.py::test_apply_overwrites_invalid_multichoice_values

test_generate_context.py::test_apply_overwrites_invalid_multichoice_values
template_context = OrderedDict([('full_name', 'Raphael Pierzina'), ('github_username', 'hackebrot'), ('project_name', 'Kivy Project'), ('repo_name', '{{cookiecutter.project_name|lower}}'), ('orientation', ['all', 'landscape', 'portrait']), ('deployment_regions', ['eu', 'us', 'ap', 'na']), ('deployments', {'preprod': ['eu', 'us', 'ap'], 'prod': ['eu', 'us', 'ap']})])

    def test_apply_overwrites_invalid_multichoice_values(template_context):
        """Verify variable overwrite for list given invalid list entries not ignored."""
>       with pytest.raises(ValueError):
E       Failed: DID NOT RAISE 

tests/test_generate_context.py:219: Failed

test_generate_context.py::test_apply_overwrites_error_additional_values

test_generate_context.py::test_apply_overwrites_error_additional_values
template_context = OrderedDict([('full_name', 'Raphael Pierzina'), ('github_username', 'hackebrot'), ('project_name', 'Kivy Project'), ('repo_name', '{{cookiecutter.project_name|lower}}'), ('orientation', ['all', 'landscape', 'portrait']), ('deployment_regions', ['eu', 'us', 'ap', 'eu', 'na']), ('deployments', {'preprod': ['eu', 'us', 'ap'], 'prod': ['eu', 'us', 'ap']})])

    def test_apply_overwrites_error_additional_values(template_context):
        """Verify variable overwrite for list given additional entries not ignored."""
>       with pytest.raises(ValueError):
E       Failed: DID NOT RAISE 

tests/test_generate_context.py:228: Failed

test_generate_context.py::test_apply_overwrites_in_dictionaries

test_generate_context.py::test_apply_overwrites_in_dictionaries
template_context = OrderedDict([('full_name', 'Raphael Pierzina'), ('github_username', 'hackebrot'), ('project_name', 'Kivy Project'), ('repo_name', '{{cookiecutter.project_name|lower}}'), ('orientation', ['all', 'landscape', 'portrait']), ('deployment_regions', ['eu', 'us', 'ap']), ('deployments', {'preprod': ['eu', 'us', 'ap', 'eu'], 'prod': ['eu', 'us', 'ap', 'ap']})])

    def test_apply_overwrites_in_dictionaries(template_context):
        """Verify variable overwrite for lists nested in dictionary variables."""
        generate.apply_overwrites_to_context(
            context=template_context,
            overwrite_context={'deployments': {'preprod': ['eu'], 'prod': ['ap']}},
        )
>       assert template_context['deployments']['preprod'] == ['eu']
E       AssertionError: assert ['eu', 'us', 'ap', 'eu'] == ['eu']
E         
E         Left contains 3 more items, first extra item: 'us'
E         
E         Full diff:
E           [
E               'eu',
E         +     'us',
E         +     'ap',
E         +     'eu',
E           ]

tests/test_generate_context.py:241: AssertionError

test_generate_context.py::test_apply_overwrites_sets_default_for_choice_variable

test_generate_context.py::test_apply_overwrites_sets_default_for_choice_variable
template_context = OrderedDict([('full_name', 'Raphael Pierzina'), ('github_username', 'hackebrot'), ('project_name', 'Kivy Project'), ('repo_name', '{{cookiecutter.project_name|lower}}'), ('orientation', 'landscape'), ('deployment_regions', ['eu', 'us', 'ap']), ('deployments', {'preprod': ['eu', 'us', 'ap'], 'prod': ['eu', 'us', 'ap']})])

    def test_apply_overwrites_sets_default_for_choice_variable(template_context):
        """Verify overwritten list member became a default value."""
        generate.apply_overwrites_to_context(
            context=template_context, overwrite_context={'orientation': 'landscape'}
        )

>       assert template_context['orientation'] == ['landscape', 'all', 'portrait']
E       AssertionError: assert 'landscape' == ['landscape', 'all', 'portrait']

tests/test_generate_context.py:251: AssertionError

test_generate_context.py::test_apply_overwrites_in_nested_dict

test_generate_context.py::test_apply_overwrites_in_nested_dict
def test_apply_overwrites_in_nested_dict():
        """Verify nested dict in default content settings are correctly replaced."""
        expected_context = {
            'nested_dict': OrderedDict(
                [
                    ('full_name', 'Raphael Pierzina'),
                    ('github_username', 'hackebrot'),
                    (
                        'project',
                        OrderedDict(
                            [
                                ('name', 'My Kivy Project'),
                                ('description', 'My Kivy Project'),
                                ('repo_name', '{{cookiecutter.project_name|lower}}'),
                                ('orientation', ["all", "landscape", "portrait"]),
                            ]
                        ),
                    ),
                ]
            )
        }

        generated_context = generate.generate_context(
            context_file='tests/test-generate-context/nested_dict.json',
            default_context={
                'not_in_template': 'foobar',
                'project': {
                    'description': 'My Kivy Project',
                },
            },
            extra_context={
                'also_not_in_template': 'foobar2',
                'github_username': 'hackebrot',
                'project': {
                    'name': 'My Kivy Project',
                },
            },
        )

>       assert generated_context == expected_context
E       AssertionError: assert OrderedDict([('full_name', 'Raphael Pierzina'), ('github_username', 'hackebrot'), ('project', OrderedDict([('name', 'My Kivy Project'), ('description', 'My Kivy Project'), ('repo_name', '{{cookiecutter.project_name|lower}}'), ('orientation', ['all', 'landscape', 'portrait'])])), ('not_in_template', 'foobar'), ('also_not_in_template', 'foobar2')]) == {'nested_dict': OrderedDict([('full_name', 'Raphael Pierzina'), ('github_username', 'hackebrot'), ('project', OrderedDict([('name', 'My Kivy Project'), ('description', 'My Kivy Project'), ('repo_name', '{{cookiecutter.project_name|lower}}'), ('orientation', ['all', 'landscape', 'portrait'])]))])}
E         
E         Left contains 5 more items:
E         {'also_not_in_template': 'foobar2',
E          'full_name': 'Raphael Pierzina',
E          'github_username': 'hackebrot',
E          'not_in_template': 'foobar',
E          'project': OrderedDict([('name', 'My Kivy Project'),
E                                  ('description', 'My Kivy Project'),
E                                  ('repo_name', '{{cookiecutter.project_name|lower}}'),
E                                  ('orientation', ['all', 'landscape', 'portrait'])])}
E         Right contains 1 more item:
E         {'nested_dict': OrderedDict([('full_name', 'Raphael Pierzina'),
E                                      ('github_username', 'hackebrot'),
E                                      ('project',
E                                       OrderedDict([('name', 'My Kivy Project'),
E                                                    ('description', 'My Kivy Project'),
E                                                    ('repo_name',
E                                                     '{{cookiecutter.project_name|lower}}'),
E                                                    ('orientation',
E                                                     ['all',
E                                                      'landscape',
E                                                      'portrait'])]))])}
E         
E         Full diff:
E         - {
E         -     'nested_dict': OrderedDict({
E         + OrderedDict({
E         +     'also_not_in_template': 'foobar2',
E         -         'full_name': 'Raphael Pierzina',
E         ? ----
E         +     'full_name': 'Raphael Pierzina',
E         -         'github_username': 'hackebrot',
E         ? ----
E         +     'github_username': 'hackebrot',
E         +     'not_in_template': 'foobar',
E         -         'project': OrderedDict({
E         ? ----
E         +     'project': OrderedDict({
E         -             'description': 'My Kivy Project',
E         ? ----
E         +         'description': 'My Kivy Project',
E         -             'name': 'My Kivy Project',
E         ? ----
E         +         'name': 'My Kivy Project',
E         -             'orientation': [
E         ? ----
E         +         'orientation': [
E         -                 'all',
E         ? ----
E         +             'all',
E         -                 'landscape',
E         ? ----
E         +             'landscape',
E         -                 'portrait',
E         ? ----
E         +             'portrait',
E         -             ],
E         ? ----
E         +         ],
E         -             'repo_name': '{{cookiecutter.project_name|lower}}',
E         ? ----
E         +         'repo_name': '{{cookiecutter.project_name|lower}}',
E         -         }),
E               }),
E         - }
E         + })

tests/test_generate_context.py:293: AssertionError

test_generate_context.py::test_apply_overwrites_in_nested_dict_additional_values

test_generate_context.py::test_apply_overwrites_in_nested_dict_additional_values
def test_apply_overwrites_in_nested_dict_additional_values():
        """Verify nested dict in default content settings are correctly added."""
        expected_context = {
            'nested_dict_additional': OrderedDict(
                [
                    ('mainkey1', 'mainvalue1'),
                    (
                        'mainkey2',
                        OrderedDict(
                            [
                                ('subkey1', 'subvalue1'),
                                (
                                    'subkey2',
                                    OrderedDict(
                                        [
                                            ('subsubkey1', 'subsubvalue1'),
                                            ('subsubkey2', 'subsubvalue2_default'),
                                            ('subsubkey3', 'subsubvalue3_extra'),
                                        ]
                                    ),
                                ),
                                ('subkey4', 'subvalue4_default'),
                                ('subkey5', 'subvalue5_extra'),
                            ]
                        ),
                    ),
                ]
            )
        }

        generated_context = generate.generate_context(
            context_file='tests/test-generate-context/nested_dict_additional.json',
            default_context={
                'not_in_template': 'foobar',
                'mainkey2': {
                    'subkey2': {
                        'subsubkey2': 'subsubvalue2_default',
                    },
                    'subkey4': 'subvalue4_default',
                },
            },
            extra_context={
                'also_not_in_template': 'foobar2',
                'mainkey2': {
                    'subkey2': {
                        'subsubkey3': 'subsubvalue3_extra',
                    },
                    'subkey5': 'subvalue5_extra',
                },
            },
        )

>       assert generated_context == expected_context
E       AssertionError: assert OrderedDict([('mainkey1', 'mainvalue1'), ('mainkey2', OrderedDict([('subkey1', 'subvalue1'), ('subkey2', OrderedDict([('subsubkey1', 'subsubvalue1'), ('subsubkey2', 'subsubvalue2_default'), ('subsubkey3', 'subsubvalue3_extra')])), ('subkey4', 'subvalue4_default'), ('subkey5', 'subvalue5_extra')])), ('not_in_template', 'foobar'), ('also_not_in_template', 'foobar2')]) == {'nested_dict_additional': OrderedDict([('mainkey1', 'mainvalue1'), ('mainkey2', OrderedDict([('subkey1', 'subvalue1'), ('subkey2', OrderedDict([('subsubkey1', 'subsubvalue1'), ('subsubkey2', 'subsubvalue2_default'), ('subsubkey3', 'subsubvalue3_extra')])), ('subkey4', 'subvalue4_default'), ('subkey5', 'subvalue5_extra')]))])}
E         
E         Left contains 4 more items:
E         {'also_not_in_template': 'foobar2',
E          'mainkey1': 'mainvalue1',
E          'mainkey2': OrderedDict([('subkey1', 'subvalue1'),
E                                   ('subkey2',
E                                    OrderedDict([('subsubkey1', 'subsubvalue1'),
E                                                 ('subsubkey2', 'subsubvalue2_default'),
E                                                 ('subsubkey3', 'subsubvalue3_extra')])),
E                                   ('subkey4', 'subvalue4_default'),
E                                   ('subkey5', 'subvalue5_extra')]),
E          'not_in_template': 'foobar'}
E         Right contains 1 more item:
E         {'nested_dict_additional': OrderedDict([('mainkey1', 'mainvalue1'),
E                                                 ('mainkey2',
E                                                  OrderedDict([('subkey1', 'subvalue1'),
E                                                               ('subkey2',
E                                                                OrderedDict([('subsubkey1',
E                                                                              'subsubvalue1'),
E                                                                             ('subsubkey2',
E                                                                              'subsubvalue2_default'),
E                                                                             ('subsubkey3',
E                                                                              'subsubvalue3_extra')])),
E                                                               ('subkey4',
E                                                                'subvalue4_default'),
E                                                               ('subkey5',
E                                                                'subvalue5_extra')]))])}
E         
E         Full diff:
E         - {
E         -     'nested_dict_additional': OrderedDict({
E         + OrderedDict({
E         +     'also_not_in_template': 'foobar2',
E         -         'mainkey1': 'mainvalue1',
E         ? ----
E         +     'mainkey1': 'mainvalue1',
E         -         'mainkey2': OrderedDict({
E         ? ----
E         +     'mainkey2': OrderedDict({
E         -             'subkey1': 'subvalue1',
E         ? ----
E         +         'subkey1': 'subvalue1',
E         -             'subkey2': OrderedDict({
E         ? ----
E         +         'subkey2': OrderedDict({
E         -                 'subsubkey1': 'subsubvalue1',
E         ? ----
E         +             'subsubkey1': 'subsubvalue1',
E         -                 'subsubkey2': 'subsubvalue2_default',
E         ? ----
E         +             'subsubkey2': 'subsubvalue2_default',
E         -                 'subsubkey3': 'subsubvalue3_extra',
E         ? ----
E         +             'subsubkey3': 'subsubvalue3_extra',
E         -             }),
E         -             'subkey4': 'subvalue4_default',
E         -             'subkey5': 'subvalue5_extra',
E                   }),
E         +         'subkey4': 'subvalue4_default',
E         +         'subkey5': 'subvalue5_extra',
E               }),
E         - }
E         +     'not_in_template': 'foobar',
E         + })

tests/test_generate_context.py:364: AssertionError

test_generate_copy_without_render.py::test_generate_copy_without_render_extensions

test_generate_copy_without_render.py::test_generate_copy_without_render_extensions
@pytest.mark.usefixtures('clean_system', 'remove_test_dir')
    def test_generate_copy_without_render_extensions():
        """Verify correct work of `_copy_without_render` context option.

        Some files/directories should be rendered during invocation,
        some just copied, without any modification.
        """
>       generate.generate_files(
            context={
                'cookiecutter': {
                    'repo_name': 'test_copy_without_render',
                    'render_test': 'I have been rendered!',
                    '_copy_without_render': [
                        '*not-rendered',
                        'rendered/not_rendered.yml',
                        '*.txt',
                        '{{cookiecutter.repo_name}}-rendered/README.md',
                    ],
                }
            },
            repo_dir='tests/test-generate-copy-without-render',
        )

tests/test_generate_copy_without_render.py:26: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

repo_dir = 'tests/test-generate-copy-without-render'
context = {'cookiecutter': {'_copy_without_render': ['*not-rendered', 'rendered/not_rendered.yml', '*.txt', '{{cookiecutter.repo_name}}-rendered/README.md'], 'render_test': 'I have been rendered!', 'repo_name': 'test_copy_without_render'}}
output_dir = '.', overwrite_if_exists = False, skip_if_file_exists = False
accept_hooks = True, keep_project_on_failure = False

    def generate_files(repo_dir, context=None, output_dir='.',
        overwrite_if_exists=False, skip_if_file_exists=False, accept_hooks=True,
        keep_project_on_failure=False):
        """Render the templates and saves them to files.

        :param repo_dir: Project template input directory.
        :param context: Dict for populating the template's variables.
        :param output_dir: Where to output the generated project dir into.
        :param overwrite_if_exists: Overwrite the contents of the output directory
            if it exists.
        :param skip_if_file_exists: Skip the files in the corresponding directories
            if they already exist
        :param accept_hooks: Accept pre and post hooks if set to `True`.
        :param keep_project_on_failure: If `True` keep generated project directory even when
            generation fails
        """
>       template_dir = find_template(repo_dir)
E       TypeError: find_template() missing 1 required positional argument: 'env'

cookiecutter/generate.py:225: TypeError

test_generate_copy_without_render_override.py::test_generate_copy_without_render_extensions

test_generate_copy_without_render_override.py::test_generate_copy_without_render_extensions
@pytest.mark.usefixtures('clean_system', 'remove_test_dir')
    def test_generate_copy_without_render_extensions():
        """Verify correct work of `_copy_without_render` context option.

        Some files/directories should be rendered during invocation,
        some just copied, without any modification.
        """
        # first run
>       generate.generate_files(
            context={
                'cookiecutter': {
                    'repo_name': 'test_copy_without_render',
                    'render_test': 'I have been rendered!',
                    '_copy_without_render': [
                        '*not-rendered',
                        'rendered/not_rendered.yml',
                        '*.txt',
                        '{{cookiecutter.repo_name}}-rendered/README.md',
                    ],
                }
            },
            repo_dir='tests/test-generate-copy-without-render-override',
        )

tests/test_generate_copy_without_render_override.py:27: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

repo_dir = 'tests/test-generate-copy-without-render-override'
context = {'cookiecutter': {'_copy_without_render': ['*not-rendered', 'rendered/not_rendered.yml', '*.txt', '{{cookiecutter.repo_name}}-rendered/README.md'], 'render_test': 'I have been rendered!', 'repo_name': 'test_copy_without_render'}}
output_dir = '.', overwrite_if_exists = False, skip_if_file_exists = False
accept_hooks = True, keep_project_on_failure = False

    def generate_files(repo_dir, context=None, output_dir='.',
        overwrite_if_exists=False, skip_if_file_exists=False, accept_hooks=True,
        keep_project_on_failure=False):
        """Render the templates and saves them to files.

        :param repo_dir: Project template input directory.
        :param context: Dict for populating the template's variables.
        :param output_dir: Where to output the generated project dir into.
        :param overwrite_if_exists: Overwrite the contents of the output directory
            if it exists.
        :param skip_if_file_exists: Skip the files in the corresponding directories
            if they already exist
        :param accept_hooks: Accept pre and post hooks if set to `True`.
        :param keep_project_on_failure: If `True` keep generated project directory even when
            generation fails
        """
>       template_dir = find_template(repo_dir)
E       TypeError: find_template() missing 1 required positional argument: 'env'

cookiecutter/generate.py:225: TypeError

test_generate_file.py::test_generate_file_with_false_condition

test_generate_file.py::test_generate_file_with_false_condition
env = 

    def test_generate_file_with_false_condition(env):
        """Verify correct work of boolean condition in file name on file generation.

        This test has negative answer, so file should not be rendered.
        """
        infile = (
            'tests/files/{% if cookiecutter.generate_file == \'y\' %}cheese.txt{% endif %}'
        )
>       generate.generate_file(
            project_dir=".",
            infile=infile,
            context={'cookiecutter': {'generate_file': 'n'}},
            env=env,
        )

tests/test_generate_file.py:110: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

project_dir = '.'
infile = "tests/files/{% if cookiecutter.generate_file == 'y' %}cheese.txt{% endif %}"
context = {'cookiecutter': {'generate_file': 'n'}}
env = 
skip_if_file_exists = False

    def generate_file(project_dir, infile, context, env, skip_if_file_exists=False
        ):
        """Render filename of infile as name of outfile, handle infile correctly.

        Dealing with infile appropriately:

            a. If infile is a binary file, copy it over without rendering.
            b. If infile is a text file, render its contents and write the
               rendered infile to outfile.

        Precondition:

            When calling `generate_file()`, the root template dir must be the
            current working directory. Using `utils.work_in()` is the recommended
            way to perform this directory change.

        :param project_dir: Absolute path to the resulting generated project.
        :param infile: Input file to generate the file from. Relative to the root
            template dir.
        :param context: Dict for populating the cookiecutter's variables.
        :param env: Jinja2 template execution environment.
        """
        logger.debug('Generating file %s', infile)

        # Render the path to the output file
        outfile_tmpl = env.from_string(infile)
        outfile = os.path.join(project_dir, outfile_tmpl.render(**context))

        # Ensure output directory exists
        dirname = os.path.dirname(outfile)
        make_sure_path_exists(dirname)

        # Skip if file exists and skip_if_file_exists is True
        if skip_if_file_exists and os.path.exists(outfile):
            logger.debug('File %s already exists, skipping', outfile)
            return False

        # Check if infile is binary
        if is_binary(infile):
            logger.debug("Copying binary %s to %s without rendering", infile, outfile)
            shutil.copyfile(infile, outfile)
        else:
            # Render the file
            try:
                with open(infile, 'r') as in_file:
                    tmpl = env.from_string(in_file.read())
                rendered_file = tmpl.render(**context)
>               with open(outfile, 'w') as out_file:
E               IsADirectoryError: [Errno 21] Is a directory: './tests/files/'

cookiecutter/generate.py:133: IsADirectoryError

test_generate_file.py::test_generate_file_verbose_template_syntax_error

test_generate_file.py::test_generate_file_verbose_template_syntax_error
env = 
expected_msg_regex = re.compile('Missing end of comment tag\n {2}File "(.[/\\\\])*tests[/\\\\]files[/\\\\]syntax_error.txt", line 1\n {4}I eat {{ syntax_error }} {# this comment is not closed}')

    def test_generate_file_verbose_template_syntax_error(env, expected_msg_regex):
        """Verify correct exception raised on syntax error in file before generation."""
        with pytest.raises(TemplateSyntaxError) as exception:
            generate.generate_file(
                project_dir=".",
                infile='tests/files/syntax_error.txt',
                context={'syntax_error': 'syntax_error'},
                env=env,
            )
>       assert expected_msg_regex.match(str(exception.value))
E       assert None
E        +  where None = ('Missing end of comment tag')
E        +    where  = re.compile('Missing end of comment tag\n {2}File "(.[/\\\\])*tests[/\\\\]files[/\\\\]syntax_error.txt", line 1\n {4}I eat {{ syntax_error }} {# this comment is not closed}').match
E        +    and   'Missing end of comment tag' = str(TemplateSyntaxError('Missing end of comment tag'))
E        +      where TemplateSyntaxError('Missing end of comment tag') = .value

tests/test_generate_file.py:138: AssertionError

test_generate_file.py::test_generate_file_does_not_translate_crlf_newlines_to_lf

test_generate_file.py::test_generate_file_does_not_translate_crlf_newlines_to_lf
env = 

    def test_generate_file_does_not_translate_crlf_newlines_to_lf(env):
        """Verify that file generation use same line ending, as in source file."""
        infile = 'tests/files/{{cookiecutter.generate_file}}_crlf_newlines.txt'
        generate.generate_file(
            project_dir=".",
            infile=infile,
            context={'cookiecutter': {'generate_file': 'cheese'}},
            env=env,
        )

        # this generated file should have a CRLF line ending
        gf = 'tests/files/cheese_crlf_newlines.txt'
        with Path(gf).open(encoding='utf-8', newline='') as f:
            simple_text = f.readline()
>       assert simple_text == 'newline is CRLF\r\n'
E       AssertionError: assert 'newline is CRLF\n' == 'newline is CRLF\r\n'
E         
E         - newline is CRLF
E         ?                -
E         + newline is CRLF

tests/test_generate_file.py:173: AssertionError

test_generate_files.py::test_generate_files_nontemplated_exception

test_generate_files.py::test_generate_files_nontemplated_exception
tmp_path = PosixPath('/tmp/pytest-of-root/pytest-0/test_generate_files_nontemplat0')

    def test_generate_files_nontemplated_exception(tmp_path):
        """
        Verify `generate_files` raises when no directories to render exist.

        Note: Check `tests/test-generate-files-nontemplated` location to understand.
        """
        with pytest.raises(exceptions.NonTemplatedInputDirException):
>           generate.generate_files(
                context={'cookiecutter': {'food': 'pizza'}},
                repo_dir='tests/test-generate-files-nontemplated',
                output_dir=tmp_path,
            )

tests/test_generate_files.py:22: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

repo_dir = 'tests/test-generate-files-nontemplated'
context = {'cookiecutter': {'food': 'pizza'}}
output_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_generate_files_nontemplat0')
overwrite_if_exists = False, skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False

    def generate_files(repo_dir, context=None, output_dir='.',
        overwrite_if_exists=False, skip_if_file_exists=False, accept_hooks=True,
        keep_project_on_failure=False):
        """Render the templates and saves them to files.

        :param repo_dir: Project template input directory.
        :param context: Dict for populating the template's variables.
        :param output_dir: Where to output the generated project dir into.
        :param overwrite_if_exists: Overwrite the contents of the output directory
            if it exists.
        :param skip_if_file_exists: Skip the files in the corresponding directories
            if they already exist
        :param accept_hooks: Accept pre and post hooks if set to `True`.
        :param keep_project_on_failure: If `True` keep generated project directory even when
            generation fails
        """
>       template_dir = find_template(repo_dir)
E       TypeError: find_template() missing 1 required positional argument: 'env'

cookiecutter/generate.py:225: TypeError

test_generate_files.py::test_generate_files

test_generate_files.py::test_generate_files
tmp_path = PosixPath('/tmp/pytest-of-root/pytest-0/test_generate_files0')

    def test_generate_files(tmp_path):
        """Verify directory name correctly rendered with unicode containing context."""
>       generate.generate_files(
            context={'cookiecutter': {'food': 'pizzä'}},
            repo_dir='tests/test-generate-files',
            output_dir=tmp_path,
        )

tests/test_generate_files.py:31: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

repo_dir = 'tests/test-generate-files'
context = {'cookiecutter': {'food': 'pizzä'}}
output_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_generate_files0')
overwrite_if_exists = False, skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False

    def generate_files(repo_dir, context=None, output_dir='.',
        overwrite_if_exists=False, skip_if_file_exists=False, accept_hooks=True,
        keep_project_on_failure=False):
        """Render the templates and saves them to files.

        :param repo_dir: Project template input directory.
        :param context: Dict for populating the template's variables.
        :param output_dir: Where to output the generated project dir into.
        :param overwrite_if_exists: Overwrite the contents of the output directory
            if it exists.
        :param skip_if_file_exists: Skip the files in the corresponding directories
            if they already exist
        :param accept_hooks: Accept pre and post hooks if set to `True`.
        :param keep_project_on_failure: If `True` keep generated project directory even when
            generation fails
        """
>       template_dir = find_template(repo_dir)
E       TypeError: find_template() missing 1 required positional argument: 'env'

cookiecutter/generate.py:225: TypeError

test_generate_files.py::test_generate_files_with_linux_newline

test_generate_files.py::test_generate_files_with_linux_newline
tmp_path = PosixPath('/tmp/pytest-of-root/pytest-0/test_generate_files_with_linux0')

    def test_generate_files_with_linux_newline(tmp_path):
        """Verify new line not removed by templating engine after folder generation."""
>       generate.generate_files(
            context={'cookiecutter': {'food': 'pizzä'}},
            repo_dir='tests/test-generate-files',
            output_dir=tmp_path,
        )

tests/test_generate_files.py:47: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

repo_dir = 'tests/test-generate-files'
context = {'cookiecutter': {'food': 'pizzä'}}
output_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_generate_files_with_linux0')
overwrite_if_exists = False, skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False

    def generate_files(repo_dir, context=None, output_dir='.',
        overwrite_if_exists=False, skip_if_file_exists=False, accept_hooks=True,
        keep_project_on_failure=False):
        """Render the templates and saves them to files.

        :param repo_dir: Project template input directory.
        :param context: Dict for populating the template's variables.
        :param output_dir: Where to output the generated project dir into.
        :param overwrite_if_exists: Overwrite the contents of the output directory
            if it exists.
        :param skip_if_file_exists: Skip the files in the corresponding directories
            if they already exist
        :param accept_hooks: Accept pre and post hooks if set to `True`.
        :param keep_project_on_failure: If `True` keep generated project directory even when
            generation fails
        """
>       template_dir = find_template(repo_dir)
E       TypeError: find_template() missing 1 required positional argument: 'env'

cookiecutter/generate.py:225: TypeError

test_generate_files.py::test_generate_files_with_jinja2_environment

test_generate_files.py::test_generate_files_with_jinja2_environment
tmp_path = PosixPath('/tmp/pytest-of-root/pytest-0/test_generate_files_with_jinja0')

    def test_generate_files_with_jinja2_environment(tmp_path):
        """Extend StrictEnvironment with _jinja2_env_vars cookiecutter template option."""
>       generate.generate_files(
            context={
                'cookiecutter': {
                    'food': 'pizzä',
                    '_jinja2_env_vars': {'lstrip_blocks': True, 'trim_blocks': True},
                }
            },
            repo_dir='tests/test-generate-files',
            output_dir=tmp_path,
        )

tests/test_generate_files.py:65: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

repo_dir = 'tests/test-generate-files'
context = {'cookiecutter': {'_jinja2_env_vars': {'lstrip_blocks': True, 'trim_blocks': True}, 'food': 'pizzä'}}
output_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_generate_files_with_jinja0')
overwrite_if_exists = False, skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False

    def generate_files(repo_dir, context=None, output_dir='.',
        overwrite_if_exists=False, skip_if_file_exists=False, accept_hooks=True,
        keep_project_on_failure=False):
        """Render the templates and saves them to files.

        :param repo_dir: Project template input directory.
        :param context: Dict for populating the template's variables.
        :param output_dir: Where to output the generated project dir into.
        :param overwrite_if_exists: Overwrite the contents of the output directory
            if it exists.
        :param skip_if_file_exists: Skip the files in the corresponding directories
            if they already exist
        :param accept_hooks: Accept pre and post hooks if set to `True`.
        :param keep_project_on_failure: If `True` keep generated project directory even when
            generation fails
        """
>       template_dir = find_template(repo_dir)
E       TypeError: find_template() missing 1 required positional argument: 'env'

cookiecutter/generate.py:225: TypeError

test_generate_files.py::test_generate_files_with_trailing_newline_forced_to_linux_by_context

test_generate_files.py::test_generate_files_with_trailing_newline_forced_to_linux_by_context
tmp_path = PosixPath('/tmp/pytest-of-root/pytest-0/test_generate_files_with_trail0')

    def test_generate_files_with_trailing_newline_forced_to_linux_by_context(tmp_path):
        """Verify new line not removed by templating engine after folder generation."""
>       generate.generate_files(
            context={'cookiecutter': {'food': 'pizzä', '_new_lines': '\r\n'}},
            repo_dir='tests/test-generate-files',
            output_dir=tmp_path,
        )

tests/test_generate_files.py:86: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

repo_dir = 'tests/test-generate-files'
context = {'cookiecutter': {'_new_lines': '\r\n', 'food': 'pizzä'}}
output_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_generate_files_with_trail0')
overwrite_if_exists = False, skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False

    def generate_files(repo_dir, context=None, output_dir='.',
        overwrite_if_exists=False, skip_if_file_exists=False, accept_hooks=True,
        keep_project_on_failure=False):
        """Render the templates and saves them to files.

        :param repo_dir: Project template input directory.
        :param context: Dict for populating the template's variables.
        :param output_dir: Where to output the generated project dir into.
        :param overwrite_if_exists: Overwrite the contents of the output directory
            if it exists.
        :param skip_if_file_exists: Skip the files in the corresponding directories
            if they already exist
        :param accept_hooks: Accept pre and post hooks if set to `True`.
        :param keep_project_on_failure: If `True` keep generated project directory even when
            generation fails
        """
>       template_dir = find_template(repo_dir)
E       TypeError: find_template() missing 1 required positional argument: 'env'

cookiecutter/generate.py:225: TypeError

test_generate_files.py::test_generate_files_with_windows_newline

test_generate_files.py::test_generate_files_with_windows_newline
tmp_path = PosixPath('/tmp/pytest-of-root/pytest-0/test_generate_files_with_windo0')

    def test_generate_files_with_windows_newline(tmp_path):
        """Verify windows source line end not changed during files generation."""
>       generate.generate_files(
            context={'cookiecutter': {'food': 'pizzä'}},
            repo_dir='tests/test-generate-files',
            output_dir=tmp_path,
        )

tests/test_generate_files.py:105: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

repo_dir = 'tests/test-generate-files'
context = {'cookiecutter': {'food': 'pizzä'}}
output_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_generate_files_with_windo0')
overwrite_if_exists = False, skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False

    def generate_files(repo_dir, context=None, output_dir='.',
        overwrite_if_exists=False, skip_if_file_exists=False, accept_hooks=True,
        keep_project_on_failure=False):
        """Render the templates and saves them to files.

        :param repo_dir: Project template input directory.
        :param context: Dict for populating the template's variables.
        :param output_dir: Where to output the generated project dir into.
        :param overwrite_if_exists: Overwrite the contents of the output directory
            if it exists.
        :param skip_if_file_exists: Skip the files in the corresponding directories
            if they already exist
        :param accept_hooks: Accept pre and post hooks if set to `True`.
        :param keep_project_on_failure: If `True` keep generated project directory even when
            generation fails
        """
>       template_dir = find_template(repo_dir)
E       TypeError: find_template() missing 1 required positional argument: 'env'

cookiecutter/generate.py:225: TypeError

test_generate_files.py::test_generate_files_with_windows_newline_forced_to_linux_by_context

test_generate_files.py::test_generate_files_with_windows_newline_forced_to_linux_by_context
tmp_path = PosixPath('/tmp/pytest-of-root/pytest-0/test_generate_files_with_windo1')

    def test_generate_files_with_windows_newline_forced_to_linux_by_context(tmp_path):
        """Verify windows line end changed to linux during files generation."""
>       generate.generate_files(
            context={'cookiecutter': {'food': 'pizzä', '_new_lines': '\n'}},
            repo_dir='tests/test-generate-files',
            output_dir=tmp_path,
        )

tests/test_generate_files.py:123: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

repo_dir = 'tests/test-generate-files'
context = {'cookiecutter': {'_new_lines': '\n', 'food': 'pizzä'}}
output_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_generate_files_with_windo1')
overwrite_if_exists = False, skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False

    def generate_files(repo_dir, context=None, output_dir='.',
        overwrite_if_exists=False, skip_if_file_exists=False, accept_hooks=True,
        keep_project_on_failure=False):
        """Render the templates and saves them to files.

        :param repo_dir: Project template input directory.
        :param context: Dict for populating the template's variables.
        :param output_dir: Where to output the generated project dir into.
        :param overwrite_if_exists: Overwrite the contents of the output directory
            if it exists.
        :param skip_if_file_exists: Skip the files in the corresponding directories
            if they already exist
        :param accept_hooks: Accept pre and post hooks if set to `True`.
        :param keep_project_on_failure: If `True` keep generated project directory even when
            generation fails
        """
>       template_dir = find_template(repo_dir)
E       TypeError: find_template() missing 1 required positional argument: 'env'

cookiecutter/generate.py:225: TypeError

test_generate_files.py::test_generate_files_binaries

test_generate_files.py::test_generate_files_binaries
tmp_path = PosixPath('/tmp/pytest-of-root/pytest-0/test_generate_files_binaries0')

    def test_generate_files_binaries(tmp_path):
        """Verify binary files created during directory generation."""
>       generate.generate_files(
            context={'cookiecutter': {'binary_test': 'binary_files'}},
            repo_dir='tests/test-generate-binaries',
            output_dir=tmp_path,
        )

tests/test_generate_files.py:142: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

repo_dir = 'tests/test-generate-binaries'
context = {'cookiecutter': {'binary_test': 'binary_files'}}
output_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_generate_files_binaries0')
overwrite_if_exists = False, skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False

    def generate_files(repo_dir, context=None, output_dir='.',
        overwrite_if_exists=False, skip_if_file_exists=False, accept_hooks=True,
        keep_project_on_failure=False):
        """Render the templates and saves them to files.

        :param repo_dir: Project template input directory.
        :param context: Dict for populating the template's variables.
        :param output_dir: Where to output the generated project dir into.
        :param overwrite_if_exists: Overwrite the contents of the output directory
            if it exists.
        :param skip_if_file_exists: Skip the files in the corresponding directories
            if they already exist
        :param accept_hooks: Accept pre and post hooks if set to `True`.
        :param keep_project_on_failure: If `True` keep generated project directory even when
            generation fails
        """
>       template_dir = find_template(repo_dir)
E       TypeError: find_template() missing 1 required positional argument: 'env'

cookiecutter/generate.py:225: TypeError

test_generate_files.py::test_generate_files_absolute_path

test_generate_files.py::test_generate_files_absolute_path
tmp_path = PosixPath('/tmp/pytest-of-root/pytest-0/test_generate_files_absolute_p0')

    def test_generate_files_absolute_path(tmp_path):
        """Verify usage of absolute path does not change files generation behaviour."""
>       generate.generate_files(
            context={'cookiecutter': {'food': 'pizzä'}},
            repo_dir=Path('tests/test-generate-files').absolute(),
            output_dir=tmp_path,
        )

tests/test_generate_files.py:163: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

repo_dir = PosixPath('/testbed/tests/test-generate-files')
context = {'cookiecutter': {'food': 'pizzä'}}
output_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_generate_files_absolute_p0')
overwrite_if_exists = False, skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False

    def generate_files(repo_dir, context=None, output_dir='.',
        overwrite_if_exists=False, skip_if_file_exists=False, accept_hooks=True,
        keep_project_on_failure=False):
        """Render the templates and saves them to files.

        :param repo_dir: Project template input directory.
        :param context: Dict for populating the template's variables.
        :param output_dir: Where to output the generated project dir into.
        :param overwrite_if_exists: Overwrite the contents of the output directory
            if it exists.
        :param skip_if_file_exists: Skip the files in the corresponding directories
            if they already exist
        :param accept_hooks: Accept pre and post hooks if set to `True`.
        :param keep_project_on_failure: If `True` keep generated project directory even when
            generation fails
        """
>       template_dir = find_template(repo_dir)
E       TypeError: find_template() missing 1 required positional argument: 'env'

cookiecutter/generate.py:225: TypeError

test_generate_files.py::test_generate_files_output_dir

test_generate_files.py::test_generate_files_output_dir
tmp_path = PosixPath('/tmp/pytest-of-root/pytest-0/test_generate_files_output_dir0')

    def test_generate_files_output_dir(tmp_path):
        """Verify `output_dir` option for `generate_files` changing location correctly."""
        output_dir = Path(tmp_path, 'custom_output_dir')
        output_dir.mkdir()

>       project_dir = generate.generate_files(
            context={'cookiecutter': {'food': 'pizzä'}},
            repo_dir=Path('tests/test-generate-files').absolute(),
            output_dir=output_dir,
        )

tests/test_generate_files.py:176: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

repo_dir = PosixPath('/testbed/tests/test-generate-files')
context = {'cookiecutter': {'food': 'pizzä'}}
output_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_generate_files_output_dir0/custom_output_dir')
overwrite_if_exists = False, skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False

    def generate_files(repo_dir, context=None, output_dir='.',
        overwrite_if_exists=False, skip_if_file_exists=False, accept_hooks=True,
        keep_project_on_failure=False):
        """Render the templates and saves them to files.

        :param repo_dir: Project template input directory.
        :param context: Dict for populating the template's variables.
        :param output_dir: Where to output the generated project dir into.
        :param overwrite_if_exists: Overwrite the contents of the output directory
            if it exists.
        :param skip_if_file_exists: Skip the files in the corresponding directories
            if they already exist
        :param accept_hooks: Accept pre and post hooks if set to `True`.
        :param keep_project_on_failure: If `True` keep generated project directory even when
            generation fails
        """
>       template_dir = find_template(repo_dir)
E       TypeError: find_template() missing 1 required positional argument: 'env'

cookiecutter/generate.py:225: TypeError

test_generate_files.py::test_generate_files_permissions

test_generate_files.py::test_generate_files_permissions
tmp_path = PosixPath('/tmp/pytest-of-root/pytest-0/test_generate_files_permission0')

    def test_generate_files_permissions(tmp_path):
        """Verify generates files respect source files permissions.

        simple.txt and script.sh should retain their respective 0o644 and 0o755
        permissions.
        """
>       generate.generate_files(
            context={'cookiecutter': {'permissions': 'permissions'}},
            repo_dir='tests/test-generate-files-permissions',
            output_dir=tmp_path,
        )

tests/test_generate_files.py:193: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

repo_dir = 'tests/test-generate-files-permissions'
context = {'cookiecutter': {'permissions': 'permissions'}}
output_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_generate_files_permission0')
overwrite_if_exists = False, skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False

    def generate_files(repo_dir, context=None, output_dir='.',
        overwrite_if_exists=False, skip_if_file_exists=False, accept_hooks=True,
        keep_project_on_failure=False):
        """Render the templates and saves them to files.

        :param repo_dir: Project template input directory.
        :param context: Dict for populating the template's variables.
        :param output_dir: Where to output the generated project dir into.
        :param overwrite_if_exists: Overwrite the contents of the output directory
            if it exists.
        :param skip_if_file_exists: Skip the files in the corresponding directories
            if they already exist
        :param accept_hooks: Accept pre and post hooks if set to `True`.
        :param keep_project_on_failure: If `True` keep generated project directory even when
            generation fails
        """
>       template_dir = find_template(repo_dir)
E       TypeError: find_template() missing 1 required positional argument: 'env'

cookiecutter/generate.py:225: TypeError

test_generate_files.py::test_generate_files_with_overwrite_if_exists_with_skip_if_file_exists

test_generate_files.py::test_generate_files_with_overwrite_if_exists_with_skip_if_file_exists
tmp_path = PosixPath('/tmp/pytest-of-root/pytest-0/test_generate_files_with_overw0')

    def test_generate_files_with_overwrite_if_exists_with_skip_if_file_exists(tmp_path):
        """Verify `skip_if_file_exist` has priority over `overwrite_if_exists`."""
        simple_file = Path(tmp_path, 'inputpizzä/simple.txt')
        simple_with_new_line_file = Path(tmp_path, 'inputpizzä/simple-with-newline.txt')

        Path(tmp_path, 'inputpizzä').mkdir(parents=True)
        with Path(simple_file).open('w') as f:
            f.write('temp')

>       generate.generate_files(
            context={'cookiecutter': {'food': 'pizzä'}},
            repo_dir='tests/test-generate-files',
            overwrite_if_exists=True,
            skip_if_file_exists=True,
            output_dir=tmp_path,
        )

tests/test_generate_files.py:240: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

repo_dir = 'tests/test-generate-files'
context = {'cookiecutter': {'food': 'pizzä'}}
output_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_generate_files_with_overw0')
overwrite_if_exists = True, skip_if_file_exists = True, accept_hooks = True
keep_project_on_failure = False

    def generate_files(repo_dir, context=None, output_dir='.',
        overwrite_if_exists=False, skip_if_file_exists=False, accept_hooks=True,
        keep_project_on_failure=False):
        """Render the templates and saves them to files.

        :param repo_dir: Project template input directory.
        :param context: Dict for populating the template's variables.
        :param output_dir: Where to output the generated project dir into.
        :param overwrite_if_exists: Overwrite the contents of the output directory
            if it exists.
        :param skip_if_file_exists: Skip the files in the corresponding directories
            if they already exist
        :param accept_hooks: Accept pre and post hooks if set to `True`.
        :param keep_project_on_failure: If `True` keep generated project directory even when
            generation fails
        """
>       template_dir = find_template(repo_dir)
E       TypeError: find_template() missing 1 required positional argument: 'env'

cookiecutter/generate.py:225: TypeError

test_generate_files.py::test_generate_files_with_skip_if_file_exists

test_generate_files.py::test_generate_files_with_skip_if_file_exists
tmp_path = PosixPath('/tmp/pytest-of-root/pytest-0/test_generate_files_with_skip_0')

    def test_generate_files_with_skip_if_file_exists(tmp_path):
        """Verify existed files not removed if error raised with `skip_if_file_exists`."""
        simple_file = Path(tmp_path, 'inputpizzä/simple.txt')
        simple_with_new_line_file = Path(tmp_path, 'inputpizzä/simple-with-newline.txt')

        Path(tmp_path, 'inputpizzä').mkdir(parents=True)
        Path(simple_file).write_text('temp')

        with pytest.raises(exceptions.OutputDirExistsException):
>           generate.generate_files(
                context={'cookiecutter': {'food': 'pizzä'}},
                repo_dir='tests/test-generate-files',
                skip_if_file_exists=True,
                output_dir=tmp_path,
            )

tests/test_generate_files.py:266: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

repo_dir = 'tests/test-generate-files'
context = {'cookiecutter': {'food': 'pizzä'}}
output_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_generate_files_with_skip_0')
overwrite_if_exists = False, skip_if_file_exists = True, accept_hooks = True
keep_project_on_failure = False

    def generate_files(repo_dir, context=None, output_dir='.',
        overwrite_if_exists=False, skip_if_file_exists=False, accept_hooks=True,
        keep_project_on_failure=False):
        """Render the templates and saves them to files.

        :param repo_dir: Project template input directory.
        :param context: Dict for populating the template's variables.
        :param output_dir: Where to output the generated project dir into.
        :param overwrite_if_exists: Overwrite the contents of the output directory
            if it exists.
        :param skip_if_file_exists: Skip the files in the corresponding directories
            if they already exist
        :param accept_hooks: Accept pre and post hooks if set to `True`.
        :param keep_project_on_failure: If `True` keep generated project directory even when
            generation fails
        """
>       template_dir = find_template(repo_dir)
E       TypeError: find_template() missing 1 required positional argument: 'env'

cookiecutter/generate.py:225: TypeError

test_generate_files.py::test_generate_files_with_overwrite_if_exists

test_generate_files.py::test_generate_files_with_overwrite_if_exists
tmp_path = PosixPath('/tmp/pytest-of-root/pytest-0/test_generate_files_with_overw1')

    def test_generate_files_with_overwrite_if_exists(tmp_path):
        """Verify overwrite_if_exists overwrites old files."""
        simple_file = Path(tmp_path, 'inputpizzä/simple.txt')
        simple_with_new_line_file = Path(tmp_path, 'inputpizzä/simple-with-newline.txt')

        Path(tmp_path, 'inputpizzä').mkdir(parents=True)
        Path(simple_file).write_text('temp')

>       generate.generate_files(
            context={'cookiecutter': {'food': 'pizzä'}},
            repo_dir='tests/test-generate-files',
            overwrite_if_exists=True,
            output_dir=tmp_path,
        )

tests/test_generate_files.py:289: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

repo_dir = 'tests/test-generate-files'
context = {'cookiecutter': {'food': 'pizzä'}}
output_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_generate_files_with_overw1')
overwrite_if_exists = True, skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False

    def generate_files(repo_dir, context=None, output_dir='.',
        overwrite_if_exists=False, skip_if_file_exists=False, accept_hooks=True,
        keep_project_on_failure=False):
        """Render the templates and saves them to files.

        :param repo_dir: Project template input directory.
        :param context: Dict for populating the template's variables.
        :param output_dir: Where to output the generated project dir into.
        :param overwrite_if_exists: Overwrite the contents of the output directory
            if it exists.
        :param skip_if_file_exists: Skip the files in the corresponding directories
            if they already exist
        :param accept_hooks: Accept pre and post hooks if set to `True`.
        :param keep_project_on_failure: If `True` keep generated project directory even when
            generation fails
        """
>       template_dir = find_template(repo_dir)
E       TypeError: find_template() missing 1 required positional argument: 'env'

cookiecutter/generate.py:225: TypeError

test_generate_files.py::test_raise_undefined_variable_file_name

test_generate_files.py::test_raise_undefined_variable_file_name
output_dir = '/tmp/pytest-of-root/pytest-0/test_raise_undefined_variable_0/output'
undefined_context = {'cookiecutter': {'github_username': 'hackebrot', 'project_slug': 'testproject'}}

    def test_raise_undefined_variable_file_name(output_dir, undefined_context):
        """Verify correct error raised when file name cannot be rendered."""
        with pytest.raises(exceptions.UndefinedVariableInTemplate) as err:
>           generate.generate_files(
                repo_dir='tests/undefined-variable/file-name/',
                output_dir=output_dir,
                context=undefined_context,
            )

tests/test_generate_files.py:316: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

repo_dir = 'tests/undefined-variable/file-name/'
context = {'cookiecutter': {'github_username': 'hackebrot', 'project_slug': 'testproject'}}
output_dir = '/tmp/pytest-of-root/pytest-0/test_raise_undefined_variable_0/output'
overwrite_if_exists = False, skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False

    def generate_files(repo_dir, context=None, output_dir='.',
        overwrite_if_exists=False, skip_if_file_exists=False, accept_hooks=True,
        keep_project_on_failure=False):
        """Render the templates and saves them to files.

        :param repo_dir: Project template input directory.
        :param context: Dict for populating the template's variables.
        :param output_dir: Where to output the generated project dir into.
        :param overwrite_if_exists: Overwrite the contents of the output directory
            if it exists.
        :param skip_if_file_exists: Skip the files in the corresponding directories
            if they already exist
        :param accept_hooks: Accept pre and post hooks if set to `True`.
        :param keep_project_on_failure: If `True` keep generated project directory even when
            generation fails
        """
>       template_dir = find_template(repo_dir)
E       TypeError: find_template() missing 1 required positional argument: 'env'

cookiecutter/generate.py:225: TypeError

test_generate_files.py::test_raise_undefined_variable_file_name_existing_project

test_generate_files.py::test_raise_undefined_variable_file_name_existing_project
output_dir = '/tmp/pytest-of-root/pytest-0/test_raise_undefined_variable_1/output'
undefined_context = {'cookiecutter': {'github_username': 'hackebrot', 'project_slug': 'testproject'}}

    def test_raise_undefined_variable_file_name_existing_project(
        output_dir, undefined_context
    ):
        """Verify correct error raised when file name cannot be rendered."""
        testproj_path = Path(output_dir, 'testproject')
        testproj_path.mkdir()

        with pytest.raises(exceptions.UndefinedVariableInTemplate) as err:
>           generate.generate_files(
                repo_dir='tests/undefined-variable/file-name/',
                output_dir=output_dir,
                context=undefined_context,
                overwrite_if_exists=True,
            )

tests/test_generate_files.py:336: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

repo_dir = 'tests/undefined-variable/file-name/'
context = {'cookiecutter': {'github_username': 'hackebrot', 'project_slug': 'testproject'}}
output_dir = '/tmp/pytest-of-root/pytest-0/test_raise_undefined_variable_1/output'
overwrite_if_exists = True, skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False

    def generate_files(repo_dir, context=None, output_dir='.',
        overwrite_if_exists=False, skip_if_file_exists=False, accept_hooks=True,
        keep_project_on_failure=False):
        """Render the templates and saves them to files.

        :param repo_dir: Project template input directory.
        :param context: Dict for populating the template's variables.
        :param output_dir: Where to output the generated project dir into.
        :param overwrite_if_exists: Overwrite the contents of the output directory
            if it exists.
        :param skip_if_file_exists: Skip the files in the corresponding directories
            if they already exist
        :param accept_hooks: Accept pre and post hooks if set to `True`.
        :param keep_project_on_failure: If `True` keep generated project directory even when
            generation fails
        """
>       template_dir = find_template(repo_dir)
E       TypeError: find_template() missing 1 required positional argument: 'env'

cookiecutter/generate.py:225: TypeError

test_generate_files.py::test_raise_undefined_variable_file_content

test_generate_files.py::test_raise_undefined_variable_file_content
output_dir = '/tmp/pytest-of-root/pytest-0/test_raise_undefined_variable_2/output'
undefined_context = {'cookiecutter': {'github_username': 'hackebrot', 'project_slug': 'testproject'}}

    def test_raise_undefined_variable_file_content(output_dir, undefined_context):
        """Verify correct error raised when file content cannot be rendered."""
        with pytest.raises(exceptions.UndefinedVariableInTemplate) as err:
>           generate.generate_files(
                repo_dir='tests/undefined-variable/file-content/',
                output_dir=output_dir,
                context=undefined_context,
            )

tests/test_generate_files.py:352: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

repo_dir = 'tests/undefined-variable/file-content/'
context = {'cookiecutter': {'github_username': 'hackebrot', 'project_slug': 'testproject'}}
output_dir = '/tmp/pytest-of-root/pytest-0/test_raise_undefined_variable_2/output'
overwrite_if_exists = False, skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False

    def generate_files(repo_dir, context=None, output_dir='.',
        overwrite_if_exists=False, skip_if_file_exists=False, accept_hooks=True,
        keep_project_on_failure=False):
        """Render the templates and saves them to files.

        :param repo_dir: Project template input directory.
        :param context: Dict for populating the template's variables.
        :param output_dir: Where to output the generated project dir into.
        :param overwrite_if_exists: Overwrite the contents of the output directory
            if it exists.
        :param skip_if_file_exists: Skip the files in the corresponding directories
            if they already exist
        :param accept_hooks: Accept pre and post hooks if set to `True`.
        :param keep_project_on_failure: If `True` keep generated project directory even when
            generation fails
        """
>       template_dir = find_template(repo_dir)
E       TypeError: find_template() missing 1 required positional argument: 'env'

cookiecutter/generate.py:225: TypeError

test_generate_files.py::test_raise_undefined_variable_dir_name

test_generate_files.py::test_raise_undefined_variable_dir_name
output_dir = '/tmp/pytest-of-root/pytest-0/test_raise_undefined_variable_3/output'
undefined_context = {'cookiecutter': {'github_username': 'hackebrot', 'project_slug': 'testproject'}}

    def test_raise_undefined_variable_dir_name(output_dir, undefined_context):
        """Verify correct error raised when directory name cannot be rendered."""
        with pytest.raises(exceptions.UndefinedVariableInTemplate) as err:
>           generate.generate_files(
                repo_dir='tests/undefined-variable/dir-name/',
                output_dir=output_dir,
                context=undefined_context,
            )

tests/test_generate_files.py:367: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

repo_dir = 'tests/undefined-variable/dir-name/'
context = {'cookiecutter': {'github_username': 'hackebrot', 'project_slug': 'testproject'}}
output_dir = '/tmp/pytest-of-root/pytest-0/test_raise_undefined_variable_3/output'
overwrite_if_exists = False, skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False

    def generate_files(repo_dir, context=None, output_dir='.',
        overwrite_if_exists=False, skip_if_file_exists=False, accept_hooks=True,
        keep_project_on_failure=False):
        """Render the templates and saves them to files.

        :param repo_dir: Project template input directory.
        :param context: Dict for populating the template's variables.
        :param output_dir: Where to output the generated project dir into.
        :param overwrite_if_exists: Overwrite the contents of the output directory
            if it exists.
        :param skip_if_file_exists: Skip the files in the corresponding directories
            if they already exist
        :param accept_hooks: Accept pre and post hooks if set to `True`.
        :param keep_project_on_failure: If `True` keep generated project directory even when
            generation fails
        """
>       template_dir = find_template(repo_dir)
E       TypeError: find_template() missing 1 required positional argument: 'env'

cookiecutter/generate.py:225: TypeError

test_generate_files.py::test_keep_project_dir_on_failure

test_generate_files.py::test_keep_project_dir_on_failure
output_dir = '/tmp/pytest-of-root/pytest-0/test_keep_project_dir_on_failu0/output'
undefined_context = {'cookiecutter': {'github_username': 'hackebrot', 'project_slug': 'testproject'}}

    def test_keep_project_dir_on_failure(output_dir, undefined_context):
        """Verify correct error raised when directory name cannot be rendered."""
        with pytest.raises(exceptions.UndefinedVariableInTemplate):
>           generate.generate_files(
                repo_dir='tests/undefined-variable/dir-name/',
                output_dir=output_dir,
                context=undefined_context,
                keep_project_on_failure=True,
            )

tests/test_generate_files.py:386: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

repo_dir = 'tests/undefined-variable/dir-name/'
context = {'cookiecutter': {'github_username': 'hackebrot', 'project_slug': 'testproject'}}
output_dir = '/tmp/pytest-of-root/pytest-0/test_keep_project_dir_on_failu0/output'
overwrite_if_exists = False, skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = True

    def generate_files(repo_dir, context=None, output_dir='.',
        overwrite_if_exists=False, skip_if_file_exists=False, accept_hooks=True,
        keep_project_on_failure=False):
        """Render the templates and saves them to files.

        :param repo_dir: Project template input directory.
        :param context: Dict for populating the template's variables.
        :param output_dir: Where to output the generated project dir into.
        :param overwrite_if_exists: Overwrite the contents of the output directory
            if it exists.
        :param skip_if_file_exists: Skip the files in the corresponding directories
            if they already exist
        :param accept_hooks: Accept pre and post hooks if set to `True`.
        :param keep_project_on_failure: If `True` keep generated project directory even when
            generation fails
        """
>       template_dir = find_template(repo_dir)
E       TypeError: find_template() missing 1 required positional argument: 'env'

cookiecutter/generate.py:225: TypeError

test_generate_files.py::test_raise_undefined_variable_dir_name_existing_project

test_generate_files.py::test_raise_undefined_variable_dir_name_existing_project
output_dir = '/tmp/pytest-of-root/pytest-0/test_raise_undefined_variable_4/output'
undefined_context = {'cookiecutter': {'github_username': 'hackebrot', 'project_slug': 'testproject'}}

    def test_raise_undefined_variable_dir_name_existing_project(
        output_dir, undefined_context
    ):
        """Verify correct error raised when directory name cannot be rendered."""
        testproj_path = Path(output_dir, 'testproject')
        testproj_path.mkdir()

        with pytest.raises(exceptions.UndefinedVariableInTemplate) as err:
>           generate.generate_files(
                repo_dir='tests/undefined-variable/dir-name/',
                output_dir=output_dir,
                context=undefined_context,
                overwrite_if_exists=True,
            )

tests/test_generate_files.py:403: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

repo_dir = 'tests/undefined-variable/dir-name/'
context = {'cookiecutter': {'github_username': 'hackebrot', 'project_slug': 'testproject'}}
output_dir = '/tmp/pytest-of-root/pytest-0/test_raise_undefined_variable_4/output'
overwrite_if_exists = True, skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False

    def generate_files(repo_dir, context=None, output_dir='.',
        overwrite_if_exists=False, skip_if_file_exists=False, accept_hooks=True,
        keep_project_on_failure=False):
        """Render the templates and saves them to files.

        :param repo_dir: Project template input directory.
        :param context: Dict for populating the template's variables.
        :param output_dir: Where to output the generated project dir into.
        :param overwrite_if_exists: Overwrite the contents of the output directory
            if it exists.
        :param skip_if_file_exists: Skip the files in the corresponding directories
            if they already exist
        :param accept_hooks: Accept pre and post hooks if set to `True`.
        :param keep_project_on_failure: If `True` keep generated project directory even when
            generation fails
        """
>       template_dir = find_template(repo_dir)
E       TypeError: find_template() missing 1 required positional argument: 'env'

cookiecutter/generate.py:225: TypeError

test_generate_files.py::test_raise_undefined_variable_project_dir

test_generate_files.py::test_raise_undefined_variable_project_dir
tmp_path = PosixPath('/tmp/pytest-of-root/pytest-0/test_raise_undefined_variable_5')

    def test_raise_undefined_variable_project_dir(tmp_path):
        """Verify correct error raised when directory name cannot be rendered."""
        with pytest.raises(exceptions.UndefinedVariableInTemplate) as err:
>           generate.generate_files(
                repo_dir='tests/undefined-variable/dir-name/',
                output_dir=tmp_path,
                context={},
            )

tests/test_generate_files.py:423: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

repo_dir = 'tests/undefined-variable/dir-name/', context = {}
output_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_raise_undefined_variable_5')
overwrite_if_exists = False, skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False

    def generate_files(repo_dir, context=None, output_dir='.',
        overwrite_if_exists=False, skip_if_file_exists=False, accept_hooks=True,
        keep_project_on_failure=False):
        """Render the templates and saves them to files.

        :param repo_dir: Project template input directory.
        :param context: Dict for populating the template's variables.
        :param output_dir: Where to output the generated project dir into.
        :param overwrite_if_exists: Overwrite the contents of the output directory
            if it exists.
        :param skip_if_file_exists: Skip the files in the corresponding directories
            if they already exist
        :param accept_hooks: Accept pre and post hooks if set to `True`.
        :param keep_project_on_failure: If `True` keep generated project directory even when
            generation fails
        """
>       template_dir = find_template(repo_dir)
E       TypeError: find_template() missing 1 required positional argument: 'env'

cookiecutter/generate.py:225: TypeError

test_generate_hooks.py::test_ignore_hooks_dirs

test_generate_hooks.py::test_ignore_hooks_dirs
@pytest.mark.usefixtures('clean_system', 'remove_additional_folders')
    def test_ignore_hooks_dirs():
        """Verify hooks directory not created in target location on files generation."""
>       generate.generate_files(
            context={'cookiecutter': {'pyhooks': 'pyhooks'}},
            repo_dir='tests/test-pyhooks/',
            output_dir='tests/test-pyhooks/',
        )

tests/test_generate_hooks.py:35: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

repo_dir = 'tests/test-pyhooks/'
context = {'cookiecutter': {'pyhooks': 'pyhooks'}}
output_dir = 'tests/test-pyhooks/', overwrite_if_exists = False
skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False

    def generate_files(repo_dir, context=None, output_dir='.',
        overwrite_if_exists=False, skip_if_file_exists=False, accept_hooks=True,
        keep_project_on_failure=False):
        """Render the templates and saves them to files.

        :param repo_dir: Project template input directory.
        :param context: Dict for populating the template's variables.
        :param output_dir: Where to output the generated project dir into.
        :param overwrite_if_exists: Overwrite the contents of the output directory
            if it exists.
        :param skip_if_file_exists: Skip the files in the corresponding directories
            if they already exist
        :param accept_hooks: Accept pre and post hooks if set to `True`.
        :param keep_project_on_failure: If `True` keep generated project directory even when
            generation fails
        """
>       template_dir = find_template(repo_dir)
E       TypeError: find_template() missing 1 required positional argument: 'env'

cookiecutter/generate.py:225: TypeError

test_generate_hooks.py::test_run_python_hooks

test_generate_hooks.py::test_run_python_hooks
@pytest.mark.usefixtures('clean_system', 'remove_additional_folders')
    def test_run_python_hooks():
        """Verify pre and post generation python hooks executed and result in output_dir.

        Each hook should create in target directory. Test verifies that these files
        created.
        """
>       generate.generate_files(
            context={'cookiecutter': {'pyhooks': 'pyhooks'}},
            repo_dir='tests/test-pyhooks/',
            output_dir='tests/test-pyhooks/',
        )

tests/test_generate_hooks.py:50: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

repo_dir = 'tests/test-pyhooks/'
context = {'cookiecutter': {'pyhooks': 'pyhooks'}}
output_dir = 'tests/test-pyhooks/', overwrite_if_exists = False
skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False

    def generate_files(repo_dir, context=None, output_dir='.',
        overwrite_if_exists=False, skip_if_file_exists=False, accept_hooks=True,
        keep_project_on_failure=False):
        """Render the templates and saves them to files.

        :param repo_dir: Project template input directory.
        :param context: Dict for populating the template's variables.
        :param output_dir: Where to output the generated project dir into.
        :param overwrite_if_exists: Overwrite the contents of the output directory
            if it exists.
        :param skip_if_file_exists: Skip the files in the corresponding directories
            if they already exist
        :param accept_hooks: Accept pre and post hooks if set to `True`.
        :param keep_project_on_failure: If `True` keep generated project directory even when
            generation fails
        """
>       template_dir = find_template(repo_dir)
E       TypeError: find_template() missing 1 required positional argument: 'env'

cookiecutter/generate.py:225: TypeError

test_generate_hooks.py::test_run_python_hooks_cwd

test_generate_hooks.py::test_run_python_hooks_cwd
@pytest.mark.usefixtures('clean_system', 'remove_additional_folders')
    def test_run_python_hooks_cwd():
        """Verify pre and post generation python hooks executed and result in current dir.

        Each hook should create in target directory. Test verifies that these files
        created.
        """
>       generate.generate_files(
            context={'cookiecutter': {'pyhooks': 'pyhooks'}}, repo_dir='tests/test-pyhooks/'
        )

tests/test_generate_hooks.py:66: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

repo_dir = 'tests/test-pyhooks/'
context = {'cookiecutter': {'pyhooks': 'pyhooks'}}, output_dir = '.'
overwrite_if_exists = False, skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False

    def generate_files(repo_dir, context=None, output_dir='.',
        overwrite_if_exists=False, skip_if_file_exists=False, accept_hooks=True,
        keep_project_on_failure=False):
        """Render the templates and saves them to files.

        :param repo_dir: Project template input directory.
        :param context: Dict for populating the template's variables.
        :param output_dir: Where to output the generated project dir into.
        :param overwrite_if_exists: Overwrite the contents of the output directory
            if it exists.
        :param skip_if_file_exists: Skip the files in the corresponding directories
            if they already exist
        :param accept_hooks: Accept pre and post hooks if set to `True`.
        :param keep_project_on_failure: If `True` keep generated project directory even when
            generation fails
        """
>       template_dir = find_template(repo_dir)
E       TypeError: find_template() missing 1 required positional argument: 'env'

cookiecutter/generate.py:225: TypeError

test_generate_hooks.py::test_empty_hooks

test_generate_hooks.py::test_empty_hooks
@pytest.mark.skipif(WINDOWS, reason='OSError.errno=8 is not thrown on Windows')
    @pytest.mark.usefixtures('clean_system', 'remove_additional_folders')
    def test_empty_hooks():
        """Verify error is raised on empty hook script. Ignored on windows.

        OSError.errno=8 is not thrown on Windows when the script is empty
        because it always runs through shell instead of needing a shebang.
        """
        with pytest.raises(FailedHookException) as excinfo:
>           generate.generate_files(
                context={'cookiecutter': {'shellhooks': 'shellhooks'}},
                repo_dir='tests/test-shellhooks-empty/',
                overwrite_if_exists=True,
            )

tests/test_generate_hooks.py:82: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

repo_dir = 'tests/test-shellhooks-empty/'
context = {'cookiecutter': {'shellhooks': 'shellhooks'}}, output_dir = '.'
overwrite_if_exists = True, skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False

    def generate_files(repo_dir, context=None, output_dir='.',
        overwrite_if_exists=False, skip_if_file_exists=False, accept_hooks=True,
        keep_project_on_failure=False):
        """Render the templates and saves them to files.

        :param repo_dir: Project template input directory.
        :param context: Dict for populating the template's variables.
        :param output_dir: Where to output the generated project dir into.
        :param overwrite_if_exists: Overwrite the contents of the output directory
            if it exists.
        :param skip_if_file_exists: Skip the files in the corresponding directories
            if they already exist
        :param accept_hooks: Accept pre and post hooks if set to `True`.
        :param keep_project_on_failure: If `True` keep generated project directory even when
            generation fails
        """
>       template_dir = find_template(repo_dir)
E       TypeError: find_template() missing 1 required positional argument: 'env'

cookiecutter/generate.py:225: TypeError

test_generate_hooks.py::test_oserror_hooks

test_generate_hooks.py::test_oserror_hooks
mocker = 

    @pytest.mark.usefixtures('clean_system', 'remove_additional_folders')
    def test_oserror_hooks(mocker):
        """Verify script error passed correctly to cookiecutter error.

        Here subprocess.Popen function mocked, ie we do not call hook script,
        just produce expected error.
        """
        message = 'Out of memory'

        err = OSError(message)
        err.errno = errno.ENOMEM

        prompt = mocker.patch('subprocess.Popen')
        prompt.side_effect = err

        with pytest.raises(FailedHookException) as excinfo:
>           generate.generate_files(
                context={'cookiecutter': {'shellhooks': 'shellhooks'}},
                repo_dir='tests/test-shellhooks-empty/',
                overwrite_if_exists=True,
            )

tests/test_generate_hooks.py:106: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

repo_dir = 'tests/test-shellhooks-empty/'
context = {'cookiecutter': {'shellhooks': 'shellhooks'}}, output_dir = '.'
overwrite_if_exists = True, skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False

    def generate_files(repo_dir, context=None, output_dir='.',
        overwrite_if_exists=False, skip_if_file_exists=False, accept_hooks=True,
        keep_project_on_failure=False):
        """Render the templates and saves them to files.

        :param repo_dir: Project template input directory.
        :param context: Dict for populating the template's variables.
        :param output_dir: Where to output the generated project dir into.
        :param overwrite_if_exists: Overwrite the contents of the output directory
            if it exists.
        :param skip_if_file_exists: Skip the files in the corresponding directories
            if they already exist
        :param accept_hooks: Accept pre and post hooks if set to `True`.
        :param keep_project_on_failure: If `True` keep generated project directory even when
            generation fails
        """
>       template_dir = find_template(repo_dir)
E       TypeError: find_template() missing 1 required positional argument: 'env'

cookiecutter/generate.py:225: TypeError

test_generate_hooks.py::test_run_failing_hook_removes_output_directory

test_generate_hooks.py::test_run_failing_hook_removes_output_directory
@pytest.mark.usefixtures('clean_system', 'remove_additional_folders')
    def test_run_failing_hook_removes_output_directory():
        """Verify project directory not created or removed if hook failed."""
        repo_path = os.path.abspath('tests/test-hooks/')
        hooks_path = os.path.abspath('tests/test-hooks/hooks')

        hook_dir = os.path.join(repo_path, 'hooks')
        template = os.path.join(repo_path, 'input{{cookiecutter.hooks}}')
        os.mkdir(repo_path)
        os.mkdir(hook_dir)
        os.mkdir(template)

        hook_path = os.path.join(hooks_path, 'pre_gen_project.py')

        with Path(hook_path).open('w') as f:
            f.write("#!/usr/bin/env python\n")
            f.write("import sys; sys.exit(1)\n")

        with pytest.raises(FailedHookException) as excinfo:
>           generate.generate_files(
                context={'cookiecutter': {'hooks': 'hooks'}},
                repo_dir='tests/test-hooks/',
                overwrite_if_exists=True,
            )

tests/test_generate_hooks.py:133: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

repo_dir = 'tests/test-hooks/', context = {'cookiecutter': {'hooks': 'hooks'}}
output_dir = '.', overwrite_if_exists = True, skip_if_file_exists = False
accept_hooks = True, keep_project_on_failure = False

    def generate_files(repo_dir, context=None, output_dir='.',
        overwrite_if_exists=False, skip_if_file_exists=False, accept_hooks=True,
        keep_project_on_failure=False):
        """Render the templates and saves them to files.

        :param repo_dir: Project template input directory.
        :param context: Dict for populating the template's variables.
        :param output_dir: Where to output the generated project dir into.
        :param overwrite_if_exists: Overwrite the contents of the output directory
            if it exists.
        :param skip_if_file_exists: Skip the files in the corresponding directories
            if they already exist
        :param accept_hooks: Accept pre and post hooks if set to `True`.
        :param keep_project_on_failure: If `True` keep generated project directory even when
            generation fails
        """
>       template_dir = find_template(repo_dir)
E       TypeError: find_template() missing 1 required positional argument: 'env'

cookiecutter/generate.py:225: TypeError

test_generate_hooks.py::test_run_failing_hook_preserves_existing_output_directory

test_generate_hooks.py::test_run_failing_hook_preserves_existing_output_directory
@pytest.mark.usefixtures('clean_system', 'remove_additional_folders')
    def test_run_failing_hook_preserves_existing_output_directory():
        """Verify project directory not removed if exist before hook failed."""
        repo_path = os.path.abspath('tests/test-hooks/')
        hooks_path = os.path.abspath('tests/test-hooks/hooks')

        hook_dir = os.path.join(repo_path, 'hooks')
        template = os.path.join(repo_path, 'input{{cookiecutter.hooks}}')
        os.mkdir(repo_path)
        os.mkdir(hook_dir)
        os.mkdir(template)

        hook_path = os.path.join(hooks_path, 'pre_gen_project.py')

        with Path(hook_path).open('w') as f:
            f.write("#!/usr/bin/env python\n")
            f.write("import sys; sys.exit(1)\n")

        os.mkdir('inputhooks')
        with pytest.raises(FailedHookException) as excinfo:
>           generate.generate_files(
                context={'cookiecutter': {'hooks': 'hooks'}},
                repo_dir='tests/test-hooks/',
                overwrite_if_exists=True,
            )

tests/test_generate_hooks.py:163: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

repo_dir = 'tests/test-hooks/', context = {'cookiecutter': {'hooks': 'hooks'}}
output_dir = '.', overwrite_if_exists = True, skip_if_file_exists = False
accept_hooks = True, keep_project_on_failure = False

    def generate_files(repo_dir, context=None, output_dir='.',
        overwrite_if_exists=False, skip_if_file_exists=False, accept_hooks=True,
        keep_project_on_failure=False):
        """Render the templates and saves them to files.

        :param repo_dir: Project template input directory.
        :param context: Dict for populating the template's variables.
        :param output_dir: Where to output the generated project dir into.
        :param overwrite_if_exists: Overwrite the contents of the output directory
            if it exists.
        :param skip_if_file_exists: Skip the files in the corresponding directories
            if they already exist
        :param accept_hooks: Accept pre and post hooks if set to `True`.
        :param keep_project_on_failure: If `True` keep generated project directory even when
            generation fails
        """
>       template_dir = find_template(repo_dir)
E       TypeError: find_template() missing 1 required positional argument: 'env'

cookiecutter/generate.py:225: TypeError

test_generate_hooks.py::test_run_shell_hooks

test_generate_hooks.py::test_run_shell_hooks
tmp_path = PosixPath('/tmp/pytest-of-root/pytest-0/test_run_shell_hooks0')

    @pytest.mark.skipif(sys.platform.startswith('win'), reason="Linux only test")
    @pytest.mark.usefixtures('clean_system', 'remove_additional_folders')
    def test_run_shell_hooks(tmp_path):
        """Verify pre and post generate project shell hooks executed.

        This test for .sh files.
        """
>       generate.generate_files(
            context={'cookiecutter': {'shellhooks': 'shellhooks'}},
            repo_dir='tests/test-shellhooks/',
            output_dir=tmp_path.joinpath('test-shellhooks'),
        )

tests/test_generate_hooks.py:180: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

repo_dir = 'tests/test-shellhooks/'
context = {'cookiecutter': {'shellhooks': 'shellhooks'}}
output_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_run_shell_hooks0/test-shellhooks')
overwrite_if_exists = False, skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False

    def generate_files(repo_dir, context=None, output_dir='.',
        overwrite_if_exists=False, skip_if_file_exists=False, accept_hooks=True,
        keep_project_on_failure=False):
        """Render the templates and saves them to files.

        :param repo_dir: Project template input directory.
        :param context: Dict for populating the template's variables.
        :param output_dir: Where to output the generated project dir into.
        :param overwrite_if_exists: Overwrite the contents of the output directory
            if it exists.
        :param skip_if_file_exists: Skip the files in the corresponding directories
            if they already exist
        :param accept_hooks: Accept pre and post hooks if set to `True`.
        :param keep_project_on_failure: If `True` keep generated project directory even when
            generation fails
        """
>       template_dir = find_template(repo_dir)
E       TypeError: find_template() missing 1 required positional argument: 'env'

cookiecutter/generate.py:225: TypeError

test_generate_hooks.py::test_ignore_shell_hooks

test_generate_hooks.py::test_ignore_shell_hooks
tmp_path = PosixPath('/tmp/pytest-of-root/pytest-0/test_ignore_shell_hooks0')

    @pytest.mark.usefixtures("clean_system", "remove_additional_folders")
    def test_ignore_shell_hooks(tmp_path):
        """Verify *.txt files not created, when accept_hooks=False."""
>       generate.generate_files(
            context={"cookiecutter": {"shellhooks": "shellhooks"}},
            repo_dir="tests/test-shellhooks/",
            output_dir=tmp_path.joinpath('test-shellhooks'),
            accept_hooks=False,
        )

tests/test_generate_hooks.py:220: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

repo_dir = 'tests/test-shellhooks/'
context = {'cookiecutter': {'shellhooks': 'shellhooks'}}
output_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_ignore_shell_hooks0/test-shellhooks')
overwrite_if_exists = False, skip_if_file_exists = False, accept_hooks = False
keep_project_on_failure = False

    def generate_files(repo_dir, context=None, output_dir='.',
        overwrite_if_exists=False, skip_if_file_exists=False, accept_hooks=True,
        keep_project_on_failure=False):
        """Render the templates and saves them to files.

        :param repo_dir: Project template input directory.
        :param context: Dict for populating the template's variables.
        :param output_dir: Where to output the generated project dir into.
        :param overwrite_if_exists: Overwrite the contents of the output directory
            if it exists.
        :param skip_if_file_exists: Skip the files in the corresponding directories
            if they already exist
        :param accept_hooks: Accept pre and post hooks if set to `True`.
        :param keep_project_on_failure: If `True` keep generated project directory even when
            generation fails
        """
>       template_dir = find_template(repo_dir)
E       TypeError: find_template() missing 1 required positional argument: 'env'

cookiecutter/generate.py:225: TypeError

test_generate_hooks.py::test_deprecate_run_hook_from_repo_dir

test_generate_hooks.py::test_deprecate_run_hook_from_repo_dir
repo_dir = 'tests/test-shellhooks/', hook_name = 'pre_gen_project'
project_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_deprecate_run_hook_from_r0/test-shellhooks')
context = {}, delete_project_on_failure = False

    def _run_hook_from_repo_dir(repo_dir, hook_name, project_dir, context,
        delete_project_on_failure):
        """Run hook from repo directory, clean project directory if hook fails.

        :param repo_dir: Project template input directory.
        :param hook_name: The hook to execute.
        :param project_dir: The directory to execute the script from.
        :param context: Cookiecutter project context.
        :param delete_project_on_failure: Delete the project directory on hook
            failure?
        """
        with work_in(repo_dir):
            try:
>               run_hook_from_repo_dir(
                    repo_dir=repo_dir,
                    hook_name=hook_name,
                    project_dir=project_dir,
                    context=context
                )
E               TypeError: run_hook_from_repo_dir() missing 1 required positional argument: 'delete_project_on_failure'

cookiecutter/generate.py:182: TypeError

During handling of the above exception, another exception occurred:

tmp_path = PosixPath('/tmp/pytest-of-root/pytest-0/test_deprecate_run_hook_from_r0')

    @pytest.mark.usefixtures("clean_system", "remove_additional_folders")
    def test_deprecate_run_hook_from_repo_dir(tmp_path):
        """Test deprecation warning in generate._run_hook_from_repo_dir."""
        repo_dir = "tests/test-shellhooks/"
        project_dir = Path(tmp_path.joinpath('test-shellhooks'))
        project_dir.mkdir()
        with pytest.deprecated_call():
>           generate._run_hook_from_repo_dir(
                repo_dir=repo_dir,
                hook_name="pre_gen_project",
                project_dir=project_dir,
                context={},
                delete_project_on_failure=False,
            )

tests/test_generate_hooks.py:241: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

repo_dir = 'tests/test-shellhooks/', hook_name = 'pre_gen_project'
project_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_deprecate_run_hook_from_r0/test-shellhooks')
context = {}, delete_project_on_failure = False

    def _run_hook_from_repo_dir(repo_dir, hook_name, project_dir, context,
        delete_project_on_failure):
        """Run hook from repo directory, clean project directory if hook fails.

        :param repo_dir: Project template input directory.
        :param hook_name: The hook to execute.
        :param project_dir: The directory to execute the script from.
        :param context: Cookiecutter project context.
        :param delete_project_on_failure: Delete the project directory on hook
            failure?
        """
        with work_in(repo_dir):
            try:
                run_hook_from_repo_dir(
                    repo_dir=repo_dir,
                    hook_name=hook_name,
                    project_dir=project_dir,
                    context=context
                )
>           except FailedHookException:
E           NameError: name 'FailedHookException' is not defined

cookiecutter/generate.py:188: NameError

During handling of the above exception, another exception occurred:

tmp_path = PosixPath('/tmp/pytest-of-root/pytest-0/test_deprecate_run_hook_from_r0')

    @pytest.mark.usefixtures("clean_system", "remove_additional_folders")
    def test_deprecate_run_hook_from_repo_dir(tmp_path):
        """Test deprecation warning in generate._run_hook_from_repo_dir."""
        repo_dir = "tests/test-shellhooks/"
        project_dir = Path(tmp_path.joinpath('test-shellhooks'))
        project_dir.mkdir()
>       with pytest.deprecated_call():
E       Failed: DID NOT WARN. No warnings of type (, , ) were emitted.
E        Emitted warnings: [].

tests/test_generate_hooks.py:240: Failed

test_get_config.py::test_get_config

test_get_config.py::test_get_config
def test_get_config():
        """Verify valid config opened and rendered correctly."""
        conf = config.get_config('tests/test-config/valid-config.yaml')
        expected_conf = {
            'cookiecutters_dir': '/home/example/some-path-to-templates',
            'replay_dir': '/home/example/some-path-to-replay-files',
            'default_context': {
                'full_name': 'Firstname Lastname',
                'email': 'firstname.lastname@gmail.com',
                'github_username': 'example',
                'project': {
                    'description': 'description',
                    'tags': [
                        'first',
                        'second',
                        'third',
                    ],
                },
            },
            'abbreviations': {
                'gh': 'https://github.com/{0}.git',
                'gl': 'https://gitlab.com/{0}.git',
                'bb': 'https://bitbucket.org/{0}',
                'helloworld': 'https://github.com/hackebrot/helloworld',
            },
        }
>       assert conf == expected_conf
E       AssertionError: assert {'default_context': {'full_name': 'Firstname Lastname', 'email': 'firstname.lastname@gmail.com', 'github_username': 'example', 'project': {'description': 'description', 'tags': ['first', 'second', 'third']}}, 'cookiecutters_dir': '/home/example/some-path-to-templates', 'replay_dir': '/home/example/some-path-to-replay-files', 'abbreviations': {'helloworld': 'https://github.com/hackebrot/helloworld'}} == {'cookiecutters_dir': '/home/example/some-path-to-templates', 'replay_dir': '/home/example/some-path-to-replay-files', 'default_context': {'full_name': 'Firstname Lastname', 'email': 'firstname.lastname@gmail.com', 'github_username': 'example', 'project': {'description': 'description', 'tags': ['first', 'second', 'third']}}, 'abbreviations': {'gh': 'https://github.com/{0}.git', 'gl': 'https://gitlab.com/{0}.git', 'bb': 'https://bitbucket.org/{0}', 'helloworld': 'https://github.com/hackebrot/helloworld'}}
E         
E         Common items:
E         {'cookiecutters_dir': '/home/example/some-path-to-templates',
E          'default_context': {'email': 'firstname.lastname@gmail.com',
E                              'full_name': 'Firstname Lastname',
E                              'github_username': 'example',
E                              'project': {'description': 'description',
E                                          'tags': ['first', 'second', 'third']}},
E          'replay_dir': '/home/example/some-path-to-replay-files'}
E         Differing items:
E         {'abbreviations': {'helloworld': 'https://github.com/hackebrot/helloworld'}} != {'abbreviations': {'bb': 'https://bitbucket.org/{0}', 'gh': 'https://github.com/{0}.git', 'gl': 'https://gitlab.com/{0}.git', 'helloworld': 'https://github.com/hackebrot/helloworld'}}
E         
E         Full diff:
E           {
E               'abbreviations': {
E         -         'bb': 'https://bitbucket.org/{0}',
E         -         'gh': 'https://github.com/{0}.git',
E         -         'gl': 'https://gitlab.com/{0}.git',
E                   'helloworld': 'https://github.com/hackebrot/helloworld',
E               },
E               'cookiecutters_dir': '/home/example/some-path-to-templates',
E               'default_context': {
E                   'email': 'firstname.lastname@gmail.com',
E                   'full_name': 'Firstname Lastname',
E                   'github_username': 'example',
E                   'project': {
E                       'description': 'description',
E                       'tags': [
E                           'first',
E                           'second',
E                           'third',
E                       ],
E                   },
E               },
E               'replay_dir': '/home/example/some-path-to-replay-files',
E           }

tests/test_get_config.py:80: AssertionError

test_get_config.py::test_get_config_with_defaults

test_get_config.py::test_get_config_with_defaults
def test_get_config_with_defaults():
        """A config file that overrides 1 of 3 defaults."""
        conf = config.get_config('tests/test-config/valid-partial-config.yaml')
        default_cookiecutters_dir = Path('~/.cookiecutters').expanduser()
        default_replay_dir = Path('~/.cookiecutter_replay').expanduser()
        expected_conf = {
            'cookiecutters_dir': str(default_cookiecutters_dir),
            'replay_dir': str(default_replay_dir),
            'default_context': {
                'full_name': 'Firstname Lastname',
                'email': 'firstname.lastname@gmail.com',
                'github_username': 'example',
            },
            'abbreviations': {
                'gh': 'https://github.com/{0}.git',
                'gl': 'https://gitlab.com/{0}.git',
                'bb': 'https://bitbucket.org/{0}',
            },
        }
>       assert conf == expected_conf
E       AssertionError: assert {'default_context': {'full_name': 'Firstname Lastname', 'email': 'firstname.lastname@gmail.com', 'github_username': 'example'}} == {'cookiecutters_dir': '/tmp/pytest-of-root/pytest-0/test_get_config_with_defaults0/home/.cookiecutters', 'replay_dir': '/tmp/pytest-of-root/pytest-0/test_get_config_with_defaults0/home/.cookiecutter_replay', 'default_context': {'full_name': 'Firstname Lastname', 'email': 'firstname.lastname@gmail.com', 'github_username': 'example'}, 'abbreviations': {'gh': 'https://github.com/{0}.git', 'gl': 'https://gitlab.com/{0}.git', 'bb': 'https://bitbucket.org/{0}'}}
E         
E         Common items:
E         {'default_context': {'email': 'firstname.lastname@gmail.com',
E                              'full_name': 'Firstname Lastname',
E                              'github_username': 'example'}}
E         Right contains 3 more items:
E         {'abbreviations': {'bb': 'https://bitbucket.org/{0}',
E                            'gh': 'https://github.com/{0}.git',
E                            'gl': 'https://gitlab.com/{0}.git'},
E          'cookiecutters_dir': '/tmp/pytest-of-root/pytest-0/test_get_config_with_defaults0/home/.cookiecutters',
E          'replay_dir': '/tmp/pytest-of-root/pytest-0/test_get_config_with_defaults0/home/.cookiecutter_replay'}
E         
E         Full diff:
E           {
E         -     'abbreviations': {
E         -         'bb': 'https://bitbucket.org/{0}',
E         -         'gh': 'https://github.com/{0}.git',
E         -         'gl': 'https://gitlab.com/{0}.git',
E         -     },
E         -     'cookiecutters_dir': '/tmp/pytest-of-root/pytest-0/test_get_config_with_defaults0/home/.cookiecutters',
E               'default_context': {
E                   'email': 'firstname.lastname@gmail.com',
E                   'full_name': 'Firstname Lastname',
E                   'github_username': 'example',
E               },
E         -     'replay_dir': '/tmp/pytest-of-root/pytest-0/test_get_config_with_defaults0/home/.cookiecutter_replay',
E           }

tests/test_get_config.py:123: AssertionError

test_get_config.py::test_get_config_empty_config_file

test_get_config.py::test_get_config_empty_config_file
def test_get_config_empty_config_file():
        """An empty config file results in the default config."""
>       conf = config.get_config('tests/test-config/empty-config.yaml')

tests/test_get_config.py:128: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

config_path = 'tests/test-config/empty-config.yaml'

    def get_config(config_path):
        """Retrieve the config from the specified path, returning a config dict."""
        if not os.path.exists(config_path):
            raise ConfigDoesNotExistException(f"Config file {config_path} does not exist.")

        with open(config_path) as file_handle:
            try:
                user_config = yaml.safe_load(file_handle)
            except yaml.YAMLError as e:
                raise InvalidConfiguration(f"Unable to parse YAML file {config_path}: {e}")

        if user_config is None:
>           raise InvalidConfiguration(f"Config file {config_path} is empty.")
E           cookiecutter.exceptions.InvalidConfiguration: Config file tests/test-config/empty-config.yaml is empty.

cookiecutter/config.py:50: InvalidConfiguration

test_get_config.py::test_get_config_invalid_file_with_array_as_top_level_element

test_get_config.py::test_get_config_invalid_file_with_array_as_top_level_element
def test_get_config_invalid_file_with_array_as_top_level_element():
        """An exception should be raised if top-level element is array."""
        expected_error_msg = (
            'Top-level element of YAML file '
            'tests/test-config/invalid-config-w-array.yaml should be an object.'
        )
>       with pytest.raises(InvalidConfiguration) as exc_info:
E       Failed: DID NOT RAISE 

tests/test_get_config.py:138: Failed

test_get_config.py::test_get_config_invalid_file_with_multiple_docs

test_get_config.py::test_get_config_invalid_file_with_multiple_docs
def test_get_config_invalid_file_with_multiple_docs():
        """An exception should be raised if config file contains multiple docs."""
        expected_error_msg = (
            'Unable to parse YAML file '
            'tests/test-config/invalid-config-w-multiple-docs.yaml.'
        )
        with pytest.raises(InvalidConfiguration) as exc_info:
            config.get_config('tests/test-config/invalid-config-w-multiple-docs.yaml')
>       assert expected_error_msg in str(exc_info.value)
E       assert 'Unable to parse YAML file tests/test-config/invalid-config-w-multiple-docs.yaml.' in 'Unable to parse YAML file tests/test-config/invalid-config-w-multiple-docs.yaml: expected a single document in the stream\n  in "tests/test-config/invalid-config-w-multiple-docs.yaml", line 2, column 1\nbut found another document\n  in "tests/test-config/invalid-config-w-multiple-docs.yaml", line 12, column 1'
E        +  where 'Unable to parse YAML file tests/test-config/invalid-config-w-multiple-docs.yaml: expected a single document in the stream\n  in "tests/test-config/invalid-config-w-multiple-docs.yaml", line 2, column 1\nbut found another document\n  in "tests/test-config/invalid-config-w-multiple-docs.yaml", line 12, column 1' = str(InvalidConfiguration('Unable to parse YAML file tests/test-config/invalid-config-w-multiple-docs.yaml: expected a single document in the stream\n  in "tests/test-config/invalid-config-w-multiple-docs.yaml", line 2, column 1\nbut found another document\n  in "tests/test-config/invalid-config-w-multiple-docs.yaml", line 12, column 1'))
E        +    where InvalidConfiguration('Unable to parse YAML file tests/test-config/invalid-config-w-multiple-docs.yaml: expected a single document in the stream\n  in "tests/test-config/invalid-config-w-multiple-docs.yaml", line 2, column 1\nbut found another document\n  in "tests/test-config/invalid-config-w-multiple-docs.yaml", line 12, column 1') = .value

tests/test_get_config.py:151: AssertionError

test_get_user_config.py::test_get_user_config_valid

test_get_user_config.py::test_get_user_config_valid
user_config_path = '/root/.cookiecutterrc'
custom_config = {'abbreviations': {'bb': 'https://bitbucket.org/{0}', 'gh': 'https://github.com/{0}.git', 'gl': 'https://gitlab.com/{0}.git', 'helloworld': 'https://github.com/hackebrot/helloworld'}, 'cookiecutters_dir': '/home/example/some-path-to-templates', 'default_context': {'email': 'firstname.lastname@gmail.com', 'full_name': 'Firstname Lastname', 'github_username': 'example', 'project': {'description': 'description', 'tags': ['first', 'second', 'third']}}, 'replay_dir': '/home/example/some-path-to-replay-files'}

    @pytest.mark.usefixtures('back_up_rc')
    def test_get_user_config_valid(user_config_path, custom_config):
        """Validate user config correctly parsed if exist and correctly formatted."""
        shutil.copy('tests/test-config/valid-config.yaml', user_config_path)
        conf = config.get_user_config()

>       assert conf == custom_config
E       AssertionError: assert {'default_context': {'full_name': 'Firstname Lastname', 'email': 'firstname.lastname@gmail.com', 'github_username': 'example', 'project': {'description': 'description', 'tags': ['first', 'second', 'third']}}, 'cookiecutters_dir': '/home/example/some-path-to-templates', 'replay_dir': '/home/example/some-path-to-replay-files', 'abbreviations': {'helloworld': 'https://github.com/hackebrot/helloworld'}} == {'default_context': {'full_name': 'Firstname Lastname', 'email': 'firstname.lastname@gmail.com', 'github_username': 'example', 'project': {'description': 'description', 'tags': ['first', 'second', 'third']}}, 'cookiecutters_dir': '/home/example/some-path-to-templates', 'replay_dir': '/home/example/some-path-to-replay-files', 'abbreviations': {'gh': 'https://github.com/{0}.git', 'gl': 'https://gitlab.com/{0}.git', 'bb': 'https://bitbucket.org/{0}', 'helloworld': 'https://github.com/hackebrot/helloworld'}}
E         
E         Common items:
E         {'cookiecutters_dir': '/home/example/some-path-to-templates',
E          'default_context': {'email': 'firstname.lastname@gmail.com',
E                              'full_name': 'Firstname Lastname',
E                              'github_username': 'example',
E                              'project': {'description': 'description',
E                                          'tags': ['first', 'second', 'third']}},
E          'replay_dir': '/home/example/some-path-to-replay-files'}
E         Differing items:
E         {'abbreviations': {'helloworld': 'https://github.com/hackebrot/helloworld'}} != {'abbreviations': {'bb': 'https://bitbucket.org/{0}', 'gh': 'https://github.com/{0}.git', 'gl': 'https://gitlab.com/{0}.git', 'helloworld': 'https://github.com/hackebrot/helloworld'}}
E         
E         Full diff:
E           {
E               'abbreviations': {
E         -         'bb': 'https://bitbucket.org/{0}',
E         -         'gh': 'https://github.com/{0}.git',
E         -         'gl': 'https://gitlab.com/{0}.git',
E                   'helloworld': 'https://github.com/hackebrot/helloworld',
E               },
E               'cookiecutters_dir': '/home/example/some-path-to-templates',
E               'default_context': {
E                   'email': 'firstname.lastname@gmail.com',
E                   'full_name': 'Firstname Lastname',
E                   'github_username': 'example',
E                   'project': {
E                       'description': 'description',
E                       'tags': [
E                           'first',
E                           'second',
E                           'third',
E                       ],
E                   },
E               },
E               'replay_dir': '/home/example/some-path-to-replay-files',
E           }

tests/test_get_user_config.py:76: AssertionError

test_get_user_config.py::test_specify_config_path

test_get_user_config.py::test_specify_config_path
mocker = 
custom_config_path = 'tests/test-config/valid-config.yaml'
custom_config = {'abbreviations': {'bb': 'https://bitbucket.org/{0}', 'gh': 'https://github.com/{0}.git', 'gl': 'https://gitlab.com/{0}.git', 'helloworld': 'https://github.com/hackebrot/helloworld'}, 'cookiecutters_dir': '/home/example/some-path-to-templates', 'default_context': {'email': 'firstname.lastname@gmail.com', 'full_name': 'Firstname Lastname', 'github_username': 'example', 'project': {'description': 'description', 'tags': ['first', 'second', 'third']}}, 'replay_dir': '/home/example/some-path-to-replay-files'}

    def test_specify_config_path(mocker, custom_config_path, custom_config):
        """Validate provided custom config path should be respected and parsed."""
        spy_get_config = mocker.spy(config, 'get_config')

        user_config = config.get_user_config(custom_config_path)
        spy_get_config.assert_called_once_with(custom_config_path)

>       assert user_config == custom_config
E       AssertionError: assert {'default_context': {'full_name': 'Firstname Lastname', 'email': 'firstname.lastname@gmail.com', 'github_username': 'example', 'project': {'description': 'description', 'tags': ['first', 'second', 'third']}}, 'cookiecutters_dir': '/home/example/some-path-to-templates', 'replay_dir': '/home/example/some-path-to-replay-files', 'abbreviations': {'helloworld': 'https://github.com/hackebrot/helloworld'}} == {'default_context': {'full_name': 'Firstname Lastname', 'email': 'firstname.lastname@gmail.com', 'github_username': 'example', 'project': {'description': 'description', 'tags': ['first', 'second', 'third']}}, 'cookiecutters_dir': '/home/example/some-path-to-templates', 'replay_dir': '/home/example/some-path-to-replay-files', 'abbreviations': {'gh': 'https://github.com/{0}.git', 'gl': 'https://gitlab.com/{0}.git', 'bb': 'https://bitbucket.org/{0}', 'helloworld': 'https://github.com/hackebrot/helloworld'}}
E         
E         Common items:
E         {'cookiecutters_dir': '/home/example/some-path-to-templates',
E          'default_context': {'email': 'firstname.lastname@gmail.com',
E                              'full_name': 'Firstname Lastname',
E                              'github_username': 'example',
E                              'project': {'description': 'description',
E                                          'tags': ['first', 'second', 'third']}},
E          'replay_dir': '/home/example/some-path-to-replay-files'}
E         Differing items:
E         {'abbreviations': {'helloworld': 'https://github.com/hackebrot/helloworld'}} != {'abbreviations': {'bb': 'https://bitbucket.org/{0}', 'gh': 'https://github.com/{0}.git', 'gl': 'https://gitlab.com/{0}.git', 'helloworld': 'https://github.com/hackebrot/helloworld'}}
E         
E         Full diff:
E           {
E               'abbreviations': {
E         -         'bb': 'https://bitbucket.org/{0}',
E         -         'gh': 'https://github.com/{0}.git',
E         -         'gl': 'https://gitlab.com/{0}.git',
E                   'helloworld': 'https://github.com/hackebrot/helloworld',
E               },
E               'cookiecutters_dir': '/home/example/some-path-to-templates',
E               'default_context': {
E                   'email': 'firstname.lastname@gmail.com',
E                   'full_name': 'Firstname Lastname',
E                   'github_username': 'example',
E                   'project': {
E                       'description': 'description',
E                       'tags': [
E                           'first',
E                           'second',
E                           'third',
E                       ],
E                   },
E               },
E               'replay_dir': '/home/example/some-path-to-replay-files',
E           }

tests/test_get_user_config.py:106: AssertionError

test_get_user_config.py::test_default_config_from_env_variable

test_get_user_config.py::test_default_config_from_env_variable
monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0x7fcb91e982b0>
custom_config_path = 'tests/test-config/valid-config.yaml'
custom_config = {'abbreviations': {'bb': 'https://bitbucket.org/{0}', 'gh': 'https://github.com/{0}.git', 'gl': 'https://gitlab.com/{0}.git', 'helloworld': 'https://github.com/hackebrot/helloworld'}, 'cookiecutters_dir': '/home/example/some-path-to-templates', 'default_context': {'email': 'firstname.lastname@gmail.com', 'full_name': 'Firstname Lastname', 'github_username': 'example', 'project': {'description': 'description', 'tags': ['first', 'second', 'third']}}, 'replay_dir': '/home/example/some-path-to-replay-files'}

    def test_default_config_from_env_variable(
        monkeypatch, custom_config_path, custom_config
    ):
        """Validate app configuration. User config path should be parsed from sys env."""
        monkeypatch.setenv('COOKIECUTTER_CONFIG', custom_config_path)

        user_config = config.get_user_config()
>       assert user_config == custom_config
E       AssertionError: assert {'default_context': {'full_name': 'Firstname Lastname', 'email': 'firstname.lastname@gmail.com', 'github_username': 'example', 'project': {'description': 'description', 'tags': ['first', 'second', 'third']}}, 'cookiecutters_dir': '/home/example/some-path-to-templates', 'replay_dir': '/home/example/some-path-to-replay-files', 'abbreviations': {'helloworld': 'https://github.com/hackebrot/helloworld'}} == {'default_context': {'full_name': 'Firstname Lastname', 'email': 'firstname.lastname@gmail.com', 'github_username': 'example', 'project': {'description': 'description', 'tags': ['first', 'second', 'third']}}, 'cookiecutters_dir': '/home/example/some-path-to-templates', 'replay_dir': '/home/example/some-path-to-replay-files', 'abbreviations': {'gh': 'https://github.com/{0}.git', 'gl': 'https://gitlab.com/{0}.git', 'bb': 'https://bitbucket.org/{0}', 'helloworld': 'https://github.com/hackebrot/helloworld'}}
E         
E         Common items:
E         {'cookiecutters_dir': '/home/example/some-path-to-templates',
E          'default_context': {'email': 'firstname.lastname@gmail.com',
E                              'full_name': 'Firstname Lastname',
E                              'github_username': 'example',
E                              'project': {'description': 'description',
E                                          'tags': ['first', 'second', 'third']}},
E          'replay_dir': '/home/example/some-path-to-replay-files'}
E         Differing items:
E         {'abbreviations': {'helloworld': 'https://github.com/hackebrot/helloworld'}} != {'abbreviations': {'bb': 'https://bitbucket.org/{0}', 'gh': 'https://github.com/{0}.git', 'gl': 'https://gitlab.com/{0}.git', 'helloworld': 'https://github.com/hackebrot/helloworld'}}
E         
E         Full diff:
E           {
E               'abbreviations': {
E         -         'bb': 'https://bitbucket.org/{0}',
E         -         'gh': 'https://github.com/{0}.git',
E         -         'gl': 'https://gitlab.com/{0}.git',
E                   'helloworld': 'https://github.com/hackebrot/helloworld',
E               },
E               'cookiecutters_dir': '/home/example/some-path-to-templates',
E               'default_context': {
E                   'email': 'firstname.lastname@gmail.com',
E                   'full_name': 'Firstname Lastname',
E                   'github_username': 'example',
E                   'project': {
E                       'description': 'description',
E                       'tags': [
E                           'first',
E                           'second',
E                           'third',
E                       ],
E                   },
E               },
E               'replay_dir': '/home/example/some-path-to-replay-files',
E           }

tests/test_get_user_config.py:121: AssertionError

test_get_user_config.py::test_expand_user_for_directories_in_config

test_get_user_config.py::test_expand_user_for_directories_in_config
monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0x7fcb92574e20>

    def test_expand_user_for_directories_in_config(monkeypatch):
        """Validate user pointers expanded in user configs."""

        def _expanduser(path):
            return path.replace('~', 'Users/bob')

        monkeypatch.setattr('os.path.expanduser', _expanduser)

        config_file = 'tests/test-config/config-expand-user.yaml'

        user_config = config.get_user_config(config_file)
>       assert user_config['replay_dir'] == 'Users/bob/replay-files'
E       AssertionError: assert '~/replay-files' == 'Users/bob/replay-files'
E         
E         - Users/bob/replay-files
E         + ~/replay-files

tests/test_get_user_config.py:145: AssertionError

test_get_user_config.py::test_expand_vars_for_directories_in_config

test_get_user_config.py::test_expand_vars_for_directories_in_config
monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0x7fcb922299f0>

    def test_expand_vars_for_directories_in_config(monkeypatch):
        """Validate environment variables expanded in user configs."""
        monkeypatch.setenv('COOKIES', 'Users/bob/cookies')

        config_file = 'tests/test-config/config-expand-vars.yaml'

        user_config = config.get_user_config(config_file)
>       assert user_config['replay_dir'] == 'Users/bob/cookies/replay-files'
E       AssertionError: assert '$COOKIES/replay-files' == 'Users/bob/cookies/replay-files'
E         
E         - Users/bob/cookies/replay-files
E         + $COOKIES/replay-files

tests/test_get_user_config.py:156: AssertionError

test_hooks.py::TestFindHooks::test_find_hook

test_hooks.py::TestFindHooks::test_find_hook
self = 

    def test_find_hook(self):
        """Finds the specified hook."""
        with utils.work_in(self.repo_path):
            expected_pre = os.path.abspath('hooks/pre_gen_project.py')
            actual_hook_path = hooks.find_hook('pre_gen_project')
>           assert expected_pre == actual_hook_path[0]
E           AssertionError: assert '/testbed/tests/test-hooks/hooks/pre_gen_project.py' == '/'
E             
E             - /
E             + /testbed/tests/test-hooks/hooks/pre_gen_project.py

tests/test_hooks.py:93: AssertionError

test_hooks.py::TestExternalHooks::test_run_failing_script

test_hooks.py::TestExternalHooks::test_run_failing_script
self = 
mocker = 

    def test_run_failing_script(self, mocker):
        """Test correct exception raise if run_script fails."""
        err = OSError()

        prompt = mocker.patch('subprocess.Popen')
        prompt.side_effect = err

        with pytest.raises(exceptions.FailedHookException) as excinfo:
>           hooks.run_script(os.path.join(self.hooks_path, self.post_hook))

tests/test_hooks.py:157: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
cookiecutter/hooks.py:65: in run_script
    subprocess.check_call([script_path], cwd=cwd)
/usr/lib/python3.10/subprocess.py:364: in check_call
    retcode = call(*popenargs, **kwargs)
/usr/lib/python3.10/subprocess.py:345: in call
    with Popen(*popenargs, **kwargs) as p:
/usr/lib/python3.10/unittest/mock.py:1114: in __call__
    return self._mock_call(*args, **kwargs)
/usr/lib/python3.10/unittest/mock.py:1118: in _mock_call
    return self._execute_mock_call(*args, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = 
args = (['/testbed/tests/test-hooks/hooks/post_gen_project.sh'],)
kwargs = {'cwd': '.'}, effect = OSError()

    def _execute_mock_call(self, /, *args, **kwargs):
        # separate from _increment_mock_call so that awaited functions are
        # executed separately from their call, also AsyncMock overrides this method

        effect = self.side_effect
        if effect is not None:
            if _is_exception(effect):
>               raise effect
E               OSError

/usr/lib/python3.10/unittest/mock.py:1173: OSError

test_hooks.py::TestExternalHooks::test_run_failing_script_enoexec

test_hooks.py::TestExternalHooks::test_run_failing_script_enoexec
self = 
mocker = 

    def test_run_failing_script_enoexec(self, mocker):
        """Test correct exception raise if run_script fails."""
        err = OSError()
        err.errno = errno.ENOEXEC

        prompt = mocker.patch('subprocess.Popen')
        prompt.side_effect = err

        with pytest.raises(exceptions.FailedHookException) as excinfo:
>           hooks.run_script(os.path.join(self.hooks_path, self.post_hook))

tests/test_hooks.py:169: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
cookiecutter/hooks.py:65: in run_script
    subprocess.check_call([script_path], cwd=cwd)
/usr/lib/python3.10/subprocess.py:364: in check_call
    retcode = call(*popenargs, **kwargs)
/usr/lib/python3.10/subprocess.py:345: in call
    with Popen(*popenargs, **kwargs) as p:
/usr/lib/python3.10/unittest/mock.py:1114: in __call__
    return self._mock_call(*args, **kwargs)
/usr/lib/python3.10/unittest/mock.py:1118: in _mock_call
    return self._execute_mock_call(*args, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = 
args = (['/testbed/tests/test-hooks/hooks/post_gen_project.sh'],)
kwargs = {'cwd': '.'}, effect = OSError()

    def _execute_mock_call(self, /, *args, **kwargs):
        # separate from _increment_mock_call so that awaited functions are
        # executed separately from their call, also AsyncMock overrides this method

        effect = self.side_effect
        if effect is not None:
            if _is_exception(effect):
>               raise effect
E               OSError

/usr/lib/python3.10/unittest/mock.py:1173: OSError

test_hooks.py::TestExternalHooks::test_run_script_cwd

test_hooks.py::TestExternalHooks::test_run_script_cwd
self = 

    def test_run_script_cwd(self):
        """Change directory before running hook."""
>       hooks.run_script(os.path.join(self.hooks_path, self.post_hook), 'tests')

tests/test_hooks.py:176: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
cookiecutter/hooks.py:65: in run_script
    subprocess.check_call([script_path], cwd=cwd)
/usr/lib/python3.10/subprocess.py:364: in check_call
    retcode = call(*popenargs, **kwargs)
/usr/lib/python3.10/subprocess.py:345: in call
    with Popen(*popenargs, **kwargs) as p:
/usr/lib/python3.10/subprocess.py:971: in __init__
    self._execute_child(args, executable, preexec_fn, close_fds,
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = 
args = ['/testbed/tests/test-hooks/hooks/post_gen_project.sh']
executable = b'/testbed/tests/test-hooks/hooks/post_gen_project.sh'
preexec_fn = None, close_fds = True, pass_fds = (), cwd = 'tests', env = None
startupinfo = None, creationflags = 0, shell = False, p2cread = -1
p2cwrite = -1, c2pread = -1, c2pwrite = -1, errread = -1, errwrite = -1
restore_signals = True, gid = None, gids = None, uid = None, umask = -1
start_new_session = False

    def _execute_child(self, args, executable, preexec_fn, close_fds,
                       pass_fds, cwd, env,
                       startupinfo, creationflags, shell,
                       p2cread, p2cwrite,
                       c2pread, c2pwrite,
                       errread, errwrite,
                       restore_signals,
                       gid, gids, uid, umask,
                       start_new_session):
        """Execute program (POSIX version)"""

        if isinstance(args, (str, bytes)):
            args = [args]
        elif isinstance(args, os.PathLike):
            if shell:
                raise TypeError('path-like args is not allowed when '
                                'shell is true')
            args = [args]
        else:
            args = list(args)

        if shell:
            # On Android the default shell is at '/system/bin/sh'.
            unix_shell = ('/system/bin/sh' if
                      hasattr(sys, 'getandroidapilevel') else '/bin/sh')
            args = [unix_shell, "-c"] + args
            if executable:
                args[0] = executable

        if executable is None:
            executable = args[0]

        sys.audit("subprocess.Popen", executable, args, cwd, env)

        if (_USE_POSIX_SPAWN
                and os.path.dirname(executable)
                and preexec_fn is None
                and not close_fds
                and not pass_fds
                and cwd is None
                and (p2cread == -1 or p2cread > 2)
                and (c2pwrite == -1 or c2pwrite > 2)
                and (errwrite == -1 or errwrite > 2)
                and not start_new_session
                and gid is None
                and gids is None
                and uid is None
                and umask < 0):
            self._posix_spawn(args, executable, env, restore_signals,
                              p2cread, p2cwrite,
                              c2pread, c2pwrite,
                              errread, errwrite)
            return

        orig_executable = executable

        # For transferring possible exec failure from child to parent.
        # Data format: "exception name:hex errno:description"
        # Pickle is not used; it is complex and involves memory allocation.
        errpipe_read, errpipe_write = os.pipe()
        # errpipe_write must not be in the standard io 0, 1, or 2 fd range.
        low_fds_to_close = []
        while errpipe_write < 3:
            low_fds_to_close.append(errpipe_write)
            errpipe_write = os.dup(errpipe_write)
        for low_fd in low_fds_to_close:
            os.close(low_fd)
        try:
            try:
                # We must avoid complex work that could involve
                # malloc or free in the child process to avoid
                # potential deadlocks, thus we do all this here.
                # and pass it to fork_exec()

                if env is not None:
                    env_list = []
                    for k, v in env.items():
                        k = os.fsencode(k)
                        if b'=' in k:
                            raise ValueError("illegal environment variable name")
                        env_list.append(k + b'=' + os.fsencode(v))
                else:
                    env_list = None  # Use execv instead of execve.
                executable = os.fsencode(executable)
                if os.path.dirname(executable):
                    executable_list = (executable,)
                else:
                    # This matches the behavior of os._execvpe().
                    executable_list = tuple(
                        os.path.join(os.fsencode(dir), executable)
                        for dir in os.get_exec_path(env))
                fds_to_keep = set(pass_fds)
                fds_to_keep.add(errpipe_write)
                self.pid = _posixsubprocess.fork_exec(
                        args, executable_list,
                        close_fds, tuple(sorted(map(int, fds_to_keep))),
                        cwd, env_list,
                        p2cread, p2cwrite, c2pread, c2pwrite,
                        errread, errwrite,
                        errpipe_read, errpipe_write,
                        restore_signals, start_new_session,
                        gid, gids, uid, umask,
                        preexec_fn)
                self._child_created = True
            finally:
                # be sure the FD is closed no matter what
                os.close(errpipe_write)

            self._close_pipe_fds(p2cread, p2cwrite,
                                 c2pread, c2pwrite,
                                 errread, errwrite)

            # Wait for exec to fail or succeed; possibly raising an
            # exception (limited in size)
            errpipe_data = bytearray()
            while True:
                part = os.read(errpipe_read, 50000)
                errpipe_data += part
                if not part or len(errpipe_data) > 50000:
                    break
        finally:
            # be sure the FD is closed no matter what
            os.close(errpipe_read)

        if errpipe_data:
            try:
                pid, sts = os.waitpid(self.pid, 0)
                if pid == self.pid:
                    self._handle_exitstatus(sts)
                else:
                    self.returncode = sys.maxsize
            except ChildProcessError:
                pass

            try:
                exception_name, hex_errno, err_msg = (
                        errpipe_data.split(b':', 2))
                # The encoding here should match the encoding
                # written in by the subprocess implementations
                # like _posixsubprocess
                err_msg = err_msg.decode()
            except ValueError:
                exception_name = b'SubprocessError'
                hex_errno = b'0'
                err_msg = 'Bad exception data from child: {!r}'.format(
                              bytes(errpipe_data))
            child_exception_type = getattr(
                    builtins, exception_name.decode('ascii'),
                    SubprocessError)
            if issubclass(child_exception_type, OSError) and hex_errno:
                errno_num = int(hex_errno, 16)
                child_exec_never_called = (err_msg == "noexec")
                if child_exec_never_called:
                    err_msg = ""
                    # The error must be from chdir(cwd).
                    err_filename = cwd
                else:
                    err_filename = orig_executable
                if errno_num != 0:
                    err_msg = os.strerror(errno_num)
>               raise child_exception_type(errno_num, err_msg, err_filename)
E               FileNotFoundError: [Errno 2] No such file or directory: 'tests'

/usr/lib/python3.10/subprocess.py:1863: FileNotFoundError

test_hooks.py::TestExternalHooks::test_run_script_with_context

test_hooks.py::TestExternalHooks::test_run_script_with_context
self = 

    def test_run_script_with_context(self):
        """Execute a hook script, passing a context."""
        hook_path = os.path.join(self.hooks_path, 'post_gen_project.sh')

        if sys.platform.startswith('win'):
            post = 'post_gen_project.bat'
            with Path(self.hooks_path, post).open('w') as f:
                f.write("@echo off\n")
                f.write("\n")
                f.write("echo post generation hook\n")
                f.write("echo. >{{cookiecutter.file}}\n")
        else:
            with Path(hook_path).open('w') as fh:
                fh.write("#!/bin/bash\n")
                fh.write("\n")
                fh.write("echo 'post generation hook';\n")
                fh.write("touch 'shell_post.txt'\n")
                fh.write("touch '{{cookiecutter.file}}'\n")
                os.chmod(hook_path, os.stat(hook_path).st_mode | stat.S_IXUSR)

>       hooks.run_script_with_context(
            os.path.join(self.hooks_path, self.post_hook),
            'tests',
            {'cookiecutter': {'file': 'context_post.txt'}},
        )

tests/test_hooks.py:200: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
cookiecutter/hooks.py:91: in run_script_with_context
    run_script(temp_script_path, cwd)
cookiecutter/hooks.py:65: in run_script
    subprocess.check_call([script_path], cwd=cwd)
/usr/lib/python3.10/subprocess.py:364: in check_call
    retcode = call(*popenargs, **kwargs)
/usr/lib/python3.10/subprocess.py:345: in call
    with Popen(*popenargs, **kwargs) as p:
/usr/lib/python3.10/subprocess.py:971: in __init__
    self._execute_child(args, executable, preexec_fn, close_fds,
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = 
args = ['/tmp/tmpbe0ep3qe'], executable = b'/tmp/tmpbe0ep3qe', preexec_fn = None
close_fds = True, pass_fds = (), cwd = 'tests', env = None, startupinfo = None
creationflags = 0, shell = False, p2cread = -1, p2cwrite = -1, c2pread = -1
c2pwrite = -1, errread = -1, errwrite = -1, restore_signals = True, gid = None
gids = None, uid = None, umask = -1, start_new_session = False

    def _execute_child(self, args, executable, preexec_fn, close_fds,
                       pass_fds, cwd, env,
                       startupinfo, creationflags, shell,
                       p2cread, p2cwrite,
                       c2pread, c2pwrite,
                       errread, errwrite,
                       restore_signals,
                       gid, gids, uid, umask,
                       start_new_session):
        """Execute program (POSIX version)"""

        if isinstance(args, (str, bytes)):
            args = [args]
        elif isinstance(args, os.PathLike):
            if shell:
                raise TypeError('path-like args is not allowed when '
                                'shell is true')
            args = [args]
        else:
            args = list(args)

        if shell:
            # On Android the default shell is at '/system/bin/sh'.
            unix_shell = ('/system/bin/sh' if
                      hasattr(sys, 'getandroidapilevel') else '/bin/sh')
            args = [unix_shell, "-c"] + args
            if executable:
                args[0] = executable

        if executable is None:
            executable = args[0]

        sys.audit("subprocess.Popen", executable, args, cwd, env)

        if (_USE_POSIX_SPAWN
                and os.path.dirname(executable)
                and preexec_fn is None
                and not close_fds
                and not pass_fds
                and cwd is None
                and (p2cread == -1 or p2cread > 2)
                and (c2pwrite == -1 or c2pwrite > 2)
                and (errwrite == -1 or errwrite > 2)
                and not start_new_session
                and gid is None
                and gids is None
                and uid is None
                and umask < 0):
            self._posix_spawn(args, executable, env, restore_signals,
                              p2cread, p2cwrite,
                              c2pread, c2pwrite,
                              errread, errwrite)
            return

        orig_executable = executable

        # For transferring possible exec failure from child to parent.
        # Data format: "exception name:hex errno:description"
        # Pickle is not used; it is complex and involves memory allocation.
        errpipe_read, errpipe_write = os.pipe()
        # errpipe_write must not be in the standard io 0, 1, or 2 fd range.
        low_fds_to_close = []
        while errpipe_write < 3:
            low_fds_to_close.append(errpipe_write)
            errpipe_write = os.dup(errpipe_write)
        for low_fd in low_fds_to_close:
            os.close(low_fd)
        try:
            try:
                # We must avoid complex work that could involve
                # malloc or free in the child process to avoid
                # potential deadlocks, thus we do all this here.
                # and pass it to fork_exec()

                if env is not None:
                    env_list = []
                    for k, v in env.items():
                        k = os.fsencode(k)
                        if b'=' in k:
                            raise ValueError("illegal environment variable name")
                        env_list.append(k + b'=' + os.fsencode(v))
                else:
                    env_list = None  # Use execv instead of execve.
                executable = os.fsencode(executable)
                if os.path.dirname(executable):
                    executable_list = (executable,)
                else:
                    # This matches the behavior of os._execvpe().
                    executable_list = tuple(
                        os.path.join(os.fsencode(dir), executable)
                        for dir in os.get_exec_path(env))
                fds_to_keep = set(pass_fds)
                fds_to_keep.add(errpipe_write)
                self.pid = _posixsubprocess.fork_exec(
                        args, executable_list,
                        close_fds, tuple(sorted(map(int, fds_to_keep))),
                        cwd, env_list,
                        p2cread, p2cwrite, c2pread, c2pwrite,
                        errread, errwrite,
                        errpipe_read, errpipe_write,
                        restore_signals, start_new_session,
                        gid, gids, uid, umask,
                        preexec_fn)
                self._child_created = True
            finally:
                # be sure the FD is closed no matter what
                os.close(errpipe_write)

            self._close_pipe_fds(p2cread, p2cwrite,
                                 c2pread, c2pwrite,
                                 errread, errwrite)

            # Wait for exec to fail or succeed; possibly raising an
            # exception (limited in size)
            errpipe_data = bytearray()
            while True:
                part = os.read(errpipe_read, 50000)
                errpipe_data += part
                if not part or len(errpipe_data) > 50000:
                    break
        finally:
            # be sure the FD is closed no matter what
            os.close(errpipe_read)

        if errpipe_data:
            try:
                pid, sts = os.waitpid(self.pid, 0)
                if pid == self.pid:
                    self._handle_exitstatus(sts)
                else:
                    self.returncode = sys.maxsize
            except ChildProcessError:
                pass

            try:
                exception_name, hex_errno, err_msg = (
                        errpipe_data.split(b':', 2))
                # The encoding here should match the encoding
                # written in by the subprocess implementations
                # like _posixsubprocess
                err_msg = err_msg.decode()
            except ValueError:
                exception_name = b'SubprocessError'
                hex_errno = b'0'
                err_msg = 'Bad exception data from child: {!r}'.format(
                              bytes(errpipe_data))
            child_exception_type = getattr(
                    builtins, exception_name.decode('ascii'),
                    SubprocessError)
            if issubclass(child_exception_type, OSError) and hex_errno:
                errno_num = int(hex_errno, 16)
                child_exec_never_called = (err_msg == "noexec")
                if child_exec_never_called:
                    err_msg = ""
                    # The error must be from chdir(cwd).
                    err_filename = cwd
                else:
                    err_filename = orig_executable
                if errno_num != 0:
                    err_msg = os.strerror(errno_num)
>               raise child_exception_type(errno_num, err_msg, err_filename)
E               FileNotFoundError: [Errno 2] No such file or directory: 'tests'

/usr/lib/python3.10/subprocess.py:1863: FileNotFoundError

test_hooks.py::TestExternalHooks::test_run_hook

test_hooks.py::TestExternalHooks::test_run_hook
self = 

    def test_run_hook(self):
        """Execute hook from specified template in specified output \
        directory."""
        tests_dir = os.path.join(self.repo_path, 'input{{hooks}}')
        with utils.work_in(self.repo_path):
>           hooks.run_hook('pre_gen_project', tests_dir, {})

tests/test_hooks.py:213: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
cookiecutter/hooks.py:108: in run_hook
    run_script_with_context(hook_path, project_dir, context)
cookiecutter/hooks.py:91: in run_script_with_context
    run_script(temp_script_path, cwd)
cookiecutter/hooks.py:65: in run_script
    subprocess.check_call([script_path], cwd=cwd)
/usr/lib/python3.10/subprocess.py:364: in check_call
    retcode = call(*popenargs, **kwargs)
/usr/lib/python3.10/subprocess.py:345: in call
    with Popen(*popenargs, **kwargs) as p:
/usr/lib/python3.10/subprocess.py:971: in __init__
    self._execute_child(args, executable, preexec_fn, close_fds,
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = 
args = ['/tmp/tmpb0_vwcr8'], executable = b'/tmp/tmpb0_vwcr8', preexec_fn = None
close_fds = True, pass_fds = ()
cwd = '/testbed/tests/test-hooks/input{{hooks}}', env = None, startupinfo = None
creationflags = 0, shell = False, p2cread = -1, p2cwrite = -1, c2pread = -1
c2pwrite = -1, errread = -1, errwrite = -1, restore_signals = True, gid = None
gids = None, uid = None, umask = -1, start_new_session = False

    def _execute_child(self, args, executable, preexec_fn, close_fds,
                       pass_fds, cwd, env,
                       startupinfo, creationflags, shell,
                       p2cread, p2cwrite,
                       c2pread, c2pwrite,
                       errread, errwrite,
                       restore_signals,
                       gid, gids, uid, umask,
                       start_new_session):
        """Execute program (POSIX version)"""

        if isinstance(args, (str, bytes)):
            args = [args]
        elif isinstance(args, os.PathLike):
            if shell:
                raise TypeError('path-like args is not allowed when '
                                'shell is true')
            args = [args]
        else:
            args = list(args)

        if shell:
            # On Android the default shell is at '/system/bin/sh'.
            unix_shell = ('/system/bin/sh' if
                      hasattr(sys, 'getandroidapilevel') else '/bin/sh')
            args = [unix_shell, "-c"] + args
            if executable:
                args[0] = executable

        if executable is None:
            executable = args[0]

        sys.audit("subprocess.Popen", executable, args, cwd, env)

        if (_USE_POSIX_SPAWN
                and os.path.dirname(executable)
                and preexec_fn is None
                and not close_fds
                and not pass_fds
                and cwd is None
                and (p2cread == -1 or p2cread > 2)
                and (c2pwrite == -1 or c2pwrite > 2)
                and (errwrite == -1 or errwrite > 2)
                and not start_new_session
                and gid is None
                and gids is None
                and uid is None
                and umask < 0):
            self._posix_spawn(args, executable, env, restore_signals,
                              p2cread, p2cwrite,
                              c2pread, c2pwrite,
                              errread, errwrite)
            return

        orig_executable = executable

        # For transferring possible exec failure from child to parent.
        # Data format: "exception name:hex errno:description"
        # Pickle is not used; it is complex and involves memory allocation.
        errpipe_read, errpipe_write = os.pipe()
        # errpipe_write must not be in the standard io 0, 1, or 2 fd range.
        low_fds_to_close = []
        while errpipe_write < 3:
            low_fds_to_close.append(errpipe_write)
            errpipe_write = os.dup(errpipe_write)
        for low_fd in low_fds_to_close:
            os.close(low_fd)
        try:
            try:
                # We must avoid complex work that could involve
                # malloc or free in the child process to avoid
                # potential deadlocks, thus we do all this here.
                # and pass it to fork_exec()

                if env is not None:
                    env_list = []
                    for k, v in env.items():
                        k = os.fsencode(k)
                        if b'=' in k:
                            raise ValueError("illegal environment variable name")
                        env_list.append(k + b'=' + os.fsencode(v))
                else:
                    env_list = None  # Use execv instead of execve.
                executable = os.fsencode(executable)
                if os.path.dirname(executable):
                    executable_list = (executable,)
                else:
                    # This matches the behavior of os._execvpe().
                    executable_list = tuple(
                        os.path.join(os.fsencode(dir), executable)
                        for dir in os.get_exec_path(env))
                fds_to_keep = set(pass_fds)
                fds_to_keep.add(errpipe_write)
                self.pid = _posixsubprocess.fork_exec(
                        args, executable_list,
                        close_fds, tuple(sorted(map(int, fds_to_keep))),
                        cwd, env_list,
                        p2cread, p2cwrite, c2pread, c2pwrite,
                        errread, errwrite,
                        errpipe_read, errpipe_write,
                        restore_signals, start_new_session,
                        gid, gids, uid, umask,
                        preexec_fn)
                self._child_created = True
            finally:
                # be sure the FD is closed no matter what
                os.close(errpipe_write)

            self._close_pipe_fds(p2cread, p2cwrite,
                                 c2pread, c2pwrite,
                                 errread, errwrite)

            # Wait for exec to fail or succeed; possibly raising an
            # exception (limited in size)
            errpipe_data = bytearray()
            while True:
                part = os.read(errpipe_read, 50000)
                errpipe_data += part
                if not part or len(errpipe_data) > 50000:
                    break
        finally:
            # be sure the FD is closed no matter what
            os.close(errpipe_read)

        if errpipe_data:
            try:
                pid, sts = os.waitpid(self.pid, 0)
                if pid == self.pid:
                    self._handle_exitstatus(sts)
                else:
                    self.returncode = sys.maxsize
            except ChildProcessError:
                pass

            try:
                exception_name, hex_errno, err_msg = (
                        errpipe_data.split(b':', 2))
                # The encoding here should match the encoding
                # written in by the subprocess implementations
                # like _posixsubprocess
                err_msg = err_msg.decode()
            except ValueError:
                exception_name = b'SubprocessError'
                hex_errno = b'0'
                err_msg = 'Bad exception data from child: {!r}'.format(
                              bytes(errpipe_data))
            child_exception_type = getattr(
                    builtins, exception_name.decode('ascii'),
                    SubprocessError)
            if issubclass(child_exception_type, OSError) and hex_errno:
                errno_num = int(hex_errno, 16)
                child_exec_never_called = (err_msg == "noexec")
                if child_exec_never_called:
                    err_msg = ""
                    # The error must be from chdir(cwd).
                    err_filename = cwd
                else:
                    err_filename = orig_executable
                if errno_num != 0:
                    err_msg = os.strerror(errno_num)
>               raise child_exception_type(errno_num, err_msg, err_filename)
E               PermissionError: [Errno 13] Permission denied: '/tmp/tmpb0_vwcr8'

/usr/lib/python3.10/subprocess.py:1863: PermissionError

test_hooks.py::TestExternalHooks::test_run_failing_hook

test_hooks.py::TestExternalHooks::test_run_failing_hook
self = 

    def test_run_failing_hook(self):
        """Test correct exception raise if hook exit code is not zero."""
        hook_path = os.path.join(self.hooks_path, 'pre_gen_project.py')
        tests_dir = os.path.join(self.repo_path, 'input{{hooks}}')

        with Path(hook_path).open('w') as f:
            f.write("#!/usr/bin/env python\n")
            f.write("import sys; sys.exit(1)\n")

        with utils.work_in(self.repo_path):
            with pytest.raises(exceptions.FailedHookException) as excinfo:
>               hooks.run_hook('pre_gen_project', tests_dir, {})

tests/test_hooks.py:231: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
cookiecutter/hooks.py:108: in run_hook
    run_script_with_context(hook_path, project_dir, context)
cookiecutter/hooks.py:91: in run_script_with_context
    run_script(temp_script_path, cwd)
cookiecutter/hooks.py:65: in run_script
    subprocess.check_call([script_path], cwd=cwd)
/usr/lib/python3.10/subprocess.py:364: in check_call
    retcode = call(*popenargs, **kwargs)
/usr/lib/python3.10/subprocess.py:345: in call
    with Popen(*popenargs, **kwargs) as p:
/usr/lib/python3.10/subprocess.py:971: in __init__
    self._execute_child(args, executable, preexec_fn, close_fds,
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = 
args = ['/tmp/tmp4e0wtdaj'], executable = b'/tmp/tmp4e0wtdaj', preexec_fn = None
close_fds = True, pass_fds = ()
cwd = '/testbed/tests/test-hooks/input{{hooks}}', env = None, startupinfo = None
creationflags = 0, shell = False, p2cread = -1, p2cwrite = -1, c2pread = -1
c2pwrite = -1, errread = -1, errwrite = -1, restore_signals = True, gid = None
gids = None, uid = None, umask = -1, start_new_session = False

    def _execute_child(self, args, executable, preexec_fn, close_fds,
                       pass_fds, cwd, env,
                       startupinfo, creationflags, shell,
                       p2cread, p2cwrite,
                       c2pread, c2pwrite,
                       errread, errwrite,
                       restore_signals,
                       gid, gids, uid, umask,
                       start_new_session):
        """Execute program (POSIX version)"""

        if isinstance(args, (str, bytes)):
            args = [args]
        elif isinstance(args, os.PathLike):
            if shell:
                raise TypeError('path-like args is not allowed when '
                                'shell is true')
            args = [args]
        else:
            args = list(args)

        if shell:
            # On Android the default shell is at '/system/bin/sh'.
            unix_shell = ('/system/bin/sh' if
                      hasattr(sys, 'getandroidapilevel') else '/bin/sh')
            args = [unix_shell, "-c"] + args
            if executable:
                args[0] = executable

        if executable is None:
            executable = args[0]

        sys.audit("subprocess.Popen", executable, args, cwd, env)

        if (_USE_POSIX_SPAWN
                and os.path.dirname(executable)
                and preexec_fn is None
                and not close_fds
                and not pass_fds
                and cwd is None
                and (p2cread == -1 or p2cread > 2)
                and (c2pwrite == -1 or c2pwrite > 2)
                and (errwrite == -1 or errwrite > 2)
                and not start_new_session
                and gid is None
                and gids is None
                and uid is None
                and umask < 0):
            self._posix_spawn(args, executable, env, restore_signals,
                              p2cread, p2cwrite,
                              c2pread, c2pwrite,
                              errread, errwrite)
            return

        orig_executable = executable

        # For transferring possible exec failure from child to parent.
        # Data format: "exception name:hex errno:description"
        # Pickle is not used; it is complex and involves memory allocation.
        errpipe_read, errpipe_write = os.pipe()
        # errpipe_write must not be in the standard io 0, 1, or 2 fd range.
        low_fds_to_close = []
        while errpipe_write < 3:
            low_fds_to_close.append(errpipe_write)
            errpipe_write = os.dup(errpipe_write)
        for low_fd in low_fds_to_close:
            os.close(low_fd)
        try:
            try:
                # We must avoid complex work that could involve
                # malloc or free in the child process to avoid
                # potential deadlocks, thus we do all this here.
                # and pass it to fork_exec()

                if env is not None:
                    env_list = []
                    for k, v in env.items():
                        k = os.fsencode(k)
                        if b'=' in k:
                            raise ValueError("illegal environment variable name")
                        env_list.append(k + b'=' + os.fsencode(v))
                else:
                    env_list = None  # Use execv instead of execve.
                executable = os.fsencode(executable)
                if os.path.dirname(executable):
                    executable_list = (executable,)
                else:
                    # This matches the behavior of os._execvpe().
                    executable_list = tuple(
                        os.path.join(os.fsencode(dir), executable)
                        for dir in os.get_exec_path(env))
                fds_to_keep = set(pass_fds)
                fds_to_keep.add(errpipe_write)
                self.pid = _posixsubprocess.fork_exec(
                        args, executable_list,
                        close_fds, tuple(sorted(map(int, fds_to_keep))),
                        cwd, env_list,
                        p2cread, p2cwrite, c2pread, c2pwrite,
                        errread, errwrite,
                        errpipe_read, errpipe_write,
                        restore_signals, start_new_session,
                        gid, gids, uid, umask,
                        preexec_fn)
                self._child_created = True
            finally:
                # be sure the FD is closed no matter what
                os.close(errpipe_write)

            self._close_pipe_fds(p2cread, p2cwrite,
                                 c2pread, c2pwrite,
                                 errread, errwrite)

            # Wait for exec to fail or succeed; possibly raising an
            # exception (limited in size)
            errpipe_data = bytearray()
            while True:
                part = os.read(errpipe_read, 50000)
                errpipe_data += part
                if not part or len(errpipe_data) > 50000:
                    break
        finally:
            # be sure the FD is closed no matter what
            os.close(errpipe_read)

        if errpipe_data:
            try:
                pid, sts = os.waitpid(self.pid, 0)
                if pid == self.pid:
                    self._handle_exitstatus(sts)
                else:
                    self.returncode = sys.maxsize
            except ChildProcessError:
                pass

            try:
                exception_name, hex_errno, err_msg = (
                        errpipe_data.split(b':', 2))
                # The encoding here should match the encoding
                # written in by the subprocess implementations
                # like _posixsubprocess
                err_msg = err_msg.decode()
            except ValueError:
                exception_name = b'SubprocessError'
                hex_errno = b'0'
                err_msg = 'Bad exception data from child: {!r}'.format(
                              bytes(errpipe_data))
            child_exception_type = getattr(
                    builtins, exception_name.decode('ascii'),
                    SubprocessError)
            if issubclass(child_exception_type, OSError) and hex_errno:
                errno_num = int(hex_errno, 16)
                child_exec_never_called = (err_msg == "noexec")
                if child_exec_never_called:
                    err_msg = ""
                    # The error must be from chdir(cwd).
                    err_filename = cwd
                else:
                    err_filename = orig_executable
                if errno_num != 0:
                    err_msg = os.strerror(errno_num)
>               raise child_exception_type(errno_num, err_msg, err_filename)
E               PermissionError: [Errno 13] Permission denied: '/tmp/tmp4e0wtdaj'

/usr/lib/python3.10/subprocess.py:1863: PermissionError

test_log.py::test_info_stdout_logging

test_log.py::test_info_stdout_logging
caplog = <_pytest.logging.LogCaptureFixture object at 0x7fcb925d6cb0>
info_logger = None
info_messages = ['INFO: Welcome to Cookiecutter', 'INFO: Loading user config from home dir', 'ERROR: Aw, snap! Something went wrong']

    def test_info_stdout_logging(caplog, info_logger, info_messages):
        """Test that stdout logs use info format and level."""
>       [stream_handler] = info_logger.handlers
E       AttributeError: 'NoneType' object has no attribute 'handlers'

tests/test_log.py:75: AttributeError

test_log.py::test_debug_stdout_logging

test_log.py::test_debug_stdout_logging
caplog = <_pytest.logging.LogCaptureFixture object at 0x7fcb91ecc340>
debug_logger = None
debug_messages = ['INFO cookiecutter: Welcome to Cookiecutter', 'DEBUG cookiecutter: Generating project from pytest-plugin', 'INFO cookiecutter.foo: Loading user config from home dir', "DEBUG cookiecutter.foo.bar: I don't know.", 'DEBUG cookiecutter.foo.bar: I wanted to save the world.', 'ERROR cookiecutter.foo: Aw, snap! Something went wrong', ...]

    def test_debug_stdout_logging(caplog, debug_logger, debug_messages):
        """Test that stdout logs use debug format and level."""
>       [stream_handler] = debug_logger.handlers
E       AttributeError: 'NoneType' object has no attribute 'handlers'

tests/test_log.py:92: AttributeError

test_log.py::test_debug_file_logging

test_log.py::test_debug_file_logging
caplog = <_pytest.logging.LogCaptureFixture object at 0x7fcb925d4340>
info_logger_with_file = None
debug_file = PosixPath('/tmp/pytest-of-root/pytest-0/test_debug_file_logging0/pytest-plugin.log')
debug_messages = ['INFO cookiecutter: Welcome to Cookiecutter', 'DEBUG cookiecutter: Generating project from pytest-plugin', 'INFO cookiecutter.foo: Loading user config from home dir', "DEBUG cookiecutter.foo.bar: I don't know.", 'DEBUG cookiecutter.foo.bar: I wanted to save the world.', 'ERROR cookiecutter.foo: Aw, snap! Something went wrong', ...]

    def test_debug_file_logging(caplog, info_logger_with_file, debug_file, debug_messages):
        """Test that logging to stdout uses a different format and level than \
        the the file handler."""
>       [file_handler, stream_handler] = info_logger_with_file.handlers
E       AttributeError: 'NoneType' object has no attribute 'handlers'

tests/test_log.py:110: AttributeError

test_main.py::test_original_cookiecutter_options_preserved_in__cookiecutter

test_main.py::test_original_cookiecutter_options_preserved_in__cookiecutter
monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0x7fcb92c3ba00>
mocker = 
user_config_file = '/tmp/pytest-of-root/pytest-0/user_dir0/config'

    def test_original_cookiecutter_options_preserved_in__cookiecutter(
        monkeypatch,
        mocker,
        user_config_file,
    ):
        """Preserve original context options.

        Tests you can access the original context options via
        `context['_cookiecutter']`.
        """
        monkeypatch.chdir('tests/fake-repo-tmpl-_cookiecutter')
        mock_generate_files = mocker.patch('cookiecutter.main.generate_files')
>       cookiecutter(
            '.',
            no_input=True,
            replay=False,
            config_file=user_config_file,
        )

/testbed/tests/test_main.py:18: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

template = '.', checkout = None, no_input = True, extra_context = None
replay = False, overwrite_if_exists = False, output_dir = '.'
config_file = '/tmp/pytest-of-root/pytest-0/user_dir0/config'
default_config = False, password = None, directory = None
skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False

    def cookiecutter(template, checkout=None, no_input=False, extra_context=
        None, replay=None, overwrite_if_exists=False, output_dir='.',
        config_file=None, default_config=False, password=None, directory=None,
        skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False
        ):
        """
        Run Cookiecutter just as if using it from the command line.

        :param template: A directory containing a project template directory,
            or a URL to a git repository.
        :param checkout: The branch, tag or commit ID to checkout after clone.
        :param no_input: Do not prompt for user input.
            Use default values for template parameters taken from `cookiecutter.json`, user
            config and `extra_dict`. Force a refresh of cached resources.
        :param extra_context: A dictionary of context that overrides default
            and user configuration.
        :param replay: Do not prompt for input, instead read from saved json. If
            ``True`` read from the ``replay_dir``.
            if it exists
        :param overwrite_if_exists: Overwrite the contents of the output directory
            if it exists.
        :param output_dir: Where to output the generated project dir into.
        :param config_file: User configuration file path.
        :param default_config: Use default values rather than a config file.
        :param password: The password to use when extracting the repository.
        :param directory: Relative path to a cookiecutter template in a repository.
        :param skip_if_file_exists: Skip the files in the corresponding directories
            if they already exist.
        :param accept_hooks: Accept pre and post hooks if set to `True`.
        :param keep_project_on_failure: If `True` keep generated project directory even when
            generation fails
        """
        # Get user configuration
        config_dict = get_user_config(config_file=config_file, default_config=default_config)

        # Determine the template directory
>       repo_dir, cleanup = determine_repo_dir(
            template=template,
            checkout=checkout,
            clone_to_dir=config_dict['cookiecutters_dir'],
            no_input=no_input,
            password=password,
            directory=directory
        )
E       TypeError: determine_repo_dir() missing 1 required positional argument: 'abbreviations'

/testbed/cookiecutter/main.py:59: TypeError

test_main.py::test_replay_dump_template_name

test_main.py::test_replay_dump_template_name
monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0x7fcb92cf9750>
mocker = 
user_config_data = {'cookiecutters_dir': '/tmp/pytest-of-root/pytest-0/user_dir0/cookiecutters', 'replay_dir': '/tmp/pytest-of-root/pytest-0/user_dir0/cookiecutter_replay'}
user_config_file = '/tmp/pytest-of-root/pytest-0/user_dir0/config'

    def test_replay_dump_template_name(
        monkeypatch, mocker, user_config_data, user_config_file
    ):
        """Check that replay_dump is called with a valid template_name.

        Template name must not be a relative path.

        Otherwise files such as ``..json`` are created, which are not just cryptic
        but also later mistaken for replay files of other templates if invoked with
        '.' and '--replay'.

        Change the current working directory temporarily to 'tests/fake-repo-tmpl'
        for this test and call cookiecutter with '.' for the target template.
        """
        monkeypatch.chdir('tests/fake-repo-tmpl')

        mock_replay_dump = mocker.patch('cookiecutter.main.dump')
        mocker.patch('cookiecutter.main.generate_files')

>       cookiecutter(
            '.',
            no_input=True,
            replay=False,
            config_file=user_config_file,
        )

/testbed/tests/test_main.py:51: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

template = '.', checkout = None, no_input = True, extra_context = None
replay = False, overwrite_if_exists = False, output_dir = '.'
config_file = '/tmp/pytest-of-root/pytest-0/user_dir0/config'
default_config = False, password = None, directory = None
skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False

    def cookiecutter(template, checkout=None, no_input=False, extra_context=
        None, replay=None, overwrite_if_exists=False, output_dir='.',
        config_file=None, default_config=False, password=None, directory=None,
        skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False
        ):
        """
        Run Cookiecutter just as if using it from the command line.

        :param template: A directory containing a project template directory,
            or a URL to a git repository.
        :param checkout: The branch, tag or commit ID to checkout after clone.
        :param no_input: Do not prompt for user input.
            Use default values for template parameters taken from `cookiecutter.json`, user
            config and `extra_dict`. Force a refresh of cached resources.
        :param extra_context: A dictionary of context that overrides default
            and user configuration.
        :param replay: Do not prompt for input, instead read from saved json. If
            ``True`` read from the ``replay_dir``.
            if it exists
        :param overwrite_if_exists: Overwrite the contents of the output directory
            if it exists.
        :param output_dir: Where to output the generated project dir into.
        :param config_file: User configuration file path.
        :param default_config: Use default values rather than a config file.
        :param password: The password to use when extracting the repository.
        :param directory: Relative path to a cookiecutter template in a repository.
        :param skip_if_file_exists: Skip the files in the corresponding directories
            if they already exist.
        :param accept_hooks: Accept pre and post hooks if set to `True`.
        :param keep_project_on_failure: If `True` keep generated project directory even when
            generation fails
        """
        # Get user configuration
        config_dict = get_user_config(config_file=config_file, default_config=default_config)

        # Determine the template directory
>       repo_dir, cleanup = determine_repo_dir(
            template=template,
            checkout=checkout,
            clone_to_dir=config_dict['cookiecutters_dir'],
            no_input=no_input,
            password=password,
            directory=directory
        )
E       TypeError: determine_repo_dir() missing 1 required positional argument: 'abbreviations'

/testbed/cookiecutter/main.py:59: TypeError

test_main.py::test_replay_load_template_name

test_main.py::test_replay_load_template_name
monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0x7fcb92179db0>
mocker = 
user_config_data = {'cookiecutters_dir': '/tmp/pytest-of-root/pytest-0/user_dir0/cookiecutters', 'replay_dir': '/tmp/pytest-of-root/pytest-0/user_dir0/cookiecutter_replay'}
user_config_file = '/tmp/pytest-of-root/pytest-0/user_dir0/config'

    def test_replay_load_template_name(
        monkeypatch, mocker, user_config_data, user_config_file
    ):
        """Check that replay_load is called correctly.

        Calls require valid template_name that is not a relative path.

        Change the current working directory temporarily to 'tests/fake-repo-tmpl'
        for this test and call cookiecutter with '.' for the target template.
        """
        monkeypatch.chdir('tests/fake-repo-tmpl')

        mock_replay_load = mocker.patch('cookiecutter.main.load')
        mocker.patch('cookiecutter.main.generate_context').return_value = {
            'cookiecutter': {}
        }
        mocker.patch('cookiecutter.main.generate_files')
        mocker.patch('cookiecutter.main.dump')

>       cookiecutter(
            '.',
            replay=True,
            config_file=user_config_file,
        )

/testbed/tests/test_main.py:84: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

template = '.', checkout = None, no_input = False, extra_context = None
replay = True, overwrite_if_exists = False, output_dir = '.'
config_file = '/tmp/pytest-of-root/pytest-0/user_dir0/config'
default_config = False, password = None, directory = None
skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False

    def cookiecutter(template, checkout=None, no_input=False, extra_context=
        None, replay=None, overwrite_if_exists=False, output_dir='.',
        config_file=None, default_config=False, password=None, directory=None,
        skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False
        ):
        """
        Run Cookiecutter just as if using it from the command line.

        :param template: A directory containing a project template directory,
            or a URL to a git repository.
        :param checkout: The branch, tag or commit ID to checkout after clone.
        :param no_input: Do not prompt for user input.
            Use default values for template parameters taken from `cookiecutter.json`, user
            config and `extra_dict`. Force a refresh of cached resources.
        :param extra_context: A dictionary of context that overrides default
            and user configuration.
        :param replay: Do not prompt for input, instead read from saved json. If
            ``True`` read from the ``replay_dir``.
            if it exists
        :param overwrite_if_exists: Overwrite the contents of the output directory
            if it exists.
        :param output_dir: Where to output the generated project dir into.
        :param config_file: User configuration file path.
        :param default_config: Use default values rather than a config file.
        :param password: The password to use when extracting the repository.
        :param directory: Relative path to a cookiecutter template in a repository.
        :param skip_if_file_exists: Skip the files in the corresponding directories
            if they already exist.
        :param accept_hooks: Accept pre and post hooks if set to `True`.
        :param keep_project_on_failure: If `True` keep generated project directory even when
            generation fails
        """
        # Get user configuration
        config_dict = get_user_config(config_file=config_file, default_config=default_config)

        # Determine the template directory
>       repo_dir, cleanup = determine_repo_dir(
            template=template,
            checkout=checkout,
            clone_to_dir=config_dict['cookiecutters_dir'],
            no_input=no_input,
            password=password,
            directory=directory
        )
E       TypeError: determine_repo_dir() missing 1 required positional argument: 'abbreviations'

/testbed/cookiecutter/main.py:59: TypeError

test_main.py::test_custom_replay_file

test_main.py::test_custom_replay_file
monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0x7fcb91e9bc40>
mocker = 
user_config_file = '/tmp/pytest-of-root/pytest-0/user_dir0/config'

    def test_custom_replay_file(monkeypatch, mocker, user_config_file):
        """Check that reply.load is called with the custom replay_file."""
        monkeypatch.chdir('tests/fake-repo-tmpl')

        mock_replay_load = mocker.patch('cookiecutter.main.load')
        mocker.patch('cookiecutter.main.generate_context').return_value = {
            'cookiecutter': {}
        }
        mocker.patch('cookiecutter.main.generate_files')
        mocker.patch('cookiecutter.main.dump')

>       cookiecutter(
            '.',
            replay='./custom-replay-file',
            config_file=user_config_file,
        )

/testbed/tests/test_main.py:107: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

template = '.', checkout = None, no_input = False, extra_context = None
replay = './custom-replay-file', overwrite_if_exists = False, output_dir = '.'
config_file = '/tmp/pytest-of-root/pytest-0/user_dir0/config'
default_config = False, password = None, directory = None
skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False

    def cookiecutter(template, checkout=None, no_input=False, extra_context=
        None, replay=None, overwrite_if_exists=False, output_dir='.',
        config_file=None, default_config=False, password=None, directory=None,
        skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False
        ):
        """
        Run Cookiecutter just as if using it from the command line.

        :param template: A directory containing a project template directory,
            or a URL to a git repository.
        :param checkout: The branch, tag or commit ID to checkout after clone.
        :param no_input: Do not prompt for user input.
            Use default values for template parameters taken from `cookiecutter.json`, user
            config and `extra_dict`. Force a refresh of cached resources.
        :param extra_context: A dictionary of context that overrides default
            and user configuration.
        :param replay: Do not prompt for input, instead read from saved json. If
            ``True`` read from the ``replay_dir``.
            if it exists
        :param overwrite_if_exists: Overwrite the contents of the output directory
            if it exists.
        :param output_dir: Where to output the generated project dir into.
        :param config_file: User configuration file path.
        :param default_config: Use default values rather than a config file.
        :param password: The password to use when extracting the repository.
        :param directory: Relative path to a cookiecutter template in a repository.
        :param skip_if_file_exists: Skip the files in the corresponding directories
            if they already exist.
        :param accept_hooks: Accept pre and post hooks if set to `True`.
        :param keep_project_on_failure: If `True` keep generated project directory even when
            generation fails
        """
        # Get user configuration
        config_dict = get_user_config(config_file=config_file, default_config=default_config)

        # Determine the template directory
>       repo_dir, cleanup = determine_repo_dir(
            template=template,
            checkout=checkout,
            clone_to_dir=config_dict['cookiecutters_dir'],
            no_input=no_input,
            password=password,
            directory=directory
        )
E       TypeError: determine_repo_dir() missing 1 required positional argument: 'abbreviations'

/testbed/cookiecutter/main.py:59: TypeError

test_output_folder.py::test_output_folder

test_output_folder.py::test_output_folder
@pytest.mark.usefixtures('clean_system', 'remove_output_folder')
    def test_output_folder():
        """Tests should correctly create content, as output_folder does not yet exist."""
        context = generate.generate_context(
            context_file='tests/test-output-folder/cookiecutter.json'
        )
>       generate.generate_files(context=context, repo_dir='tests/test-output-folder')

tests/test_output_folder.py:30: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

repo_dir = 'tests/test-output-folder'
context = OrderedDict([('full_name', 'Audrey Greenfeld'), ('year', '2014'), ('color', 'green'), ('letter', 'D'), ('folder_name', 'im_a.dir'), ('filename', 'im_a.file'), ('test_name', 'output_folder')])
output_dir = '.', overwrite_if_exists = False, skip_if_file_exists = False
accept_hooks = True, keep_project_on_failure = False

    def generate_files(repo_dir, context=None, output_dir='.',
        overwrite_if_exists=False, skip_if_file_exists=False, accept_hooks=True,
        keep_project_on_failure=False):
        """Render the templates and saves them to files.

        :param repo_dir: Project template input directory.
        :param context: Dict for populating the template's variables.
        :param output_dir: Where to output the generated project dir into.
        :param overwrite_if_exists: Overwrite the contents of the output directory
            if it exists.
        :param skip_if_file_exists: Skip the files in the corresponding directories
            if they already exist
        :param accept_hooks: Accept pre and post hooks if set to `True`.
        :param keep_project_on_failure: If `True` keep generated project directory even when
            generation fails
        """
>       template_dir = find_template(repo_dir)
E       TypeError: find_template() missing 1 required positional argument: 'env'

cookiecutter/generate.py:225: TypeError

test_output_folder.py::test_exception_when_output_folder_exists

test_output_folder.py::test_exception_when_output_folder_exists
@pytest.mark.usefixtures('clean_system', 'remove_output_folder')
    def test_exception_when_output_folder_exists():
        """Tests should raise error as output folder created before `generate_files`."""
        context = generate.generate_context(
            context_file='tests/test-output-folder/cookiecutter.json'
        )
>       output_folder = context['cookiecutter']['test_name']
E       KeyError: 'cookiecutter'

tests/test_output_folder.py:53: KeyError

test_pre_prompt_hooks.py::test_run_pre_prompt_python_hook

test_pre_prompt_hooks.py::test_run_pre_prompt_python_hook
remove_tmp_repo_dir = ._func at 0x7fcb91de1990>

    def test_run_pre_prompt_python_hook(remove_tmp_repo_dir):
        """Verify pre_prompt.py runs and creates a copy of cookiecutter.json."""
>       new_repo_dir = hooks.run_pre_prompt_hook(repo_dir='tests/test-pyhooks/')

tests/test_pre_prompt_hooks.py:27: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

repo_dir = 'tests/test-pyhooks/'

    def run_pre_prompt_hook(repo_dir: 'os.PathLike[str]') ->Path:
        """Run pre_prompt hook from repo directory.

        :param repo_dir: Project template input directory.
        """
        with work_in(repo_dir):
            hook_path = find_hook('pre_prompt')
            if hook_path:
                logger.debug("Running pre_prompt hook")
>               tmp_repo_dir = create_tmp_repo_dir()
E               TypeError: create_tmp_repo_dir() missing 1 required positional argument: 'repo_dir'

cookiecutter/hooks.py:157: TypeError

test_pre_prompt_hooks.py::test_run_pre_prompt_python_hook_fail

test_pre_prompt_hooks.py::test_run_pre_prompt_python_hook_fail
monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0x7fcb91e99270>

    def test_run_pre_prompt_python_hook_fail(monkeypatch):
        """Verify pre_prompt.py will fail when a given env var is present."""
        message = 'Pre-Prompt Hook script failed'
        with monkeypatch.context() as m:
            m.setenv('COOKIECUTTER_FAIL_PRE_PROMPT', '1')
            with pytest.raises(FailedHookException) as excinfo:
>               hooks.run_pre_prompt_hook(repo_dir='tests/test-pyhooks/')

tests/test_pre_prompt_hooks.py:40: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

repo_dir = 'tests/test-pyhooks/'

    def run_pre_prompt_hook(repo_dir: 'os.PathLike[str]') ->Path:
        """Run pre_prompt hook from repo directory.

        :param repo_dir: Project template input directory.
        """
        with work_in(repo_dir):
            hook_path = find_hook('pre_prompt')
            if hook_path:
                logger.debug("Running pre_prompt hook")
>               tmp_repo_dir = create_tmp_repo_dir()
E               TypeError: create_tmp_repo_dir() missing 1 required positional argument: 'repo_dir'

cookiecutter/hooks.py:157: TypeError

test_pre_prompt_hooks.py::test_run_pre_prompt_shell_hook

test_pre_prompt_hooks.py::test_run_pre_prompt_shell_hook
remove_tmp_repo_dir = ._func at 0x7fcb91de3760>

    @pytest.mark.skipif(WINDOWS, reason='shell script will not run in Windows')
    def test_run_pre_prompt_shell_hook(remove_tmp_repo_dir):
        """Verify pre_prompt.sh runs and creates a copy of cookiecutter.json."""
>       new_repo_dir = hooks.run_pre_prompt_hook(repo_dir='tests/test-pyshellhooks/')

tests/test_pre_prompt_hooks.py:47: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

repo_dir = 'tests/test-pyshellhooks/'

    def run_pre_prompt_hook(repo_dir: 'os.PathLike[str]') ->Path:
        """Run pre_prompt hook from repo directory.

        :param repo_dir: Project template input directory.
        """
        with work_in(repo_dir):
            hook_path = find_hook('pre_prompt')
            if hook_path:
                logger.debug("Running pre_prompt hook")
>               tmp_repo_dir = create_tmp_repo_dir()
E               TypeError: create_tmp_repo_dir() missing 1 required positional argument: 'repo_dir'

cookiecutter/hooks.py:157: TypeError

test_prompt.py::TestRenderVariable::test_convert_to_str[1-1]

test_prompt.py::TestRenderVariable::test_convert_to_str[1-1]
self = 
mocker = 
raw_var = 1, rendered_var = '1'

    @pytest.mark.parametrize(
        'raw_var, rendered_var',
        [
            (1, '1'),
            (True, True),
            ('foo', 'foo'),
            ('{{cookiecutter.project}}', 'foobar'),
            (None, None),
        ],
    )
    def test_convert_to_str(self, mocker, raw_var, rendered_var):
        """Verify simple items correctly rendered to strings."""
        env = environment.StrictEnvironment()
        from_string = mocker.patch(
            'cookiecutter.utils.StrictEnvironment.from_string', wraps=env.from_string
        )
        context = {'project': 'foobar'}

        result = prompt.render_variable(env, raw_var, context)
>       assert result == rendered_var
E       AssertionError: assert 1 == '1'

tests/test_prompt.py:44: AssertionError

test_prompt.py::TestRenderVariable::test_convert_to_str[{{cookiecutter.project}}-foobar]

test_prompt.py::TestRenderVariable::test_convert_to_str[{{cookiecutter.project}}-foobar]
env = 
raw = '{{cookiecutter.project}}', cookiecutter_dict = {'project': 'foobar'}

    def render_variable(env, raw, cookiecutter_dict):
        """Render the next variable to be displayed in the user prompt.

        Inside the prompting taken from the cookiecutter.json file, this renders
        the next variable. For example, if a project_name is "Peanut Butter
        Cookie", the repo_name could be be rendered with:

            `{{ cookiecutter.project_name.replace(" ", "_") }}`.

        This is then presented to the user as the default.

        :param Environment env: A Jinja2 Environment object.
        :param raw: The next value to be prompted for by the user.
        :param dict cookiecutter_dict: The current context as it's gradually
            being populated with variables.
        :return: The rendered value for the default variable.
        """
        if not isinstance(raw, str):
            return raw

        template = env.from_string(raw)
        try:
>           return template.render(**cookiecutter_dict)

cookiecutter/prompt.py:160: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.venv/lib/python3.10/site-packages/jinja2/environment.py:1304: in render
    self.environment.handle_exception()
.venv/lib/python3.10/site-packages/jinja2/environment.py:939: in handle_exception
    raise rewrite_traceback_stack(source=source)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = 
obj = Undefined, attribute = 'project'

    def getattr(self, obj: t.Any, attribute: str) -> t.Any:
        """Get an item or attribute of an object but prefer the attribute.
        Unlike :meth:`getitem` the attribute *must* be a string.
        """
        try:
>           return getattr(obj, attribute)
E           jinja2.exceptions.UndefinedError: 'cookiecutter' is undefined

.venv/lib/python3.10/site-packages/jinja2/environment.py:487: UndefinedError

During handling of the above exception, another exception occurred:

self = 
mocker = 
raw_var = '{{cookiecutter.project}}', rendered_var = 'foobar'

    @pytest.mark.parametrize(
        'raw_var, rendered_var',
        [
            (1, '1'),
            (True, True),
            ('foo', 'foo'),
            ('{{cookiecutter.project}}', 'foobar'),
            (None, None),
        ],
    )
    def test_convert_to_str(self, mocker, raw_var, rendered_var):
        """Verify simple items correctly rendered to strings."""
        env = environment.StrictEnvironment()
        from_string = mocker.patch(
            'cookiecutter.utils.StrictEnvironment.from_string', wraps=env.from_string
        )
        context = {'project': 'foobar'}

>       result = prompt.render_variable(env, raw_var, context)

tests/test_prompt.py:43: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

env = 
raw = '{{cookiecutter.project}}', cookiecutter_dict = {'project': 'foobar'}

    def render_variable(env, raw, cookiecutter_dict):
        """Render the next variable to be displayed in the user prompt.

        Inside the prompting taken from the cookiecutter.json file, this renders
        the next variable. For example, if a project_name is "Peanut Butter
        Cookie", the repo_name could be be rendered with:

            `{{ cookiecutter.project_name.replace(" ", "_") }}`.

        This is then presented to the user as the default.

        :param Environment env: A Jinja2 Environment object.
        :param raw: The next value to be prompted for by the user.
        :param dict cookiecutter_dict: The current context as it's gradually
            being populated with variables.
        :return: The rendered value for the default variable.
        """
        if not isinstance(raw, str):
            return raw

        template = env.from_string(raw)
        try:
            return template.render(**cookiecutter_dict)
        except UndefinedError as err:
>           raise UndefinedVariableInTemplate(str(err), err, cookiecutter_dict)
E           cookiecutter.exceptions.UndefinedVariableInTemplate: 'cookiecutter' is undefined. Error message: 'cookiecutter' is undefined. Context: {'project': 'foobar'}

cookiecutter/prompt.py:162: UndefinedVariableInTemplate

test_prompt.py::TestRenderVariable::test_convert_to_str_complex_variables[raw_var0-rendered_var0]

test_prompt.py::TestRenderVariable::test_convert_to_str_complex_variables[raw_var0-rendered_var0]
self = 
raw_var = {1: True, 'foo': False}, rendered_var = {'1': True, 'foo': False}

    @pytest.mark.parametrize(
        'raw_var, rendered_var',
        [
            ({1: True, 'foo': False}, {'1': True, 'foo': False}),
            (
                {'{{cookiecutter.project}}': ['foo', 1], 'bar': False},
                {'foobar': ['foo', '1'], 'bar': False},
            ),
            (['foo', '{{cookiecutter.project}}', None], ['foo', 'foobar', None]),
        ],
    )
    def test_convert_to_str_complex_variables(self, raw_var, rendered_var):
        """Verify tree items correctly rendered."""
        env = environment.StrictEnvironment()
        context = {'project': 'foobar'}

        result = prompt.render_variable(env, raw_var, context)
>       assert result == rendered_var
E       AssertionError: assert {1: True, 'foo': False} == {'1': True, 'foo': False}
E         
E         Common items:
E         {'foo': False}
E         Left contains 1 more item:
E         {1: True}
E         Right contains 1 more item:
E         {'1': True}
E         
E         Full diff:
E           {
E         -     '1': True,
E         ?     - -
E         +     1: True,
E               'foo': False,
E           }

tests/test_prompt.py:71: AssertionError

test_prompt.py::TestRenderVariable::test_convert_to_str_complex_variables[raw_var1-rendered_var1]

test_prompt.py::TestRenderVariable::test_convert_to_str_complex_variables[raw_var1-rendered_var1]
self = 
raw_var = {'bar': False, '{{cookiecutter.project}}': ['foo', 1]}
rendered_var = {'bar': False, 'foobar': ['foo', '1']}

    @pytest.mark.parametrize(
        'raw_var, rendered_var',
        [
            ({1: True, 'foo': False}, {'1': True, 'foo': False}),
            (
                {'{{cookiecutter.project}}': ['foo', 1], 'bar': False},
                {'foobar': ['foo', '1'], 'bar': False},
            ),
            (['foo', '{{cookiecutter.project}}', None], ['foo', 'foobar', None]),
        ],
    )
    def test_convert_to_str_complex_variables(self, raw_var, rendered_var):
        """Verify tree items correctly rendered."""
        env = environment.StrictEnvironment()
        context = {'project': 'foobar'}

        result = prompt.render_variable(env, raw_var, context)
>       assert result == rendered_var
E       AssertionError: assert {'{{cookiecutter.project}}': ['foo', 1], 'bar': False} == {'foobar': ['foo', '1'], 'bar': False}
E         
E         Common items:
E         {'bar': False}
E         Left contains 1 more item:
E         {'{{cookiecutter.project}}': ['foo', 1]}
E         Right contains 1 more item:
E         {'foobar': ['foo', '1']}
E         
E         Full diff:
E           {
E               'bar': False,
E         -     'foobar': [
E         +     '{{cookiecutter.project}}': [
E                   'foo',
E         -         '1',
E         ?         - -
E         +         1,
E               ],
E           }

tests/test_prompt.py:71: AssertionError

test_prompt.py::TestRenderVariable::test_convert_to_str_complex_variables[raw_var2-rendered_var2]

test_prompt.py::TestRenderVariable::test_convert_to_str_complex_variables[raw_var2-rendered_var2]
self = 
raw_var = ['foo', '{{cookiecutter.project}}', None]
rendered_var = ['foo', 'foobar', None]

    @pytest.mark.parametrize(
        'raw_var, rendered_var',
        [
            ({1: True, 'foo': False}, {'1': True, 'foo': False}),
            (
                {'{{cookiecutter.project}}': ['foo', 1], 'bar': False},
                {'foobar': ['foo', '1'], 'bar': False},
            ),
            (['foo', '{{cookiecutter.project}}', None], ['foo', 'foobar', None]),
        ],
    )
    def test_convert_to_str_complex_variables(self, raw_var, rendered_var):
        """Verify tree items correctly rendered."""
        env = environment.StrictEnvironment()
        context = {'project': 'foobar'}

        result = prompt.render_variable(env, raw_var, context)
>       assert result == rendered_var
E       AssertionError: assert ['foo', '{{cookiecutter.project}}', None] == ['foo', 'foobar', None]
E         
E         At index 1 diff: '{{cookiecutter.project}}' != 'foobar'
E         
E         Full diff:
E           [
E               'foo',
E         -     'foobar',
E         +     '{{cookiecutter.project}}',
E               None,
E           ]

tests/test_prompt.py:71: AssertionError

input]

input]
self = 
monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0x7fcb92c3b910>
context = {'cookiecutter': {'full_name': 'Your Name'}}

    @pytest.mark.parametrize(
        'context',
        [
            {'cookiecutter': {'full_name': 'Your Name'}},
            {'cookiecutter': {'full_name': 'Řekni či napiš své jméno'}},
        ],
        ids=['ASCII default prompt/input', 'Unicode default prompt/input'],
    )
    def test_prompt_for_config(self, monkeypatch, context):
        """Verify `prompt_for_config` call `read_user_variable` on text request."""
        monkeypatch.setattr(
            'cookiecutter.prompt.read_user_variable',
            lambda var, default, prompts, prefix: default,
        )

>       cookiecutter_dict = prompt.prompt_for_config(context)

tests/test_prompt.py:92: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

context = {'cookiecutter': {'full_name': 'Your Name'}}, no_input = False

    def prompt_for_config(context, no_input=False):
        """Prompt user to enter a new config.

        :param dict context: Source for field names and sample values.
        :param no_input: Do not prompt for user input and use only values from context.
        """
        cookiecutter_dict = OrderedDict([])
        env = create_env_with_context(context)

        for key, raw in context['cookiecutter'].items():
            if key.startswith('_'):
                cookiecutter_dict[key] = raw
                continue

            if isinstance(raw, dict):
                cookiecutter_dict[key] = prompt_choice_for_config(
                    cookiecutter_dict, env, key, raw, no_input
                )
            else:
                if no_input:
                    cookiecutter_dict[key] = render_variable(env, raw, cookiecutter_dict)
                else:
>                   cookiecutter_dict[key] = read_user_variable(key, raw)
E                   TypeError: TestPrompt.test_prompt_for_config..() missing 2 required positional arguments: 'prompts' and 'prefix'

cookiecutter/prompt.py:228: TypeError

input]

input]
self = 
monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0x7fcb91ecde70>
context = {'cookiecutter': {'full_name': 'Řekni či napiš své jméno'}}

    @pytest.mark.parametrize(
        'context',
        [
            {'cookiecutter': {'full_name': 'Your Name'}},
            {'cookiecutter': {'full_name': 'Řekni či napiš své jméno'}},
        ],
        ids=['ASCII default prompt/input', 'Unicode default prompt/input'],
    )
    def test_prompt_for_config(self, monkeypatch, context):
        """Verify `prompt_for_config` call `read_user_variable` on text request."""
        monkeypatch.setattr(
            'cookiecutter.prompt.read_user_variable',
            lambda var, default, prompts, prefix: default,
        )

>       cookiecutter_dict = prompt.prompt_for_config(context)

tests/test_prompt.py:92: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

context = {'cookiecutter': {'full_name': 'Řekni či napiš své jméno'}}
no_input = False

    def prompt_for_config(context, no_input=False):
        """Prompt user to enter a new config.

        :param dict context: Source for field names and sample values.
        :param no_input: Do not prompt for user input and use only values from context.
        """
        cookiecutter_dict = OrderedDict([])
        env = create_env_with_context(context)

        for key, raw in context['cookiecutter'].items():
            if key.startswith('_'):
                cookiecutter_dict[key] = raw
                continue

            if isinstance(raw, dict):
                cookiecutter_dict[key] = prompt_choice_for_config(
                    cookiecutter_dict, env, key, raw, no_input
                )
            else:
                if no_input:
                    cookiecutter_dict[key] = render_variable(env, raw, cookiecutter_dict)
                else:
>                   cookiecutter_dict[key] = read_user_variable(key, raw)
E                   TypeError: TestPrompt.test_prompt_for_config..() missing 2 required positional arguments: 'prompts' and 'prefix'

cookiecutter/prompt.py:228: TypeError

input]

input]
self = 
monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0x7fcb927602b0>
context = {'cookiecutter': {'__prompts__': {'check': 'Checking', 'full_name': 'Name please'}, 'check': ['yes', 'no'], 'full_name': 'Your Name', 'nothing': 'ok'}}

    @pytest.mark.parametrize(
        'context',
        [
            {
                'cookiecutter': {
                    'full_name': 'Your Name',
                    'check': ['yes', 'no'],
                    'nothing': 'ok',
                    '__prompts__': {
                        'full_name': 'Name please',
                        'check': 'Checking',
                    },
                }
            },
        ],
        ids=['ASCII default prompt/input'],
    )
    def test_prompt_for_config_with_human_prompts(self, monkeypatch, context):
        """Verify call `read_user_variable` on request when human-readable prompts."""
        monkeypatch.setattr(
            'cookiecutter.prompt.read_user_variable',
            lambda var, default, prompts, prefix: default,
        )
        monkeypatch.setattr(
            'cookiecutter.prompt.read_user_yes_no',
            lambda var, default, prompts, prefix: default,
        )
        monkeypatch.setattr(
            'cookiecutter.prompt.read_user_choice',
            lambda var, default, prompts, prefix: default,
        )

>       cookiecutter_dict = prompt.prompt_for_config(context)

tests/test_prompt.py:127: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

context = {'cookiecutter': {'__prompts__': {'check': 'Checking', 'full_name': 'Name please'}, 'check': ['yes', 'no'], 'full_name': 'Your Name', 'nothing': 'ok'}}
no_input = False

    def prompt_for_config(context, no_input=False):
        """Prompt user to enter a new config.

        :param dict context: Source for field names and sample values.
        :param no_input: Do not prompt for user input and use only values from context.
        """
        cookiecutter_dict = OrderedDict([])
        env = create_env_with_context(context)

        for key, raw in context['cookiecutter'].items():
            if key.startswith('_'):
                cookiecutter_dict[key] = raw
                continue

            if isinstance(raw, dict):
                cookiecutter_dict[key] = prompt_choice_for_config(
                    cookiecutter_dict, env, key, raw, no_input
                )
            else:
                if no_input:
                    cookiecutter_dict[key] = render_variable(env, raw, cookiecutter_dict)
                else:
>                   cookiecutter_dict[key] = read_user_variable(key, raw)
E                   TypeError: TestPrompt.test_prompt_for_config_with_human_prompts..() missing 2 required positional arguments: 'prompts' and 'prefix'

cookiecutter/prompt.py:228: TypeError

test_prompt.py::TestPrompt::test_prompt_for_config_with_human_choices[context0]

test_prompt.py::TestPrompt::test_prompt_for_config_with_human_choices[context0]
self = 
monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0x7fcb91e998d0>
context = {'cookiecutter': {'__prompts__': {'check': 'Checking'}, 'check': ['yes', 'no'], 'full_name': 'Your Name'}}

    @pytest.mark.parametrize(
        'context',
        [
            {
                'cookiecutter': {
                    'full_name': 'Your Name',
                    'check': ['yes', 'no'],
                    '__prompts__': {
                        'check': 'Checking',
                    },
                }
            },
            {
                'cookiecutter': {
                    'full_name': 'Your Name',
                    'check': ['yes', 'no'],
                    '__prompts__': {
                        'full_name': 'Name please',
                        'check': {'__prompt__': 'Checking', 'yes': 'Yes', 'no': 'No'},
                    },
                }
            },
            {
                'cookiecutter': {
                    'full_name': 'Your Name',
                    'check': ['yes', 'no'],
                    '__prompts__': {
                        'full_name': 'Name please',
                        'check': {'no': 'No'},
                    },
                }
            },
        ],
    )
    def test_prompt_for_config_with_human_choices(self, monkeypatch, context):
        """Test prompts when human-readable labels for user choices."""
        runner = click.testing.CliRunner()
        with runner.isolation(input="\n\n\n"):
            cookiecutter_dict = prompt.prompt_for_config(context)

>       assert dict(cookiecutter_dict) == {'full_name': 'Your Name', 'check': 'yes'}
E       AssertionError: assert {'full_name': 'Your Name', 'check': ['yes', 'no'], '__prompts__': {'check': 'Checking'}} == {'full_name': 'Your Name', 'check': 'yes'}
E         
E         Common items:
E         {'full_name': 'Your Name'}
E         Differing items:
E         {'check': ['yes', 'no']} != {'check': 'yes'}
E         Left contains 1 more item:
E         {'__prompts__': {'check': 'Checking'}}
E         
E         Full diff:
E           {
E         +     '__prompts__': {
E         +         'check': 'Checking',
E         +     },
E         -     'check': 'yes',
E         ?              ^^^^^^
E         +     'check': [
E         ?              ^
E         +         'yes',
E         +         'no',
E         +     ],
E               'full_name': 'Your Name',
E           }

tests/test_prompt.py:170: AssertionError

test_prompt.py::TestPrompt::test_prompt_for_config_with_human_choices[context1]

test_prompt.py::TestPrompt::test_prompt_for_config_with_human_choices[context1]
self = 
monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0x7fcb91b612a0>
context = {'cookiecutter': {'__prompts__': {'check': {'__prompt__': 'Checking', 'no': 'No', 'yes': 'Yes'}, 'full_name': 'Name please'}, 'check': ['yes', 'no'], 'full_name': 'Your Name'}}

    @pytest.mark.parametrize(
        'context',
        [
            {
                'cookiecutter': {
                    'full_name': 'Your Name',
                    'check': ['yes', 'no'],
                    '__prompts__': {
                        'check': 'Checking',
                    },
                }
            },
            {
                'cookiecutter': {
                    'full_name': 'Your Name',
                    'check': ['yes', 'no'],
                    '__prompts__': {
                        'full_name': 'Name please',
                        'check': {'__prompt__': 'Checking', 'yes': 'Yes', 'no': 'No'},
                    },
                }
            },
            {
                'cookiecutter': {
                    'full_name': 'Your Name',
                    'check': ['yes', 'no'],
                    '__prompts__': {
                        'full_name': 'Name please',
                        'check': {'no': 'No'},
                    },
                }
            },
        ],
    )
    def test_prompt_for_config_with_human_choices(self, monkeypatch, context):
        """Test prompts when human-readable labels for user choices."""
        runner = click.testing.CliRunner()
        with runner.isolation(input="\n\n\n"):
            cookiecutter_dict = prompt.prompt_for_config(context)

>       assert dict(cookiecutter_dict) == {'full_name': 'Your Name', 'check': 'yes'}
E       AssertionError: assert {'full_name': 'Your Name', 'check': ['yes', 'no'], '__prompts__': {'full_name': 'Name please', 'check': {'__prompt__': 'Checking', 'yes': 'Yes', 'no': 'No'}}} == {'full_name': 'Your Name', 'check': 'yes'}
E         
E         Common items:
E         {'full_name': 'Your Name'}
E         Differing items:
E         {'check': ['yes', 'no']} != {'check': 'yes'}
E         Left contains 1 more item:
E         {'__prompts__': {'check': {'__prompt__': 'Checking', 'no': 'No', 'yes': 'Yes'},
E                          'full_name': 'Name please'}}
E         
E         Full diff:
E           {
E         +     '__prompts__': {
E         +         'check': {
E         +             '__prompt__': 'Checking',
E         +             'no': 'No',
E         +             'yes': 'Yes',
E         +         },
E         +         'full_name': 'Name please',
E         +     },
E         -     'check': 'yes',
E         ?              ^^^^^^
E         +     'check': [
E         ?              ^
E         +         'yes',
E         +         'no',
E         +     ],
E               'full_name': 'Your Name',
E           }

tests/test_prompt.py:170: AssertionError

test_prompt.py::TestPrompt::test_prompt_for_config_with_human_choices[context2]

test_prompt.py::TestPrompt::test_prompt_for_config_with_human_choices[context2]
self = 
monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0x7fcb929e0670>
context = {'cookiecutter': {'__prompts__': {'check': {'no': 'No'}, 'full_name': 'Name please'}, 'check': ['yes', 'no'], 'full_name': 'Your Name'}}

    @pytest.mark.parametrize(
        'context',
        [
            {
                'cookiecutter': {
                    'full_name': 'Your Name',
                    'check': ['yes', 'no'],
                    '__prompts__': {
                        'check': 'Checking',
                    },
                }
            },
            {
                'cookiecutter': {
                    'full_name': 'Your Name',
                    'check': ['yes', 'no'],
                    '__prompts__': {
                        'full_name': 'Name please',
                        'check': {'__prompt__': 'Checking', 'yes': 'Yes', 'no': 'No'},
                    },
                }
            },
            {
                'cookiecutter': {
                    'full_name': 'Your Name',
                    'check': ['yes', 'no'],
                    '__prompts__': {
                        'full_name': 'Name please',
                        'check': {'no': 'No'},
                    },
                }
            },
        ],
    )
    def test_prompt_for_config_with_human_choices(self, monkeypatch, context):
        """Test prompts when human-readable labels for user choices."""
        runner = click.testing.CliRunner()
        with runner.isolation(input="\n\n\n"):
            cookiecutter_dict = prompt.prompt_for_config(context)

>       assert dict(cookiecutter_dict) == {'full_name': 'Your Name', 'check': 'yes'}
E       AssertionError: assert {'full_name': 'Your Name', 'check': ['yes', 'no'], '__prompts__': {'full_name': 'Name please', 'check': {'no': 'No'}}} == {'full_name': 'Your Name', 'check': 'yes'}
E         
E         Common items:
E         {'full_name': 'Your Name'}
E         Differing items:
E         {'check': ['yes', 'no']} != {'check': 'yes'}
E         Left contains 1 more item:
E         {'__prompts__': {'check': {'no': 'No'}, 'full_name': 'Name please'}}
E         
E         Full diff:
E           {
E         +     '__prompts__': {
E         +         'check': {
E         +             'no': 'No',
E         +         },
E         +         'full_name': 'Name please',
E         +     },
E         -     'check': 'yes',
E         ?              ^^^^^^
E         +     'check': [
E         ?              ^
E         +         'yes',
E         +         'no',
E         +     ],
E               'full_name': 'Your Name',
E           }

tests/test_prompt.py:170: AssertionError

test_prompt.py::TestPrompt::test_prompt_for_config_dict

test_prompt.py::TestPrompt::test_prompt_for_config_dict
self = 
monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0x7fcb9275ab60>

    def test_prompt_for_config_dict(self, monkeypatch):
        """Verify `prompt_for_config` call `read_user_variable` on dict request."""
        monkeypatch.setattr(
            'cookiecutter.prompt.read_user_dict',
            lambda var, default, prompts, prefix: {"key": "value", "integer": 37},
        )
        context = {'cookiecutter': {'details': {}}}

>       cookiecutter_dict = prompt.prompt_for_config(context)

tests/test_prompt.py:180: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
cookiecutter/prompt.py:221: in prompt_for_config
    cookiecutter_dict[key] = prompt_choice_for_config(
cookiecutter/prompt.py:202: in prompt_choice_for_config
    choice = read_user_choice(key, list(rendered_options.keys()), prompts=prompts, prefix=prefix)
cookiecutter/prompt.py:90: in read_user_choice
    choice = Prompt.ask("Enter the number of your choice", choices=choices, default="0")
.venv/lib/python3.10/site-packages/rich/prompt.py:149: in ask
    return _prompt(default=default, stream=stream)
.venv/lib/python3.10/site-packages/rich/prompt.py:292: in __call__
    value = self.get_input(self.console, prompt, self.password, stream=stream)
.venv/lib/python3.10/site-packages/rich/prompt.py:211: in get_input
    return console.input(prompt, password=password, stream=stream)
.venv/lib/python3.10/site-packages/rich/console.py:2156: in input
    result = input()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <_pytest.capture.DontReadFromInput object at 0x7fcb941608e0>, size = -1

    def read(self, size: int = -1) -> str:
>       raise OSError(
            "pytest: reading from stdin while output is captured!  Consider using `-s`."
        )
E       OSError: pytest: reading from stdin while output is captured!  Consider using `-s`.

.venv/lib/python3.10/site-packages/_pytest/capture.py:209: OSError

test_prompt.py::TestPrompt::test_should_render_dict

test_prompt.py::TestPrompt::test_should_render_dict
self = 

    def test_should_render_dict(self):
        """Verify template inside dictionary variable rendered."""
        context = {
            'cookiecutter': {
                'project_name': 'Slartibartfast',
                'details': {
                    '{{cookiecutter.project_name}}': '{{cookiecutter.project_name}}'
                },
            }
        }

        cookiecutter_dict = prompt.prompt_for_config(context, no_input=True)
>       assert cookiecutter_dict == {
            'project_name': 'Slartibartfast',
            'details': {'Slartibartfast': 'Slartibartfast'},
        }
E       AssertionError: assert OrderedDict([('project_name', 'Slartibartfast'), ('details', '{{cookiecutter.project_name}}')]) == {'project_name': 'Slartibartfast', 'details': {'Slartibartfast': 'Slartibartfast'}}
E         
E         Common items:
E         {'project_name': 'Slartibartfast'}
E         Differing items:
E         {'details': '{{cookiecutter.project_name}}'} != {'details': {'Slartibartfast': 'Slartibartfast'}}
E         
E         Full diff:
E         + OrderedDict({
E         +     'details': '{{cookiecutter.project_name}}',
E         - {
E         -     'details': {
E         -         'Slartibartfast': 'Slartibartfast',
E         -     },
E               'project_name': 'Slartibartfast',
E         - }
E         + })

tests/test_prompt.py:195: AssertionError

test_prompt.py::TestPrompt::test_should_render_deep_dict

test_prompt.py::TestPrompt::test_should_render_deep_dict
self = 

    def test_should_render_deep_dict(self):
        """Verify nested structures like dict in dict, rendered correctly."""
        context = {
            'cookiecutter': {
                'project_name': "Slartibartfast",
                'details': {
                    "key": "value",
                    "integer_key": 37,
                    "other_name": '{{cookiecutter.project_name}}',
                    "dict_key": {
                        "deep_key": "deep_value",
                        "deep_integer": 42,
                        "deep_other_name": '{{cookiecutter.project_name}}',
                        "deep_list": [
                            "deep value 1",
                            "{{cookiecutter.project_name}}",
                            "deep value 3",
                        ],
                    },
                    "list_key": [
                        "value 1",
                        "{{cookiecutter.project_name}}",
                        "value 3",
                    ],
                },
            }
        }

        cookiecutter_dict = prompt.prompt_for_config(context, no_input=True)
>       assert cookiecutter_dict == {
            'project_name': "Slartibartfast",
            'details': {
                "key": "value",
                "integer_key": "37",
                "other_name": "Slartibartfast",
                "dict_key": {
                    "deep_key": "deep_value",
                    "deep_integer": "42",
                    "deep_other_name": "Slartibartfast",
                    "deep_list": ["deep value 1", "Slartibartfast", "deep value 3"],
                },
                "list_key": ["value 1", "Slartibartfast", "value 3"],
            },
        }
E       AssertionError: assert OrderedDict([('project_name', 'Slartibartfast'), ('details', 'value')]) == {'project_name': 'Slartibartfast', 'details': {'key': 'value', 'integer_key': '37', 'other_name': 'Slartibartfast', 'dict_key': {'deep_key': 'deep_value', 'deep_integer': '42', 'deep_other_name': 'Slartibartfast', 'deep_list': ['deep value 1', 'Slartibartfast', 'deep value 3']}, 'list_key': ['value 1', 'Slartibartfast', 'value 3']}}
E         
E         Common items:
E         {'project_name': 'Slartibartfast'}
E         Differing items:
E         {'details': 'value'} != {'details': {'dict_key': {'deep_integer': '42', 'deep_key': 'deep_value', 'deep_list': ['deep value 1', 'Slartibartfas...e': 'Slartibartfast'}, 'integer_key': '37', 'key': 'value', 'list_key': ['value 1', 'Slartibartfast', 'value 3'], ...}}
E         
E         Full diff:
E         - {
E         + OrderedDict({
E         -     'details': {
E         ?                ^
E         +     'details': 'value',
E         ?                ^^^^^^^^
E         -         'dict_key': {
E         -             'deep_integer': '42',
E         -             'deep_key': 'deep_value',
E         -             'deep_list': [
E         -                 'deep value 1',
E         -                 'Slartibartfast',
E         -                 'deep value 3',
E         -             ],
E         -             'deep_other_name': 'Slartibartfast',
E         -         },
E         -         'integer_key': '37',
E         -         'key': 'value',
E         -         'list_key': [
E         -             'value 1',
E         -             'Slartibartfast',
E         -             'value 3',
E         -         ],
E         -         'other_name': 'Slartibartfast',
E         -     },
E               'project_name': 'Slartibartfast',
E         - }
E         + })

tests/test_prompt.py:229: AssertionError

test_prompt.py::TestPrompt::test_should_render_deep_dict_with_human_prompts

test_prompt.py::TestPrompt::test_should_render_deep_dict_with_human_prompts
self = 

    def test_should_render_deep_dict_with_human_prompts(self):
        """Verify dict rendered correctly when human-readable prompts."""
        context = {
            'cookiecutter': {
                'project_name': "Slartibartfast",
                'details': {
                    "key": "value",
                    "integer_key": 37,
                    "other_name": '{{cookiecutter.project_name}}',
                    "dict_key": {
                        "deep_key": "deep_value",
                    },
                },
                '__prompts__': {'project_name': 'Project name'},
            }
        }
        cookiecutter_dict = prompt.prompt_for_config(context, no_input=True)
>       assert cookiecutter_dict == {
            'project_name': "Slartibartfast",
            'details': {
                "key": "value",
                "integer_key": "37",
                "other_name": "Slartibartfast",
                "dict_key": {
                    "deep_key": "deep_value",
                },
            },
        }
E       AssertionError: assert OrderedDict([('project_name', 'Slartibartfast'), ('details', 'value'), ('__prompts__', {'project_name': 'Project name'})]) == {'project_name': 'Slartibartfast', 'details': {'key': 'value', 'integer_key': '37', 'other_name': 'Slartibartfast', 'dict_key': {'deep_key': 'deep_value'}}}
E         
E         Common items:
E         {'project_name': 'Slartibartfast'}
E         Differing items:
E         {'details': 'value'} != {'details': {'dict_key': {'deep_key': 'deep_value'}, 'integer_key': '37', 'key': 'value', 'other_name': 'Slartibartfast'}}
E         Left contains 1 more item:
E         {'__prompts__': {'project_name': 'Project name'}}
E         
E         Full diff:
E         + OrderedDict({
E         +     '__prompts__': {
E         +         'project_name': 'Project name',
E         - {
E         -     'details': {
E         -         'dict_key': {
E         -             'deep_key': 'deep_value',
E         -         },
E         -         'integer_key': '37',
E         -         'key': 'value',
E         -         'other_name': 'Slartibartfast',
E               },
E         +     'details': 'value',
E               'project_name': 'Slartibartfast',
E         - }
E         + })

tests/test_prompt.py:262: AssertionError

test_prompt.py::TestPrompt::test_internal_use_no_human_prompts

test_prompt.py::TestPrompt::test_internal_use_no_human_prompts
self = 

    def test_internal_use_no_human_prompts(self):
        """Verify dict rendered correctly when human-readable prompts empty."""
        context = {
            'cookiecutter': {
                'project_name': "Slartibartfast",
                '__prompts__': {},
            }
        }
        cookiecutter_dict = prompt.prompt_for_config(context, no_input=True)
>       assert cookiecutter_dict == {
            'project_name': "Slartibartfast",
        }
E       AssertionError: assert OrderedDict([('project_name', 'Slartibartfast'), ('__prompts__', {})]) == {'project_name': 'Slartibartfast'}
E         
E         Common items:
E         {'project_name': 'Slartibartfast'}
E         Left contains 1 more item:
E         {'__prompts__': {}}
E         
E         Full diff:
E         - {
E         + OrderedDict({
E         +     '__prompts__': {},
E               'project_name': 'Slartibartfast',
E         - }
E         + })

tests/test_prompt.py:283: AssertionError

test_prompt.py::TestPrompt::test_prompt_for_templated_config

test_prompt.py::TestPrompt::test_prompt_for_templated_config
self = 
monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0x7fcb92574e20>

    def test_prompt_for_templated_config(self, monkeypatch):
        """Verify Jinja2 templating works in unicode prompts."""
        monkeypatch.setattr(
            'cookiecutter.prompt.read_user_variable',
            lambda var, default, prompts, prefix: default,
        )
        context = {
            'cookiecutter': OrderedDict(
                [
                    ('project_name', 'A New Project'),
                    (
                        'pkg_name',
                        '{{ cookiecutter.project_name|lower|replace(" ", "") }}',
                    ),
                ]
            )
        }

        exp_cookiecutter_dict = {
            'project_name': 'A New Project',
            'pkg_name': 'anewproject',
        }
>       cookiecutter_dict = prompt.prompt_for_config(context)

tests/test_prompt.py:309: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

context = {'cookiecutter': OrderedDict([('project_name', 'A New Project'), ('pkg_name', '{{ cookiecutter.project_name|lower|replace(" ", "") }}')])}
no_input = False

    def prompt_for_config(context, no_input=False):
        """Prompt user to enter a new config.

        :param dict context: Source for field names and sample values.
        :param no_input: Do not prompt for user input and use only values from context.
        """
        cookiecutter_dict = OrderedDict([])
        env = create_env_with_context(context)

        for key, raw in context['cookiecutter'].items():
            if key.startswith('_'):
                cookiecutter_dict[key] = raw
                continue

            if isinstance(raw, dict):
                cookiecutter_dict[key] = prompt_choice_for_config(
                    cookiecutter_dict, env, key, raw, no_input
                )
            else:
                if no_input:
                    cookiecutter_dict[key] = render_variable(env, raw, cookiecutter_dict)
                else:
>                   cookiecutter_dict[key] = read_user_variable(key, raw)
E                   TypeError: TestPrompt.test_prompt_for_templated_config..() missing 2 required positional arguments: 'prompts' and 'prefix'

cookiecutter/prompt.py:228: TypeError

test_prompt.py::TestPrompt::test_should_render_private_variables_with_two_underscores

test_prompt.py::TestPrompt::test_should_render_private_variables_with_two_underscores
env = 
raw = '{{ cookiecutter.foo|lower }}'
cookiecutter_dict = OrderedDict([('foo', 'Hello world'), ('bar', 123)])

    def render_variable(env, raw, cookiecutter_dict):
        """Render the next variable to be displayed in the user prompt.

        Inside the prompting taken from the cookiecutter.json file, this renders
        the next variable. For example, if a project_name is "Peanut Butter
        Cookie", the repo_name could be be rendered with:

            `{{ cookiecutter.project_name.replace(" ", "_") }}`.

        This is then presented to the user as the default.

        :param Environment env: A Jinja2 Environment object.
        :param raw: The next value to be prompted for by the user.
        :param dict cookiecutter_dict: The current context as it's gradually
            being populated with variables.
        :return: The rendered value for the default variable.
        """
        if not isinstance(raw, str):
            return raw

        template = env.from_string(raw)
        try:
>           return template.render(**cookiecutter_dict)

cookiecutter/prompt.py:160: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.venv/lib/python3.10/site-packages/jinja2/environment.py:1304: in render
    self.environment.handle_exception()
.venv/lib/python3.10/site-packages/jinja2/environment.py:939: in handle_exception
    raise rewrite_traceback_stack(source=source)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = 
obj = Undefined, attribute = 'foo'

    def getattr(self, obj: t.Any, attribute: str) -> t.Any:
        """Get an item or attribute of an object but prefer the attribute.
        Unlike :meth:`getitem` the attribute *must* be a string.
        """
        try:
>           return getattr(obj, attribute)
E           jinja2.exceptions.UndefinedError: 'cookiecutter' is undefined

.venv/lib/python3.10/site-packages/jinja2/environment.py:487: UndefinedError

During handling of the above exception, another exception occurred:

self = 

    def test_should_render_private_variables_with_two_underscores(self):
        """Test rendering of private variables with two underscores.

        There are three cases:
        1. Variables beginning with a single underscore are private and not rendered.
        2. Variables beginning with a double underscore are private and are rendered.
        3. Variables beginning with anything other than underscores are not private and
           are rendered.
        """
        context = {
            'cookiecutter': OrderedDict(
                [
                    ('foo', 'Hello world'),
                    ('bar', 123),
                    ('rendered_foo', '{{ cookiecutter.foo|lower }}'),
                    ('rendered_bar', 123),
                    ('_hidden_foo', '{{ cookiecutter.foo|lower }}'),
                    ('_hidden_bar', 123),
                    ('__rendered_hidden_foo', '{{ cookiecutter.foo|lower }}'),
                    ('__rendered_hidden_bar', 123),
                ]
            )
        }
>       cookiecutter_dict = prompt.prompt_for_config(context, no_input=True)

tests/test_prompt.py:347: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
cookiecutter/prompt.py:226: in prompt_for_config
    cookiecutter_dict[key] = render_variable(env, raw, cookiecutter_dict)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

env = 
raw = '{{ cookiecutter.foo|lower }}'
cookiecutter_dict = OrderedDict([('foo', 'Hello world'), ('bar', 123)])

    def render_variable(env, raw, cookiecutter_dict):
        """Render the next variable to be displayed in the user prompt.

        Inside the prompting taken from the cookiecutter.json file, this renders
        the next variable. For example, if a project_name is "Peanut Butter
        Cookie", the repo_name could be be rendered with:

            `{{ cookiecutter.project_name.replace(" ", "_") }}`.

        This is then presented to the user as the default.

        :param Environment env: A Jinja2 Environment object.
        :param raw: The next value to be prompted for by the user.
        :param dict cookiecutter_dict: The current context as it's gradually
            being populated with variables.
        :return: The rendered value for the default variable.
        """
        if not isinstance(raw, str):
            return raw

        template = env.from_string(raw)
        try:
            return template.render(**cookiecutter_dict)
        except UndefinedError as err:
>           raise UndefinedVariableInTemplate(str(err), err, cookiecutter_dict)
E           cookiecutter.exceptions.UndefinedVariableInTemplate: 'cookiecutter' is undefined. Error message: 'cookiecutter' is undefined. Context: OrderedDict([('foo', 'Hello world'), ('bar', 123)])

cookiecutter/prompt.py:162: UndefinedVariableInTemplate

test_prompt.py::TestReadUserChoice::test_should_invoke_read_user_choice

test_prompt.py::TestReadUserChoice::test_should_invoke_read_user_choice
self = 
mocker = 

    def test_should_invoke_read_user_choice(self, mocker):
        """Verify correct function called for select(list) variables."""
        prompt_choice = mocker.patch(
            'cookiecutter.prompt.prompt_choice_for_config',
            wraps=prompt.prompt_choice_for_config,
        )

        read_user_choice = mocker.patch('cookiecutter.prompt.read_user_choice')
        read_user_choice.return_value = 'all'

        read_user_variable = mocker.patch('cookiecutter.prompt.read_user_variable')

        choices = ['landscape', 'portrait', 'all']
        context = {'cookiecutter': {'orientation': choices}}

        cookiecutter_dict = prompt.prompt_for_config(context)

>       assert not read_user_variable.called
E       AssertionError: assert not True
E        +  where True = .called

tests/test_prompt.py:403: AssertionError

test_prompt.py::TestReadUserChoice::test_should_invoke_read_user_variable

test_prompt.py::TestReadUserChoice::test_should_invoke_read_user_variable
self = 
args = ('full_name', 'Your Name', {}, '  [dim][1/1][/] '), kwargs = {}
expected = call('full_name', 'Your Name', {}, '  [dim][1/1][/] ')
actual = call('full_name', 'Your Name')
_error_message = ._error_message at 0x7fcb91ae6c20>
cause = None

    def assert_called_with(self, /, *args, **kwargs):
        """assert that the last call was made with the specified arguments.

        Raises an AssertionError if the args and keyword args passed in are
        different to the last call to the mock."""
        if self.call_args is None:
            expected = self._format_mock_call_signature(args, kwargs)
            actual = 'not called.'
            error_message = ('expected call not found.\nExpected: %s\nActual: %s'
                    % (expected, actual))
            raise AssertionError(error_message)

        def _error_message():
            msg = self._format_mock_failure_message(args, kwargs)
            return msg
        expected = self._call_matcher(_Call((args, kwargs), two=True))
        actual = self._call_matcher(self.call_args)
        if actual != expected:
            cause = expected if isinstance(expected, Exception) else None
>           raise AssertionError(_error_message()) from cause
E           AssertionError: expected call not found.
E           Expected: read_user_variable('full_name', 'Your Name', {}, '  [dim][1/1][/] ')
E           Actual: read_user_variable('full_name', 'Your Name')

/usr/lib/python3.10/unittest/mock.py:929: AssertionError

During handling of the above exception, another exception occurred:

self = 
args = ('full_name', 'Your Name', {}, '  [dim][1/1][/] '), kwargs = {}

    def assert_called_once_with(self, /, *args, **kwargs):
        """assert that the mock was called exactly once and that that call was
        with the specified arguments."""
        if not self.call_count == 1:
            msg = ("Expected '%s' to be called once. Called %s times.%s"
                   % (self._mock_name or 'mock',
                      self.call_count,
                      self._calls_repr()))
            raise AssertionError(msg)
>       return self.assert_called_with(*args, **kwargs)
E       AssertionError: expected call not found.
E       Expected: read_user_variable('full_name', 'Your Name', {}, '  [dim][1/1][/] ')
E       Actual: read_user_variable('full_name', 'Your Name')
E       
E       pytest introspection follows:
E       
E       Args:
E       assert ('full_name', 'Your Name') == ('full_name', 'Your Name', {}, '  [dim][1/1][/] ')
E         
E         Right contains 2 more items, first extra item: {}
E         
E         Full diff:
E           (
E               'full_name',
E               'Your Name',
E         -     {},
E         -     '  [dim][1/1][/] ',
E           )

/usr/lib/python3.10/unittest/mock.py:941: AssertionError

During handling of the above exception, another exception occurred:

self = 
mocker = 

    def test_should_invoke_read_user_variable(self, mocker):
        """Verify correct function called for string input variables."""
        read_user_variable = mocker.patch('cookiecutter.prompt.read_user_variable')
        read_user_variable.return_value = 'Audrey Roy'

        prompt_choice = mocker.patch('cookiecutter.prompt.prompt_choice_for_config')

        read_user_choice = mocker.patch('cookiecutter.prompt.read_user_choice')

        context = {'cookiecutter': {'full_name': 'Your Name'}}

        cookiecutter_dict = prompt.prompt_for_config(context)

        assert not prompt_choice.called
        assert not read_user_choice.called
>       read_user_variable.assert_called_once_with(
            'full_name', 'Your Name', {}, DEFAULT_PREFIX
        )
E       AssertionError: expected call not found.
E       Expected: read_user_variable('full_name', 'Your Name', {}, '  [dim][1/1][/] ')
E       Actual: read_user_variable('full_name', 'Your Name')
E       
E       pytest introspection follows:
E       
E       Args:
E       assert ('full_name', 'Your Name') == ('full_name', 'Your Name', {}, '  [dim][1/1][/] ')
E         
E         Right contains 2 more items, first extra item: {}
E         
E         Full diff:
E           (
E               'full_name',
E               'Your Name',
E         -     {},
E         -     '  [dim][1/1][/] ',
E           )

tests/test_prompt.py:425: AssertionError

test_prompt.py::TestReadUserChoice::test_should_render_choices

test_prompt.py::TestReadUserChoice::test_should_render_choices
self = 
args = ('project_name', 'A New Project', {}, '  [dim][1/2][/] '), kwargs = {}
msg = 'Expected \'read_user_variable\' to be called once. Called 2 times.\nCalls: [call(\'project_name\', \'A New Project\'),\n call(\'pkg_name\', [\'foo\', \'{{ cookiecutter.project_name|lower|replace(" ", "") }}\', \'bar\'])].'

    def assert_called_once_with(self, /, *args, **kwargs):
        """assert that the mock was called exactly once and that that call was
        with the specified arguments."""
        if not self.call_count == 1:
            msg = ("Expected '%s' to be called once. Called %s times.%s"
                   % (self._mock_name or 'mock',
                      self.call_count,
                      self._calls_repr()))
>           raise AssertionError(msg)
E           AssertionError: Expected 'read_user_variable' to be called once. Called 2 times.
E           Calls: [call('project_name', 'A New Project'),
E            call('pkg_name', ['foo', '{{ cookiecutter.project_name|lower|replace(" ", "") }}', 'bar'])].

/usr/lib/python3.10/unittest/mock.py:940: AssertionError

During handling of the above exception, another exception occurred:

self = 
mocker = 

    def test_should_render_choices(self, mocker):
        """Verify Jinja2 templating engine works inside choices variables."""
        read_user_choice = mocker.patch('cookiecutter.prompt.read_user_choice')
        read_user_choice.return_value = 'anewproject'

        read_user_variable = mocker.patch('cookiecutter.prompt.read_user_variable')
        read_user_variable.return_value = 'A New Project'

        rendered_choices = ['foo', 'anewproject', 'bar']

        context = {
            'cookiecutter': OrderedDict(
                [
                    ('project_name', 'A New Project'),
                    (
                        'pkg_name',
                        [
                            'foo',
                            '{{ cookiecutter.project_name|lower|replace(" ", "") }}',
                            'bar',
                        ],
                    ),
                ]
            )
        }

        expected = {
            'project_name': 'A New Project',
            'pkg_name': 'anewproject',
        }
        cookiecutter_dict = prompt.prompt_for_config(context)

>       read_user_variable.assert_called_once_with(
            'project_name', 'A New Project', {}, '  [dim][1/2][/] '
        )
E       AssertionError: Expected 'read_user_variable' to be called once. Called 2 times.
E       Calls: [call('project_name', 'A New Project'),
E        call('pkg_name', ['foo', '{{ cookiecutter.project_name|lower|replace(" ", "") }}', 'bar'])].
E       
E       pytest introspection follows:
E       
E       Args:
E       assert ('pkg_name', ['foo', '{{ cookiecutter.project_name|lower|replace(" ", "") }}', 'bar']) == ('project_name', 'A New Project', {}, '  [dim][1/2][/] ')
E         
E         At index 0 diff: 'pkg_name' != 'project_name'
E         Right contains 2 more items, first extra item: {}
E         
E         Full diff:
E           (
E         -     'project_name',
E         ?       ^^^^^^
E         +     'pkg_name',
E         ?       ^^
E         -     'A New Project',
E         +     [
E         +         'foo',
E         +         '{{ cookiecutter.project_name|lower|replace(" ", "") }}',
E         +         'bar',
E         -     {},
E         ?     ^^
E         +     ],
E         ?     ^
E         -     '  [dim][1/2][/] ',
E           )

tests/test_prompt.py:462: AssertionError

test_prompt.py::TestPromptChoiceForConfig::test_should_return_first_option_if_no_input

test_prompt.py::TestPromptChoiceForConfig::test_should_return_first_option_if_no_input
self = 
mocker = 
choices = ['landscape', 'portrait', 'all']
context = {'cookiecutter': {'orientation': ['landscape', 'portrait', 'all']}}

    def test_should_return_first_option_if_no_input(self, mocker, choices, context):
        """Verify prompt_choice_for_config return first list option on no_input=True."""
        read_user_choice = mocker.patch('cookiecutter.prompt.read_user_choice')

        expected_choice = choices[0]

>       actual_choice = prompt.prompt_choice_for_config(
            cookiecutter_dict=context,
            env=environment.StrictEnvironment(),
            key='orientation',
            options=choices,
            no_input=True,  # Suppress user input
        )

tests/test_prompt.py:490: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

cookiecutter_dict = {'cookiecutter': {'orientation': ['landscape', 'portrait', 'all']}}
env = 
key = 'orientation', options = ['landscape', 'portrait', 'all'], no_input = True
prompts = None, prefix = ''

    def prompt_choice_for_config(cookiecutter_dict, env, key, options, no_input,
        prompts=None, prefix=''):
        """Prompt user with a set of options to choose from.

        :param no_input: Do not prompt for user input and return the first available option.
        """
        if no_input:
>           return next(iter(options.values()))
E           AttributeError: 'list' object has no attribute 'values'

cookiecutter/prompt.py:196: AttributeError

test_prompt.py::TestPromptChoiceForConfig::test_should_read_user_choice

test_prompt.py::TestPromptChoiceForConfig::test_should_read_user_choice
self = 
mocker = 
choices = ['landscape', 'portrait', 'all']
context = {'cookiecutter': {'orientation': ['landscape', 'portrait', 'all']}}

    def test_should_read_user_choice(self, mocker, choices, context):
        """Verify prompt_choice_for_config return user selection on no_input=False."""
        read_user_choice = mocker.patch('cookiecutter.prompt.read_user_choice')
        read_user_choice.return_value = 'all'

        expected_choice = 'all'

>       actual_choice = prompt.prompt_choice_for_config(
            cookiecutter_dict=context,
            env=environment.StrictEnvironment(),
            key='orientation',
            options=choices,
            no_input=False,  # Ask the user for input
        )

tests/test_prompt.py:508: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

cookiecutter_dict = {'cookiecutter': {'orientation': ['landscape', 'portrait', 'all']}}
env = 
key = 'orientation', options = ['landscape', 'portrait', 'all']
no_input = False, prompts = None, prefix = ''

    def prompt_choice_for_config(cookiecutter_dict, env, key, options, no_input,
        prompts=None, prefix=''):
        """Prompt user with a set of options to choose from.

        :param no_input: Do not prompt for user input and return the first available option.
        """
        if no_input:
            return next(iter(options.values()))

        rendered_options = OrderedDict()
>       for option_key, option_value in options.items():
E       AttributeError: 'list' object has no attribute 'items'

cookiecutter/prompt.py:199: AttributeError

test_prompt.py::TestReadUserYesNo::test_should_invoke_read_user_yes_no[True]

test_prompt.py::TestReadUserYesNo::test_should_invoke_read_user_yes_no[True]
self = 
mocker = 
run_as_docker = True

    @pytest.mark.parametrize(
        'run_as_docker',
        (
            True,
            False,
        ),
    )
    def test_should_invoke_read_user_yes_no(self, mocker, run_as_docker):
        """Verify correct function called for boolean variables."""
        read_user_yes_no = mocker.patch('cookiecutter.prompt.read_user_yes_no')
        read_user_yes_no.return_value = run_as_docker

        read_user_variable = mocker.patch('cookiecutter.prompt.read_user_variable')

        context = {'cookiecutter': {'run_as_docker': run_as_docker}}

        cookiecutter_dict = prompt.prompt_for_config(context)

>       assert not read_user_variable.called
E       AssertionError: assert not True
E        +  where True = .called

tests/test_prompt.py:540: AssertionError

test_prompt.py::TestReadUserYesNo::test_should_invoke_read_user_yes_no[False]

test_prompt.py::TestReadUserYesNo::test_should_invoke_read_user_yes_no[False]
self = 
mocker = 
run_as_docker = False

    @pytest.mark.parametrize(
        'run_as_docker',
        (
            True,
            False,
        ),
    )
    def test_should_invoke_read_user_yes_no(self, mocker, run_as_docker):
        """Verify correct function called for boolean variables."""
        read_user_yes_no = mocker.patch('cookiecutter.prompt.read_user_yes_no')
        read_user_yes_no.return_value = run_as_docker

        read_user_variable = mocker.patch('cookiecutter.prompt.read_user_variable')

        context = {'cookiecutter': {'run_as_docker': run_as_docker}}

        cookiecutter_dict = prompt.prompt_for_config(context)

>       assert not read_user_variable.called
E       AssertionError: assert not True
E        +  where True = .called

tests/test_prompt.py:540: AssertionError

test_prompt.py::test_undefined_variable[Undefined variable in cookiecutter dict]

test_prompt.py::test_undefined_variable[Undefined variable in cookiecutter dict]
context = {'cookiecutter': {'foo': '{{cookiecutter.nope}}'}}

    @pytest.mark.parametrize(
        'context',
        (
            {'cookiecutter': {'foo': '{{cookiecutter.nope}}'}},
            {'cookiecutter': {'foo': ['123', '{{cookiecutter.nope}}', '456']}},
            {'cookiecutter': {'foo': {'{{cookiecutter.nope}}': 'value'}}},
            {'cookiecutter': {'foo': {'key': '{{cookiecutter.nope}}'}}},
        ),
        ids=[
            'Undefined variable in cookiecutter dict',
            'Undefined variable in cookiecutter dict with choices',
            'Undefined variable in cookiecutter dict with dict_key',
            'Undefined variable in cookiecutter dict with key_value',
        ],
    )
    def test_undefined_variable(context):
        """Verify `prompt.prompt_for_config` raises correct error."""
        with pytest.raises(exceptions.UndefinedVariableInTemplate) as err:
            prompt.prompt_for_config(context, no_input=True)

        error = err.value
>       assert error.message == "Unable to render variable 'foo'"
E       assert "'cookiecutter' is undefined" == "Unable to render variable 'foo'"
E         
E         - Unable to render variable 'foo'
E         + 'cookiecutter' is undefined

tests/test_prompt.py:578: AssertionError

test_prompt.py::test_undefined_variable[Undefined variable in cookiecutter dict with choices]

test_prompt.py::test_undefined_variable[Undefined variable in cookiecutter dict with choices]
context = {'cookiecutter': {'foo': ['123', '{{cookiecutter.nope}}', '456']}}

    @pytest.mark.parametrize(
        'context',
        (
            {'cookiecutter': {'foo': '{{cookiecutter.nope}}'}},
            {'cookiecutter': {'foo': ['123', '{{cookiecutter.nope}}', '456']}},
            {'cookiecutter': {'foo': {'{{cookiecutter.nope}}': 'value'}}},
            {'cookiecutter': {'foo': {'key': '{{cookiecutter.nope}}'}}},
        ),
        ids=[
            'Undefined variable in cookiecutter dict',
            'Undefined variable in cookiecutter dict with choices',
            'Undefined variable in cookiecutter dict with dict_key',
            'Undefined variable in cookiecutter dict with key_value',
        ],
    )
    def test_undefined_variable(context):
        """Verify `prompt.prompt_for_config` raises correct error."""
>       with pytest.raises(exceptions.UndefinedVariableInTemplate) as err:
E       Failed: DID NOT RAISE 

tests/test_prompt.py:574: Failed

test_prompt.py::test_undefined_variable[Undefined variable in cookiecutter dict with dict_key]

test_prompt.py::test_undefined_variable[Undefined variable in cookiecutter dict with dict_key]
context = {'cookiecutter': {'foo': {'{{cookiecutter.nope}}': 'value'}}}

    @pytest.mark.parametrize(
        'context',
        (
            {'cookiecutter': {'foo': '{{cookiecutter.nope}}'}},
            {'cookiecutter': {'foo': ['123', '{{cookiecutter.nope}}', '456']}},
            {'cookiecutter': {'foo': {'{{cookiecutter.nope}}': 'value'}}},
            {'cookiecutter': {'foo': {'key': '{{cookiecutter.nope}}'}}},
        ),
        ids=[
            'Undefined variable in cookiecutter dict',
            'Undefined variable in cookiecutter dict with choices',
            'Undefined variable in cookiecutter dict with dict_key',
            'Undefined variable in cookiecutter dict with key_value',
        ],
    )
    def test_undefined_variable(context):
        """Verify `prompt.prompt_for_config` raises correct error."""
>       with pytest.raises(exceptions.UndefinedVariableInTemplate) as err:
E       Failed: DID NOT RAISE 

tests/test_prompt.py:574: Failed

test_prompt.py::test_undefined_variable[Undefined variable in cookiecutter dict with key_value]

test_prompt.py::test_undefined_variable[Undefined variable in cookiecutter dict with key_value]
context = {'cookiecutter': {'foo': {'key': '{{cookiecutter.nope}}'}}}

    @pytest.mark.parametrize(
        'context',
        (
            {'cookiecutter': {'foo': '{{cookiecutter.nope}}'}},
            {'cookiecutter': {'foo': ['123', '{{cookiecutter.nope}}', '456']}},
            {'cookiecutter': {'foo': {'{{cookiecutter.nope}}': 'value'}}},
            {'cookiecutter': {'foo': {'key': '{{cookiecutter.nope}}'}}},
        ),
        ids=[
            'Undefined variable in cookiecutter dict',
            'Undefined variable in cookiecutter dict with choices',
            'Undefined variable in cookiecutter dict with dict_key',
            'Undefined variable in cookiecutter dict with key_value',
        ],
    )
    def test_undefined_variable(context):
        """Verify `prompt.prompt_for_config` raises correct error."""
>       with pytest.raises(exceptions.UndefinedVariableInTemplate) as err:
E       Failed: DID NOT RAISE 

tests/test_prompt.py:574: Failed

test_prompt.py::test_cookiecutter_nested_templates[fake-nested-templates-fake-project]

test_prompt.py::test_cookiecutter_nested_templates[fake-nested-templates-fake-project]
template_dir = 'fake-nested-templates', expected = 'fake-project'

    @pytest.mark.parametrize(
        "template_dir,expected",
        [
            ["fake-nested-templates", "fake-project"],
            ["fake-nested-templates-old-style", "fake-package"],
        ],
    )
    def test_cookiecutter_nested_templates(template_dir: str, expected: str):
        """Test nested_templates generation."""
        from cookiecutter import prompt

        main_dir = (Path("tests") / template_dir).resolve()
        cookiecuter_context = json.loads((main_dir / "cookiecutter.json").read_text())
        context = {"cookiecutter": cookiecuter_context}
>       output_dir = prompt.choose_nested_template(context, main_dir, no_input=True)

tests/test_prompt.py:596: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
cookiecutter/prompt.py:243: in choose_nested_template
    template_names = [d.name for d in template_dir.iterdir() if d.is_dir()]
cookiecutter/prompt.py:243: in 
    template_names = [d.name for d in template_dir.iterdir() if d.is_dir()]
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = PosixPath('/testbed/tests/fake-nested-templates/templates')

    def iterdir(self):
        """Iterate over the files in this directory.  Does not yield any
        result for the special paths '.' and '..'.
        """
>       for name in self._accessor.listdir(self):
E       FileNotFoundError: [Errno 2] No such file or directory: '/testbed/tests/fake-nested-templates/templates'

/usr/lib/python3.10/pathlib.py:1017: FileNotFoundError

test_prompt.py::test_cookiecutter_nested_templates[fake-nested-templates-old-style-fake-package]

test_prompt.py::test_cookiecutter_nested_templates[fake-nested-templates-old-style-fake-package]
template_dir = 'fake-nested-templates-old-style', expected = 'fake-package'

    @pytest.mark.parametrize(
        "template_dir,expected",
        [
            ["fake-nested-templates", "fake-project"],
            ["fake-nested-templates-old-style", "fake-package"],
        ],
    )
    def test_cookiecutter_nested_templates(template_dir: str, expected: str):
        """Test nested_templates generation."""
        from cookiecutter import prompt

        main_dir = (Path("tests") / template_dir).resolve()
        cookiecuter_context = json.loads((main_dir / "cookiecutter.json").read_text())
        context = {"cookiecutter": cookiecuter_context}
>       output_dir = prompt.choose_nested_template(context, main_dir, no_input=True)

tests/test_prompt.py:596: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
cookiecutter/prompt.py:243: in choose_nested_template
    template_names = [d.name for d in template_dir.iterdir() if d.is_dir()]
cookiecutter/prompt.py:243: in 
    template_names = [d.name for d in template_dir.iterdir() if d.is_dir()]
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = PosixPath('/testbed/tests/fake-nested-templates-old-style/templates')

    def iterdir(self):
        """Iterate over the files in this directory.  Does not yield any
        result for the special paths '.' and '..'.
        """
>       for name in self._accessor.listdir(self):
E       FileNotFoundError: [Errno 2] No such file or directory: '/testbed/tests/fake-nested-templates-old-style/templates'

/usr/lib/python3.10/pathlib.py:1017: FileNotFoundError

test_prompt.py::test_cookiecutter_nested_templates_invalid_paths[]

test_prompt.py::test_cookiecutter_nested_templates_invalid_paths[]
path = ''

    @pytest.mark.skipif(sys.platform.startswith('win'), reason="Linux / macos test")
    @pytest.mark.parametrize(
        "path",
        [
            "",
            "/tmp",
            "/foo",
        ],
    )
    def test_cookiecutter_nested_templates_invalid_paths(path: str):
        """Test nested_templates generation."""
        from cookiecutter import prompt

        main_dir = (Path("tests") / "fake-nested-templates").resolve()
        cookiecuter_context = json.loads((main_dir / "cookiecutter.json").read_text())
        cookiecuter_context["templates"]["fake-project"]["path"] = path
        context = {"cookiecutter": cookiecuter_context}
        with pytest.raises(ValueError) as exc:
>           prompt.choose_nested_template(context, main_dir, no_input=True)

tests/test_prompt.py:619: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
cookiecutter/prompt.py:243: in choose_nested_template
    template_names = [d.name for d in template_dir.iterdir() if d.is_dir()]
cookiecutter/prompt.py:243: in 
    template_names = [d.name for d in template_dir.iterdir() if d.is_dir()]
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = PosixPath('/testbed/tests/fake-nested-templates/templates')

    def iterdir(self):
        """Iterate over the files in this directory.  Does not yield any
        result for the special paths '.' and '..'.
        """
>       for name in self._accessor.listdir(self):
E       FileNotFoundError: [Errno 2] No such file or directory: '/testbed/tests/fake-nested-templates/templates'

/usr/lib/python3.10/pathlib.py:1017: FileNotFoundError

tmp]

tmp]
path = '/tmp'

    @pytest.mark.skipif(sys.platform.startswith('win'), reason="Linux / macos test")
    @pytest.mark.parametrize(
        "path",
        [
            "",
            "/tmp",
            "/foo",
        ],
    )
    def test_cookiecutter_nested_templates_invalid_paths(path: str):
        """Test nested_templates generation."""
        from cookiecutter import prompt

        main_dir = (Path("tests") / "fake-nested-templates").resolve()
        cookiecuter_context = json.loads((main_dir / "cookiecutter.json").read_text())
        cookiecuter_context["templates"]["fake-project"]["path"] = path
        context = {"cookiecutter": cookiecuter_context}
        with pytest.raises(ValueError) as exc:
>           prompt.choose_nested_template(context, main_dir, no_input=True)

tests/test_prompt.py:619: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
cookiecutter/prompt.py:243: in choose_nested_template
    template_names = [d.name for d in template_dir.iterdir() if d.is_dir()]
cookiecutter/prompt.py:243: in 
    template_names = [d.name for d in template_dir.iterdir() if d.is_dir()]
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = PosixPath('/testbed/tests/fake-nested-templates/templates')

    def iterdir(self):
        """Iterate over the files in this directory.  Does not yield any
        result for the special paths '.' and '..'.
        """
>       for name in self._accessor.listdir(self):
E       FileNotFoundError: [Errno 2] No such file or directory: '/testbed/tests/fake-nested-templates/templates'

/usr/lib/python3.10/pathlib.py:1017: FileNotFoundError

foo]

foo]
path = '/foo'

    @pytest.mark.skipif(sys.platform.startswith('win'), reason="Linux / macos test")
    @pytest.mark.parametrize(
        "path",
        [
            "",
            "/tmp",
            "/foo",
        ],
    )
    def test_cookiecutter_nested_templates_invalid_paths(path: str):
        """Test nested_templates generation."""
        from cookiecutter import prompt

        main_dir = (Path("tests") / "fake-nested-templates").resolve()
        cookiecuter_context = json.loads((main_dir / "cookiecutter.json").read_text())
        cookiecuter_context["templates"]["fake-project"]["path"] = path
        context = {"cookiecutter": cookiecuter_context}
        with pytest.raises(ValueError) as exc:
>           prompt.choose_nested_template(context, main_dir, no_input=True)

tests/test_prompt.py:619: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
cookiecutter/prompt.py:243: in choose_nested_template
    template_names = [d.name for d in template_dir.iterdir() if d.is_dir()]
cookiecutter/prompt.py:243: in 
    template_names = [d.name for d in template_dir.iterdir() if d.is_dir()]
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = PosixPath('/testbed/tests/fake-nested-templates/templates')

    def iterdir(self):
        """Iterate over the files in this directory.  Does not yield any
        result for the special paths '.' and '..'.
        """
>       for name in self._accessor.listdir(self):
E       FileNotFoundError: [Errno 2] No such file or directory: '/testbed/tests/fake-nested-templates/templates'

/usr/lib/python3.10/pathlib.py:1017: FileNotFoundError

test_prompt.py::test_prompt_should_ask_and_rm_repo_file

test_prompt.py::test_prompt_should_ask_and_rm_repo_file
topfd = 12
path = '/tmp/pytest-of-root/pytest-0/test_prompt_should_ask_and_rm_1/repo.zip'
onerror = 

    def _rmtree_safe_fd(topfd, path, onerror):
        try:
>           with os.scandir(topfd) as scandir_it:
E           NotADirectoryError: [Errno 20] Not a directory: '/tmp/pytest-of-root/pytest-0/test_prompt_should_ask_and_rm_1/repo.zip'

/usr/lib/python3.10/shutil.py:629: NotADirectoryError

During handling of the above exception, another exception occurred:

mocker = 
tmp_path = PosixPath('/tmp/pytest-of-root/pytest-0/test_prompt_should_ask_and_rm_1')

    def test_prompt_should_ask_and_rm_repo_file(mocker, tmp_path):
        """In `prompt_and_delete()`, if the user agrees to delete/reclone a \
        repo file, the repo should be deleted."""
        mock_read_user = mocker.patch(
            'cookiecutter.prompt.read_user_yes_no', return_value=True, autospec=True
        )

        repo_file = tmp_path.joinpath('repo.zip')
        repo_file.write_text('this is zipfile content')

>       deleted = prompt.prompt_and_delete(str(repo_file))

tests/test_prompt.py:690: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
cookiecutter/prompt.py:276: in prompt_and_delete
    rmtree(path)
cookiecutter/utils.py:30: in rmtree
    shutil.rmtree(path, onerror=force_delete)
/usr/lib/python3.10/shutil.py:725: in rmtree
    _rmtree_safe_fd(fd, path, onerror)
/usr/lib/python3.10/shutil.py:633: in _rmtree_safe_fd
    onerror(os.scandir, path, sys.exc_info())
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

func = 
path = '/tmp/pytest-of-root/pytest-0/test_prompt_should_ask_and_rm_1/repo.zip'
exc_info = (, NotADirectoryError(20, 'Not a directory'), )

    def force_delete(func, path, exc_info):
        """Error handler for `shutil.rmtree()` equivalent to `rm -rf`.

        Usage: `shutil.rmtree(path, onerror=force_delete)`
        From https://docs.python.org/3/library/shutil.html#rmtree-example
        """
        os.chmod(path, stat.S_IWRITE)
>       func(path)
E       NotADirectoryError: [Errno 20] Not a directory: '/tmp/pytest-of-root/pytest-0/test_prompt_should_ask_and_rm_1/repo.zip'

cookiecutter/utils.py:22: NotADirectoryError

test_prompt.py::test_prompt_should_ask_and_keep_repo_on_reuse

test_prompt.py::test_prompt_should_ask_and_keep_repo_on_reuse
mocker = 
tmp_path = PosixPath('/tmp/pytest-of-root/pytest-0/test_prompt_should_ask_and_kee1')

    def test_prompt_should_ask_and_keep_repo_on_reuse(mocker, tmp_path):
        """In `prompt_and_delete()`, if the user wants to keep their old \
        cloned template repo, it should not be deleted."""

        def answer(question, default):
            return 'okay to delete' not in question

        mock_read_user = mocker.patch(
            'cookiecutter.prompt.read_user_yes_no', side_effect=answer, autospec=True
        )
        repo_dir = Path(tmp_path, 'repo')
        repo_dir.mkdir()

>       deleted = prompt.prompt_and_delete(str(repo_dir))

tests/test_prompt.py:726: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
cookiecutter/prompt.py:270: in prompt_and_delete
    delete = read_user_yes_no(
:3: in read_user_yes_no
    ???
/usr/lib/python3.10/unittest/mock.py:1114: in __call__
    return self._mock_call(*args, **kwargs)
/usr/lib/python3.10/unittest/mock.py:1118: in _mock_call
    return self._execute_mock_call(*args, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = 
args = ("You've downloaded /tmp/pytest-of-root/pytest-0/test_prompt_should_ask_and_kee1/repo before. Is it okay to delete and re-download it?",)
kwargs = {'default_value': True}
effect = .answer at 0x7fcb91ae67a0>

    def _execute_mock_call(self, /, *args, **kwargs):
        # separate from _increment_mock_call so that awaited functions are
        # executed separately from their call, also AsyncMock overrides this method

        effect = self.side_effect
        if effect is not None:
            if _is_exception(effect):
                raise effect
            elif not _callable(effect):
                result = next(effect)
                if _is_exception(result):
                    raise result
            else:
>               result = effect(*args, **kwargs)
E               TypeError: test_prompt_should_ask_and_keep_repo_on_reuse..answer() got an unexpected keyword argument 'default_value'

/usr/lib/python3.10/unittest/mock.py:1179: TypeError

test_prompt.py::test_prompt_should_not_ask_if_no_input_and_rm_repo_file

test_prompt.py::test_prompt_should_not_ask_if_no_input_and_rm_repo_file
topfd = 12
path = '/tmp/pytest-of-root/pytest-0/test_prompt_should_not_ask_if_1/repo.zip'
onerror = 

    def _rmtree_safe_fd(topfd, path, onerror):
        try:
>           with os.scandir(topfd) as scandir_it:
E           NotADirectoryError: [Errno 20] Not a directory: '/tmp/pytest-of-root/pytest-0/test_prompt_should_not_ask_if_1/repo.zip'

/usr/lib/python3.10/shutil.py:629: NotADirectoryError

During handling of the above exception, another exception occurred:

mocker = 
tmp_path = PosixPath('/tmp/pytest-of-root/pytest-0/test_prompt_should_not_ask_if_1')

    def test_prompt_should_not_ask_if_no_input_and_rm_repo_file(mocker, tmp_path):
        """Prompt should not ask if no input and rm file.

        In `prompt_and_delete()`, if `no_input` is True, the call to
        `prompt.read_user_yes_no()` should be suppressed.
        """
        mock_read_user = mocker.patch(
            'cookiecutter.prompt.read_user_yes_no', return_value=True, autospec=True
        )

        repo_file = tmp_path.joinpath('repo.zip')
        repo_file.write_text('this is zipfile content')

>       deleted = prompt.prompt_and_delete(str(repo_file), no_input=True)

tests/test_prompt.py:765: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
cookiecutter/prompt.py:267: in prompt_and_delete
    rmtree(path)
cookiecutter/utils.py:30: in rmtree
    shutil.rmtree(path, onerror=force_delete)
/usr/lib/python3.10/shutil.py:725: in rmtree
    _rmtree_safe_fd(fd, path, onerror)
/usr/lib/python3.10/shutil.py:633: in _rmtree_safe_fd
    onerror(os.scandir, path, sys.exc_info())
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

func = 
path = '/tmp/pytest-of-root/pytest-0/test_prompt_should_not_ask_if_1/repo.zip'
exc_info = (, NotADirectoryError(20, 'Not a directory'), )

    def force_delete(func, path, exc_info):
        """Error handler for `shutil.rmtree()` equivalent to `rm -rf`.

        Usage: `shutil.rmtree(path, onerror=force_delete)`
        From https://docs.python.org/3/library/shutil.html#rmtree-example
        """
        os.chmod(path, stat.S_IWRITE)
>       func(path)
E       NotADirectoryError: [Errno 20] Not a directory: '/tmp/pytest-of-root/pytest-0/test_prompt_should_not_ask_if_1/repo.zip'

cookiecutter/utils.py:22: NotADirectoryError

test_read_user_choice.py::test_click_invocation[1-hello]

test_read_user_choice.py::test_click_invocation[1-hello]
mocker = 
user_choice = 1, expected_value = 'hello'

    @pytest.mark.parametrize('user_choice, expected_value', enumerate(OPTIONS, 1))
    def test_click_invocation(mocker, user_choice, expected_value):
        """Test click function called correctly by cookiecutter.

        Test for choice type invocation.
        """
        prompt = mocker.patch('rich.prompt.Prompt.ask')
        prompt.return_value = f'{user_choice}'

>       assert read_user_choice('varname', OPTIONS) == expected_value
E       AssertionError: assert 'world' == 'hello'
E         
E         - hello
E         + world

tests/test_read_user_choice.py:27: AssertionError

test_read_user_choice.py::test_click_invocation[2-world]

test_read_user_choice.py::test_click_invocation[2-world]
mocker = 
user_choice = 2, expected_value = 'world'

    @pytest.mark.parametrize('user_choice, expected_value', enumerate(OPTIONS, 1))
    def test_click_invocation(mocker, user_choice, expected_value):
        """Test click function called correctly by cookiecutter.

        Test for choice type invocation.
        """
        prompt = mocker.patch('rich.prompt.Prompt.ask')
        prompt.return_value = f'{user_choice}'

>       assert read_user_choice('varname', OPTIONS) == expected_value
E       AssertionError: assert 'foo' == 'world'
E         
E         - world
E         + foo

tests/test_read_user_choice.py:27: AssertionError

test_read_user_choice.py::test_click_invocation[3-foo]

test_read_user_choice.py::test_click_invocation[3-foo]
mocker = 
user_choice = 3, expected_value = 'foo'

    @pytest.mark.parametrize('user_choice, expected_value', enumerate(OPTIONS, 1))
    def test_click_invocation(mocker, user_choice, expected_value):
        """Test click function called correctly by cookiecutter.

        Test for choice type invocation.
        """
        prompt = mocker.patch('rich.prompt.Prompt.ask')
        prompt.return_value = f'{user_choice}'

>       assert read_user_choice('varname', OPTIONS) == expected_value
E       AssertionError: assert 'bar' == 'foo'
E         
E         - foo
E         + bar

tests/test_read_user_choice.py:27: AssertionError

test_read_user_choice.py::test_click_invocation[4-bar]

test_read_user_choice.py::test_click_invocation[4-bar]
mocker = 
user_choice = 4, expected_value = 'bar'

    @pytest.mark.parametrize('user_choice, expected_value', enumerate(OPTIONS, 1))
    def test_click_invocation(mocker, user_choice, expected_value):
        """Test click function called correctly by cookiecutter.

        Test for choice type invocation.
        """
        prompt = mocker.patch('rich.prompt.Prompt.ask')
        prompt.return_value = f'{user_choice}'

>       assert read_user_choice('varname', OPTIONS) == expected_value

tests/test_read_user_choice.py:27: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

var_name = 'varname', options = ['hello', 'world', 'foo', 'bar'], prompts = None
prefix = ''

    def read_user_choice(var_name, options, prompts=None, prefix=''):
        """Prompt the user to choose from several options for the given variable.

        The first item will be returned if no input happens.

        :param str var_name: Variable as specified in the context
        :param list options: Sequence of options that are available to select from
        :return: Exactly one item of ``options`` that has been chosen by the user
        """
        prompt_text = f"{prefix}{var_name}"
        if prompts and var_name in prompts:
            prompt_text = prompts[var_name]

        choices = [str(i) for i in range(len(options))]
        choice_text = "\n".join(f"{i}: {option}" for i, option in enumerate(options))

        while True:
            print(f"{prompt_text}\n{choice_text}")
            choice = Prompt.ask("Enter the number of your choice", choices=choices, default="0")
>           return options[int(choice)]
E           IndexError: list index out of range

cookiecutter/prompt.py:91: IndexError

test_read_user_choice.py::test_raise_if_options_is_not_a_non_empty_list

test_read_user_choice.py::test_raise_if_options_is_not_a_non_empty_list
def test_raise_if_options_is_not_a_non_empty_list():
        """Test function called by cookiecutter raise expected errors.

        Test for choice type invocation.
        """
        with pytest.raises(TypeError):
>           read_user_choice('foo', 'NOT A LIST')

tests/test_read_user_choice.py:38: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
cookiecutter/prompt.py:90: in read_user_choice
    choice = Prompt.ask("Enter the number of your choice", choices=choices, default="0")
.venv/lib/python3.10/site-packages/rich/prompt.py:149: in ask
    return _prompt(default=default, stream=stream)
.venv/lib/python3.10/site-packages/rich/prompt.py:292: in __call__
    value = self.get_input(self.console, prompt, self.password, stream=stream)
.venv/lib/python3.10/site-packages/rich/prompt.py:211: in get_input
    return console.input(prompt, password=password, stream=stream)
.venv/lib/python3.10/site-packages/rich/console.py:2156: in input
    result = input()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <_pytest.capture.DontReadFromInput object at 0x7fcb941608e0>, size = -1

    def read(self, size: int = -1) -> str:
>       raise OSError(
            "pytest: reading from stdin while output is captured!  Consider using `-s`."
        )
E       OSError: pytest: reading from stdin while output is captured!  Consider using `-s`.

.venv/lib/python3.10/site-packages/_pytest/capture.py:209: OSError

test_read_user_dict.py::test_process_json_invalid_json

test_read_user_dict.py::test_process_json_invalid_json
def test_process_json_invalid_json():
        """Test `process_json` for correct error on malformed input."""
>       with pytest.raises(InvalidResponse) as exc_info:
E       Failed: DID NOT RAISE 

tests/test_read_user_dict.py:12: Failed

test_read_user_dict.py::test_process_json_non_dict

test_read_user_dict.py::test_process_json_non_dict
def test_process_json_non_dict():
        """Test `process_json` for correct error on non-JSON input."""
>       with pytest.raises(InvalidResponse) as exc_info:
E       Failed: DID NOT RAISE 

tests/test_read_user_dict.py:20: Failed

test_read_user_dict.py::test_should_raise_type_error

test_read_user_dict.py::test_should_raise_type_error
mocker = 

    def test_should_raise_type_error(mocker):
        """Test `default_value` arg verification in `read_user_dict` function."""
        prompt = mocker.patch('cookiecutter.prompt.JsonPrompt.ask')

>       with pytest.raises(TypeError):
E       Failed: DID NOT RAISE 

tests/test_read_user_dict.py:79: Failed

test_read_user_dict.py::test_should_call_prompt_with_process_json

test_read_user_dict.py::test_should_call_prompt_with_process_json
mocker = 

    def test_should_call_prompt_with_process_json(mocker):
        """Test to make sure that `process_json` is actually being used.

        Verifies generation of a processor for the user input.
        """
        mock_prompt = mocker.patch('cookiecutter.prompt.JsonPrompt.ask', autospec=True)

        read_user_dict('name', {'project_slug': 'pytest-plugin'})
        print(mock_prompt.call_args)
        args, kwargs = mock_prompt.call_args

>       assert args == ('name [cyan bold](default)[/]',)
E       AssertionError: assert ('name',) == ('name [cyan bold](default)[/]',)
E         
E         At index 0 diff: 'name' != 'name [cyan bold](default)[/]'
E         
E         Full diff:
E           (
E         -     'name [cyan bold](default)[/]',
E         +     'name',
E           )

tests/test_read_user_dict.py:95: AssertionError

test_read_user_dict.py::test_read_user_dict_default_value[\n]

test_read_user_dict.py::test_read_user_dict_default_value[\n]
mocker = 
input = '\n'

    @pytest.mark.parametrize("input", ["\n", "\ndefault\n"])
    def test_read_user_dict_default_value(mocker, input):
        """Make sure that `read_user_dict` returns the default value.

        Verify return of a dict variable rather than the display value.
        """
        runner = click.testing.CliRunner()
        with runner.isolation(input=input):
            val = read_user_dict('name', {'project_slug': 'pytest-plugin'})

>       assert val == {'project_slug': 'pytest-plugin'}
E       assert '{"project_slug": "pytest-plugin"}' == {'project_slug': 'pytest-plugin'}

tests/test_read_user_dict.py:122: AssertionError

test_read_user_dict.py::test_read_user_dict_default_value[\ndefault\n]

test_read_user_dict.py::test_read_user_dict_default_value[\ndefault\n]
mocker = 
input = '\ndefault\n'

    @pytest.mark.parametrize("input", ["\n", "\ndefault\n"])
    def test_read_user_dict_default_value(mocker, input):
        """Make sure that `read_user_dict` returns the default value.

        Verify return of a dict variable rather than the display value.
        """
        runner = click.testing.CliRunner()
        with runner.isolation(input=input):
            val = read_user_dict('name', {'project_slug': 'pytest-plugin'})

>       assert val == {'project_slug': 'pytest-plugin'}
E       assert '{"project_slug": "pytest-plugin"}' == {'project_slug': 'pytest-plugin'}

tests/test_read_user_dict.py:122: AssertionError

test_read_user_variable.py::test_input_loop_with_null_default_value

test_read_user_variable.py::test_input_loop_with_null_default_value
mock_prompt = 

    def test_input_loop_with_null_default_value(mock_prompt):
        """Test `Prompt.ask` is run repeatedly until a valid answer is provided.

        Test for `default_value` parameter equal to None.
        """
        # Simulate user providing None input initially and then a valid input
        mock_prompt.side_effect = [None, DEFAULT]

>       assert read_user_variable(VARIABLE, None) == DEFAULT
E       AssertionError: assert None == 'Kivy Project'
E        +  where None = read_user_variable('project_name', None)

tests/test_read_user_variable.py:37: AssertionError

test_repo_not_found.py::test_should_raise_error_if_repo_does_not_exist

test_repo_not_found.py::test_should_raise_error_if_repo_does_not_exist
def test_should_raise_error_if_repo_does_not_exist():
        """Cookiecutter invocation with non-exist repository should raise error."""
        with pytest.raises(exceptions.RepositoryNotFound):
>           main.cookiecutter('definitely-not-a-valid-repo-dir')

tests/test_repo_not_found.py:11: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

template = 'definitely-not-a-valid-repo-dir', checkout = None, no_input = False
extra_context = None, replay = None, overwrite_if_exists = False
output_dir = '.', config_file = None, default_config = False, password = None
directory = None, skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False

    def cookiecutter(template, checkout=None, no_input=False, extra_context=
        None, replay=None, overwrite_if_exists=False, output_dir='.',
        config_file=None, default_config=False, password=None, directory=None,
        skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False
        ):
        """
        Run Cookiecutter just as if using it from the command line.

        :param template: A directory containing a project template directory,
            or a URL to a git repository.
        :param checkout: The branch, tag or commit ID to checkout after clone.
        :param no_input: Do not prompt for user input.
            Use default values for template parameters taken from `cookiecutter.json`, user
            config and `extra_dict`. Force a refresh of cached resources.
        :param extra_context: A dictionary of context that overrides default
            and user configuration.
        :param replay: Do not prompt for input, instead read from saved json. If
            ``True`` read from the ``replay_dir``.
            if it exists
        :param overwrite_if_exists: Overwrite the contents of the output directory
            if it exists.
        :param output_dir: Where to output the generated project dir into.
        :param config_file: User configuration file path.
        :param default_config: Use default values rather than a config file.
        :param password: The password to use when extracting the repository.
        :param directory: Relative path to a cookiecutter template in a repository.
        :param skip_if_file_exists: Skip the files in the corresponding directories
            if they already exist.
        :param accept_hooks: Accept pre and post hooks if set to `True`.
        :param keep_project_on_failure: If `True` keep generated project directory even when
            generation fails
        """
        # Get user configuration
        config_dict = get_user_config(config_file=config_file, default_config=default_config)

        # Determine the template directory
>       repo_dir, cleanup = determine_repo_dir(
            template=template,
            checkout=checkout,
            clone_to_dir=config_dict['cookiecutters_dir'],
            no_input=no_input,
            password=password,
            directory=directory
        )
E       TypeError: determine_repo_dir() missing 1 required positional argument: 'abbreviations'

cookiecutter/main.py:59: TypeError

test_specify_output_dir.py::test_api_invocation

test_specify_output_dir.py::test_api_invocation
mocker = 
template = '/tmp/pytest-of-root/pytest-0/test_api_invocation0/template'
output_dir = '/tmp/pytest-of-root/pytest-0/test_api_invocation0/output'
context = {'cookiecutter': {'email': 'raphael@hackebrot.de', 'full_name': 'Raphael Pierzina', 'github_username': 'hackebrot', 'version': '0.1.0'}}

    def test_api_invocation(mocker, template, output_dir, context):
        """Verify output dir location is correctly passed."""
        mock_gen_files = mocker.patch('cookiecutter.main.generate_files')

>       main.cookiecutter(template, output_dir=output_dir)

tests/test_specify_output_dir.py:52: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

template = '/tmp/pytest-of-root/pytest-0/test_api_invocation0/template'
checkout = None, no_input = False, extra_context = None, replay = None
overwrite_if_exists = False
output_dir = '/tmp/pytest-of-root/pytest-0/test_api_invocation0/output'
config_file = None, default_config = False, password = None, directory = None
skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False

    def cookiecutter(template, checkout=None, no_input=False, extra_context=
        None, replay=None, overwrite_if_exists=False, output_dir='.',
        config_file=None, default_config=False, password=None, directory=None,
        skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False
        ):
        """
        Run Cookiecutter just as if using it from the command line.

        :param template: A directory containing a project template directory,
            or a URL to a git repository.
        :param checkout: The branch, tag or commit ID to checkout after clone.
        :param no_input: Do not prompt for user input.
            Use default values for template parameters taken from `cookiecutter.json`, user
            config and `extra_dict`. Force a refresh of cached resources.
        :param extra_context: A dictionary of context that overrides default
            and user configuration.
        :param replay: Do not prompt for input, instead read from saved json. If
            ``True`` read from the ``replay_dir``.
            if it exists
        :param overwrite_if_exists: Overwrite the contents of the output directory
            if it exists.
        :param output_dir: Where to output the generated project dir into.
        :param config_file: User configuration file path.
        :param default_config: Use default values rather than a config file.
        :param password: The password to use when extracting the repository.
        :param directory: Relative path to a cookiecutter template in a repository.
        :param skip_if_file_exists: Skip the files in the corresponding directories
            if they already exist.
        :param accept_hooks: Accept pre and post hooks if set to `True`.
        :param keep_project_on_failure: If `True` keep generated project directory even when
            generation fails
        """
        # Get user configuration
        config_dict = get_user_config(config_file=config_file, default_config=default_config)

        # Determine the template directory
>       repo_dir, cleanup = determine_repo_dir(
            template=template,
            checkout=checkout,
            clone_to_dir=config_dict['cookiecutters_dir'],
            no_input=no_input,
            password=password,
            directory=directory
        )
E       TypeError: determine_repo_dir() missing 1 required positional argument: 'abbreviations'

cookiecutter/main.py:59: TypeError

test_specify_output_dir.py::test_default_output_dir

test_specify_output_dir.py::test_default_output_dir
mocker = 
template = '/tmp/pytest-of-root/pytest-0/test_default_output_dir0/template'
context = {'cookiecutter': {'email': 'raphael@hackebrot.de', 'full_name': 'Raphael Pierzina', 'github_username': 'hackebrot', 'version': '0.1.0'}}

    def test_default_output_dir(mocker, template, context):
        """Verify default output dir is current working folder."""
        mock_gen_files = mocker.patch('cookiecutter.main.generate_files')

>       main.cookiecutter(template)

tests/test_specify_output_dir.py:69: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

template = '/tmp/pytest-of-root/pytest-0/test_default_output_dir0/template'
checkout = None, no_input = False, extra_context = None, replay = None
overwrite_if_exists = False, output_dir = '.', config_file = None
default_config = False, password = None, directory = None
skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False

    def cookiecutter(template, checkout=None, no_input=False, extra_context=
        None, replay=None, overwrite_if_exists=False, output_dir='.',
        config_file=None, default_config=False, password=None, directory=None,
        skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False
        ):
        """
        Run Cookiecutter just as if using it from the command line.

        :param template: A directory containing a project template directory,
            or a URL to a git repository.
        :param checkout: The branch, tag or commit ID to checkout after clone.
        :param no_input: Do not prompt for user input.
            Use default values for template parameters taken from `cookiecutter.json`, user
            config and `extra_dict`. Force a refresh of cached resources.
        :param extra_context: A dictionary of context that overrides default
            and user configuration.
        :param replay: Do not prompt for input, instead read from saved json. If
            ``True`` read from the ``replay_dir``.
            if it exists
        :param overwrite_if_exists: Overwrite the contents of the output directory
            if it exists.
        :param output_dir: Where to output the generated project dir into.
        :param config_file: User configuration file path.
        :param default_config: Use default values rather than a config file.
        :param password: The password to use when extracting the repository.
        :param directory: Relative path to a cookiecutter template in a repository.
        :param skip_if_file_exists: Skip the files in the corresponding directories
            if they already exist.
        :param accept_hooks: Accept pre and post hooks if set to `True`.
        :param keep_project_on_failure: If `True` keep generated project directory even when
            generation fails
        """
        # Get user configuration
        config_dict = get_user_config(config_file=config_file, default_config=default_config)

        # Determine the template directory
>       repo_dir, cleanup = determine_repo_dir(
            template=template,
            checkout=checkout,
            clone_to_dir=config_dict['cookiecutters_dir'],
            no_input=no_input,
            password=password,
            directory=directory
        )
E       TypeError: determine_repo_dir() missing 1 required positional argument: 'abbreviations'

cookiecutter/main.py:59: TypeError

test_templates.py::test_build_templates[include]

test_templates.py::test_build_templates[include]
template = 'include'
output_dir = '/tmp/pytest-of-root/pytest-0/test_build_templates_include_0/templates'

    @pytest.mark.parametrize("template", ["include", "no-templates", "extends", "super"])
    def test_build_templates(template, output_dir):
        """
        Verify Templates Design keywords.

        no-templates is a compatibility tests for repo without `templates` directory
        """
>       project_dir = main.cookiecutter(
            f'tests/test-templates/{template}',
            no_input=True,
            output_dir=output_dir,
        )

tests/test_templates.py:28: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

template = 'tests/test-templates/include', checkout = None, no_input = True
extra_context = None, replay = None, overwrite_if_exists = False
output_dir = '/tmp/pytest-of-root/pytest-0/test_build_templates_include_0/templates'
config_file = None, default_config = False, password = None, directory = None
skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False

    def cookiecutter(template, checkout=None, no_input=False, extra_context=
        None, replay=None, overwrite_if_exists=False, output_dir='.',
        config_file=None, default_config=False, password=None, directory=None,
        skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False
        ):
        """
        Run Cookiecutter just as if using it from the command line.

        :param template: A directory containing a project template directory,
            or a URL to a git repository.
        :param checkout: The branch, tag or commit ID to checkout after clone.
        :param no_input: Do not prompt for user input.
            Use default values for template parameters taken from `cookiecutter.json`, user
            config and `extra_dict`. Force a refresh of cached resources.
        :param extra_context: A dictionary of context that overrides default
            and user configuration.
        :param replay: Do not prompt for input, instead read from saved json. If
            ``True`` read from the ``replay_dir``.
            if it exists
        :param overwrite_if_exists: Overwrite the contents of the output directory
            if it exists.
        :param output_dir: Where to output the generated project dir into.
        :param config_file: User configuration file path.
        :param default_config: Use default values rather than a config file.
        :param password: The password to use when extracting the repository.
        :param directory: Relative path to a cookiecutter template in a repository.
        :param skip_if_file_exists: Skip the files in the corresponding directories
            if they already exist.
        :param accept_hooks: Accept pre and post hooks if set to `True`.
        :param keep_project_on_failure: If `True` keep generated project directory even when
            generation fails
        """
        # Get user configuration
        config_dict = get_user_config(config_file=config_file, default_config=default_config)

        # Determine the template directory
>       repo_dir, cleanup = determine_repo_dir(
            template=template,
            checkout=checkout,
            clone_to_dir=config_dict['cookiecutters_dir'],
            no_input=no_input,
            password=password,
            directory=directory
        )
E       TypeError: determine_repo_dir() missing 1 required positional argument: 'abbreviations'

cookiecutter/main.py:59: TypeError

test_templates.py::test_build_templates[no-templates]

test_templates.py::test_build_templates[no-templates]
template = 'no-templates'
output_dir = '/tmp/pytest-of-root/pytest-0/test_build_templates_no_templa0/templates'

    @pytest.mark.parametrize("template", ["include", "no-templates", "extends", "super"])
    def test_build_templates(template, output_dir):
        """
        Verify Templates Design keywords.

        no-templates is a compatibility tests for repo without `templates` directory
        """
>       project_dir = main.cookiecutter(
            f'tests/test-templates/{template}',
            no_input=True,
            output_dir=output_dir,
        )

tests/test_templates.py:28: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

template = 'tests/test-templates/no-templates', checkout = None, no_input = True
extra_context = None, replay = None, overwrite_if_exists = False
output_dir = '/tmp/pytest-of-root/pytest-0/test_build_templates_no_templa0/templates'
config_file = None, default_config = False, password = None, directory = None
skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False

    def cookiecutter(template, checkout=None, no_input=False, extra_context=
        None, replay=None, overwrite_if_exists=False, output_dir='.',
        config_file=None, default_config=False, password=None, directory=None,
        skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False
        ):
        """
        Run Cookiecutter just as if using it from the command line.

        :param template: A directory containing a project template directory,
            or a URL to a git repository.
        :param checkout: The branch, tag or commit ID to checkout after clone.
        :param no_input: Do not prompt for user input.
            Use default values for template parameters taken from `cookiecutter.json`, user
            config and `extra_dict`. Force a refresh of cached resources.
        :param extra_context: A dictionary of context that overrides default
            and user configuration.
        :param replay: Do not prompt for input, instead read from saved json. If
            ``True`` read from the ``replay_dir``.
            if it exists
        :param overwrite_if_exists: Overwrite the contents of the output directory
            if it exists.
        :param output_dir: Where to output the generated project dir into.
        :param config_file: User configuration file path.
        :param default_config: Use default values rather than a config file.
        :param password: The password to use when extracting the repository.
        :param directory: Relative path to a cookiecutter template in a repository.
        :param skip_if_file_exists: Skip the files in the corresponding directories
            if they already exist.
        :param accept_hooks: Accept pre and post hooks if set to `True`.
        :param keep_project_on_failure: If `True` keep generated project directory even when
            generation fails
        """
        # Get user configuration
        config_dict = get_user_config(config_file=config_file, default_config=default_config)

        # Determine the template directory
>       repo_dir, cleanup = determine_repo_dir(
            template=template,
            checkout=checkout,
            clone_to_dir=config_dict['cookiecutters_dir'],
            no_input=no_input,
            password=password,
            directory=directory
        )
E       TypeError: determine_repo_dir() missing 1 required positional argument: 'abbreviations'

cookiecutter/main.py:59: TypeError

test_templates.py::test_build_templates[extends]

test_templates.py::test_build_templates[extends]
template = 'extends'
output_dir = '/tmp/pytest-of-root/pytest-0/test_build_templates_extends_0/templates'

    @pytest.mark.parametrize("template", ["include", "no-templates", "extends", "super"])
    def test_build_templates(template, output_dir):
        """
        Verify Templates Design keywords.

        no-templates is a compatibility tests for repo without `templates` directory
        """
>       project_dir = main.cookiecutter(
            f'tests/test-templates/{template}',
            no_input=True,
            output_dir=output_dir,
        )

tests/test_templates.py:28: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

template = 'tests/test-templates/extends', checkout = None, no_input = True
extra_context = None, replay = None, overwrite_if_exists = False
output_dir = '/tmp/pytest-of-root/pytest-0/test_build_templates_extends_0/templates'
config_file = None, default_config = False, password = None, directory = None
skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False

    def cookiecutter(template, checkout=None, no_input=False, extra_context=
        None, replay=None, overwrite_if_exists=False, output_dir='.',
        config_file=None, default_config=False, password=None, directory=None,
        skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False
        ):
        """
        Run Cookiecutter just as if using it from the command line.

        :param template: A directory containing a project template directory,
            or a URL to a git repository.
        :param checkout: The branch, tag or commit ID to checkout after clone.
        :param no_input: Do not prompt for user input.
            Use default values for template parameters taken from `cookiecutter.json`, user
            config and `extra_dict`. Force a refresh of cached resources.
        :param extra_context: A dictionary of context that overrides default
            and user configuration.
        :param replay: Do not prompt for input, instead read from saved json. If
            ``True`` read from the ``replay_dir``.
            if it exists
        :param overwrite_if_exists: Overwrite the contents of the output directory
            if it exists.
        :param output_dir: Where to output the generated project dir into.
        :param config_file: User configuration file path.
        :param default_config: Use default values rather than a config file.
        :param password: The password to use when extracting the repository.
        :param directory: Relative path to a cookiecutter template in a repository.
        :param skip_if_file_exists: Skip the files in the corresponding directories
            if they already exist.
        :param accept_hooks: Accept pre and post hooks if set to `True`.
        :param keep_project_on_failure: If `True` keep generated project directory even when
            generation fails
        """
        # Get user configuration
        config_dict = get_user_config(config_file=config_file, default_config=default_config)

        # Determine the template directory
>       repo_dir, cleanup = determine_repo_dir(
            template=template,
            checkout=checkout,
            clone_to_dir=config_dict['cookiecutters_dir'],
            no_input=no_input,
            password=password,
            directory=directory
        )
E       TypeError: determine_repo_dir() missing 1 required positional argument: 'abbreviations'

cookiecutter/main.py:59: TypeError

test_templates.py::test_build_templates[super]

test_templates.py::test_build_templates[super]
template = 'super'
output_dir = '/tmp/pytest-of-root/pytest-0/test_build_templates_super_0/templates'

    @pytest.mark.parametrize("template", ["include", "no-templates", "extends", "super"])
    def test_build_templates(template, output_dir):
        """
        Verify Templates Design keywords.

        no-templates is a compatibility tests for repo without `templates` directory
        """
>       project_dir = main.cookiecutter(
            f'tests/test-templates/{template}',
            no_input=True,
            output_dir=output_dir,
        )

tests/test_templates.py:28: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

template = 'tests/test-templates/super', checkout = None, no_input = True
extra_context = None, replay = None, overwrite_if_exists = False
output_dir = '/tmp/pytest-of-root/pytest-0/test_build_templates_super_0/templates'
config_file = None, default_config = False, password = None, directory = None
skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False

    def cookiecutter(template, checkout=None, no_input=False, extra_context=
        None, replay=None, overwrite_if_exists=False, output_dir='.',
        config_file=None, default_config=False, password=None, directory=None,
        skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False
        ):
        """
        Run Cookiecutter just as if using it from the command line.

        :param template: A directory containing a project template directory,
            or a URL to a git repository.
        :param checkout: The branch, tag or commit ID to checkout after clone.
        :param no_input: Do not prompt for user input.
            Use default values for template parameters taken from `cookiecutter.json`, user
            config and `extra_dict`. Force a refresh of cached resources.
        :param extra_context: A dictionary of context that overrides default
            and user configuration.
        :param replay: Do not prompt for input, instead read from saved json. If
            ``True`` read from the ``replay_dir``.
            if it exists
        :param overwrite_if_exists: Overwrite the contents of the output directory
            if it exists.
        :param output_dir: Where to output the generated project dir into.
        :param config_file: User configuration file path.
        :param default_config: Use default values rather than a config file.
        :param password: The password to use when extracting the repository.
        :param directory: Relative path to a cookiecutter template in a repository.
        :param skip_if_file_exists: Skip the files in the corresponding directories
            if they already exist.
        :param accept_hooks: Accept pre and post hooks if set to `True`.
        :param keep_project_on_failure: If `True` keep generated project directory even when
            generation fails
        """
        # Get user configuration
        config_dict = get_user_config(config_file=config_file, default_config=default_config)

        # Determine the template directory
>       repo_dir, cleanup = determine_repo_dir(
            template=template,
            checkout=checkout,
            clone_to_dir=config_dict['cookiecutters_dir'],
            no_input=no_input,
            password=password,
            directory=directory
        )
E       TypeError: determine_repo_dir() missing 1 required positional argument: 'abbreviations'

cookiecutter/main.py:59: TypeError

test_time_extension.py::test_tz_is_required

test_time_extension.py::test_tz_is_required
environment = 

    def test_tz_is_required(environment):
        """Verify template parsing fails without a timezone."""
        with pytest.raises(exceptions.TemplateSyntaxError):
>           environment.from_string('{% now %}')

tests/test_time_extension.py:26: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.venv/lib/python3.10/site-packages/jinja2/environment.py:1108: in from_string
    return cls.from_code(self, self.compile(source), gs, None)
.venv/lib/python3.10/site-packages/jinja2/environment.py:760: in compile
    source = self._parse(source, name, filename)
.venv/lib/python3.10/site-packages/jinja2/environment.py:619: in _parse
    return Parser(self, source, name, filename).parse()
.venv/lib/python3.10/site-packages/jinja2/parser.py:1039: in parse
    result = nodes.Template(self.subparse(), lineno=1)
.venv/lib/python3.10/site-packages/jinja2/parser.py:1022: in subparse
    rv = self.parse_statement()
.venv/lib/python3.10/site-packages/jinja2/parser.py:184: in parse_statement
    return ext(self)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = 
parser = 

    def parse(self, parser):
        """Parse datetime template and add datetime value."""
        lineno = next(parser.stream).lineno
>       token = parser.stream.next()
E       AttributeError: 'TokenStream' object has no attribute 'next'

cookiecutter/extensions.py:79: AttributeError

test_time_extension.py::test_utc_default_datetime_format

test_time_extension.py::test_utc_default_datetime_format
environment = 

    def test_utc_default_datetime_format(environment):
        """Verify default datetime format can be parsed."""
>       template = environment.from_string("{% now 'utc' %}")

tests/test_time_extension.py:31: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.venv/lib/python3.10/site-packages/jinja2/environment.py:1108: in from_string
    return cls.from_code(self, self.compile(source), gs, None)
.venv/lib/python3.10/site-packages/jinja2/environment.py:760: in compile
    source = self._parse(source, name, filename)
.venv/lib/python3.10/site-packages/jinja2/environment.py:619: in _parse
    return Parser(self, source, name, filename).parse()
.venv/lib/python3.10/site-packages/jinja2/parser.py:1039: in parse
    result = nodes.Template(self.subparse(), lineno=1)
.venv/lib/python3.10/site-packages/jinja2/parser.py:1022: in subparse
    rv = self.parse_statement()
.venv/lib/python3.10/site-packages/jinja2/parser.py:184: in parse_statement
    return ext(self)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = 
parser = 

    def parse(self, parser):
        """Parse datetime template and add datetime value."""
        lineno = next(parser.stream).lineno
>       token = parser.stream.next()
E       AttributeError: 'TokenStream' object has no attribute 'next'

cookiecutter/extensions.py:79: AttributeError

test_time_extension.py::test_accept_valid_timezones[utc]

test_time_extension.py::test_accept_valid_timezones[utc]
environment = 
valid_tz = 'utc'

    @pytest.mark.parametrize("valid_tz", ['utc', 'local', 'Europe/Berlin'])
    def test_accept_valid_timezones(environment, valid_tz):
        """Verify that valid timezones are accepted."""
>       template = environment.from_string(f"{{% now '{valid_tz}', '%Y-%m' %}}")

tests/test_time_extension.py:39: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.venv/lib/python3.10/site-packages/jinja2/environment.py:1108: in from_string
    return cls.from_code(self, self.compile(source), gs, None)
.venv/lib/python3.10/site-packages/jinja2/environment.py:760: in compile
    source = self._parse(source, name, filename)
.venv/lib/python3.10/site-packages/jinja2/environment.py:619: in _parse
    return Parser(self, source, name, filename).parse()
.venv/lib/python3.10/site-packages/jinja2/parser.py:1039: in parse
    result = nodes.Template(self.subparse(), lineno=1)
.venv/lib/python3.10/site-packages/jinja2/parser.py:1022: in subparse
    rv = self.parse_statement()
.venv/lib/python3.10/site-packages/jinja2/parser.py:184: in parse_statement
    return ext(self)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = 
parser = 

    def parse(self, parser):
        """Parse datetime template and add datetime value."""
        lineno = next(parser.stream).lineno
>       token = parser.stream.next()
E       AttributeError: 'TokenStream' object has no attribute 'next'

cookiecutter/extensions.py:79: AttributeError

test_time_extension.py::test_accept_valid_timezones[local]

test_time_extension.py::test_accept_valid_timezones[local]
environment = 
valid_tz = 'local'

    @pytest.mark.parametrize("valid_tz", ['utc', 'local', 'Europe/Berlin'])
    def test_accept_valid_timezones(environment, valid_tz):
        """Verify that valid timezones are accepted."""
>       template = environment.from_string(f"{{% now '{valid_tz}', '%Y-%m' %}}")

tests/test_time_extension.py:39: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.venv/lib/python3.10/site-packages/jinja2/environment.py:1108: in from_string
    return cls.from_code(self, self.compile(source), gs, None)
.venv/lib/python3.10/site-packages/jinja2/environment.py:760: in compile
    source = self._parse(source, name, filename)
.venv/lib/python3.10/site-packages/jinja2/environment.py:619: in _parse
    return Parser(self, source, name, filename).parse()
.venv/lib/python3.10/site-packages/jinja2/parser.py:1039: in parse
    result = nodes.Template(self.subparse(), lineno=1)
.venv/lib/python3.10/site-packages/jinja2/parser.py:1022: in subparse
    rv = self.parse_statement()
.venv/lib/python3.10/site-packages/jinja2/parser.py:184: in parse_statement
    return ext(self)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = 
parser = 

    def parse(self, parser):
        """Parse datetime template and add datetime value."""
        lineno = next(parser.stream).lineno
>       token = parser.stream.next()
E       AttributeError: 'TokenStream' object has no attribute 'next'

cookiecutter/extensions.py:79: AttributeError

Berlin]

Berlin]
environment = 
valid_tz = 'Europe/Berlin'

    @pytest.mark.parametrize("valid_tz", ['utc', 'local', 'Europe/Berlin'])
    def test_accept_valid_timezones(environment, valid_tz):
        """Verify that valid timezones are accepted."""
>       template = environment.from_string(f"{{% now '{valid_tz}', '%Y-%m' %}}")

tests/test_time_extension.py:39: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.venv/lib/python3.10/site-packages/jinja2/environment.py:1108: in from_string
    return cls.from_code(self, self.compile(source), gs, None)
.venv/lib/python3.10/site-packages/jinja2/environment.py:760: in compile
    source = self._parse(source, name, filename)
.venv/lib/python3.10/site-packages/jinja2/environment.py:619: in _parse
    return Parser(self, source, name, filename).parse()
.venv/lib/python3.10/site-packages/jinja2/parser.py:1039: in parse
    result = nodes.Template(self.subparse(), lineno=1)
.venv/lib/python3.10/site-packages/jinja2/parser.py:1022: in subparse
    rv = self.parse_statement()
.venv/lib/python3.10/site-packages/jinja2/parser.py:184: in parse_statement
    return ext(self)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = 
parser = 

    def parse(self, parser):
        """Parse datetime template and add datetime value."""
        lineno = next(parser.stream).lineno
>       token = parser.stream.next()
E       AttributeError: 'TokenStream' object has no attribute 'next'

cookiecutter/extensions.py:79: AttributeError

test_time_extension.py::test_environment_datetime_format

test_time_extension.py::test_environment_datetime_format
environment = 

    def test_environment_datetime_format(environment):
        """Verify datetime format can be parsed from environment."""
        environment.datetime_format = '%a, %d %b %Y %H:%M:%S'

>       template = environment.from_string("{% now 'utc' %}")

tests/test_time_extension.py:48: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.venv/lib/python3.10/site-packages/jinja2/environment.py:1108: in from_string
    return cls.from_code(self, self.compile(source), gs, None)
.venv/lib/python3.10/site-packages/jinja2/environment.py:760: in compile
    source = self._parse(source, name, filename)
.venv/lib/python3.10/site-packages/jinja2/environment.py:619: in _parse
    return Parser(self, source, name, filename).parse()
.venv/lib/python3.10/site-packages/jinja2/parser.py:1039: in parse
    result = nodes.Template(self.subparse(), lineno=1)
.venv/lib/python3.10/site-packages/jinja2/parser.py:1022: in subparse
    rv = self.parse_statement()
.venv/lib/python3.10/site-packages/jinja2/parser.py:184: in parse_statement
    return ext(self)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = 
parser = 

    def parse(self, parser):
        """Parse datetime template and add datetime value."""
        lineno = next(parser.stream).lineno
>       token = parser.stream.next()
E       AttributeError: 'TokenStream' object has no attribute 'next'

cookiecutter/extensions.py:79: AttributeError

test_time_extension.py::test_add_time

test_time_extension.py::test_add_time
environment = 

    def test_add_time(environment):
        """Verify that added time offset can be parsed."""
        environment.datetime_format = '%a, %d %b %Y %H:%M:%S'

>       template = environment.from_string("{% now 'utc' + 'hours=2,seconds=30' %}")

tests/test_time_extension.py:57: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.venv/lib/python3.10/site-packages/jinja2/environment.py:1108: in from_string
    return cls.from_code(self, self.compile(source), gs, None)
.venv/lib/python3.10/site-packages/jinja2/environment.py:760: in compile
    source = self._parse(source, name, filename)
.venv/lib/python3.10/site-packages/jinja2/environment.py:619: in _parse
    return Parser(self, source, name, filename).parse()
.venv/lib/python3.10/site-packages/jinja2/parser.py:1039: in parse
    result = nodes.Template(self.subparse(), lineno=1)
.venv/lib/python3.10/site-packages/jinja2/parser.py:1022: in subparse
    rv = self.parse_statement()
.venv/lib/python3.10/site-packages/jinja2/parser.py:184: in parse_statement
    return ext(self)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = 
parser = 

    def parse(self, parser):
        """Parse datetime template and add datetime value."""
        lineno = next(parser.stream).lineno
>       token = parser.stream.next()
E       AttributeError: 'TokenStream' object has no attribute 'next'

cookiecutter/extensions.py:79: AttributeError

test_time_extension.py::test_substract_time

test_time_extension.py::test_substract_time
environment = 

    def test_substract_time(environment):
        """Verify that substracted time offset can be parsed."""
        environment.datetime_format = '%a, %d %b %Y %H:%M:%S'

>       template = environment.from_string("{% now 'utc' - 'minutes=11' %}")

tests/test_time_extension.py:66: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.venv/lib/python3.10/site-packages/jinja2/environment.py:1108: in from_string
    return cls.from_code(self, self.compile(source), gs, None)
.venv/lib/python3.10/site-packages/jinja2/environment.py:760: in compile
    source = self._parse(source, name, filename)
.venv/lib/python3.10/site-packages/jinja2/environment.py:619: in _parse
    return Parser(self, source, name, filename).parse()
.venv/lib/python3.10/site-packages/jinja2/parser.py:1039: in parse
    result = nodes.Template(self.subparse(), lineno=1)
.venv/lib/python3.10/site-packages/jinja2/parser.py:1022: in subparse
    rv = self.parse_statement()
.venv/lib/python3.10/site-packages/jinja2/parser.py:184: in parse_statement
    return ext(self)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = 
parser = 

    def parse(self, parser):
        """Parse datetime template and add datetime value."""
        lineno = next(parser.stream).lineno
>       token = parser.stream.next()
E       AttributeError: 'TokenStream' object has no attribute 'next'

cookiecutter/extensions.py:79: AttributeError

test_time_extension.py::test_offset_with_format

test_time_extension.py::test_offset_with_format
environment = 

    def test_offset_with_format(environment):
        """Verify that offset works together with datetime format."""
        environment.datetime_format = '%d %b %Y %H:%M:%S'

>       template = environment.from_string(
            "{% now 'utc' - 'days=2,minutes=33,seconds=1', '%d %b %Y %H:%M:%S' %}"
        )

tests/test_time_extension.py:75: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.venv/lib/python3.10/site-packages/jinja2/environment.py:1108: in from_string
    return cls.from_code(self, self.compile(source), gs, None)
.venv/lib/python3.10/site-packages/jinja2/environment.py:760: in compile
    source = self._parse(source, name, filename)
.venv/lib/python3.10/site-packages/jinja2/environment.py:619: in _parse
    return Parser(self, source, name, filename).parse()
.venv/lib/python3.10/site-packages/jinja2/parser.py:1039: in parse
    result = nodes.Template(self.subparse(), lineno=1)
.venv/lib/python3.10/site-packages/jinja2/parser.py:1022: in subparse
    rv = self.parse_statement()
.venv/lib/python3.10/site-packages/jinja2/parser.py:184: in parse_statement
    return ext(self)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = 
parser = 

    def parse(self, parser):
        """Parse datetime template and add datetime value."""
        lineno = next(parser.stream).lineno
>       token = parser.stream.next()
E       AttributeError: 'TokenStream' object has no attribute 'next'

cookiecutter/extensions.py:79: AttributeError

test_utils.py::test_make_sure_path_exists_correctly_handle_os_error

test_utils.py::test_make_sure_path_exists_correctly_handle_os_error
mocker = 

    def test_make_sure_path_exists_correctly_handle_os_error(mocker):
        """Verify correct True/False response from `utils.make_sure_path_exists`.

        Should return True if directory exist or created.
        Should return False if impossible to create directory (for example protected)
        """
        mocker.patch("pathlib.Path.mkdir", side_effect=OSError)
>       with pytest.raises(OSError) as err:
E       Failed: DID NOT RAISE 

tests/test_utils.py:70: Failed

test_utils.py::test_create_tmp_repo_dir

test_utils.py::test_create_tmp_repo_dir
tmp_path = PosixPath('/tmp/pytest-of-root/pytest-0/test_create_tmp_repo_dir0')

    def test_create_tmp_repo_dir(tmp_path):
        """Verify `utils.create_tmp_repo_dir` creates a copy."""
        repo_dir = Path(tmp_path) / 'bar'
        repo_dir.mkdir()
        subdirs = ('foo', 'bar', 'foobar')
        for name in subdirs:
            (repo_dir / name).mkdir()

>       new_repo_dir = utils.create_tmp_repo_dir(repo_dir)

tests/test_utils.py:108: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
cookiecutter/utils.py:78: in create_tmp_repo_dir
    shutil.copytree(repo_dir, temp_dir, symlinks=True)
/usr/lib/python3.10/shutil.py:559: in copytree
    return _copytree(entries=entries, src=src, dst=dst, symlinks=symlinks,
/usr/lib/python3.10/shutil.py:457: in _copytree
    os.makedirs(dst, exist_ok=dirs_exist_ok)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

name = PosixPath('/tmp/tmp8663syi9'), mode = 511, exist_ok = False

    def makedirs(name, mode=0o777, exist_ok=False):
        """makedirs(name [, mode=0o777][, exist_ok=False])

        Super-mkdir; create a leaf directory and all intermediate ones.  Works like
        mkdir, except that any intermediate path segment (not just the rightmost)
        will be created if it does not exist. If the target directory already
        exists, raise an OSError if exist_ok is False. Otherwise no exception is
        raised.  This is recursive.

        """
        head, tail = path.split(name)
        if not tail:
            head, tail = path.split(head)
        if head and tail and not path.exists(head):
            try:
                makedirs(head, exist_ok=exist_ok)
            except FileExistsError:
                # Defeats race condition when another thread created the path
                pass
            cdir = curdir
            if isinstance(tail, bytes):
                cdir = bytes(curdir, 'ASCII')
            if tail == cdir:           # xxx/newdir/. exists if xxx/newdir exists
                return
        try:
>           mkdir(name, mode)
E           FileExistsError: [Errno 17] File exists: '/tmp/tmp8663syi9'

/usr/lib/python3.10/os.py:225: FileExistsError

test_clone.py::test_clone_should_rstrip_trailing_slash_in_repo_url

test_clone.py::test_clone_should_rstrip_trailing_slash_in_repo_url
self = 
args = (['git', 'clone', 'https://github.com/foo/bar'],)
kwargs = {'cwd': PosixPath('/tmp/pytest-of-root/pytest-0/test_clone_should_rstrip_trail0/clone_dir'), 'stderr': -2}
expected = call('', (['git', 'clone', 'https://github.com/foo/bar'],), {'cwd': PosixPath('/tmp/pytest-of-root/pytest-0/test_clone_should_rstrip_trail0/clone_dir'), 'stderr': -2})
actual = call('', (['git', 'clone', 'https://github.com/foo/bar/', '/tmp/pytest-of-root/pytest-0/test_clone_should_rstrip_trail0/clone_dir/bar'],), {'stderr': -2})
_error_message = ._error_message at 0x7fcb917df9a0>
cause = None

    def assert_called_with(self, /, *args, **kwargs):
        """assert that the last call was made with the specified arguments.

        Raises an AssertionError if the args and keyword args passed in are
        different to the last call to the mock."""
        if self.call_args is None:
            expected = self._format_mock_call_signature(args, kwargs)
            actual = 'not called.'
            error_message = ('expected call not found.\nExpected: %s\nActual: %s'
                    % (expected, actual))
            raise AssertionError(error_message)

        def _error_message():
            msg = self._format_mock_failure_message(args, kwargs)
            return msg
        expected = self._call_matcher(_Call((args, kwargs), two=True))
        actual = self._call_matcher(self.call_args)
        if actual != expected:
            cause = expected if isinstance(expected, Exception) else None
>           raise AssertionError(_error_message()) from cause
E           AssertionError: expected call not found.
E           Expected: check_output(['git', 'clone', 'https://github.com/foo/bar'], cwd=PosixPath('/tmp/pytest-of-root/pytest-0/test_clone_should_rstrip_trail0/clone_dir'), stderr=-2)
E           Actual: check_output(['git', 'clone', 'https://github.com/foo/bar/', '/tmp/pytest-of-root/pytest-0/test_clone_should_rstrip_trail0/clone_dir/bar'], stderr=-2)

/usr/lib/python3.10/unittest/mock.py:929: AssertionError

During handling of the above exception, another exception occurred:

self = 
args = (['git', 'clone', 'https://github.com/foo/bar'],)
kwargs = {'cwd': PosixPath('/tmp/pytest-of-root/pytest-0/test_clone_should_rstrip_trail0/clone_dir'), 'stderr': -2}

    def assert_called_once_with(self, /, *args, **kwargs):
        """assert that the mock was called exactly once and that that call was
        with the specified arguments."""
        if not self.call_count == 1:
            msg = ("Expected '%s' to be called once. Called %s times.%s"
                   % (self._mock_name or 'mock',
                      self.call_count,
                      self._calls_repr()))
            raise AssertionError(msg)
>       return self.assert_called_with(*args, **kwargs)
E       AssertionError: expected call not found.
E       Expected: check_output(['git', 'clone', 'https://github.com/foo/bar'], cwd=PosixPath('/tmp/pytest-of-root/pytest-0/test_clone_should_rstrip_trail0/clone_dir'), stderr=-2)
E       Actual: check_output(['git', 'clone', 'https://github.com/foo/bar/', '/tmp/pytest-of-root/pytest-0/test_clone_should_rstrip_trail0/clone_dir/bar'], stderr=-2)
E       
E       pytest introspection follows:
E       
E       Args:
E       assert (['git', 'clone', 'https://github.com/foo/bar/', '/tmp/pytest-of-root/pytest-0/test_clone_should_rstrip_trail0/clone_dir/bar'],) == (['git', 'clone', 'https://github.com/foo/bar'],)
E         
E         At index 0 diff: ['git', 'clone', 'https://github.com/foo/bar/', '/tmp/pytest-of-root/pytest-0/test_clone_should_rstrip_trail0/clone_dir/bar'] != ['git', 'clone', 'https://github.com/foo/bar']
E         
E         Full diff:
E           (
E               [
E                   'git',
E                   'clone',
E         -         'https://github.com/foo/bar',
E         +         'https://github.com/foo/bar/',
E         ?                                    +
E         +         '/tmp/pytest-of-root/pytest-0/test_clone_should_rstrip_trail0/clone_dir/bar',
E               ],
E           )
E       Kwargs:
E       assert {'stderr': -2} == {'cwd': PosixPath('/tmp/pytest-of-root/pytest-0/test_clone_should_rstrip_trail0/clone_dir'), 'stderr': -2}
E         
E         Common items:
E         {'stderr': -2}
E         Right contains 1 more item:
E         {'cwd': PosixPath('/tmp/pytest-of-root/pytest-0/test_clone_should_rstrip_trail0/clone_dir')}
E         
E         Full diff:
E           {
E         -     'cwd': PosixPath('/tmp/pytest-of-root/pytest-0/test_clone_should_rstrip_trail0/clone_dir'),
E               'stderr': -2,
E           }

/usr/lib/python3.10/unittest/mock.py:941: AssertionError

During handling of the above exception, another exception occurred:

mocker = 
clone_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_clone_should_rstrip_trail0/clone_dir')

    def test_clone_should_rstrip_trailing_slash_in_repo_url(mocker, clone_dir):
        """In `clone()`, repo URL's trailing slash should be stripped if one is \
        present."""
        mocker.patch('cookiecutter.vcs.is_vcs_installed', autospec=True, return_value=True)

        mock_subprocess = mocker.patch(
            'cookiecutter.vcs.subprocess.check_output',
            autospec=True,
        )

        vcs.clone('https://github.com/foo/bar/', clone_to_dir=clone_dir, no_input=True)

>       mock_subprocess.assert_called_once_with(
            ['git', 'clone', 'https://github.com/foo/bar'],
            cwd=clone_dir,
            stderr=subprocess.STDOUT,
        )

tests/vcs/test_clone.py:34: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

args = (['git', 'clone', 'https://github.com/foo/bar'],)
kwargs = {'cwd': PosixPath('/tmp/pytest-of-root/pytest-0/test_clone_should_rstrip_trail0/clone_dir'), 'stderr': -2}

    def assert_called_once_with(*args, **kwargs):
>       return mock.assert_called_once_with(*args, **kwargs)
E       AssertionError: expected call not found.
E       Expected: check_output(['git', 'clone', 'https://github.com/foo/bar'], cwd=PosixPath('/tmp/pytest-of-root/pytest-0/test_clone_should_rstrip_trail0/clone_dir'), stderr=-2)
E       Actual: check_output(['git', 'clone', 'https://github.com/foo/bar/', '/tmp/pytest-of-root/pytest-0/test_clone_should_rstrip_trail0/clone_dir/bar'], stderr=-2)
E       
E       pytest introspection follows:
E       
E       Args:
E       assert (['git', 'clone', 'https://github.com/foo/bar/', '/tmp/pytest-of-root/pytest-0/test_clone_should_rstrip_trail0/clone_dir/bar'],) == (['git', 'clone', 'https://github.com/foo/bar'],)
E         
E         At index 0 diff: ['git', 'clone', 'https://github.com/foo/bar/', '/tmp/pytest-of-root/pytest-0/test_clone_should_rstrip_trail0/clone_dir/bar'] != ['git', 'clone', 'https://github.com/foo/bar']
E         
E         Full diff:
E           (
E               [
E                   'git',
E                   'clone',
E         -         'https://github.com/foo/bar',
E         +         'https://github.com/foo/bar/',
E         ?                                    +
E         +         '/tmp/pytest-of-root/pytest-0/test_clone_should_rstrip_trail0/clone_dir/bar',
E               ],
E           )
E       Kwargs:
E       assert {'stderr': -2} == {'cwd': PosixPath('/tmp/pytest-of-root/pytest-0/test_clone_should_rstrip_trail0/clone_dir'), 'stderr': -2}
E         
E         Common items:
E         {'stderr': -2}
E         Right contains 1 more item:
E         {'cwd': PosixPath('/tmp/pytest-of-root/pytest-0/test_clone_should_rstrip_trail0/clone_dir')}
E         
E         Full diff:
E           {
E         -     'cwd': PosixPath('/tmp/pytest-of-root/pytest-0/test_clone_should_rstrip_trail0/clone_dir'),
E               'stderr': -2,
E           }

/usr/lib/python3.10/unittest/mock.py:213: AssertionError

test_clone.py::test_clone_should_silent_exit_if_ok_to_reuse

test_clone.py::test_clone_should_silent_exit_if_ok_to_reuse
mocker = 
tmpdir = local('/tmp/pytest-of-root/pytest-0/test_clone_should_silent_exit_0')

    def test_clone_should_silent_exit_if_ok_to_reuse(mocker, tmpdir):
        """In `clone()`, if user doesn't want to reclone, Cookiecutter should exit \
        without cloning anything."""
        mocker.patch('cookiecutter.vcs.is_vcs_installed', autospec=True, return_value=True)
        mocker.patch(
            'cookiecutter.vcs.prompt_and_delete', return_value=False, autospec=True
        )
        mock_subprocess = mocker.patch(
            'cookiecutter.vcs.subprocess.check_output',
            autospec=True,
        )

        clone_to_dir = tmpdir.mkdir('clone')

        # Create repo_dir to trigger prompt_and_delete
        clone_to_dir.mkdir('cookiecutter-pytest-plugin')

        repo_url = 'https://github.com/pytest-dev/cookiecutter-pytest-plugin.git'

        vcs.clone(repo_url, clone_to_dir=str(clone_to_dir))
>       assert not mock_subprocess.called
E       assert not True
E        +  where True = .called

tests/vcs/test_clone.py:84: AssertionError

world.git-world]

world.git-world]
mocker = 
clone_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_clone_should_invoke_vcs_c0/clone_dir')
repo_type = 'git', repo_url = 'https://github.com/hello/world.git'
repo_name = 'world'

    @pytest.mark.parametrize(
        'repo_type, repo_url, repo_name',
        [
            ('git', 'https://github.com/hello/world.git', 'world'),
            ('hg', 'https://bitbucket.org/foo/bar', 'bar'),
            ('git', 'git@host:gitoliterepo', 'gitoliterepo'),
            ('git', 'git@gitlab.com:cookiecutter/cookiecutter.git', 'cookiecutter'),
            ('git', 'git@github.com:cookiecutter/cookiecutter.git', 'cookiecutter'),
        ],
    )
    def test_clone_should_invoke_vcs_command(
        mocker, clone_dir, repo_type, repo_url, repo_name
    ):
        """When `clone()` is called with a git/hg repo, the corresponding VCS \
        command should be run via `subprocess.check_output()`.

        This should take place:
        * In the correct dir
        * With the correct args.
        """
        mocker.patch('cookiecutter.vcs.is_vcs_installed', autospec=True, return_value=True)

        mock_subprocess = mocker.patch(
            'cookiecutter.vcs.subprocess.check_output',
            autospec=True,
        )
        expected_repo_dir = os.path.normpath(os.path.join(clone_dir, repo_name))

        branch = 'foobar'

>       repo_dir = vcs.clone(
            repo_url, checkout=branch, clone_to_dir=clone_dir, no_input=True
        )

tests/vcs/test_clone.py:117: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

repo_url = 'https://github.com/hello/world.git', checkout = 'foobar'
clone_to_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_clone_should_invoke_vcs_c0/clone_dir')
no_input = True

    def clone(repo_url: str, checkout: Optional[str]=None, clone_to_dir:
        'os.PathLike[str]'='.', no_input: bool=False):
        """Clone a repo to the current directory.

        :param repo_url: Repo URL of unknown type.
        :param checkout: The branch, tag or commit ID to checkout after clone.
        :param clone_to_dir: The directory to clone to.
                             Defaults to the current directory.
        :param no_input: Do not prompt for user input and eventually force a refresh of
            cached resources.
        :returns: str with path to the new directory of the repository.
        """
        repo_type, repo_url = identify_repo(repo_url)
        if repo_type is None:
            raise UnknownRepoType(f"Couldn't determine repository type for {repo_url}")

        if not is_vcs_installed(repo_type):
            raise VCSNotInstalled(f"{repo_type} is not installed.")

        clone_to_dir = Path(clone_to_dir).resolve()
        make_sure_path_exists(clone_to_dir)

        repo_dir = clone_to_dir / Path(repo_url).stem

        if repo_dir.exists():
            if no_input:
                logger.warning("'%s' directory already exists, deleting it", repo_dir)
                subprocess.check_call([repo_type, 'init', str(repo_dir)])
            else:
                prompt_and_delete(repo_dir)

        if repo_type == 'git':
            clone_cmd = ['git', 'clone', repo_url, str(repo_dir)]
        else:  # hg
            clone_cmd = ['hg', 'clone', repo_url, str(repo_dir)]

        try:
            subprocess.check_output(clone_cmd, stderr=subprocess.STDOUT)
        except subprocess.CalledProcessError as e:
            output = e.output.decode('utf-8')
            if 'Repository not found' in output:
                raise RepositoryNotFound(f"The repository {repo_url} could not be found")
            else:
                raise RepositoryCloneFailed(f"Cloning {repo_url} failed: {output}")

        if checkout:
            if repo_type == 'git':
                checkout_cmd = ['git', 'checkout', checkout]
            else:  # hg
                checkout_cmd = ['hg', 'update', checkout]

            with Path.cwd():
>               os.chdir(repo_dir)
E               FileNotFoundError: [Errno 2] No such file or directory: '/tmp/pytest-of-root/pytest-0/test_clone_should_invoke_vcs_c0/clone_dir/world'

cookiecutter/vcs.py:101: FileNotFoundError

bar-bar]

bar-bar]
mocker = 
clone_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_clone_should_invoke_vcs_c1/clone_dir')
repo_type = 'hg', repo_url = 'https://bitbucket.org/foo/bar', repo_name = 'bar'

    @pytest.mark.parametrize(
        'repo_type, repo_url, repo_name',
        [
            ('git', 'https://github.com/hello/world.git', 'world'),
            ('hg', 'https://bitbucket.org/foo/bar', 'bar'),
            ('git', 'git@host:gitoliterepo', 'gitoliterepo'),
            ('git', 'git@gitlab.com:cookiecutter/cookiecutter.git', 'cookiecutter'),
            ('git', 'git@github.com:cookiecutter/cookiecutter.git', 'cookiecutter'),
        ],
    )
    def test_clone_should_invoke_vcs_command(
        mocker, clone_dir, repo_type, repo_url, repo_name
    ):
        """When `clone()` is called with a git/hg repo, the corresponding VCS \
        command should be run via `subprocess.check_output()`.

        This should take place:
        * In the correct dir
        * With the correct args.
        """
        mocker.patch('cookiecutter.vcs.is_vcs_installed', autospec=True, return_value=True)

        mock_subprocess = mocker.patch(
            'cookiecutter.vcs.subprocess.check_output',
            autospec=True,
        )
        expected_repo_dir = os.path.normpath(os.path.join(clone_dir, repo_name))

        branch = 'foobar'

>       repo_dir = vcs.clone(
            repo_url, checkout=branch, clone_to_dir=clone_dir, no_input=True
        )

tests/vcs/test_clone.py:117: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

repo_url = 'https://bitbucket.org/foo/bar', checkout = 'foobar'
clone_to_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_clone_should_invoke_vcs_c1/clone_dir')
no_input = True

    def clone(repo_url: str, checkout: Optional[str]=None, clone_to_dir:
        'os.PathLike[str]'='.', no_input: bool=False):
        """Clone a repo to the current directory.

        :param repo_url: Repo URL of unknown type.
        :param checkout: The branch, tag or commit ID to checkout after clone.
        :param clone_to_dir: The directory to clone to.
                             Defaults to the current directory.
        :param no_input: Do not prompt for user input and eventually force a refresh of
            cached resources.
        :returns: str with path to the new directory of the repository.
        """
        repo_type, repo_url = identify_repo(repo_url)
        if repo_type is None:
            raise UnknownRepoType(f"Couldn't determine repository type for {repo_url}")

        if not is_vcs_installed(repo_type):
            raise VCSNotInstalled(f"{repo_type} is not installed.")

        clone_to_dir = Path(clone_to_dir).resolve()
        make_sure_path_exists(clone_to_dir)

        repo_dir = clone_to_dir / Path(repo_url).stem

        if repo_dir.exists():
            if no_input:
                logger.warning("'%s' directory already exists, deleting it", repo_dir)
                subprocess.check_call([repo_type, 'init', str(repo_dir)])
            else:
                prompt_and_delete(repo_dir)

        if repo_type == 'git':
            clone_cmd = ['git', 'clone', repo_url, str(repo_dir)]
        else:  # hg
            clone_cmd = ['hg', 'clone', repo_url, str(repo_dir)]

        try:
            subprocess.check_output(clone_cmd, stderr=subprocess.STDOUT)
        except subprocess.CalledProcessError as e:
            output = e.output.decode('utf-8')
            if 'Repository not found' in output:
                raise RepositoryNotFound(f"The repository {repo_url} could not be found")
            else:
                raise RepositoryCloneFailed(f"Cloning {repo_url} failed: {output}")

        if checkout:
            if repo_type == 'git':
                checkout_cmd = ['git', 'checkout', checkout]
            else:  # hg
                checkout_cmd = ['hg', 'update', checkout]

            with Path.cwd():
>               os.chdir(repo_dir)
E               FileNotFoundError: [Errno 2] No such file or directory: '/tmp/pytest-of-root/pytest-0/test_clone_should_invoke_vcs_c1/clone_dir/bar'

cookiecutter/vcs.py:101: FileNotFoundError

test_clone.py::test_clone_should_invoke_vcs_command[git-git@host:gitoliterepo-gitoliterepo]

test_clone.py::test_clone_should_invoke_vcs_command[git-git@host:gitoliterepo-gitoliterepo]
mocker = 
clone_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_clone_should_invoke_vcs_c2/clone_dir')
repo_type = 'git', repo_url = 'git@host:gitoliterepo'
repo_name = 'gitoliterepo'

    @pytest.mark.parametrize(
        'repo_type, repo_url, repo_name',
        [
            ('git', 'https://github.com/hello/world.git', 'world'),
            ('hg', 'https://bitbucket.org/foo/bar', 'bar'),
            ('git', 'git@host:gitoliterepo', 'gitoliterepo'),
            ('git', 'git@gitlab.com:cookiecutter/cookiecutter.git', 'cookiecutter'),
            ('git', 'git@github.com:cookiecutter/cookiecutter.git', 'cookiecutter'),
        ],
    )
    def test_clone_should_invoke_vcs_command(
        mocker, clone_dir, repo_type, repo_url, repo_name
    ):
        """When `clone()` is called with a git/hg repo, the corresponding VCS \
        command should be run via `subprocess.check_output()`.

        This should take place:
        * In the correct dir
        * With the correct args.
        """
        mocker.patch('cookiecutter.vcs.is_vcs_installed', autospec=True, return_value=True)

        mock_subprocess = mocker.patch(
            'cookiecutter.vcs.subprocess.check_output',
            autospec=True,
        )
        expected_repo_dir = os.path.normpath(os.path.join(clone_dir, repo_name))

        branch = 'foobar'

>       repo_dir = vcs.clone(
            repo_url, checkout=branch, clone_to_dir=clone_dir, no_input=True
        )

tests/vcs/test_clone.py:117: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

repo_url = 'git@host:gitoliterepo', checkout = 'foobar'
clone_to_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_clone_should_invoke_vcs_c2/clone_dir')
no_input = True

    def clone(repo_url: str, checkout: Optional[str]=None, clone_to_dir:
        'os.PathLike[str]'='.', no_input: bool=False):
        """Clone a repo to the current directory.

        :param repo_url: Repo URL of unknown type.
        :param checkout: The branch, tag or commit ID to checkout after clone.
        :param clone_to_dir: The directory to clone to.
                             Defaults to the current directory.
        :param no_input: Do not prompt for user input and eventually force a refresh of
            cached resources.
        :returns: str with path to the new directory of the repository.
        """
>       repo_type, repo_url = identify_repo(repo_url)
E       TypeError: cannot unpack non-iterable NoneType object

cookiecutter/vcs.py:61: TypeError

cookiecutter.git-cookiecutter]

cookiecutter.git-cookiecutter]
mocker = 
clone_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_clone_should_invoke_vcs_c3/clone_dir')
repo_type = 'git', repo_url = 'git@gitlab.com:cookiecutter/cookiecutter.git'
repo_name = 'cookiecutter'

    @pytest.mark.parametrize(
        'repo_type, repo_url, repo_name',
        [
            ('git', 'https://github.com/hello/world.git', 'world'),
            ('hg', 'https://bitbucket.org/foo/bar', 'bar'),
            ('git', 'git@host:gitoliterepo', 'gitoliterepo'),
            ('git', 'git@gitlab.com:cookiecutter/cookiecutter.git', 'cookiecutter'),
            ('git', 'git@github.com:cookiecutter/cookiecutter.git', 'cookiecutter'),
        ],
    )
    def test_clone_should_invoke_vcs_command(
        mocker, clone_dir, repo_type, repo_url, repo_name
    ):
        """When `clone()` is called with a git/hg repo, the corresponding VCS \
        command should be run via `subprocess.check_output()`.

        This should take place:
        * In the correct dir
        * With the correct args.
        """
        mocker.patch('cookiecutter.vcs.is_vcs_installed', autospec=True, return_value=True)

        mock_subprocess = mocker.patch(
            'cookiecutter.vcs.subprocess.check_output',
            autospec=True,
        )
        expected_repo_dir = os.path.normpath(os.path.join(clone_dir, repo_name))

        branch = 'foobar'

>       repo_dir = vcs.clone(
            repo_url, checkout=branch, clone_to_dir=clone_dir, no_input=True
        )

tests/vcs/test_clone.py:117: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

repo_url = 'git@gitlab.com:cookiecutter/cookiecutter.git', checkout = 'foobar'
clone_to_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_clone_should_invoke_vcs_c3/clone_dir')
no_input = True

    def clone(repo_url: str, checkout: Optional[str]=None, clone_to_dir:
        'os.PathLike[str]'='.', no_input: bool=False):
        """Clone a repo to the current directory.

        :param repo_url: Repo URL of unknown type.
        :param checkout: The branch, tag or commit ID to checkout after clone.
        :param clone_to_dir: The directory to clone to.
                             Defaults to the current directory.
        :param no_input: Do not prompt for user input and eventually force a refresh of
            cached resources.
        :returns: str with path to the new directory of the repository.
        """
        repo_type, repo_url = identify_repo(repo_url)
        if repo_type is None:
            raise UnknownRepoType(f"Couldn't determine repository type for {repo_url}")

        if not is_vcs_installed(repo_type):
            raise VCSNotInstalled(f"{repo_type} is not installed.")

        clone_to_dir = Path(clone_to_dir).resolve()
        make_sure_path_exists(clone_to_dir)

        repo_dir = clone_to_dir / Path(repo_url).stem

        if repo_dir.exists():
            if no_input:
                logger.warning("'%s' directory already exists, deleting it", repo_dir)
                subprocess.check_call([repo_type, 'init', str(repo_dir)])
            else:
                prompt_and_delete(repo_dir)

        if repo_type == 'git':
            clone_cmd = ['git', 'clone', repo_url, str(repo_dir)]
        else:  # hg
            clone_cmd = ['hg', 'clone', repo_url, str(repo_dir)]

        try:
            subprocess.check_output(clone_cmd, stderr=subprocess.STDOUT)
        except subprocess.CalledProcessError as e:
            output = e.output.decode('utf-8')
            if 'Repository not found' in output:
                raise RepositoryNotFound(f"The repository {repo_url} could not be found")
            else:
                raise RepositoryCloneFailed(f"Cloning {repo_url} failed: {output}")

        if checkout:
            if repo_type == 'git':
                checkout_cmd = ['git', 'checkout', checkout]
            else:  # hg
                checkout_cmd = ['hg', 'update', checkout]

            with Path.cwd():
>               os.chdir(repo_dir)
E               FileNotFoundError: [Errno 2] No such file or directory: '/tmp/pytest-of-root/pytest-0/test_clone_should_invoke_vcs_c3/clone_dir/cookiecutter'

cookiecutter/vcs.py:101: FileNotFoundError

cookiecutter.git-cookiecutter]

cookiecutter.git-cookiecutter]
mocker = 
clone_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_clone_should_invoke_vcs_c4/clone_dir')
repo_type = 'git', repo_url = 'git@github.com:cookiecutter/cookiecutter.git'
repo_name = 'cookiecutter'

    @pytest.mark.parametrize(
        'repo_type, repo_url, repo_name',
        [
            ('git', 'https://github.com/hello/world.git', 'world'),
            ('hg', 'https://bitbucket.org/foo/bar', 'bar'),
            ('git', 'git@host:gitoliterepo', 'gitoliterepo'),
            ('git', 'git@gitlab.com:cookiecutter/cookiecutter.git', 'cookiecutter'),
            ('git', 'git@github.com:cookiecutter/cookiecutter.git', 'cookiecutter'),
        ],
    )
    def test_clone_should_invoke_vcs_command(
        mocker, clone_dir, repo_type, repo_url, repo_name
    ):
        """When `clone()` is called with a git/hg repo, the corresponding VCS \
        command should be run via `subprocess.check_output()`.

        This should take place:
        * In the correct dir
        * With the correct args.
        """
        mocker.patch('cookiecutter.vcs.is_vcs_installed', autospec=True, return_value=True)

        mock_subprocess = mocker.patch(
            'cookiecutter.vcs.subprocess.check_output',
            autospec=True,
        )
        expected_repo_dir = os.path.normpath(os.path.join(clone_dir, repo_name))

        branch = 'foobar'

>       repo_dir = vcs.clone(
            repo_url, checkout=branch, clone_to_dir=clone_dir, no_input=True
        )

tests/vcs/test_clone.py:117: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

repo_url = 'git@github.com:cookiecutter/cookiecutter.git', checkout = 'foobar'
clone_to_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_clone_should_invoke_vcs_c4/clone_dir')
no_input = True

    def clone(repo_url: str, checkout: Optional[str]=None, clone_to_dir:
        'os.PathLike[str]'='.', no_input: bool=False):
        """Clone a repo to the current directory.

        :param repo_url: Repo URL of unknown type.
        :param checkout: The branch, tag or commit ID to checkout after clone.
        :param clone_to_dir: The directory to clone to.
                             Defaults to the current directory.
        :param no_input: Do not prompt for user input and eventually force a refresh of
            cached resources.
        :returns: str with path to the new directory of the repository.
        """
        repo_type, repo_url = identify_repo(repo_url)
        if repo_type is None:
            raise UnknownRepoType(f"Couldn't determine repository type for {repo_url}")

        if not is_vcs_installed(repo_type):
            raise VCSNotInstalled(f"{repo_type} is not installed.")

        clone_to_dir = Path(clone_to_dir).resolve()
        make_sure_path_exists(clone_to_dir)

        repo_dir = clone_to_dir / Path(repo_url).stem

        if repo_dir.exists():
            if no_input:
                logger.warning("'%s' directory already exists, deleting it", repo_dir)
                subprocess.check_call([repo_type, 'init', str(repo_dir)])
            else:
                prompt_and_delete(repo_dir)

        if repo_type == 'git':
            clone_cmd = ['git', 'clone', repo_url, str(repo_dir)]
        else:  # hg
            clone_cmd = ['hg', 'clone', repo_url, str(repo_dir)]

        try:
            subprocess.check_output(clone_cmd, stderr=subprocess.STDOUT)
        except subprocess.CalledProcessError as e:
            output = e.output.decode('utf-8')
            if 'Repository not found' in output:
                raise RepositoryNotFound(f"The repository {repo_url} could not be found")
            else:
                raise RepositoryCloneFailed(f"Cloning {repo_url} failed: {output}")

        if checkout:
            if repo_type == 'git':
                checkout_cmd = ['git', 'checkout', checkout]
            else:  # hg
                checkout_cmd = ['hg', 'update', checkout]

            with Path.cwd():
>               os.chdir(repo_dir)
E               FileNotFoundError: [Errno 2] No such file or directory: '/tmp/pytest-of-root/pytest-0/test_clone_should_invoke_vcs_c4/clone_dir/cookiecutter'

cookiecutter/vcs.py:101: FileNotFoundError

cookiedozer' not found]

cookiedozer' not found]
repo_url = 'https://github.com/hackebro/cookiedozer', checkout = None
clone_to_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_clone_handles_repo_typo_f0/clone_dir')
no_input = True

    def clone(repo_url: str, checkout: Optional[str]=None, clone_to_dir:
        'os.PathLike[str]'='.', no_input: bool=False):
        """Clone a repo to the current directory.

        :param repo_url: Repo URL of unknown type.
        :param checkout: The branch, tag or commit ID to checkout after clone.
        :param clone_to_dir: The directory to clone to.
                             Defaults to the current directory.
        :param no_input: Do not prompt for user input and eventually force a refresh of
            cached resources.
        :returns: str with path to the new directory of the repository.
        """
        repo_type, repo_url = identify_repo(repo_url)
        if repo_type is None:
            raise UnknownRepoType(f"Couldn't determine repository type for {repo_url}")

        if not is_vcs_installed(repo_type):
            raise VCSNotInstalled(f"{repo_type} is not installed.")

        clone_to_dir = Path(clone_to_dir).resolve()
        make_sure_path_exists(clone_to_dir)

        repo_dir = clone_to_dir / Path(repo_url).stem

        if repo_dir.exists():
            if no_input:
                logger.warning("'%s' directory already exists, deleting it", repo_dir)
                subprocess.check_call([repo_type, 'init', str(repo_dir)])
            else:
                prompt_and_delete(repo_dir)

        if repo_type == 'git':
            clone_cmd = ['git', 'clone', repo_url, str(repo_dir)]
        else:  # hg
            clone_cmd = ['hg', 'clone', repo_url, str(repo_dir)]

        try:
>           subprocess.check_output(clone_cmd, stderr=subprocess.STDOUT)

cookiecutter/vcs.py:86: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
/usr/lib/python3.10/unittest/mock.py:1114: in __call__
    return self._mock_call(*args, **kwargs)
/usr/lib/python3.10/unittest/mock.py:1118: in _mock_call
    return self._execute_mock_call(*args, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = 
args = (['git', 'clone', 'https://github.com/hackebro/cookiedozer', '/tmp/pytest-of-root/pytest-0/test_clone_handles_repo_typo_f0/clone_dir/cookiedozer'],)
kwargs = {'stderr': -2}
effect = 
result = CalledProcessError(-1, 'cmd')

    def _execute_mock_call(self, /, *args, **kwargs):
        # separate from _increment_mock_call so that awaited functions are
        # executed separately from their call, also AsyncMock overrides this method

        effect = self.side_effect
        if effect is not None:
            if _is_exception(effect):
                raise effect
            elif not _callable(effect):
                result = next(effect)
                if _is_exception(result):
>                   raise result
E                   subprocess.CalledProcessError: Command 'cmd' died with .

/usr/lib/python3.10/unittest/mock.py:1177: CalledProcessError

During handling of the above exception, another exception occurred:

mocker = 
clone_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_clone_handles_repo_typo_f0/clone_dir')
error_message = b"fatal: repository 'https://github.com/hackebro/cookiedozer' not found"

    @pytest.mark.parametrize(
        'error_message',
        [
            (b"fatal: repository 'https://github.com/hackebro/cookiedozer' not found"),
            b'hg: abort: HTTP Error 404: Not Found',
        ],
    )
    def test_clone_handles_repo_typo(mocker, clone_dir, error_message):
        """In `clone()`, repository not found errors should raise an \
        appropriate exception."""
        # side_effect is set to an iterable here (and below),
        # because of a Python 3.4 unittest.mock regression
        # http://bugs.python.org/issue23661
        mocker.patch(
            'cookiecutter.vcs.subprocess.check_output',
            autospec=True,
            side_effect=[subprocess.CalledProcessError(-1, 'cmd', output=error_message)],
        )

        repository_url = 'https://github.com/hackebro/cookiedozer'
        with pytest.raises(exceptions.RepositoryNotFound) as err:
>           vcs.clone(repository_url, clone_to_dir=str(clone_dir), no_input=True)

tests/vcs/test_clone.py:160: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

repo_url = 'https://github.com/hackebro/cookiedozer', checkout = None
clone_to_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_clone_handles_repo_typo_f0/clone_dir')
no_input = True

    def clone(repo_url: str, checkout: Optional[str]=None, clone_to_dir:
        'os.PathLike[str]'='.', no_input: bool=False):
        """Clone a repo to the current directory.

        :param repo_url: Repo URL of unknown type.
        :param checkout: The branch, tag or commit ID to checkout after clone.
        :param clone_to_dir: The directory to clone to.
                             Defaults to the current directory.
        :param no_input: Do not prompt for user input and eventually force a refresh of
            cached resources.
        :returns: str with path to the new directory of the repository.
        """
        repo_type, repo_url = identify_repo(repo_url)
        if repo_type is None:
            raise UnknownRepoType(f"Couldn't determine repository type for {repo_url}")

        if not is_vcs_installed(repo_type):
            raise VCSNotInstalled(f"{repo_type} is not installed.")

        clone_to_dir = Path(clone_to_dir).resolve()
        make_sure_path_exists(clone_to_dir)

        repo_dir = clone_to_dir / Path(repo_url).stem

        if repo_dir.exists():
            if no_input:
                logger.warning("'%s' directory already exists, deleting it", repo_dir)
                subprocess.check_call([repo_type, 'init', str(repo_dir)])
            else:
                prompt_and_delete(repo_dir)

        if repo_type == 'git':
            clone_cmd = ['git', 'clone', repo_url, str(repo_dir)]
        else:  # hg
            clone_cmd = ['hg', 'clone', repo_url, str(repo_dir)]

        try:
            subprocess.check_output(clone_cmd, stderr=subprocess.STDOUT)
        except subprocess.CalledProcessError as e:
            output = e.output.decode('utf-8')
            if 'Repository not found' in output:
                raise RepositoryNotFound(f"The repository {repo_url} could not be found")
            else:
>               raise RepositoryCloneFailed(f"Cloning {repo_url} failed: {output}")
E               cookiecutter.exceptions.RepositoryCloneFailed: Cloning https://github.com/hackebro/cookiedozer failed: fatal: repository 'https://github.com/hackebro/cookiedozer' not found

cookiecutter/vcs.py:92: RepositoryCloneFailed

test_clone.py::test_clone_handles_repo_typo[hg: abort: HTTP Error 404: Not Found]

test_clone.py::test_clone_handles_repo_typo[hg: abort: HTTP Error 404: Not Found]
repo_url = 'https://github.com/hackebro/cookiedozer', checkout = None
clone_to_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_clone_handles_repo_typo_h0/clone_dir')
no_input = True

    def clone(repo_url: str, checkout: Optional[str]=None, clone_to_dir:
        'os.PathLike[str]'='.', no_input: bool=False):
        """Clone a repo to the current directory.

        :param repo_url: Repo URL of unknown type.
        :param checkout: The branch, tag or commit ID to checkout after clone.
        :param clone_to_dir: The directory to clone to.
                             Defaults to the current directory.
        :param no_input: Do not prompt for user input and eventually force a refresh of
            cached resources.
        :returns: str with path to the new directory of the repository.
        """
        repo_type, repo_url = identify_repo(repo_url)
        if repo_type is None:
            raise UnknownRepoType(f"Couldn't determine repository type for {repo_url}")

        if not is_vcs_installed(repo_type):
            raise VCSNotInstalled(f"{repo_type} is not installed.")

        clone_to_dir = Path(clone_to_dir).resolve()
        make_sure_path_exists(clone_to_dir)

        repo_dir = clone_to_dir / Path(repo_url).stem

        if repo_dir.exists():
            if no_input:
                logger.warning("'%s' directory already exists, deleting it", repo_dir)
                subprocess.check_call([repo_type, 'init', str(repo_dir)])
            else:
                prompt_and_delete(repo_dir)

        if repo_type == 'git':
            clone_cmd = ['git', 'clone', repo_url, str(repo_dir)]
        else:  # hg
            clone_cmd = ['hg', 'clone', repo_url, str(repo_dir)]

        try:
>           subprocess.check_output(clone_cmd, stderr=subprocess.STDOUT)

cookiecutter/vcs.py:86: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
/usr/lib/python3.10/unittest/mock.py:1114: in __call__
    return self._mock_call(*args, **kwargs)
/usr/lib/python3.10/unittest/mock.py:1118: in _mock_call
    return self._execute_mock_call(*args, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = 
args = (['git', 'clone', 'https://github.com/hackebro/cookiedozer', '/tmp/pytest-of-root/pytest-0/test_clone_handles_repo_typo_h0/clone_dir/cookiedozer'],)
kwargs = {'stderr': -2}
effect = 
result = CalledProcessError(-1, 'cmd')

    def _execute_mock_call(self, /, *args, **kwargs):
        # separate from _increment_mock_call so that awaited functions are
        # executed separately from their call, also AsyncMock overrides this method

        effect = self.side_effect
        if effect is not None:
            if _is_exception(effect):
                raise effect
            elif not _callable(effect):
                result = next(effect)
                if _is_exception(result):
>                   raise result
E                   subprocess.CalledProcessError: Command 'cmd' died with .

/usr/lib/python3.10/unittest/mock.py:1177: CalledProcessError

During handling of the above exception, another exception occurred:

mocker = 
clone_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_clone_handles_repo_typo_h0/clone_dir')
error_message = b'hg: abort: HTTP Error 404: Not Found'

    @pytest.mark.parametrize(
        'error_message',
        [
            (b"fatal: repository 'https://github.com/hackebro/cookiedozer' not found"),
            b'hg: abort: HTTP Error 404: Not Found',
        ],
    )
    def test_clone_handles_repo_typo(mocker, clone_dir, error_message):
        """In `clone()`, repository not found errors should raise an \
        appropriate exception."""
        # side_effect is set to an iterable here (and below),
        # because of a Python 3.4 unittest.mock regression
        # http://bugs.python.org/issue23661
        mocker.patch(
            'cookiecutter.vcs.subprocess.check_output',
            autospec=True,
            side_effect=[subprocess.CalledProcessError(-1, 'cmd', output=error_message)],
        )

        repository_url = 'https://github.com/hackebro/cookiedozer'
        with pytest.raises(exceptions.RepositoryNotFound) as err:
>           vcs.clone(repository_url, clone_to_dir=str(clone_dir), no_input=True)

tests/vcs/test_clone.py:160: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

repo_url = 'https://github.com/hackebro/cookiedozer', checkout = None
clone_to_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_clone_handles_repo_typo_h0/clone_dir')
no_input = True

    def clone(repo_url: str, checkout: Optional[str]=None, clone_to_dir:
        'os.PathLike[str]'='.', no_input: bool=False):
        """Clone a repo to the current directory.

        :param repo_url: Repo URL of unknown type.
        :param checkout: The branch, tag or commit ID to checkout after clone.
        :param clone_to_dir: The directory to clone to.
                             Defaults to the current directory.
        :param no_input: Do not prompt for user input and eventually force a refresh of
            cached resources.
        :returns: str with path to the new directory of the repository.
        """
        repo_type, repo_url = identify_repo(repo_url)
        if repo_type is None:
            raise UnknownRepoType(f"Couldn't determine repository type for {repo_url}")

        if not is_vcs_installed(repo_type):
            raise VCSNotInstalled(f"{repo_type} is not installed.")

        clone_to_dir = Path(clone_to_dir).resolve()
        make_sure_path_exists(clone_to_dir)

        repo_dir = clone_to_dir / Path(repo_url).stem

        if repo_dir.exists():
            if no_input:
                logger.warning("'%s' directory already exists, deleting it", repo_dir)
                subprocess.check_call([repo_type, 'init', str(repo_dir)])
            else:
                prompt_and_delete(repo_dir)

        if repo_type == 'git':
            clone_cmd = ['git', 'clone', repo_url, str(repo_dir)]
        else:  # hg
            clone_cmd = ['hg', 'clone', repo_url, str(repo_dir)]

        try:
            subprocess.check_output(clone_cmd, stderr=subprocess.STDOUT)
        except subprocess.CalledProcessError as e:
            output = e.output.decode('utf-8')
            if 'Repository not found' in output:
                raise RepositoryNotFound(f"The repository {repo_url} could not be found")
            else:
>               raise RepositoryCloneFailed(f"Cloning {repo_url} failed: {output}")
E               cookiecutter.exceptions.RepositoryCloneFailed: Cloning https://github.com/hackebro/cookiedozer failed: hg: abort: HTTP Error 404: Not Found

cookiecutter/vcs.py:92: RepositoryCloneFailed

test_clone.py::test_clone_handles_branch_typo[error: pathspec 'unknown_branch' did not match any file(s) known to git]

test_clone.py::test_clone_handles_branch_typo[error: pathspec 'unknown_branch' did not match any file(s) known to git]
mocker = 
clone_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_clone_handles_branch_typo0/clone_dir')
error_message = b"error: pathspec 'unknown_branch' did not match any file(s) known to git"

    @pytest.mark.parametrize(
        'error_message',
        [
            b"error: pathspec 'unknown_branch' did not match any file(s) known to git",
            b"hg: abort: unknown revision 'unknown_branch'!",
        ],
    )
    def test_clone_handles_branch_typo(mocker, clone_dir, error_message):
        """In `clone()`, branch not found errors should raise an \
        appropriate exception."""
        mocker.patch(
            'cookiecutter.vcs.subprocess.check_output',
            autospec=True,
            side_effect=[subprocess.CalledProcessError(-1, 'cmd', output=error_message)],
        )

        repository_url = 'https://github.com/pytest-dev/cookiecutter-pytest-plugin'
        with pytest.raises(exceptions.RepositoryCloneFailed) as err:
            vcs.clone(
                repository_url,
                clone_to_dir=str(clone_dir),
                checkout='unknown_branch',
                no_input=True,
            )

>       assert str(err.value) == (
            'The unknown_branch branch of repository '
            f'{repository_url} could not found, have you made a typo?'
        )
E       assert "Cloning https://github.com/pytest-dev/cookiecutter-pytest-plugin failed: error: pathspec 'unknown_branch' did not match any file(s) known to git" == 'The unknown_branch branch of repository https://github.com/pytest-dev/cookiecutter-pytest-plugin could not found, have you made a typo?'
E         
E         - The unknown_branch branch of repository https://github.com/pytest-dev/cookiecutter-pytest-plugin could not found, have you made a typo?
E         + Cloning https://github.com/pytest-dev/cookiecutter-pytest-plugin failed: error: pathspec 'unknown_branch' did not match any file(s) known to git

tests/vcs/test_clone.py:192: AssertionError

test_clone.py::test_clone_handles_branch_typo[hg: abort: unknown revision 'unknown_branch'!]

test_clone.py::test_clone_handles_branch_typo[hg: abort: unknown revision 'unknown_branch'!]
mocker = 
clone_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_clone_handles_branch_typo1/clone_dir')
error_message = b"hg: abort: unknown revision 'unknown_branch'!"

    @pytest.mark.parametrize(
        'error_message',
        [
            b"error: pathspec 'unknown_branch' did not match any file(s) known to git",
            b"hg: abort: unknown revision 'unknown_branch'!",
        ],
    )
    def test_clone_handles_branch_typo(mocker, clone_dir, error_message):
        """In `clone()`, branch not found errors should raise an \
        appropriate exception."""
        mocker.patch(
            'cookiecutter.vcs.subprocess.check_output',
            autospec=True,
            side_effect=[subprocess.CalledProcessError(-1, 'cmd', output=error_message)],
        )

        repository_url = 'https://github.com/pytest-dev/cookiecutter-pytest-plugin'
        with pytest.raises(exceptions.RepositoryCloneFailed) as err:
            vcs.clone(
                repository_url,
                clone_to_dir=str(clone_dir),
                checkout='unknown_branch',
                no_input=True,
            )

>       assert str(err.value) == (
            'The unknown_branch branch of repository '
            f'{repository_url} could not found, have you made a typo?'
        )
E       assert "Cloning https://github.com/pytest-dev/cookiecutter-pytest-plugin failed: hg: abort: unknown revision 'unknown_branch'!" == 'The unknown_branch branch of repository https://github.com/pytest-dev/cookiecutter-pytest-plugin could not found, have you made a typo?'
E         
E         - The unknown_branch branch of repository https://github.com/pytest-dev/cookiecutter-pytest-plugin could not found, have you made a typo?
E         + Cloning https://github.com/pytest-dev/cookiecutter-pytest-plugin failed: hg: abort: unknown revision 'unknown_branch'!

tests/vcs/test_clone.py:192: AssertionError

test_clone.py::test_clone_unknown_subprocess_error

test_clone.py::test_clone_unknown_subprocess_error
repo_url = 'https://github.com/pytest-dev/cookiecutter-pytest-plugin'
checkout = None
clone_to_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_clone_unknown_subprocess_0/clone_dir')
no_input = True

    def clone(repo_url: str, checkout: Optional[str]=None, clone_to_dir:
        'os.PathLike[str]'='.', no_input: bool=False):
        """Clone a repo to the current directory.

        :param repo_url: Repo URL of unknown type.
        :param checkout: The branch, tag or commit ID to checkout after clone.
        :param clone_to_dir: The directory to clone to.
                             Defaults to the current directory.
        :param no_input: Do not prompt for user input and eventually force a refresh of
            cached resources.
        :returns: str with path to the new directory of the repository.
        """
        repo_type, repo_url = identify_repo(repo_url)
        if repo_type is None:
            raise UnknownRepoType(f"Couldn't determine repository type for {repo_url}")

        if not is_vcs_installed(repo_type):
            raise VCSNotInstalled(f"{repo_type} is not installed.")

        clone_to_dir = Path(clone_to_dir).resolve()
        make_sure_path_exists(clone_to_dir)

        repo_dir = clone_to_dir / Path(repo_url).stem

        if repo_dir.exists():
            if no_input:
                logger.warning("'%s' directory already exists, deleting it", repo_dir)
                subprocess.check_call([repo_type, 'init', str(repo_dir)])
            else:
                prompt_and_delete(repo_dir)

        if repo_type == 'git':
            clone_cmd = ['git', 'clone', repo_url, str(repo_dir)]
        else:  # hg
            clone_cmd = ['hg', 'clone', repo_url, str(repo_dir)]

        try:
>           subprocess.check_output(clone_cmd, stderr=subprocess.STDOUT)

cookiecutter/vcs.py:86: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
/usr/lib/python3.10/unittest/mock.py:1114: in __call__
    return self._mock_call(*args, **kwargs)
/usr/lib/python3.10/unittest/mock.py:1118: in _mock_call
    return self._execute_mock_call(*args, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = 
args = (['git', 'clone', 'https://github.com/pytest-dev/cookiecutter-pytest-plugin', '/tmp/pytest-of-root/pytest-0/test_clone_unknown_subprocess_0/clone_dir/cookiecutter-pytest-plugin'],)
kwargs = {'stderr': -2}
effect = 
result = CalledProcessError(-1, 'cmd')

    def _execute_mock_call(self, /, *args, **kwargs):
        # separate from _increment_mock_call so that awaited functions are
        # executed separately from their call, also AsyncMock overrides this method

        effect = self.side_effect
        if effect is not None:
            if _is_exception(effect):
                raise effect
            elif not _callable(effect):
                result = next(effect)
                if _is_exception(result):
>                   raise result
E                   subprocess.CalledProcessError: Command 'cmd' died with .

/usr/lib/python3.10/unittest/mock.py:1177: CalledProcessError

During handling of the above exception, another exception occurred:

mocker = 
clone_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_clone_unknown_subprocess_0/clone_dir')

    def test_clone_unknown_subprocess_error(mocker, clone_dir):
        """In `clone()`, unknown subprocess errors should be raised."""
        mocker.patch(
            'cookiecutter.vcs.subprocess.check_output',
            autospec=True,
            side_effect=[
                subprocess.CalledProcessError(-1, 'cmd', output=b'Something went wrong')
            ],
        )

        with pytest.raises(subprocess.CalledProcessError):
>           vcs.clone(
                'https://github.com/pytest-dev/cookiecutter-pytest-plugin',
                clone_to_dir=str(clone_dir),
                no_input=True,
            )

tests/vcs/test_clone.py:209: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

repo_url = 'https://github.com/pytest-dev/cookiecutter-pytest-plugin'
checkout = None
clone_to_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_clone_unknown_subprocess_0/clone_dir')
no_input = True

    def clone(repo_url: str, checkout: Optional[str]=None, clone_to_dir:
        'os.PathLike[str]'='.', no_input: bool=False):
        """Clone a repo to the current directory.

        :param repo_url: Repo URL of unknown type.
        :param checkout: The branch, tag or commit ID to checkout after clone.
        :param clone_to_dir: The directory to clone to.
                             Defaults to the current directory.
        :param no_input: Do not prompt for user input and eventually force a refresh of
            cached resources.
        :returns: str with path to the new directory of the repository.
        """
        repo_type, repo_url = identify_repo(repo_url)
        if repo_type is None:
            raise UnknownRepoType(f"Couldn't determine repository type for {repo_url}")

        if not is_vcs_installed(repo_type):
            raise VCSNotInstalled(f"{repo_type} is not installed.")

        clone_to_dir = Path(clone_to_dir).resolve()
        make_sure_path_exists(clone_to_dir)

        repo_dir = clone_to_dir / Path(repo_url).stem

        if repo_dir.exists():
            if no_input:
                logger.warning("'%s' directory already exists, deleting it", repo_dir)
                subprocess.check_call([repo_type, 'init', str(repo_dir)])
            else:
                prompt_and_delete(repo_dir)

        if repo_type == 'git':
            clone_cmd = ['git', 'clone', repo_url, str(repo_dir)]
        else:  # hg
            clone_cmd = ['hg', 'clone', repo_url, str(repo_dir)]

        try:
            subprocess.check_output(clone_cmd, stderr=subprocess.STDOUT)
        except subprocess.CalledProcessError as e:
            output = e.output.decode('utf-8')
            if 'Repository not found' in output:
                raise RepositoryNotFound(f"The repository {repo_url} could not be found")
            else:
>               raise RepositoryCloneFailed(f"Cloning {repo_url} failed: {output}")
E               cookiecutter.exceptions.RepositoryCloneFailed: Cloning https://github.com/pytest-dev/cookiecutter-pytest-plugin failed: Something went wrong

cookiecutter/vcs.py:92: RepositoryCloneFailed

test_identify_repo.py::test_identify_raise_on_unknown_repo[foo+git]

test_identify_repo.py::test_identify_raise_on_unknown_repo[foo+git]
unknown_repo_type_url = 'foo+git'

    def test_identify_raise_on_unknown_repo(unknown_repo_type_url):
        """Verify different incorrect repositories url syntax trigger error raising."""
>       with pytest.raises(exceptions.UnknownRepoType):
E       Failed: DID NOT RAISE 

tests/vcs/test_identify_repo.py:70: Failed

test_identify_repo.py::test_identify_raise_on_unknown_repo[foo+hg]

test_identify_repo.py::test_identify_raise_on_unknown_repo[foo+hg]
unknown_repo_type_url = 'foo+hg'

    def test_identify_raise_on_unknown_repo(unknown_repo_type_url):
        """Verify different incorrect repositories url syntax trigger error raising."""
>       with pytest.raises(exceptions.UnknownRepoType):
E       Failed: DID NOT RAISE 

tests/vcs/test_identify_repo.py:70: Failed

test_identify_repo.py::test_identify_raise_on_unknown_repo[foo+bar]

test_identify_repo.py::test_identify_raise_on_unknown_repo[foo+bar]
unknown_repo_type_url = 'foo+bar'

    def test_identify_raise_on_unknown_repo(unknown_repo_type_url):
        """Verify different incorrect repositories url syntax trigger error raising."""
>       with pytest.raises(exceptions.UnknownRepoType):
E       Failed: DID NOT RAISE 

tests/vcs/test_identify_repo.py:70: Failed

test_identify_repo.py::test_identify_raise_on_unknown_repo[foobar]

test_identify_repo.py::test_identify_raise_on_unknown_repo[foobar]
unknown_repo_type_url = 'foobar'

    def test_identify_raise_on_unknown_repo(unknown_repo_type_url):
        """Verify different incorrect repositories url syntax trigger error raising."""
>       with pytest.raises(exceptions.UnknownRepoType):
E       Failed: DID NOT RAISE 

tests/vcs/test_identify_repo.py:70: Failed

norepotypespecified.com]

norepotypespecified.com]
unknown_repo_type_url = 'http://norepotypespecified.com'

    def test_identify_raise_on_unknown_repo(unknown_repo_type_url):
        """Verify different incorrect repositories url syntax trigger error raising."""
>       with pytest.raises(exceptions.UnknownRepoType):
E       Failed: DID NOT RAISE 

tests/vcs/test_identify_repo.py:70: Failed

test_is_vcs_installed.py::test_is_vcs_installed[-False]

test_is_vcs_installed.py::test_is_vcs_installed[-False]
mocker = 
which_return = '', result = False

    @pytest.mark.parametrize(
        'which_return, result',
        [('', False), (None, False), (False, False), ('/usr/local/bin/git', True)],
    )
    def test_is_vcs_installed(mocker, which_return, result):
        """Verify `is_vcs_installed` function correctly handles `which` answer."""
        mocker.patch('cookiecutter.vcs.which', autospec=True, return_value=which_return)
>       assert vcs.is_vcs_installed('git') == result
E       AssertionError: assert True == False
E        +  where True = ('git')
E        +    where  = vcs.is_vcs_installed

tests/vcs/test_is_vcs_installed.py:15: AssertionError

test_is_vcs_installed.py::test_is_vcs_installed[False-False]

test_is_vcs_installed.py::test_is_vcs_installed[False-False]
mocker = 
which_return = False, result = False

    @pytest.mark.parametrize(
        'which_return, result',
        [('', False), (None, False), (False, False), ('/usr/local/bin/git', True)],
    )
    def test_is_vcs_installed(mocker, which_return, result):
        """Verify `is_vcs_installed` function correctly handles `which` answer."""
        mocker.patch('cookiecutter.vcs.which', autospec=True, return_value=which_return)
>       assert vcs.is_vcs_installed('git') == result
E       AssertionError: assert True == False
E        +  where True = ('git')
E        +    where  = vcs.is_vcs_installed

tests/vcs/test_is_vcs_installed.py:15: AssertionError

test_unzip.py::test_unzip_local_file

test_unzip.py::test_unzip_local_file
prompt = '', stream = None

    def unix_getpass(prompt='Password: ', stream=None):
        """Prompt for a password, with echo turned off.

        Args:
          prompt: Written on stream to ask for the input.  Default: 'Password: '
          stream: A writable file object to display the prompt.  Defaults to
                  the tty.  If no tty is available defaults to sys.stderr.
        Returns:
          The seKr3t input.
        Raises:
          EOFError: If our input tty or stdin was closed.
          GetPassWarning: When we were unable to turn echo off on the input.

        Always restores terminal settings before returning.
        """
        passwd = None
        with contextlib.ExitStack() as stack:
            try:
                # Always try reading and writing directly on the tty first.
>               fd = os.open('/dev/tty', os.O_RDWR|os.O_NOCTTY)
E               OSError: [Errno 5] Input/output error: '/dev/tty'

/usr/lib/python3.10/getpass.py:48: OSError

During handling of the above exception, another exception occurred:

prompt = '', stream = None

    def unix_getpass(prompt='Password: ', stream=None):
        """Prompt for a password, with echo turned off.

        Args:
          prompt: Written on stream to ask for the input.  Default: 'Password: '
          stream: A writable file object to display the prompt.  Defaults to
                  the tty.  If no tty is available defaults to sys.stderr.
        Returns:
          The seKr3t input.
        Raises:
          EOFError: If our input tty or stdin was closed.
          GetPassWarning: When we were unable to turn echo off on the input.

        Always restores terminal settings before returning.
        """
        passwd = None
        with contextlib.ExitStack() as stack:
            try:
                # Always try reading and writing directly on the tty first.
                fd = os.open('/dev/tty', os.O_RDWR|os.O_NOCTTY)
                tty = io.FileIO(fd, 'w+')
                stack.enter_context(tty)
                input = io.TextIOWrapper(tty)
                stack.enter_context(input)
                if not stream:
                    stream = input
            except OSError:
                # If that fails, see if stdin can be controlled.
                stack.close()
                try:
>                   fd = sys.stdin.fileno()
E                   io.UnsupportedOperation: redirected stdin is pseudofile, has no fileno()

/usr/lib/python3.10/getpass.py:59: UnsupportedOperation

During handling of the above exception, another exception occurred:

mocker = 
clone_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_unzip_local_file0/clone_dir')

    def test_unzip_local_file(mocker, clone_dir):
        """Local file reference can be unzipped."""
        mock_prompt_and_delete = mocker.patch(
            'cookiecutter.zipfile.prompt_and_delete', return_value=True, autospec=True
        )

>       output_dir = zipfile.unzip(
            'tests/files/fake-repo-tmpl.zip', is_url=False, clone_to_dir=str(clone_dir)
        )

tests/zipfile/test_unzip.py:38: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
cookiecutter/zipfile.py:50: in unzip
    password = read_repo_password('Enter the password for the encrypted repository:')
cookiecutter/prompt.py:69: in read_repo_password
    return Prompt.ask(question, password=True)
.venv/lib/python3.10/site-packages/rich/prompt.py:149: in ask
    return _prompt(default=default, stream=stream)
.venv/lib/python3.10/site-packages/rich/prompt.py:292: in __call__
    value = self.get_input(self.console, prompt, self.password, stream=stream)
.venv/lib/python3.10/site-packages/rich/prompt.py:211: in get_input
    return console.input(prompt, password=password, stream=stream)
.venv/lib/python3.10/site-packages/rich/console.py:2151: in input
    result = getpass("", stream=stream)
/usr/lib/python3.10/getpass.py:62: in unix_getpass
    passwd = fallback_getpass(prompt, stream)
/usr/lib/python3.10/getpass.py:126: in fallback_getpass
    return _raw_input(prompt, stream)
/usr/lib/python3.10/getpass.py:146: in _raw_input
    line = input.readline()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <_pytest.capture.DontReadFromInput object at 0x7fcb941608e0>, size = -1

    def read(self, size: int = -1) -> str:
>       raise OSError(
            "pytest: reading from stdin while output is captured!  Consider using `-s`."
        )
E       OSError: pytest: reading from stdin while output is captured!  Consider using `-s`.

.venv/lib/python3.10/site-packages/_pytest/capture.py:209: OSError

test_unzip.py::test_unzip_protected_local_file_environment_password

test_unzip.py::test_unzip_protected_local_file_environment_password
mocker = 
clone_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_unzip_protected_local_fil0/clone_dir')

    def test_unzip_protected_local_file_environment_password(mocker, clone_dir):
        """In `unzip()`, the environment can be used to provide a repo password."""
        mock_prompt_and_delete = mocker.patch(
            'cookiecutter.zipfile.prompt_and_delete', return_value=True, autospec=True
        )

>       output_dir = zipfile.unzip(
            'tests/files/protected-fake-repo-tmpl.zip',
            is_url=False,
            clone_to_dir=str(clone_dir),
            password='sekrit',
        )

tests/zipfile/test_unzip.py:52: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
cookiecutter/zipfile.py:46: in unzip
    if zip_ref.namelist() and zip_ref.testzip() is not None:
/usr/lib/python3.10/zipfile.py:1442: in testzip
    with self.open(zinfo.filename, "r") as f:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = , name = 'fake-repo-tmpl/cookiecutter.json'
mode = 'r', pwd = None

    def open(self, name, mode="r", pwd=None, *, force_zip64=False):
        """Return file-like object for 'name'.

        name is a string for the file name within the ZIP file, or a ZipInfo
        object.

        mode should be 'r' to read a file already in the ZIP file, or 'w' to
        write to a file newly added to the archive.

        pwd is the password to decrypt files (only used for reading).

        When writing, if the file size is not known in advance but may exceed
        2 GiB, pass force_zip64 to use the ZIP64 format, which can handle large
        files.  If the size is known in advance, it is best to pass a ZipInfo
        instance for name, with zinfo.file_size set.
        """
        if mode not in {"r", "w"}:
            raise ValueError('open() requires mode "r" or "w"')
        if pwd and not isinstance(pwd, bytes):
            raise TypeError("pwd: expected bytes, got %s" % type(pwd).__name__)
        if pwd and (mode == "w"):
            raise ValueError("pwd is only supported for reading files")
        if not self.fp:
            raise ValueError(
                "Attempt to use ZIP archive that was already closed")

        # Make sure we have an info object
        if isinstance(name, ZipInfo):
            # 'name' is already an info object
            zinfo = name
        elif mode == 'w':
            zinfo = ZipInfo(name)
            zinfo.compress_type = self.compression
            zinfo._compresslevel = self.compresslevel
        else:
            # Get info object for name
            zinfo = self.getinfo(name)

        if mode == 'w':
            return self._open_to_write(zinfo, force_zip64=force_zip64)

        if self._writing:
            raise ValueError("Can't read from the ZIP file while there "
                    "is an open writing handle on it. "
                    "Close the writing handle before trying to read.")

        # Open for reading:
        self._fileRefCnt += 1
        zef_file = _SharedFile(self.fp, zinfo.header_offset,
                               self._fpclose, self._lock, lambda: self._writing)
        try:
            # Skip the file header:
            fheader = zef_file.read(sizeFileHeader)
            if len(fheader) != sizeFileHeader:
                raise BadZipFile("Truncated file header")
            fheader = struct.unpack(structFileHeader, fheader)
            if fheader[_FH_SIGNATURE] != stringFileHeader:
                raise BadZipFile("Bad magic number for file header")

            fname = zef_file.read(fheader[_FH_FILENAME_LENGTH])
            if fheader[_FH_EXTRA_FIELD_LENGTH]:
                zef_file.read(fheader[_FH_EXTRA_FIELD_LENGTH])

            if zinfo.flag_bits & 0x20:
                # Zip 2.7: compressed patched data
                raise NotImplementedError("compressed patched data (flag bit 5)")

            if zinfo.flag_bits & 0x40:
                # strong encryption
                raise NotImplementedError("strong encryption (flag bit 6)")

            if fheader[_FH_GENERAL_PURPOSE_FLAG_BITS] & 0x800:
                # UTF-8 filename
                fname_str = fname.decode("utf-8")
            else:
                fname_str = fname.decode("cp437")

            if fname_str != zinfo.orig_filename:
                raise BadZipFile(
                    'File name in directory %r and header %r differ.'
                    % (zinfo.orig_filename, fname))

            if (zinfo._end_offset is not None and
                zef_file.tell() + zinfo.compress_size > zinfo._end_offset):
                raise BadZipFile(f"Overlapped entries: {zinfo.orig_filename!r} (possible zip bomb)")

            # check for encrypted flag & handle password
            is_encrypted = zinfo.flag_bits & 0x1
            if is_encrypted:
                if not pwd:
                    pwd = self.pwd
                if not pwd:
>                   raise RuntimeError("File %r is encrypted, password "
                                       "required for extraction" % name)
E                                      RuntimeError: File 'fake-repo-tmpl/cookiecutter.json' is encrypted, password required for extraction

/usr/lib/python3.10/zipfile.py:1581: RuntimeError

test_unzip.py::test_unzip_protected_local_file_bad_environment_password

test_unzip.py::test_unzip_protected_local_file_bad_environment_password
mocker = 
clone_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_unzip_protected_local_fil1/clone_dir')

    def test_unzip_protected_local_file_bad_environment_password(mocker, clone_dir):
        """In `unzip()`, an error occurs if the environment has a bad password."""
        mocker.patch(
            'cookiecutter.zipfile.prompt_and_delete', return_value=True, autospec=True
        )

        with pytest.raises(InvalidZipRepository):
>           zipfile.unzip(
                'tests/files/protected-fake-repo-tmpl.zip',
                is_url=False,
                clone_to_dir=str(clone_dir),
                password='not-the-right-password',
            )

tests/zipfile/test_unzip.py:70: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
cookiecutter/zipfile.py:46: in unzip
    if zip_ref.namelist() and zip_ref.testzip() is not None:
/usr/lib/python3.10/zipfile.py:1442: in testzip
    with self.open(zinfo.filename, "r") as f:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = , name = 'fake-repo-tmpl/cookiecutter.json'
mode = 'r', pwd = None

    def open(self, name, mode="r", pwd=None, *, force_zip64=False):
        """Return file-like object for 'name'.

        name is a string for the file name within the ZIP file, or a ZipInfo
        object.

        mode should be 'r' to read a file already in the ZIP file, or 'w' to
        write to a file newly added to the archive.

        pwd is the password to decrypt files (only used for reading).

        When writing, if the file size is not known in advance but may exceed
        2 GiB, pass force_zip64 to use the ZIP64 format, which can handle large
        files.  If the size is known in advance, it is best to pass a ZipInfo
        instance for name, with zinfo.file_size set.
        """
        if mode not in {"r", "w"}:
            raise ValueError('open() requires mode "r" or "w"')
        if pwd and not isinstance(pwd, bytes):
            raise TypeError("pwd: expected bytes, got %s" % type(pwd).__name__)
        if pwd and (mode == "w"):
            raise ValueError("pwd is only supported for reading files")
        if not self.fp:
            raise ValueError(
                "Attempt to use ZIP archive that was already closed")

        # Make sure we have an info object
        if isinstance(name, ZipInfo):
            # 'name' is already an info object
            zinfo = name
        elif mode == 'w':
            zinfo = ZipInfo(name)
            zinfo.compress_type = self.compression
            zinfo._compresslevel = self.compresslevel
        else:
            # Get info object for name
            zinfo = self.getinfo(name)

        if mode == 'w':
            return self._open_to_write(zinfo, force_zip64=force_zip64)

        if self._writing:
            raise ValueError("Can't read from the ZIP file while there "
                    "is an open writing handle on it. "
                    "Close the writing handle before trying to read.")

        # Open for reading:
        self._fileRefCnt += 1
        zef_file = _SharedFile(self.fp, zinfo.header_offset,
                               self._fpclose, self._lock, lambda: self._writing)
        try:
            # Skip the file header:
            fheader = zef_file.read(sizeFileHeader)
            if len(fheader) != sizeFileHeader:
                raise BadZipFile("Truncated file header")
            fheader = struct.unpack(structFileHeader, fheader)
            if fheader[_FH_SIGNATURE] != stringFileHeader:
                raise BadZipFile("Bad magic number for file header")

            fname = zef_file.read(fheader[_FH_FILENAME_LENGTH])
            if fheader[_FH_EXTRA_FIELD_LENGTH]:
                zef_file.read(fheader[_FH_EXTRA_FIELD_LENGTH])

            if zinfo.flag_bits & 0x20:
                # Zip 2.7: compressed patched data
                raise NotImplementedError("compressed patched data (flag bit 5)")

            if zinfo.flag_bits & 0x40:
                # strong encryption
                raise NotImplementedError("strong encryption (flag bit 6)")

            if fheader[_FH_GENERAL_PURPOSE_FLAG_BITS] & 0x800:
                # UTF-8 filename
                fname_str = fname.decode("utf-8")
            else:
                fname_str = fname.decode("cp437")

            if fname_str != zinfo.orig_filename:
                raise BadZipFile(
                    'File name in directory %r and header %r differ.'
                    % (zinfo.orig_filename, fname))

            if (zinfo._end_offset is not None and
                zef_file.tell() + zinfo.compress_size > zinfo._end_offset):
                raise BadZipFile(f"Overlapped entries: {zinfo.orig_filename!r} (possible zip bomb)")

            # check for encrypted flag & handle password
            is_encrypted = zinfo.flag_bits & 0x1
            if is_encrypted:
                if not pwd:
                    pwd = self.pwd
                if not pwd:
>                   raise RuntimeError("File %r is encrypted, password "
                                       "required for extraction" % name)
E                                      RuntimeError: File 'fake-repo-tmpl/cookiecutter.json' is encrypted, password required for extraction

/usr/lib/python3.10/zipfile.py:1581: RuntimeError

test_unzip.py::test_unzip_protected_local_file_user_password_with_noinput

test_unzip.py::test_unzip_protected_local_file_user_password_with_noinput
mocker = 
clone_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_unzip_protected_local_fil2/clone_dir')

    def test_unzip_protected_local_file_user_password_with_noinput(mocker, clone_dir):
        """Can't unpack a password-protected repo in no_input mode."""
        mocker.patch(
            'cookiecutter.zipfile.prompt_and_delete', return_value=True, autospec=True
        )

        with pytest.raises(InvalidZipRepository):
>           zipfile.unzip(
                'tests/files/protected-fake-repo-tmpl.zip',
                is_url=False,
                clone_to_dir=str(clone_dir),
                no_input=True,
            )

tests/zipfile/test_unzip.py:85: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
cookiecutter/zipfile.py:46: in unzip
    if zip_ref.namelist() and zip_ref.testzip() is not None:
/usr/lib/python3.10/zipfile.py:1442: in testzip
    with self.open(zinfo.filename, "r") as f:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = , name = 'fake-repo-tmpl/cookiecutter.json'
mode = 'r', pwd = None

    def open(self, name, mode="r", pwd=None, *, force_zip64=False):
        """Return file-like object for 'name'.

        name is a string for the file name within the ZIP file, or a ZipInfo
        object.

        mode should be 'r' to read a file already in the ZIP file, or 'w' to
        write to a file newly added to the archive.

        pwd is the password to decrypt files (only used for reading).

        When writing, if the file size is not known in advance but may exceed
        2 GiB, pass force_zip64 to use the ZIP64 format, which can handle large
        files.  If the size is known in advance, it is best to pass a ZipInfo
        instance for name, with zinfo.file_size set.
        """
        if mode not in {"r", "w"}:
            raise ValueError('open() requires mode "r" or "w"')
        if pwd and not isinstance(pwd, bytes):
            raise TypeError("pwd: expected bytes, got %s" % type(pwd).__name__)
        if pwd and (mode == "w"):
            raise ValueError("pwd is only supported for reading files")
        if not self.fp:
            raise ValueError(
                "Attempt to use ZIP archive that was already closed")

        # Make sure we have an info object
        if isinstance(name, ZipInfo):
            # 'name' is already an info object
            zinfo = name
        elif mode == 'w':
            zinfo = ZipInfo(name)
            zinfo.compress_type = self.compression
            zinfo._compresslevel = self.compresslevel
        else:
            # Get info object for name
            zinfo = self.getinfo(name)

        if mode == 'w':
            return self._open_to_write(zinfo, force_zip64=force_zip64)

        if self._writing:
            raise ValueError("Can't read from the ZIP file while there "
                    "is an open writing handle on it. "
                    "Close the writing handle before trying to read.")

        # Open for reading:
        self._fileRefCnt += 1
        zef_file = _SharedFile(self.fp, zinfo.header_offset,
                               self._fpclose, self._lock, lambda: self._writing)
        try:
            # Skip the file header:
            fheader = zef_file.read(sizeFileHeader)
            if len(fheader) != sizeFileHeader:
                raise BadZipFile("Truncated file header")
            fheader = struct.unpack(structFileHeader, fheader)
            if fheader[_FH_SIGNATURE] != stringFileHeader:
                raise BadZipFile("Bad magic number for file header")

            fname = zef_file.read(fheader[_FH_FILENAME_LENGTH])
            if fheader[_FH_EXTRA_FIELD_LENGTH]:
                zef_file.read(fheader[_FH_EXTRA_FIELD_LENGTH])

            if zinfo.flag_bits & 0x20:
                # Zip 2.7: compressed patched data
                raise NotImplementedError("compressed patched data (flag bit 5)")

            if zinfo.flag_bits & 0x40:
                # strong encryption
                raise NotImplementedError("strong encryption (flag bit 6)")

            if fheader[_FH_GENERAL_PURPOSE_FLAG_BITS] & 0x800:
                # UTF-8 filename
                fname_str = fname.decode("utf-8")
            else:
                fname_str = fname.decode("cp437")

            if fname_str != zinfo.orig_filename:
                raise BadZipFile(
                    'File name in directory %r and header %r differ.'
                    % (zinfo.orig_filename, fname))

            if (zinfo._end_offset is not None and
                zef_file.tell() + zinfo.compress_size > zinfo._end_offset):
                raise BadZipFile(f"Overlapped entries: {zinfo.orig_filename!r} (possible zip bomb)")

            # check for encrypted flag & handle password
            is_encrypted = zinfo.flag_bits & 0x1
            if is_encrypted:
                if not pwd:
                    pwd = self.pwd
                if not pwd:
>                   raise RuntimeError("File %r is encrypted, password "
                                       "required for extraction" % name)
E                                      RuntimeError: File 'fake-repo-tmpl/cookiecutter.json' is encrypted, password required for extraction

/usr/lib/python3.10/zipfile.py:1581: RuntimeError

test_unzip.py::test_unzip_protected_local_file_user_password

test_unzip.py::test_unzip_protected_local_file_user_password
mocker = 
clone_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_unzip_protected_local_fil3/clone_dir')

    def test_unzip_protected_local_file_user_password(mocker, clone_dir):
        """A password-protected local file reference can be unzipped."""
        mock_prompt_and_delete = mocker.patch(
            'cookiecutter.zipfile.prompt_and_delete', return_value=True, autospec=True
        )
        mocker.patch('cookiecutter.zipfile.read_repo_password', return_value='sekrit')

>       output_dir = zipfile.unzip(
            'tests/files/protected-fake-repo-tmpl.zip',
            is_url=False,
            clone_to_dir=str(clone_dir),
        )

tests/zipfile/test_unzip.py:100: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
cookiecutter/zipfile.py:46: in unzip
    if zip_ref.namelist() and zip_ref.testzip() is not None:
/usr/lib/python3.10/zipfile.py:1442: in testzip
    with self.open(zinfo.filename, "r") as f:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = , name = 'fake-repo-tmpl/cookiecutter.json'
mode = 'r', pwd = None

    def open(self, name, mode="r", pwd=None, *, force_zip64=False):
        """Return file-like object for 'name'.

        name is a string for the file name within the ZIP file, or a ZipInfo
        object.

        mode should be 'r' to read a file already in the ZIP file, or 'w' to
        write to a file newly added to the archive.

        pwd is the password to decrypt files (only used for reading).

        When writing, if the file size is not known in advance but may exceed
        2 GiB, pass force_zip64 to use the ZIP64 format, which can handle large
        files.  If the size is known in advance, it is best to pass a ZipInfo
        instance for name, with zinfo.file_size set.
        """
        if mode not in {"r", "w"}:
            raise ValueError('open() requires mode "r" or "w"')
        if pwd and not isinstance(pwd, bytes):
            raise TypeError("pwd: expected bytes, got %s" % type(pwd).__name__)
        if pwd and (mode == "w"):
            raise ValueError("pwd is only supported for reading files")
        if not self.fp:
            raise ValueError(
                "Attempt to use ZIP archive that was already closed")

        # Make sure we have an info object
        if isinstance(name, ZipInfo):
            # 'name' is already an info object
            zinfo = name
        elif mode == 'w':
            zinfo = ZipInfo(name)
            zinfo.compress_type = self.compression
            zinfo._compresslevel = self.compresslevel
        else:
            # Get info object for name
            zinfo = self.getinfo(name)

        if mode == 'w':
            return self._open_to_write(zinfo, force_zip64=force_zip64)

        if self._writing:
            raise ValueError("Can't read from the ZIP file while there "
                    "is an open writing handle on it. "
                    "Close the writing handle before trying to read.")

        # Open for reading:
        self._fileRefCnt += 1
        zef_file = _SharedFile(self.fp, zinfo.header_offset,
                               self._fpclose, self._lock, lambda: self._writing)
        try:
            # Skip the file header:
            fheader = zef_file.read(sizeFileHeader)
            if len(fheader) != sizeFileHeader:
                raise BadZipFile("Truncated file header")
            fheader = struct.unpack(structFileHeader, fheader)
            if fheader[_FH_SIGNATURE] != stringFileHeader:
                raise BadZipFile("Bad magic number for file header")

            fname = zef_file.read(fheader[_FH_FILENAME_LENGTH])
            if fheader[_FH_EXTRA_FIELD_LENGTH]:
                zef_file.read(fheader[_FH_EXTRA_FIELD_LENGTH])

            if zinfo.flag_bits & 0x20:
                # Zip 2.7: compressed patched data
                raise NotImplementedError("compressed patched data (flag bit 5)")

            if zinfo.flag_bits & 0x40:
                # strong encryption
                raise NotImplementedError("strong encryption (flag bit 6)")

            if fheader[_FH_GENERAL_PURPOSE_FLAG_BITS] & 0x800:
                # UTF-8 filename
                fname_str = fname.decode("utf-8")
            else:
                fname_str = fname.decode("cp437")

            if fname_str != zinfo.orig_filename:
                raise BadZipFile(
                    'File name in directory %r and header %r differ.'
                    % (zinfo.orig_filename, fname))

            if (zinfo._end_offset is not None and
                zef_file.tell() + zinfo.compress_size > zinfo._end_offset):
                raise BadZipFile(f"Overlapped entries: {zinfo.orig_filename!r} (possible zip bomb)")

            # check for encrypted flag & handle password
            is_encrypted = zinfo.flag_bits & 0x1
            if is_encrypted:
                if not pwd:
                    pwd = self.pwd
                if not pwd:
>                   raise RuntimeError("File %r is encrypted, password "
                                       "required for extraction" % name)
E                                      RuntimeError: File 'fake-repo-tmpl/cookiecutter.json' is encrypted, password required for extraction

/usr/lib/python3.10/zipfile.py:1581: RuntimeError

test_unzip.py::test_unzip_protected_local_file_user_bad_password

test_unzip.py::test_unzip_protected_local_file_user_bad_password
mocker = 
clone_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_unzip_protected_local_fil4/clone_dir')

    def test_unzip_protected_local_file_user_bad_password(mocker, clone_dir):
        """Error in `unzip()`, if user can't provide a valid password."""
        mocker.patch(
            'cookiecutter.zipfile.prompt_and_delete', return_value=True, autospec=True
        )
        mocker.patch(
            'cookiecutter.zipfile.read_repo_password', return_value='not-the-right-password'
        )

        with pytest.raises(InvalidZipRepository):
>           zipfile.unzip(
                'tests/files/protected-fake-repo-tmpl.zip',
                is_url=False,
                clone_to_dir=str(clone_dir),
            )

tests/zipfile/test_unzip.py:120: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
cookiecutter/zipfile.py:46: in unzip
    if zip_ref.namelist() and zip_ref.testzip() is not None:
/usr/lib/python3.10/zipfile.py:1442: in testzip
    with self.open(zinfo.filename, "r") as f:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = , name = 'fake-repo-tmpl/cookiecutter.json'
mode = 'r', pwd = None

    def open(self, name, mode="r", pwd=None, *, force_zip64=False):
        """Return file-like object for 'name'.

        name is a string for the file name within the ZIP file, or a ZipInfo
        object.

        mode should be 'r' to read a file already in the ZIP file, or 'w' to
        write to a file newly added to the archive.

        pwd is the password to decrypt files (only used for reading).

        When writing, if the file size is not known in advance but may exceed
        2 GiB, pass force_zip64 to use the ZIP64 format, which can handle large
        files.  If the size is known in advance, it is best to pass a ZipInfo
        instance for name, with zinfo.file_size set.
        """
        if mode not in {"r", "w"}:
            raise ValueError('open() requires mode "r" or "w"')
        if pwd and not isinstance(pwd, bytes):
            raise TypeError("pwd: expected bytes, got %s" % type(pwd).__name__)
        if pwd and (mode == "w"):
            raise ValueError("pwd is only supported for reading files")
        if not self.fp:
            raise ValueError(
                "Attempt to use ZIP archive that was already closed")

        # Make sure we have an info object
        if isinstance(name, ZipInfo):
            # 'name' is already an info object
            zinfo = name
        elif mode == 'w':
            zinfo = ZipInfo(name)
            zinfo.compress_type = self.compression
            zinfo._compresslevel = self.compresslevel
        else:
            # Get info object for name
            zinfo = self.getinfo(name)

        if mode == 'w':
            return self._open_to_write(zinfo, force_zip64=force_zip64)

        if self._writing:
            raise ValueError("Can't read from the ZIP file while there "
                    "is an open writing handle on it. "
                    "Close the writing handle before trying to read.")

        # Open for reading:
        self._fileRefCnt += 1
        zef_file = _SharedFile(self.fp, zinfo.header_offset,
                               self._fpclose, self._lock, lambda: self._writing)
        try:
            # Skip the file header:
            fheader = zef_file.read(sizeFileHeader)
            if len(fheader) != sizeFileHeader:
                raise BadZipFile("Truncated file header")
            fheader = struct.unpack(structFileHeader, fheader)
            if fheader[_FH_SIGNATURE] != stringFileHeader:
                raise BadZipFile("Bad magic number for file header")

            fname = zef_file.read(fheader[_FH_FILENAME_LENGTH])
            if fheader[_FH_EXTRA_FIELD_LENGTH]:
                zef_file.read(fheader[_FH_EXTRA_FIELD_LENGTH])

            if zinfo.flag_bits & 0x20:
                # Zip 2.7: compressed patched data
                raise NotImplementedError("compressed patched data (flag bit 5)")

            if zinfo.flag_bits & 0x40:
                # strong encryption
                raise NotImplementedError("strong encryption (flag bit 6)")

            if fheader[_FH_GENERAL_PURPOSE_FLAG_BITS] & 0x800:
                # UTF-8 filename
                fname_str = fname.decode("utf-8")
            else:
                fname_str = fname.decode("cp437")

            if fname_str != zinfo.orig_filename:
                raise BadZipFile(
                    'File name in directory %r and header %r differ.'
                    % (zinfo.orig_filename, fname))

            if (zinfo._end_offset is not None and
                zef_file.tell() + zinfo.compress_size > zinfo._end_offset):
                raise BadZipFile(f"Overlapped entries: {zinfo.orig_filename!r} (possible zip bomb)")

            # check for encrypted flag & handle password
            is_encrypted = zinfo.flag_bits & 0x1
            if is_encrypted:
                if not pwd:
                    pwd = self.pwd
                if not pwd:
>                   raise RuntimeError("File %r is encrypted, password "
                                       "required for extraction" % name)
E                                      RuntimeError: File 'fake-repo-tmpl/cookiecutter.json' is encrypted, password required for extraction

/usr/lib/python3.10/zipfile.py:1581: RuntimeError

test_unzip.py::test_empty_zip_file

test_unzip.py::test_empty_zip_file
mocker = 
clone_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_empty_zip_file0/clone_dir')

    def test_empty_zip_file(mocker, clone_dir):
        """In `unzip()`, an empty file raises an error."""
        mocker.patch(
            'cookiecutter.zipfile.prompt_and_delete', return_value=True, autospec=True
        )

        with pytest.raises(InvalidZipRepository):
>           zipfile.unzip(
                'tests/files/empty.zip', is_url=False, clone_to_dir=str(clone_dir)
            )

tests/zipfile/test_unzip.py:134: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

zip_uri = 'tests/files/empty.zip', is_url = False
clone_to_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_empty_zip_file0/clone_dir')
no_input = False, password = None

    def unzip(zip_uri: str, is_url: bool, clone_to_dir: 'os.PathLike[str]'='.',
        no_input: bool=False, password: Optional[str]=None):
        """Download and unpack a zipfile at a given URI.

        This will download the zipfile to the cookiecutter repository,
        and unpack into a temporary directory.

        :param zip_uri: The URI for the zipfile.
        :param is_url: Is the zip URI a URL or a file?
        :param clone_to_dir: The cookiecutter repository directory
            to put the archive into.
        :param no_input: Do not prompt for user input and eventually force a refresh of
            cached resources.
        :param password: The password to use when unpacking the repository.
        """
        clone_to_dir = Path(clone_to_dir)
        make_sure_path_exists(clone_to_dir)

        if is_url:
            # Download the file
            response = requests.get(zip_uri)
            response.raise_for_status()
            zip_file = tempfile.NamedTemporaryFile(delete=False, suffix='.zip', dir=clone_to_dir)
            zip_file.write(response.content)
            zip_file.close()
            zip_path = Path(zip_file.name)
        else:
            zip_path = Path(zip_uri)

        # Create a temporary directory to extract the contents
        with tempfile.TemporaryDirectory(dir=clone_to_dir) as temp_dir:
            try:
                with ZipFile(zip_path, 'r') as zip_ref:
                    if zip_ref.namelist() and zip_ref.testzip() is not None:
                        raise InvalidZipRepository(f"The zip file {zip_uri} is invalid or corrupt.")

>                   if password is None and zip_ref.namelist()[0].endswith('/'):
E                   IndexError: list index out of range

cookiecutter/zipfile.py:49: IndexError

test_unzip.py::test_non_repo_zip_file

test_unzip.py::test_non_repo_zip_file
mocker = 
clone_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_non_repo_zip_file0/clone_dir')

    def test_non_repo_zip_file(mocker, clone_dir):
        """In `unzip()`, a repository must have a top level directory."""
        mocker.patch(
            'cookiecutter.zipfile.prompt_and_delete', return_value=True, autospec=True
        )

>       with pytest.raises(InvalidZipRepository):
E       Failed: DID NOT RAISE 

tests/zipfile/test_unzip.py:145: Failed

test_unzip.py::test_unzip_url

test_unzip.py::test_unzip_url
mocker = 
clone_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_unzip_url0/clone_dir')

    def test_unzip_url(mocker, clone_dir):
        """In `unzip()`, a url will be downloaded and unzipped."""
        mock_prompt_and_delete = mocker.patch(
            'cookiecutter.zipfile.prompt_and_delete', return_value=True, autospec=True
        )

        request = mocker.MagicMock()
        request.iter_content.return_value = mock_download()

        mocker.patch(
            'cookiecutter.zipfile.requests.get',
            return_value=request,
            autospec=True,
        )

>       output_dir = zipfile.unzip(
            'https://example.com/path/to/fake-repo-tmpl.zip',
            is_url=True,
            clone_to_dir=str(clone_dir),
        )

tests/zipfile/test_unzip.py:178: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
cookiecutter/zipfile.py:36: in unzip
    zip_file.write(response.content)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

args = (,), kwargs = {}

    @_functools.wraps(func)
    def func_wrapper(*args, **kwargs):
>       return func(*args, **kwargs)
E       TypeError: a bytes-like object is required, not 'MagicMock'

/usr/lib/python3.10/tempfile.py:638: TypeError

test_unzip.py::test_unzip_url_with_empty_chunks

test_unzip.py::test_unzip_url_with_empty_chunks
mocker = 
clone_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_unzip_url_with_empty_chun0/clone_dir')

    def test_unzip_url_with_empty_chunks(mocker, clone_dir):
        """In `unzip()` empty chunk must be ignored."""
        mock_prompt_and_delete = mocker.patch(
            'cookiecutter.zipfile.prompt_and_delete', return_value=True, autospec=True
        )

        request = mocker.MagicMock()
        request.iter_content.return_value = mock_download_with_empty_chunks()

        mocker.patch(
            'cookiecutter.zipfile.requests.get',
            return_value=request,
            autospec=True,
        )

>       output_dir = zipfile.unzip(
            'https://example.com/path/to/fake-repo-tmpl.zip',
            is_url=True,
            clone_to_dir=str(clone_dir),
        )

tests/zipfile/test_unzip.py:203: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
cookiecutter/zipfile.py:36: in unzip
    zip_file.write(response.content)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

args = (,), kwargs = {}

    @_functools.wraps(func)
    def func_wrapper(*args, **kwargs):
>       return func(*args, **kwargs)
E       TypeError: a bytes-like object is required, not 'MagicMock'

/usr/lib/python3.10/tempfile.py:638: TypeError

test_unzip.py::test_unzip_url_existing_cache

test_unzip.py::test_unzip_url_existing_cache
mocker = 
clone_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_unzip_url_existing_cache0/clone_dir')

    def test_unzip_url_existing_cache(mocker, clone_dir):
        """Url should be downloaded and unzipped, old zip file will be removed."""
        mock_prompt_and_delete = mocker.patch(
            'cookiecutter.zipfile.prompt_and_delete', return_value=True, autospec=True
        )

        request = mocker.MagicMock()
        request.iter_content.return_value = mock_download()

        mocker.patch(
            'cookiecutter.zipfile.requests.get',
            return_value=request,
            autospec=True,
        )

        # Create an existing cache of the zipfile
        existing_zip = clone_dir.joinpath('fake-repo-tmpl.zip')
        existing_zip.write_text('This is an existing zipfile')

>       output_dir = zipfile.unzip(
            'https://example.com/path/to/fake-repo-tmpl.zip',
            is_url=True,
            clone_to_dir=str(clone_dir),
        )

tests/zipfile/test_unzip.py:232: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
cookiecutter/zipfile.py:36: in unzip
    zip_file.write(response.content)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

args = (,), kwargs = {}

    @_functools.wraps(func)
    def func_wrapper(*args, **kwargs):
>       return func(*args, **kwargs)
E       TypeError: a bytes-like object is required, not 'MagicMock'

/usr/lib/python3.10/tempfile.py:638: TypeError

test_unzip.py::test_unzip_url_existing_cache_no_input

test_unzip.py::test_unzip_url_existing_cache_no_input
mocker = 
clone_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_unzip_url_existing_cache_0/clone_dir')

    def test_unzip_url_existing_cache_no_input(mocker, clone_dir):
        """If no_input is provided, the existing file should be removed."""
        request = mocker.MagicMock()
        request.iter_content.return_value = mock_download()

        mocker.patch(
            'cookiecutter.zipfile.requests.get',
            return_value=request,
            autospec=True,
        )

        # Create an existing cache of the zipfile
        existing_zip = clone_dir.joinpath('fake-repo-tmpl.zip')
        existing_zip.write_text('This is an existing zipfile')

>       output_dir = zipfile.unzip(
            'https://example.com/path/to/fake-repo-tmpl.zip',
            is_url=True,
            clone_to_dir=str(clone_dir),
            no_input=True,
        )

tests/zipfile/test_unzip.py:257: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
cookiecutter/zipfile.py:36: in unzip
    zip_file.write(response.content)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

args = (,), kwargs = {}

    @_functools.wraps(func)
    def func_wrapper(*args, **kwargs):
>       return func(*args, **kwargs)
E       TypeError: a bytes-like object is required, not 'MagicMock'

/usr/lib/python3.10/tempfile.py:638: TypeError

test_unzip.py::test_unzip_should_abort_if_no_redownload

test_unzip.py::test_unzip_should_abort_if_no_redownload
mocker = 
clone_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_unzip_should_abort_if_no_0/clone_dir')

    def test_unzip_should_abort_if_no_redownload(mocker, clone_dir):
        """Should exit without cloning anything If no redownload."""
        mocker.patch(
            'cookiecutter.zipfile.prompt_and_delete', side_effect=SystemExit, autospec=True
        )

        mock_requests_get = mocker.patch(
            'cookiecutter.zipfile.requests.get',
            autospec=True,
        )

        # Create an existing cache of the zipfile
        existing_zip = clone_dir.joinpath('fake-repo-tmpl.zip')
        existing_zip.write_text('This is an existing zipfile')

        zipfile_url = 'https://example.com/path/to/fake-repo-tmpl.zip'

        with pytest.raises(SystemExit):
>           zipfile.unzip(zipfile_url, is_url=True, clone_to_dir=str(clone_dir))

tests/zipfile/test_unzip.py:285: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
cookiecutter/zipfile.py:36: in unzip
    zip_file.write(response.content)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

args = (,), kwargs = {}

    @_functools.wraps(func)
    def func_wrapper(*args, **kwargs):
>       return func(*args, **kwargs)
E       TypeError: a bytes-like object is required, not 'MagicMock'

/usr/lib/python3.10/tempfile.py:638: TypeError

test_unzip.py::test_unzip_is_ok_to_reuse

test_unzip.py::test_unzip_is_ok_to_reuse
mocker = 
clone_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_unzip_is_ok_to_reuse0/clone_dir')

    def test_unzip_is_ok_to_reuse(mocker, clone_dir):
        """Already downloaded zip should not be downloaded again."""
        mock_prompt_and_delete = mocker.patch(
            'cookiecutter.zipfile.prompt_and_delete', return_value=False, autospec=True
        )

        request = mocker.MagicMock()

        existing_zip = clone_dir.joinpath('fake-repo-tmpl.zip')
        shutil.copy('tests/files/fake-repo-tmpl.zip', existing_zip)

>       output_dir = zipfile.unzip(
            'https://example.com/path/to/fake-repo-tmpl.zip',
            is_url=True,
            clone_to_dir=str(clone_dir),
        )

tests/zipfile/test_unzip.py:301: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
cookiecutter/zipfile.py:34: in unzip
    response.raise_for_status()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = 

    def raise_for_status(self):
        """Raises :class:`HTTPError`, if one occurred."""

        http_error_msg = ""
        if isinstance(self.reason, bytes):
            # We attempt to decode utf-8 first because some servers
            # choose to localize their reason strings. If the string
            # isn't utf-8, we fall back to iso-8859-1 for all other
            # encodings. (See PR #3538)
            try:
                reason = self.reason.decode("utf-8")
            except UnicodeDecodeError:
                reason = self.reason.decode("iso-8859-1")
        else:
            reason = self.reason

        if 400 <= self.status_code < 500:
            http_error_msg = (
                f"{self.status_code} Client Error: {reason} for url: {self.url}"
            )

        elif 500 <= self.status_code < 600:
            http_error_msg = (
                f"{self.status_code} Server Error: {reason} for url: {self.url}"
            )

        if http_error_msg:
>           raise HTTPError(http_error_msg, response=self)
E           requests.exceptions.HTTPError: 404 Client Error: Not Found for url: https://example.com/path/to/fake-repo-tmpl.zip

.venv/lib/python3.10/site-packages/requests/models.py:1024: HTTPError

Patch diff

diff --git a/cookiecutter/cli.py b/cookiecutter/cli.py
index b050655..3b261fe 100644
--- a/cookiecutter/cli.py
+++ b/cookiecutter/cli.py
@@ -13,17 +13,41 @@ from cookiecutter.main import cookiecutter

 def version_msg():
     """Return the Cookiecutter version, location and Python powering it."""
-    pass
+    python_version = sys.version[:3]
+    location = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+    return f"Cookiecutter {__version__} from {location} (Python {python_version})"


 def validate_extra_context(ctx, param, value):
     """Validate extra context."""
-    pass
+    for s in value:
+        if '=' not in s:
+            raise click.BadParameter(
+                f'"{s}" is not a valid key/value pair. '
+                'Use the format key=value.'
+            )
+    return collections.OrderedDict(v.split('=', 1) for v in value)


 def list_installed_templates(default_config, passed_config_file):
     """List installed (locally cloned) templates. Use cookiecutter --list-installed."""
-    pass
+    config = get_user_config(default_config=default_config, config_file=passed_config_file)
+    template_dir = config.get('cookiecutters_dir')
+    if not os.path.exists(template_dir):
+        click.echo(f"No templates found in {template_dir}")
+        return
+
+    template_names = [
+        d for d in os.listdir(template_dir)
+        if os.path.isdir(os.path.join(template_dir, d))
+    ]
+
+    if not template_names:
+        click.echo(f"No templates found in {template_dir}")
+    else:
+        click.echo("Installed templates:")
+        for template_name in template_names:
+            click.echo(f"  {template_name}")


 @click.command(context_settings=dict(help_option_names=['-h', '--help']))
@@ -74,7 +98,37 @@ def main(template, extra_context, no_input, checkout, verbose, replay,
     volunteers. If you would like to help out or fund the project, please get
     in touch at https://github.com/cookiecutter/cookiecutter.
     """
-    pass
+    if list_installed:
+        list_installed_templates(default_config, config_file)
+        return
+
+    configure_logger(stream_level='DEBUG' if verbose else 'INFO',
+                     debug_file=debug_file)
+
+    try:
+        cookiecutter(
+            template,
+            checkout=checkout,
+            no_input=no_input,
+            extra_context=extra_context,
+            replay=replay,
+            overwrite_if_exists=overwrite_if_exists,
+            output_dir=output_dir,
+            config_file=config_file,
+            default_config=default_config,
+            password=None,
+            directory=directory,
+            skip_if_file_exists=skip_if_file_exists,
+            accept_hooks=accept_hooks,
+            keep_project_on_failure=keep_project_on_failure,
+        )
+    except (ContextDecodingException, OutputDirExistsException,
+            InvalidModeException, FailedHookException,
+            UnknownExtension, InvalidZipRepository,
+            RepositoryNotFound, RepositoryCloneFailed,
+            UndefinedVariableInTemplate) as e:
+        click.echo(f"Error: {e}")
+        sys.exit(1)


 if __name__ == '__main__':
diff --git a/cookiecutter/config.py b/cookiecutter/config.py
index 6356215..2b0e70d 100644
--- a/cookiecutter/config.py
+++ b/cookiecutter/config.py
@@ -17,7 +17,7 @@ DEFAULT_CONFIG = {'cookiecutters_dir': os.path.expanduser(

 def _expand_path(path):
     """Expand both environment variables and user home in the given path."""
-    pass
+    return os.path.expandvars(os.path.expanduser(path))


 def merge_configs(default, overwrite):
@@ -26,12 +26,30 @@ def merge_configs(default, overwrite):
     Dict values that are dictionaries themselves will be updated, whilst
     preserving existing keys.
     """
-    pass
+    new_config = copy.deepcopy(default)
+    for k, v in overwrite.items():
+        if isinstance(v, dict):
+            new_config[k] = merge_configs(new_config.get(k, {}), v)
+        else:
+            new_config[k] = v
+    return new_config


 def get_config(config_path):
     """Retrieve the config from the specified path, returning a config dict."""
-    pass
+    if not os.path.exists(config_path):
+        raise ConfigDoesNotExistException(f"Config file {config_path} does not exist.")
+
+    with open(config_path) as file_handle:
+        try:
+            user_config = yaml.safe_load(file_handle)
+        except yaml.YAMLError as e:
+            raise InvalidConfiguration(f"Unable to parse YAML file {config_path}: {e}")
+
+    if user_config is None:
+        raise InvalidConfiguration(f"Config file {config_path} is empty.")
+
+    return user_config


 def get_user_config(config_file=None, default_config=False):
@@ -53,4 +71,20 @@ def get_user_config(config_file=None, default_config=False):
     If the environment variable is not set, try the default config file path
     before falling back to the default config values.
     """
-    pass
+    if isinstance(default_config, dict):
+        return merge_configs(DEFAULT_CONFIG, default_config)
+
+    if default_config:
+        return copy.deepcopy(DEFAULT_CONFIG)
+
+    if config_file and config_file != USER_CONFIG_PATH:
+        return get_config(config_file)
+
+    user_config = os.environ.get('COOKIECUTTER_CONFIG')
+    if user_config:
+        return get_config(user_config)
+
+    if os.path.exists(USER_CONFIG_PATH):
+        return get_config(USER_CONFIG_PATH)
+
+    return copy.deepcopy(DEFAULT_CONFIG)
diff --git a/cookiecutter/environment.py b/cookiecutter/environment.py
index 8a7bb61..b2495b8 100644
--- a/cookiecutter/environment.py
+++ b/cookiecutter/environment.py
@@ -37,7 +37,8 @@ class ExtensionLoaderMixin:
         If context does not contain the relevant info, return an empty
         list instead.
         """
-        pass
+        extensions = context.get('cookiecutter', {}).get('_extensions', [])
+        return [str(ext) for ext in extensions]


 class StrictEnvironment(ExtensionLoaderMixin, Environment):
diff --git a/cookiecutter/extensions.py b/cookiecutter/extensions.py
index 8ce014a..865d856 100644
--- a/cookiecutter/extensions.py
+++ b/cookiecutter/extensions.py
@@ -5,6 +5,7 @@ import uuid
 from secrets import choice
 import arrow
 from jinja2 import nodes
+from jinja2 import nodes
 from jinja2.ext import Extension
 from slugify import slugify as pyslugify

@@ -74,4 +75,20 @@ class TimeExtension(Extension):

     def parse(self, parser):
         """Parse datetime template and add datetime value."""
-        pass
+        lineno = next(parser.stream).lineno
+        token = parser.stream.next()
+        format_string = self.environment.datetime_format
+        if token.type == 'string':
+            format_string = token.value
+        
+        node = nodes.Call(
+            self.call_method('_render_now', [nodes.Const(format_string)]),
+            [],
+            [],
+            None,
+            None
+        )
+        return nodes.Output([node]).set_lineno(lineno)
+
+    def _render_now(self, format_string):
+        return arrow.now().format(format_string)
diff --git a/cookiecutter/find.py b/cookiecutter/find.py
index 667e50d..06ba42a 100644
--- a/cookiecutter/find.py
+++ b/cookiecutter/find.py
@@ -11,6 +11,33 @@ def find_template(repo_dir: 'os.PathLike[str]', env: Environment) ->Path:
     """Determine which child directory of ``repo_dir`` is the project template.

     :param repo_dir: Local directory of newly cloned repo.
+    :param env: Jinja2 Environment object for rendering template variables.
     :return: Relative path to project template.
     """
-    pass
+    repo_dir = Path(repo_dir)
+    logger.debug('Searching %s for the project template.', repo_dir)
+
+    # First, check for a cookiecutter.json file in the repo root
+    if (repo_dir / 'cookiecutter.json').is_file():
+        logger.debug('Found cookiecutter.json at project root level')
+        return repo_dir
+
+    # If not found, search for the first directory with a cookiecutter.json file
+    for dirpath, dirnames, filenames in os.walk(repo_dir):
+        if 'cookiecutter.json' in filenames:
+            logger.debug('Found cookiecutter.json in %s', dirpath)
+            return Path(dirpath).relative_to(repo_dir)
+
+    # If no cookiecutter.json is found, look for the first directory that's not a repo artifact
+    for path in repo_dir.iterdir():
+        if path.is_dir() and path.name not in {'.git', '.hg', '.svn', '.bzr'}:
+            logger.debug('Treating %s as project template', path)
+            return path.relative_to(repo_dir)
+
+    # If we reach here, we couldn't find a valid template directory
+    raise NonTemplatedInputDirException(
+        'The repo_dir {} is not a valid template directory. '
+        'A valid template directory must either have a cookiecutter.json '
+        'file or have one or more directories that are not repo artifacts.'
+        .format(repo_dir)
+    )
diff --git a/cookiecutter/generate.py b/cookiecutter/generate.py
index 715232e..61a6452 100644
--- a/cookiecutter/generate.py
+++ b/cookiecutter/generate.py
@@ -27,13 +27,30 @@ def is_copy_only_path(path, context):
         should be rendered or just copied.
     :param context: cookiecutter context.
     """
-    pass
+    copy_without_render = context.get('_copy_without_render', [])
+    for pattern in copy_without_render:
+        if fnmatch.fnmatch(path, pattern):
+            return True
+    return False


 def apply_overwrites_to_context(context, overwrite_context, *,
     in_dictionary_variable=False):
     """Modify the given context in place based on the overwrite_context."""
-    pass
+    for key, value in overwrite_context.items():
+        if isinstance(value, dict):
+            if key not in context:
+                context[key] = {}
+            apply_overwrites_to_context(context[key], value, in_dictionary_variable=True)
+        elif isinstance(value, list):
+            if key not in context:
+                context[key] = []
+            context[key].extend(value)
+        else:
+            if in_dictionary_variable:
+                context[key] = value
+            else:
+                context[key] = str(value)


 def generate_context(context_file='cookiecutter.json', default_context=None,
@@ -47,7 +64,23 @@ def generate_context(context_file='cookiecutter.json', default_context=None,
     :param default_context: Dictionary containing config to take into account.
     :param extra_context: Dictionary containing configuration overrides
     """
-    pass
+    context = OrderedDict([])
+    try:
+        with open(context_file) as file:
+            obj = json.load(file, object_pairs_hook=OrderedDict)
+        context = obj if isinstance(obj, dict) else obj[0]
+    except ValueError as e:
+        raise ContextDecodingException(context_file, e)
+    
+    # Apply default context
+    if default_context:
+        apply_overwrites_to_context(context, default_context)
+    
+    # Apply extra context
+    if extra_context:
+        apply_overwrites_to_context(context, extra_context)
+    
+    return context


 def generate_file(project_dir, infile, context, env, skip_if_file_exists=False
@@ -72,14 +105,65 @@ def generate_file(project_dir, infile, context, env, skip_if_file_exists=False
     :param context: Dict for populating the cookiecutter's variables.
     :param env: Jinja2 template execution environment.
     """
-    pass
+    logger.debug('Generating file %s', infile)
+    
+    # Render the path to the output file
+    outfile_tmpl = env.from_string(infile)
+    outfile = os.path.join(project_dir, outfile_tmpl.render(**context))
+    
+    # Ensure output directory exists
+    dirname = os.path.dirname(outfile)
+    make_sure_path_exists(dirname)
+    
+    # Skip if file exists and skip_if_file_exists is True
+    if skip_if_file_exists and os.path.exists(outfile):
+        logger.debug('File %s already exists, skipping', outfile)
+        return False
+    
+    # Check if infile is binary
+    if is_binary(infile):
+        logger.debug("Copying binary %s to %s without rendering", infile, outfile)
+        shutil.copyfile(infile, outfile)
+    else:
+        # Render the file
+        try:
+            with open(infile, 'r') as in_file:
+                tmpl = env.from_string(in_file.read())
+            rendered_file = tmpl.render(**context)
+            with open(outfile, 'w') as out_file:
+                out_file.write(rendered_file)
+        except TemplateSyntaxError as e:
+            logger.error('Error in template syntax in %s', infile)
+            raise
+        except UndefinedError as e:
+            logger.error('Unable to render template in %s', infile)
+            raise UndefinedVariableInTemplate(str(e), infile, context, e.message)
+    
+    return True


 def render_and_create_dir(dirname: str, context: dict, output_dir:
     'os.PathLike[str]', environment: Environment, overwrite_if_exists: bool
     =False):
     """Render name of a directory, create the directory, return its path."""
-    pass
+    name_tmpl = environment.from_string(dirname)
+    rendered_dirname = name_tmpl.render(**context)
+    dir_to_create = os.path.normpath(os.path.join(output_dir, rendered_dirname))
+
+    logger.debug('Rendered dir %s must exist in output_dir %s', dir_to_create, output_dir)
+
+    if os.path.exists(dir_to_create):
+        if overwrite_if_exists:
+            logger.debug('Overwriting %s', dir_to_create)
+        else:
+            logger.error('Error that %s already exists', dir_to_create)
+            raise OutputDirExistsException(
+                'Error: "{}" directory already exists'.format(dir_to_create)
+            )
+    else:
+        make_sure_path_exists(dir_to_create)
+
+    return dir_to_create


 def _run_hook_from_repo_dir(repo_dir, hook_name, project_dir, context,
@@ -93,7 +177,33 @@ def _run_hook_from_repo_dir(repo_dir, hook_name, project_dir, context,
     :param delete_project_on_failure: Delete the project directory on hook
         failure?
     """
-    pass
+    with work_in(repo_dir):
+        try:
+            run_hook_from_repo_dir(
+                repo_dir=repo_dir,
+                hook_name=hook_name,
+                project_dir=project_dir,
+                context=context
+            )
+        except FailedHookException:
+            if delete_project_on_failure:
+                logger.warning(
+                    "Hook script failed ({}). Removing project directory {}".format(
+                        hook_name, project_dir
+                    )
+                )
+                rmtree(project_dir)
+            raise
+        except Exception:
+            # Catch all other exceptions and raise a FailedHookException
+            logger.warning(
+                "Hook script failed ({}). Removing project directory {}".format(
+                    hook_name, project_dir
+                )
+            )
+            if delete_project_on_failure:
+                rmtree(project_dir)
+            raise FailedHookException(hook_name)


 def generate_files(repo_dir, context=None, output_dir='.',
@@ -112,4 +222,57 @@ def generate_files(repo_dir, context=None, output_dir='.',
     :param keep_project_on_failure: If `True` keep generated project directory even when
         generation fails
     """
-    pass
+    template_dir = find_template(repo_dir)
+    logger.debug('Generating project from %s...', template_dir)
+    context = context or {}
+    env = create_env_with_context(context)
+
+    # Create project dir
+    project_dir = render_and_create_dir(
+        os.path.basename(repo_dir),
+        context,
+        output_dir,
+        env,
+        overwrite_if_exists
+    )
+
+    # Run pre-gen hook
+    if accept_hooks:
+        _run_hook_from_repo_dir(repo_dir, 'pre_gen_project', project_dir, context, not keep_project_on_failure)
+
+    logger.debug('Project directory is %s', project_dir)
+
+    # Render the templates and save them to files
+    with work_in(template_dir):
+        for root, dirs, files in os.walk('.'):
+            for dirname in dirs:
+                indir = os.path.normpath(os.path.join(root, dirname))
+                outdir = os.path.normpath(os.path.join(project_dir, indir))
+                render_and_create_dir(
+                    indir,
+                    context,
+                    project_dir,
+                    env,
+                    overwrite_if_exists
+                )
+
+            for filename in files:
+                infile = os.path.normpath(os.path.join(root, filename))
+                if is_copy_only_path(infile, context):
+                    outfile = os.path.join(project_dir, infile)
+                    logger.debug('Copying %s to %s without rendering', infile, outfile)
+                    shutil.copyfile(infile, outfile)
+                else:
+                    generate_file(
+                        project_dir,
+                        infile,
+                        context,
+                        env,
+                        skip_if_file_exists
+                    )
+
+    # Run post-gen hook
+    if accept_hooks:
+        _run_hook_from_repo_dir(repo_dir, 'post_gen_project', project_dir, context, not keep_project_on_failure)
+
+    return project_dir
diff --git a/cookiecutter/hooks.py b/cookiecutter/hooks.py
index 0aa9c52..010ff2b 100644
--- a/cookiecutter/hooks.py
+++ b/cookiecutter/hooks.py
@@ -22,7 +22,11 @@ def valid_hook(hook_file, hook_name):
     :param hook_name: The hook to find
     :return: The hook file validity
     """
-    pass
+    return (
+        hook_file.startswith(hook_name) and
+        hook_file.endswith(('.py', '.sh')) and
+        not hook_file.endswith('.pyc')
+    )


 def find_hook(hook_name, hooks_dir='hooks'):
@@ -37,7 +41,15 @@ def find_hook(hook_name, hooks_dir='hooks'):
     :param hooks_dir: The hook directory in the template
     :return: The absolute path to the hook script or None
     """
-    pass
+    hooks_dir = os.path.abspath(hooks_dir)
+    if not os.path.isdir(hooks_dir):
+        return None
+
+    for hook_file in os.listdir(hooks_dir):
+        if valid_hook(hook_file, hook_name):
+            return os.path.join(hooks_dir, hook_file)
+
+    return None


 def run_script(script_path, cwd='.'):
@@ -46,7 +58,11 @@ def run_script(script_path, cwd='.'):
     :param script_path: Absolute path to the script to run.
     :param cwd: The directory to run the script from.
     """
-    pass
+    with work_in(cwd):
+        if script_path.endswith('.py'):
+            subprocess.check_call([sys.executable, script_path], cwd=cwd)
+        else:
+            subprocess.check_call([script_path], cwd=cwd)


 def run_script_with_context(script_path, cwd, context):
@@ -56,7 +72,25 @@ def run_script_with_context(script_path, cwd, context):
     :param cwd: The directory to run the script from.
     :param context: Cookiecutter project template context.
     """
-    pass
+    env = create_env_with_context(context)
+    with open(script_path, 'r') as f:
+        script = f.read()
+
+    try:
+        rendered_script = env.from_string(script).render(**context)
+    except UndefinedError as err:
+        msg = f"Unable to render script '{script_path}': {err.message}"
+        raise FailedHookException(msg)
+
+    with tempfile.NamedTemporaryFile(mode='w', delete=False) as temp_script:
+        temp_script.write(rendered_script)
+        temp_script.flush()
+        temp_script_path = temp_script.name
+
+    try:
+        run_script(temp_script_path, cwd)
+    finally:
+        os.remove(temp_script_path)


 def run_hook(hook_name, project_dir, context):
@@ -67,7 +101,13 @@ def run_hook(hook_name, project_dir, context):
     :param project_dir: The directory to execute the script from.
     :param context: Cookiecutter project context.
     """
-    pass
+    hook_path = find_hook(hook_name)
+    if hook_path:
+        logger.debug(f"Running hook {hook_name}")
+        if hook_path.endswith('.py'):
+            run_script_with_context(hook_path, project_dir, context)
+        else:
+            run_script(hook_path, project_dir)


 def run_hook_from_repo_dir(repo_dir, hook_name, project_dir, context,
@@ -81,7 +121,28 @@ def run_hook_from_repo_dir(repo_dir, hook_name, project_dir, context,
     :param delete_project_on_failure: Delete the project directory on hook
         failure?
     """
-    pass
+    with work_in(repo_dir):
+        try:
+            run_hook(hook_name, project_dir, context)
+        except FailedHookException:
+            if delete_project_on_failure:
+                logger.debug(
+                    "Hook script failed ({}). Removing project directory {}"
+                    .format(hook_name, project_dir)
+                )
+                rmtree(project_dir)
+            raise
+        except Exception:
+            # Log the exception here, but do not raise it,
+            # to avoid a cryptic error message
+            logger.exception(f'Hook script failed ({hook_name})')
+            if delete_project_on_failure:
+                logger.debug(
+                    "Hook script failed ({}). Removing project directory {}"
+                    .format(hook_name, project_dir)
+                )
+                rmtree(project_dir)
+            raise


 def run_pre_prompt_hook(repo_dir: 'os.PathLike[str]') ->Path:
@@ -89,4 +150,16 @@ def run_pre_prompt_hook(repo_dir: 'os.PathLike[str]') ->Path:

     :param repo_dir: Project template input directory.
     """
-    pass
+    with work_in(repo_dir):
+        hook_path = find_hook('pre_prompt')
+        if hook_path:
+            logger.debug("Running pre_prompt hook")
+            tmp_repo_dir = create_tmp_repo_dir()
+            try:
+                run_script(hook_path, tmp_repo_dir)
+                return Path(tmp_repo_dir)
+            except Exception:
+                logger.exception('Pre-prompt hook failed')
+                rmtree(tmp_repo_dir)
+                raise
+    return Path(repo_dir)
diff --git a/cookiecutter/log.py b/cookiecutter/log.py
index 894c633..949f58f 100644
--- a/cookiecutter/log.py
+++ b/cookiecutter/log.py
@@ -13,4 +13,25 @@ def configure_logger(stream_level='DEBUG', debug_file=None):
     Set up logging to stdout with given level. If ``debug_file`` is given set
     up logging to file with DEBUG level.
     """
-    pass
+    # Get the root logger
+    logger = logging.getLogger()
+    logger.setLevel(logging.DEBUG)
+
+    # Remove any existing handlers to avoid duplicates
+    for handler in logger.handlers[:]:
+        logger.removeHandler(handler)
+
+    # Set up console handler
+    console_handler = logging.StreamHandler(sys.stdout)
+    console_handler.setLevel(LOG_LEVELS.get(stream_level.upper(), logging.DEBUG))
+    console_formatter = logging.Formatter(LOG_FORMATS.get(stream_level.upper(), LOG_FORMATS['DEBUG']))
+    console_handler.setFormatter(console_formatter)
+    logger.addHandler(console_handler)
+
+    # Set up file handler if debug_file is provided
+    if debug_file:
+        file_handler = logging.FileHandler(debug_file)
+        file_handler.setLevel(logging.DEBUG)
+        file_formatter = logging.Formatter(LOG_FORMATS['DEBUG'])
+        file_handler.setFormatter(file_formatter)
+        logger.addHandler(file_handler)
diff --git a/cookiecutter/main.py b/cookiecutter/main.py
index 4b1087d..fdf3dca 100644
--- a/cookiecutter/main.py
+++ b/cookiecutter/main.py
@@ -52,7 +52,76 @@ def cookiecutter(template, checkout=None, no_input=False, extra_context=
     :param keep_project_on_failure: If `True` keep generated project directory even when
         generation fails
     """
-    pass
+    # Get user configuration
+    config_dict = get_user_config(config_file=config_file, default_config=default_config)
+
+    # Determine the template directory
+    repo_dir, cleanup = determine_repo_dir(
+        template=template,
+        checkout=checkout,
+        clone_to_dir=config_dict['cookiecutters_dir'],
+        no_input=no_input,
+        password=password,
+        directory=directory
+    )
+
+    # Ensure cleanup function is called
+    try:
+        with _patch_import_path_for_repo(repo_dir):
+            # Run pre-prompt hook
+            if accept_hooks:
+                run_pre_prompt_hook(repo_dir, config_dict)
+
+            # Generate or load context
+            context_file = os.path.join(repo_dir, 'cookiecutter.json')
+            context = generate_context(
+                context_file=context_file,
+                default_context=config_dict['default_context'],
+                extra_context=extra_context,
+            )
+
+            # Prompt the user to manually configure the context
+            if not no_input:
+                nested_template = choose_nested_template(repo_dir, context)
+                if nested_template:
+                    repo_dir = os.path.join(repo_dir, nested_template)
+                    context_file = os.path.join(repo_dir, 'cookiecutter.json')
+                    context = generate_context(
+                        context_file=context_file,
+                        default_context=config_dict['default_context'],
+                        extra_context=extra_context,
+                    )
+                context = prompt_for_config(context, no_input)
+
+            # Load context from replay file
+            if replay:
+                context = load(config_dict['replay_dir'], template)
+
+            # Create project from local context
+            project_dir = generate_files(
+                repo_dir=repo_dir,
+                context=context,
+                overwrite_if_exists=overwrite_if_exists,
+                skip_if_file_exists=skip_if_file_exists,
+                output_dir=output_dir,
+                accept_hooks=accept_hooks,
+            )
+
+    except Exception:
+        # Cleanup on failure
+        if cleanup and not keep_project_on_failure:
+            if os.path.exists(project_dir):
+                rmtree(project_dir)
+        raise
+    else:
+        # Successful project creation
+        dump(config_dict['replay_dir'], template, context)
+
+    finally:
+        if cleanup:
+            cleanup()
+
+    return project_dir


 class _patch_import_path_for_repo:
diff --git a/cookiecutter/prompt.py b/cookiecutter/prompt.py
index 2bcc55f..da70f02 100644
--- a/cookiecutter/prompt.py
+++ b/cookiecutter/prompt.py
@@ -17,7 +17,11 @@ def read_user_variable(var_name, default_value, prompts=None, prefix=''):
     :param str var_name: Variable of the context to query the user
     :param default_value: Value that will be returned if no input happens
     """
-    pass
+    prompt_text = f"{prefix}{var_name}"
+    if prompts and var_name in prompts:
+        prompt_text = prompts[var_name]
+    
+    return Prompt.ask(prompt_text, default=default_value)


 class YesNoPrompt(Confirm):
@@ -27,7 +31,13 @@ class YesNoPrompt(Confirm):

     def process_response(self, value: str) ->bool:
         """Convert choices to a bool."""
-        pass
+        value = value.lower()
+        if value in self.yes_choices:
+            return True
+        elif value in self.no_choices:
+            return False
+        else:
+            raise InvalidResponse(self.validate_error_message)


 def read_user_yes_no(var_name, default_value, prompts=None, prefix=''):
@@ -44,7 +54,11 @@ def read_user_yes_no(var_name, default_value, prompts=None, prefix=''):
     :param str question: Question to the user
     :param default_value: Value that will be returned if no input happens
     """
-    pass
+    prompt_text = f"{prefix}{var_name}"
+    if prompts and var_name in prompts:
+        prompt_text = prompts[var_name]
+    
+    return YesNoPrompt.ask(prompt_text, default=default_value)


 def read_repo_password(question):
@@ -52,7 +66,7 @@ def read_repo_password(question):

     :param str question: Question to the user
     """
-    pass
+    return Prompt.ask(question, password=True)


 def read_user_choice(var_name, options, prompts=None, prefix=''):
@@ -64,7 +78,17 @@ def read_user_choice(var_name, options, prompts=None, prefix=''):
     :param list options: Sequence of options that are available to select from
     :return: Exactly one item of ``options`` that has been chosen by the user
     """
-    pass
+    prompt_text = f"{prefix}{var_name}"
+    if prompts and var_name in prompts:
+        prompt_text = prompts[var_name]
+    
+    choices = [str(i) for i in range(len(options))]
+    choice_text = "\n".join(f"{i}: {option}" for i, option in enumerate(options))
+    
+    while True:
+        print(f"{prompt_text}\n{choice_text}")
+        choice = Prompt.ask("Enter the number of your choice", choices=choices, default="0")
+        return options[int(choice)]


 DEFAULT_DISPLAY = 'default'
@@ -75,7 +99,10 @@ def process_json(user_value, default_value=None):

     :param str user_value: User-supplied value to load as a JSON dict
     """
-    pass
+    try:
+        return json.loads(user_value)
+    except json.JSONDecodeError:
+        return default_value


 class JsonPrompt(PromptBase[dict]):
@@ -87,7 +114,10 @@ class JsonPrompt(PromptBase[dict]):

     def process_response(self, value: str) ->dict:
         """Convert choices to a dict."""
-        pass
+        try:
+            return json.loads(value)
+        except json.JSONDecodeError:
+            raise InvalidResponse(self.validate_error_message)


 def read_user_dict(var_name, default_value, prompts=None, prefix=''):
@@ -97,7 +127,12 @@ def read_user_dict(var_name, default_value, prompts=None, prefix=''):
     :param default_value: Value that will be returned if no input is provided
     :return: A Python dictionary to use in the context.
     """
-    pass
+    prompt_text = f"{prefix}{var_name}"
+    if prompts and var_name in prompts:
+        prompt_text = prompts[var_name]
+    
+    default_json = json.dumps(default_value) if default_value else None
+    return JsonPrompt.ask(prompt_text, default=default_json)


 def render_variable(env, raw, cookiecutter_dict):
@@ -117,12 +152,25 @@ def render_variable(env, raw, cookiecutter_dict):
         being populated with variables.
     :return: The rendered value for the default variable.
     """
-    pass
+    if not isinstance(raw, str):
+        return raw
+
+    template = env.from_string(raw)
+    try:
+        return template.render(**cookiecutter_dict)
+    except UndefinedError as err:
+        raise UndefinedVariableInTemplate(str(err), err, cookiecutter_dict)


 def _prompts_from_options(options: dict) ->dict:
     """Process template options and return friendly prompt information."""
-    pass
+    prompts = {}
+    for key, value in options.items():
+        if isinstance(value, dict):
+            prompts[key] = value.get('_prompt', key)
+        else:
+            prompts[key] = key
+    return prompts


 def prompt_choice_for_template(key, options, no_input):
@@ -130,7 +178,12 @@ def prompt_choice_for_template(key, options, no_input):

     :param no_input: Do not prompt for user input and return the first available option.
     """
-    pass
+    if no_input:
+        return next(iter(options.values()))
+
+    prompts = _prompts_from_options(options)
+    choices = list(options.keys())
+    return read_user_choice(key, choices, prompts=prompts)


 def prompt_choice_for_config(cookiecutter_dict, env, key, options, no_input,
@@ -139,7 +192,15 @@ def prompt_choice_for_config(cookiecutter_dict, env, key, options, no_input,

     :param no_input: Do not prompt for user input and return the first available option.
     """
-    pass
+    if no_input:
+        return next(iter(options.values()))
+
+    rendered_options = OrderedDict()
+    for option_key, option_value in options.items():
+        rendered_options[option_key] = render_variable(env, option_value, cookiecutter_dict)
+
+    choice = read_user_choice(key, list(rendered_options.keys()), prompts=prompts, prefix=prefix)
+    return rendered_options[choice]


 def prompt_for_config(context, no_input=False):
@@ -148,7 +209,25 @@ def prompt_for_config(context, no_input=False):
     :param dict context: Source for field names and sample values.
     :param no_input: Do not prompt for user input and use only values from context.
     """
-    pass
+    cookiecutter_dict = OrderedDict([])
+    env = create_env_with_context(context)
+
+    for key, raw in context['cookiecutter'].items():
+        if key.startswith('_'):
+            cookiecutter_dict[key] = raw
+            continue
+
+        if isinstance(raw, dict):
+            cookiecutter_dict[key] = prompt_choice_for_config(
+                cookiecutter_dict, env, key, raw, no_input
+            )
+        else:
+            if no_input:
+                cookiecutter_dict[key] = render_variable(env, raw, cookiecutter_dict)
+            else:
+                cookiecutter_dict[key] = read_user_variable(key, raw)
+
+    return cookiecutter_dict


 def choose_nested_template(context: dict, repo_dir: str, no_input: bool=False
@@ -160,7 +239,17 @@ def choose_nested_template(context: dict, repo_dir: str, no_input: bool=False
     :param no_input: Do not prompt for user input and use only values from context.
     :returns: Path to the selected template.
     """
-    pass
+    template_dir = Path(repo_dir) / 'templates'
+    template_names = [d.name for d in template_dir.iterdir() if d.is_dir()]
+
+    if not template_names:
+        raise ValueError("No nested templates found in the repository.")
+
+    if no_input or len(template_names) == 1:
+        return str(template_dir / template_names[0])
+
+    choice = read_user_choice("Select a template", template_names)
+    return str(template_dir / choice)


 def prompt_and_delete(path, no_input=False):
@@ -174,4 +263,25 @@ def prompt_and_delete(path, no_input=False):
     :param no_input: Suppress prompt to delete repo and just delete it.
     :return: True if the content was deleted
     """
-    pass
+    if no_input:
+        rmtree(path)
+        return True
+
+    delete = read_user_yes_no(
+        f"You've downloaded {path} before. Is it okay to delete and re-download it?",
+        default_value=True
+    )
+
+    if delete:
+        rmtree(path)
+        return True
+
+    reuse = read_user_yes_no(
+        "Do you want to re-use the existing version?",
+        default_value=True
+    )
+
+    if reuse:
+        return False
+
+    sys.exit()
diff --git a/cookiecutter/replay.py b/cookiecutter/replay.py
index 340be41..54a1692 100644
--- a/cookiecutter/replay.py
+++ b/cookiecutter/replay.py
@@ -10,14 +10,20 @@ from cookiecutter.utils import make_sure_path_exists

 def get_file_name(replay_dir, template_name):
     """Get the name of file."""
-    pass
+    file_name = f"{template_name}.json"
+    return os.path.join(replay_dir, file_name)


 def dump(replay_dir: 'os.PathLike[str]', template_name: str, context: dict):
     """Write json data to file."""
-    pass
+    make_sure_path_exists(replay_dir)
+    file_path = get_file_name(replay_dir, template_name)
+    with open(file_path, 'w') as f:
+        json.dump(context, f, indent=2)


 def load(replay_dir, template_name):
     """Read json data from file."""
-    pass
+    file_path = get_file_name(replay_dir, template_name)
+    with open(file_path, 'r') as f:
+        return json.load(f)
diff --git a/cookiecutter/repository.py b/cookiecutter/repository.py
index e350c56..edcad60 100644
--- a/cookiecutter/repository.py
+++ b/cookiecutter/repository.py
@@ -17,12 +17,12 @@ REPO_REGEX = re.compile(

 def is_repo_url(value):
     """Return True if value is a repository URL."""
-    pass
+    return bool(REPO_REGEX.match(value))


 def is_zip_file(value):
     """Return True if value is a zip file."""
-    pass
+    return value.lower().endswith('.zip')


 def expand_abbreviations(template, abbreviations):
@@ -31,7 +31,9 @@ def expand_abbreviations(template, abbreviations):
     :param template: The project template name.
     :param abbreviations: Abbreviation definitions.
     """
-    pass
+    if template in abbreviations:
+        return abbreviations[template]
+    return template


 def repository_has_cookiecutter_json(repo_directory):
@@ -40,7 +42,10 @@ def repository_has_cookiecutter_json(repo_directory):
     :param repo_directory: The candidate repository directory.
     :return: True if the `repo_directory` is valid, else False.
     """
-    pass
+    repo_dir_exists = os.path.isdir(repo_directory)
+    cookiecutter_json_path = os.path.join(repo_directory, 'cookiecutter.json')
+    has_cookiecutter_json = os.path.isfile(cookiecutter_json_path)
+    return repo_dir_exists and has_cookiecutter_json


 def determine_repo_dir(template, abbreviations, clone_to_dir, checkout,
@@ -67,4 +72,35 @@ def determine_repo_dir(template, abbreviations, clone_to_dir, checkout,
         after the template has been instantiated.
     :raises: `RepositoryNotFound` if a repository directory could not be found.
     """
-    pass
+    template = expand_abbreviations(template, abbreviations)
+
+    if is_repo_url(template):
+        repo_dir = clone(
+            repo_url=template,
+            checkout=checkout,
+            clone_to_dir=clone_to_dir,
+            no_input=no_input
+        )
+        cleanup = True
+    elif is_zip_file(template):
+        repo_dir = unzip(
+            zip_uri=template,
+            is_url=is_repo_url(template),
+            clone_to_dir=clone_to_dir,
+            no_input=no_input,
+            password=password
+        )
+        cleanup = True
+    else:
+        repo_dir = template
+        cleanup = False
+
+    if directory:
+        repo_dir = os.path.join(repo_dir, directory)
+
+    if not repository_has_cookiecutter_json(repo_dir):
+        raise RepositoryNotFound(
+            'The repository {} does not contain a cookiecutter.json file'.format(repo_dir)
+        )
+
+    return repo_dir, cleanup
diff --git a/cookiecutter/utils.py b/cookiecutter/utils.py
index 6aa68ba..a93b5a4 100644
--- a/cookiecutter/utils.py
+++ b/cookiecutter/utils.py
@@ -18,7 +18,8 @@ def force_delete(func, path, exc_info):
     Usage: `shutil.rmtree(path, onerror=force_delete)`
     From https://docs.python.org/3/library/shutil.html#rmtree-example
     """
-    pass
+    os.chmod(path, stat.S_IWRITE)
+    func(path)


 def rmtree(path):
@@ -26,7 +27,7 @@ def rmtree(path):

     :param path: A directory path.
     """
-    pass
+    shutil.rmtree(path, onerror=force_delete)


 def make_sure_path_exists(path: 'os.PathLike[str]') ->None:
@@ -34,7 +35,7 @@ def make_sure_path_exists(path: 'os.PathLike[str]') ->None:

     :param path: A directory tree path for creation.
     """
-    pass
+    os.makedirs(path, exist_ok=True)


 @contextlib.contextmanager
@@ -43,7 +44,13 @@ def work_in(dirname=None):

     When exited, returns to the working directory prior to entering.
     """
-    pass
+    curdir = os.getcwd()
+    try:
+        if dirname is not None:
+            os.chdir(dirname)
+        yield
+    finally:
+        os.chdir(curdir)


 def make_executable(script_path):
@@ -51,19 +58,28 @@ def make_executable(script_path):

     :param script_path: The file to change
     """
-    pass
+    mode = os.stat(script_path).st_mode
+    os.chmod(script_path, mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)


 def simple_filter(filter_function):
     """Decorate a function to wrap it in a simplified jinja2 extension."""
-    pass
+    class SimpleExtension(Extension):
+        def __init__(self, environment):
+            super().__init__(environment)
+            environment.filters[filter_function.__name__] = filter_function
+
+    return SimpleExtension


 def create_tmp_repo_dir(repo_dir: 'os.PathLike[str]') ->Path:
     """Create a temporary dir with a copy of the contents of repo_dir."""
-    pass
+    temp_dir = Path(tempfile.mkdtemp())
+    shutil.copytree(repo_dir, temp_dir, symlinks=True)
+    return temp_dir


 def create_env_with_context(context: Dict):
     """Create a jinja environment using the provided context."""
-    pass
+    env = StrictEnvironment(context=context)
+    return env
diff --git a/cookiecutter/vcs.py b/cookiecutter/vcs.py
index 94d6c05..f0eae9f 100644
--- a/cookiecutter/vcs.py
+++ b/cookiecutter/vcs.py
@@ -20,16 +20,30 @@ def identify_repo(repo_url):
     :param repo_url: Repo URL of unknown type.
     :returns: ('git', repo_url), ('hg', repo_url), or None.
     """
-    pass
+    repo_url = repo_url.lower()
+    if repo_url.startswith('git+'):
+        return 'git', repo_url[4:]
+    elif repo_url.startswith('hg+'):
+        return 'hg', repo_url[3:]
+    elif repo_url.endswith('.git') or 'github.com' in repo_url:
+        return 'git', repo_url
+    elif 'bitbucket.org' in repo_url:
+        return 'hg', repo_url
+    return None


 def is_vcs_installed(repo_type):
     """
     Check if the version control system for a repo type is installed.

-    :param repo_type:
+    :param repo_type: The type of repository ('git' or 'hg').
+    :return: True if the VCS is installed, False otherwise.
     """
-    pass
+    if repo_type == 'git':
+        return which('git') is not None
+    elif repo_type == 'hg':
+        return which('hg') is not None
+    return False


 def clone(repo_url: str, checkout: Optional[str]=None, clone_to_dir:
@@ -44,4 +58,57 @@ def clone(repo_url: str, checkout: Optional[str]=None, clone_to_dir:
         cached resources.
     :returns: str with path to the new directory of the repository.
     """
-    pass
+    repo_type, repo_url = identify_repo(repo_url)
+    if repo_type is None:
+        raise UnknownRepoType(f"Couldn't determine repository type for {repo_url}")
+
+    if not is_vcs_installed(repo_type):
+        raise VCSNotInstalled(f"{repo_type} is not installed.")
+
+    clone_to_dir = Path(clone_to_dir).resolve()
+    make_sure_path_exists(clone_to_dir)
+
+    repo_dir = clone_to_dir / Path(repo_url).stem
+
+    if repo_dir.exists():
+        if no_input:
+            logger.warning("'%s' directory already exists, deleting it", repo_dir)
+            subprocess.check_call([repo_type, 'init', str(repo_dir)])
+        else:
+            prompt_and_delete(repo_dir)
+
+    if repo_type == 'git':
+        clone_cmd = ['git', 'clone', repo_url, str(repo_dir)]
+    else:  # hg
+        clone_cmd = ['hg', 'clone', repo_url, str(repo_dir)]
+
+    try:
+        subprocess.check_output(clone_cmd, stderr=subprocess.STDOUT)
+    except subprocess.CalledProcessError as e:
+        output = e.output.decode('utf-8')
+        if 'Repository not found' in output:
+            raise RepositoryNotFound(f"The repository {repo_url} could not be found")
+        else:
+            raise RepositoryCloneFailed(f"Cloning {repo_url} failed: {output}")
+
+    if checkout:
+        if repo_type == 'git':
+            checkout_cmd = ['git', 'checkout', checkout]
+        else:  # hg
+            checkout_cmd = ['hg', 'update', checkout]
+
+        with Path.cwd():
+            os.chdir(repo_dir)
+            try:
+                subprocess.check_output(checkout_cmd, stderr=subprocess.STDOUT)
+            except subprocess.CalledProcessError as e:
+                output = e.output.decode('utf-8')
+                if any(error in output for error in BRANCH_ERRORS):
+                    raise RepositoryCloneFailed(
+                        f"Couldn't checkout {checkout} in {repo_url}. "
+                        f"Error: {output}"
+                    )
+                else:
+                    raise
+
+    return str(repo_dir)
diff --git a/cookiecutter/zipfile.py b/cookiecutter/zipfile.py
index c4d398a..1448316 100644
--- a/cookiecutter/zipfile.py
+++ b/cookiecutter/zipfile.py
@@ -25,4 +25,46 @@ def unzip(zip_uri: str, is_url: bool, clone_to_dir: 'os.PathLike[str]'='.',
         cached resources.
     :param password: The password to use when unpacking the repository.
     """
-    pass
+    clone_to_dir = Path(clone_to_dir)
+    make_sure_path_exists(clone_to_dir)
+
+    if is_url:
+        # Download the file
+        response = requests.get(zip_uri)
+        response.raise_for_status()
+        zip_file = tempfile.NamedTemporaryFile(delete=False, suffix='.zip', dir=clone_to_dir)
+        zip_file.write(response.content)
+        zip_file.close()
+        zip_path = Path(zip_file.name)
+    else:
+        zip_path = Path(zip_uri)
+
+    # Create a temporary directory to extract the contents
+    with tempfile.TemporaryDirectory(dir=clone_to_dir) as temp_dir:
+        try:
+            with ZipFile(zip_path, 'r') as zip_ref:
+                if zip_ref.namelist() and zip_ref.testzip() is not None:
+                    raise InvalidZipRepository(f"The zip file {zip_uri} is invalid or corrupt.")
+
+                if password is None and zip_ref.namelist()[0].endswith('/'):
+                    password = read_repo_password('Enter the password for the encrypted repository:')
+
+                try:
+                    zip_ref.extractall(path=temp_dir, pwd=password.encode() if password else None)
+                except RuntimeError as e:
+                    if "Bad password" in str(e):
+                        raise InvalidZipRepository(f"Invalid password for encrypted repository: {zip_uri}")
+                    raise
+
+            # If everything is successful, return the path to the extracted contents
+            return Path(temp_dir)
+
+        except BadZipFile:
+            raise InvalidZipRepository(f"The zip file {zip_uri} is invalid or corrupt.")
+
+        finally:
+            if is_url:
+                if no_input:
+                    os.unlink(zip_path)
+                else:
+                    prompt_and_delete(zip_path)