Skip to content

back to Claude Sonnet 3.5 - Fill-in + Unit Test Feedback summary

Claude Sonnet 3.5 - Fill-in + Unit Test Feedback: cookiecutter

Pytest Summary for test tests

status count
passed 187
failed 177
skipped 4
total 368
collected 368

Failed pytests:

test_replay.py::test_raise_on_invalid_mode[invalid_kwargs0]

test_replay.py::test_raise_on_invalid_mode[invalid_kwargs0]
template = 'foo'
abbreviations = {'bb': 'https://bitbucket.org/{0}', 'gh': 'https://github.com/{0}.git', 'gl': 'https://gitlab.com/{0}.git'}
clone_to_dir = '/tmp/pytest-of-root/pytest-0/test_raise_on_invalid_mode_inv0/home/.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.
        """
        logger.debug(f"Determining repo directory for template: {template}")
        template = expand_abbreviations(template, abbreviations)
        logger.debug(f"Expanded template: {template}")

        try:
>           repo_type, repo_url = identify_repo(template)

cookiecutter/repository.py:91: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

repo_url = 'foo'

    def identify_repo(repo_url):
        """Determine if `repo_url` should be treated as a URL to a git, hg repo, or zip file.

        Repos can be identified by prepending "hg+" or "git+" to the repo URL.

        :param repo_url: Repo URL of unknown type.
        :returns: ('git', repo_url), ('hg', repo_url), ('zip', repo_url), or ('file', repo_url).
        :raises: UnknownRepoType if the repo type cannot be determined.
        """
        logger.debug(f"identify_repo called with repo_url: {repo_url}")

        if repo_url is None:
            logger.error("repo_url is None")
            raise ValueError("repo_url cannot be None")

        if not repo_url:
            logger.debug("Empty repo_url, returning ('file', '')")
            return 'file', ''

        logger.debug(f"Identifying repo type for URL: {repo_url}")
        repo_url = str(repo_url)

        if repo_url.lower().startswith('git+'):
            logger.debug("Identified as git repo")
            return 'git', repo_url[4:]
        elif repo_url.lower().startswith('hg+'):
            logger.debug("Identified as hg repo")
            return 'hg', repo_url[3:]
        elif repo_url.lower().endswith('.git') or 'github.com' in repo_url.lower() or repo_url.startswith('git@'):
            logger.debug("Identified as git repo")
            return 'git', repo_url
        elif 'bitbucket.org' in repo_url.lower():
            logger.debug("Identified as hg repo")
            return 'hg', repo_url
        elif repo_url.lower().endswith('.zip') or '/zipball/' in repo_url.lower():
            logger.debug("Identified as zip file")
            return 'zip', repo_url
        elif os.path.exists(repo_url):
            if os.path.isdir(repo_url):
                logger.debug(f"Identified as local directory: {repo_url}")
            else:
                logger.debug(f"Identified as local file: {repo_url}")
            return 'file', repo_url
        else:
            logger.warning(f"Unable to identify repo type for: {repo_url}")
>           raise exceptions.UnknownRepoType(f"Unable to determine repository type for {repo_url}")
E           cookiecutter.exceptions.UnknownRepoType: Unable to determine repository type for foo

cookiecutter/vcs.py:61: UnknownRepoType

During handling of the above exception, another exception occurred:

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, config_file='tests/fake-repo-tmpl/cookiecutter.json', **invalid_kwargs)

tests/replay/test_replay.py:29: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
cookiecutter/main.py:55: in cookiecutter
    return cookiecutter_invocation(
cookiecutter/main.py:77: in cookiecutter_invocation
    repo_dir, cleanup = determine_repo_dir(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

template = 'foo'
abbreviations = {'bb': 'https://bitbucket.org/{0}', 'gh': 'https://github.com/{0}.git', 'gl': 'https://gitlab.com/{0}.git'}
clone_to_dir = '/tmp/pytest-of-root/pytest-0/test_raise_on_invalid_mode_inv0/home/.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.
        """
        logger.debug(f"Determining repo directory for template: {template}")
        template = expand_abbreviations(template, abbreviations)
        logger.debug(f"Expanded template: {template}")

        try:
            repo_type, repo_url = identify_repo(template)
            logger.debug(f"Identified repo_type: {repo_type}, repo_url: {repo_url}")
        except Exception as e:
            logger.error(f"Error identifying repo: {e}")
>           raise RepositoryNotFound(f"Could not identify a repository for {template}")
E           cookiecutter.exceptions.RepositoryNotFound: The repository Could not identify a repository for foo does not contain a cookiecutter.json file

cookiecutter/repository.py:95: RepositoryNotFound

test_replay.py::test_raise_on_invalid_mode[invalid_kwargs1]

test_replay.py::test_raise_on_invalid_mode[invalid_kwargs1]
template = 'foo'
abbreviations = {'bb': 'https://bitbucket.org/{0}', 'gh': 'https://github.com/{0}.git', 'gl': 'https://gitlab.com/{0}.git'}
clone_to_dir = '/tmp/pytest-of-root/pytest-0/test_raise_on_invalid_mode_inv1/home/.cookiecutters'
checkout = None, no_input = False, 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.
        """
        logger.debug(f"Determining repo directory for template: {template}")
        template = expand_abbreviations(template, abbreviations)
        logger.debug(f"Expanded template: {template}")

        try:
>           repo_type, repo_url = identify_repo(template)

cookiecutter/repository.py:91: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

repo_url = 'foo'

    def identify_repo(repo_url):
        """Determine if `repo_url` should be treated as a URL to a git, hg repo, or zip file.

        Repos can be identified by prepending "hg+" or "git+" to the repo URL.

        :param repo_url: Repo URL of unknown type.
        :returns: ('git', repo_url), ('hg', repo_url), ('zip', repo_url), or ('file', repo_url).
        :raises: UnknownRepoType if the repo type cannot be determined.
        """
        logger.debug(f"identify_repo called with repo_url: {repo_url}")

        if repo_url is None:
            logger.error("repo_url is None")
            raise ValueError("repo_url cannot be None")

        if not repo_url:
            logger.debug("Empty repo_url, returning ('file', '')")
            return 'file', ''

        logger.debug(f"Identifying repo type for URL: {repo_url}")
        repo_url = str(repo_url)

        if repo_url.lower().startswith('git+'):
            logger.debug("Identified as git repo")
            return 'git', repo_url[4:]
        elif repo_url.lower().startswith('hg+'):
            logger.debug("Identified as hg repo")
            return 'hg', repo_url[3:]
        elif repo_url.lower().endswith('.git') or 'github.com' in repo_url.lower() or repo_url.startswith('git@'):
            logger.debug("Identified as git repo")
            return 'git', repo_url
        elif 'bitbucket.org' in repo_url.lower():
            logger.debug("Identified as hg repo")
            return 'hg', repo_url
        elif repo_url.lower().endswith('.zip') or '/zipball/' in repo_url.lower():
            logger.debug("Identified as zip file")
            return 'zip', repo_url
        elif os.path.exists(repo_url):
            if os.path.isdir(repo_url):
                logger.debug(f"Identified as local directory: {repo_url}")
            else:
                logger.debug(f"Identified as local file: {repo_url}")
            return 'file', repo_url
        else:
            logger.warning(f"Unable to identify repo type for: {repo_url}")
>           raise exceptions.UnknownRepoType(f"Unable to determine repository type for {repo_url}")
E           cookiecutter.exceptions.UnknownRepoType: Unable to determine repository type for foo

cookiecutter/vcs.py:61: UnknownRepoType

During handling of the above exception, another exception occurred:

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, config_file='tests/fake-repo-tmpl/cookiecutter.json', **invalid_kwargs)

tests/replay/test_replay.py:29: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
cookiecutter/main.py:55: in cookiecutter
    return cookiecutter_invocation(
cookiecutter/main.py:77: in cookiecutter_invocation
    repo_dir, cleanup = determine_repo_dir(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

template = 'foo'
abbreviations = {'bb': 'https://bitbucket.org/{0}', 'gh': 'https://github.com/{0}.git', 'gl': 'https://gitlab.com/{0}.git'}
clone_to_dir = '/tmp/pytest-of-root/pytest-0/test_raise_on_invalid_mode_inv1/home/.cookiecutters'
checkout = None, no_input = False, 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.
        """
        logger.debug(f"Determining repo directory for template: {template}")
        template = expand_abbreviations(template, abbreviations)
        logger.debug(f"Expanded template: {template}")

        try:
            repo_type, repo_url = identify_repo(template)
            logger.debug(f"Identified repo_type: {repo_type}, repo_url: {repo_url}")
        except Exception as e:
            logger.error(f"Error identifying repo: {e}")
>           raise RepositoryNotFound(f"Could not identify a repository for {template}")
E           cookiecutter.exceptions.RepositoryNotFound: The repository Could not identify a repository for foo does not contain a cookiecutter.json file

cookiecutter/repository.py:95: RepositoryNotFound

test_replay.py::test_raise_on_invalid_mode[invalid_kwargs2]

test_replay.py::test_raise_on_invalid_mode[invalid_kwargs2]
template = 'foo'
abbreviations = {'bb': 'https://bitbucket.org/{0}', 'gh': 'https://github.com/{0}.git', 'gl': 'https://gitlab.com/{0}.git'}
clone_to_dir = '/tmp/pytest-of-root/pytest-0/test_raise_on_invalid_mode_inv2/home/.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.
        """
        logger.debug(f"Determining repo directory for template: {template}")
        template = expand_abbreviations(template, abbreviations)
        logger.debug(f"Expanded template: {template}")

        try:
>           repo_type, repo_url = identify_repo(template)

cookiecutter/repository.py:91: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

repo_url = 'foo'

    def identify_repo(repo_url):
        """Determine if `repo_url` should be treated as a URL to a git, hg repo, or zip file.

        Repos can be identified by prepending "hg+" or "git+" to the repo URL.

        :param repo_url: Repo URL of unknown type.
        :returns: ('git', repo_url), ('hg', repo_url), ('zip', repo_url), or ('file', repo_url).
        :raises: UnknownRepoType if the repo type cannot be determined.
        """
        logger.debug(f"identify_repo called with repo_url: {repo_url}")

        if repo_url is None:
            logger.error("repo_url is None")
            raise ValueError("repo_url cannot be None")

        if not repo_url:
            logger.debug("Empty repo_url, returning ('file', '')")
            return 'file', ''

        logger.debug(f"Identifying repo type for URL: {repo_url}")
        repo_url = str(repo_url)

        if repo_url.lower().startswith('git+'):
            logger.debug("Identified as git repo")
            return 'git', repo_url[4:]
        elif repo_url.lower().startswith('hg+'):
            logger.debug("Identified as hg repo")
            return 'hg', repo_url[3:]
        elif repo_url.lower().endswith('.git') or 'github.com' in repo_url.lower() or repo_url.startswith('git@'):
            logger.debug("Identified as git repo")
            return 'git', repo_url
        elif 'bitbucket.org' in repo_url.lower():
            logger.debug("Identified as hg repo")
            return 'hg', repo_url
        elif repo_url.lower().endswith('.zip') or '/zipball/' in repo_url.lower():
            logger.debug("Identified as zip file")
            return 'zip', repo_url
        elif os.path.exists(repo_url):
            if os.path.isdir(repo_url):
                logger.debug(f"Identified as local directory: {repo_url}")
            else:
                logger.debug(f"Identified as local file: {repo_url}")
            return 'file', repo_url
        else:
            logger.warning(f"Unable to identify repo type for: {repo_url}")
>           raise exceptions.UnknownRepoType(f"Unable to determine repository type for {repo_url}")
E           cookiecutter.exceptions.UnknownRepoType: Unable to determine repository type for foo

cookiecutter/vcs.py:61: UnknownRepoType

During handling of the above exception, another exception occurred:

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, config_file='tests/fake-repo-tmpl/cookiecutter.json', **invalid_kwargs)

tests/replay/test_replay.py:29: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
cookiecutter/main.py:55: in cookiecutter
    return cookiecutter_invocation(
cookiecutter/main.py:77: in cookiecutter_invocation
    repo_dir, cleanup = determine_repo_dir(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

template = 'foo'
abbreviations = {'bb': 'https://bitbucket.org/{0}', 'gh': 'https://github.com/{0}.git', 'gl': 'https://gitlab.com/{0}.git'}
clone_to_dir = '/tmp/pytest-of-root/pytest-0/test_raise_on_invalid_mode_inv2/home/.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.
        """
        logger.debug(f"Determining repo directory for template: {template}")
        template = expand_abbreviations(template, abbreviations)
        logger.debug(f"Expanded template: {template}")

        try:
            repo_type, repo_url = identify_repo(template)
            logger.debug(f"Identified repo_type: {repo_type}, repo_url: {repo_url}")
        except Exception as e:
            logger.error(f"Error identifying repo: {e}")
>           raise RepositoryNotFound(f"Could not identify a repository for {template}")
E           cookiecutter.exceptions.RepositoryNotFound: The repository Could not identify a repository for foo does not contain a cookiecutter.json file

cookiecutter/repository.py:95: RepositoryNotFound

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: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
cookiecutter/main.py:55: in cookiecutter
    return cookiecutter_invocation(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

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_invocation(
        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
    ):
        if template is None:
            raise ValueError("Template argument cannot be None")
        try:
            logger.info(f"Starting cookiecutter invocation with template: {template}")
            # Get user configuration
            config_dict = get_user_config(config_file=config_file, default_config=default_config)
            logger.debug(f"User configuration: {config_dict}")

            # 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,
                abbreviations=config_dict.get('abbreviations', {})
            )
            logger.info(f"Template directory determined: {repo_dir}")

            # Run pre-prompt hook if accept_hooks is True
            if accept_hooks:
                logger.info("Running pre-prompt hook")
                run_pre_prompt_hook(repo_dir, config_dict)

            # Prompt for template configuration
            context_file = os.path.join(repo_dir, 'cookiecutter.json')
            logger.debug(f"Context file: {context_file}")
            if replay:
                logger.info("Loading context from replay")
                context = load(config_dict['replay_dir'], template)
            elif no_input:
                logger.info("Generating context with no input")
                context = generate_context(
                    context_file=context_file,
                    default_context=config_dict['default_context'],
                    extra_context=extra_context,
                )
            else:
                logger.info("Prompting for config")
                context = prompt_for_config(context_file, extra_context)
            logger.debug(f"Context: {context}")

            # Apply any overwrites to the context
            if 'cookiecutter' not in context:
                context['cookiecutter'] = {}
            context['cookiecutter'] = apply_overwrites_to_context(
                context['cookiecutter'], config_dict.get('overwrite_context', {})
            )
            logger.debug(f"Context after overwrites: {context}")

            # Choose nested template if applicable
>           nested_template = choose_nested_template(context)
E           TypeError: choose_nested_template() missing 1 required positional argument: 'repo_dir'

cookiecutter/main.py:120: 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: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
cookiecutter/main.py:55: in cookiecutter
    return cookiecutter_invocation(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

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_invocation(
        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
    ):
        if template is None:
            raise ValueError("Template argument cannot be None")
        try:
            logger.info(f"Starting cookiecutter invocation with template: {template}")
            # Get user configuration
            config_dict = get_user_config(config_file=config_file, default_config=default_config)
            logger.debug(f"User configuration: {config_dict}")

            # 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,
                abbreviations=config_dict.get('abbreviations', {})
            )
            logger.info(f"Template directory determined: {repo_dir}")

            # Run pre-prompt hook if accept_hooks is True
            if accept_hooks:
                logger.info("Running pre-prompt hook")
                run_pre_prompt_hook(repo_dir, config_dict)

            # Prompt for template configuration
            context_file = os.path.join(repo_dir, 'cookiecutter.json')
            logger.debug(f"Context file: {context_file}")
            if replay:
                logger.info("Loading context from replay")
                context = load(config_dict['replay_dir'], template)
            elif no_input:
                logger.info("Generating context with no input")
                context = generate_context(
                    context_file=context_file,
                    default_context=config_dict['default_context'],
                    extra_context=extra_context,
                )
            else:
                logger.info("Prompting for config")
                context = prompt_for_config(context_file, extra_context)
            logger.debug(f"Context: {context}")

            # Apply any overwrites to the context
            if 'cookiecutter' not in context:
                context['cookiecutter'] = {}
            context['cookiecutter'] = apply_overwrites_to_context(
                context['cookiecutter'], config_dict.get('overwrite_context', {})
            )
            logger.debug(f"Context after overwrites: {context}")

            # Choose nested template if applicable
>           nested_template = choose_nested_template(context)
E           TypeError: choose_nested_template() missing 1 required positional argument: 'repo_dir'

cookiecutter/main.py:120: TypeError

zipfile.zip-False]

zipfile.zip-False]
mocker = 
template = '/path/to/zipfile.zip', is_url = False
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:105: in determine_repo_dir
    repo_dir = clone(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

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

    def clone(repo_url: str, checkout: Optional[str]=None, clone_to_dir:
        'os.PathLike[str]'='.', no_input: bool=False, password: Optional[str]=None):
        """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.")
E           cookiecutter.exceptions.VCSNotInstalled: zip is not installed.

cookiecutter/vcs.py:94: VCSNotInstalled

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:105: 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, password = None

    def clone(repo_url: str, checkout: Optional[str]=None, clone_to_dir:
        'os.PathLike[str]'='.', no_input: bool=False, password: Optional[str]=None):
        """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.")
E           cookiecutter.exceptions.VCSNotInstalled: zip is not installed.

cookiecutter/vcs.py:94: VCSNotInstalled

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:105: 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, password = None

    def clone(repo_url: str, checkout: Optional[str]=None, clone_to_dir:
        'os.PathLike[str]'='.', no_input: bool=False, password: Optional[str]=None):
        """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.")
E           cookiecutter.exceptions.VCSNotInstalled: zip is not installed.

cookiecutter/vcs.py:94: VCSNotInstalled

test_determine_repo_dir_clones_repo.py::test_repository_url_should_clone

test_determine_repo_dir_clones_repo.py::test_repository_url_should_clone
self = , args = ()
kwargs = {'checkout': None, 'clone_to_dir': '/tmp/pytest-of-root/pytest-0/user_dir0/cookiecutters', 'no_input': True, 'repo_url': 'https://github.com/pytest-dev/cookiecutter-pytest-plugin.git'}
msg = "Expected 'clone' to be called once. Called 2 times.\nCalls: [call(repo_url='https://github.com/pytest-dev/cookiecutter-pytest-plugin.git', checkout=None, clone_to_dir='/tmp/pytest-of-root/pytest-0/user_dir0/cookiecutters', no_input=True, password=None),\n call(repo_url='https://github.com/pytest-dev/cookiecutter-pytest-plugin.git', checkout=None, clone_to_dir='/tmp/pytest-of-root/pytest-0/user_dir0/cookiecutters', no_input=True, password=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)
E           AssertionError: Expected 'clone' to be called once. Called 2 times.
E           Calls: [call(repo_url='https://github.com/pytest-dev/cookiecutter-pytest-plugin.git', checkout=None, clone_to_dir='/tmp/pytest-of-root/pytest-0/user_dir0/cookiecutters', no_input=True, password=None),
E            call(repo_url='https://github.com/pytest-dev/cookiecutter-pytest-plugin.git', checkout=None, clone_to_dir='/tmp/pytest-of-root/pytest-0/user_dir0/cookiecutters', no_input=True, password=None)].

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

During handling of the above exception, another exception occurred:

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,
        )

tests/repository/test_determine_repo_dir_clones_repo.py:81: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

args = ()
kwargs = {'checkout': None, 'clone_to_dir': '/tmp/pytest-of-root/pytest-0/user_dir0/cookiecutters', 'no_input': True, 'repo_url': 'https://github.com/pytest-dev/cookiecutter-pytest-plugin.git'}

    def assert_called_once_with(*args, **kwargs):
>       return mock.assert_called_once_with(*args, **kwargs)
E       AssertionError: Expected 'clone' to be called once. Called 2 times.
E       Calls: [call(repo_url='https://github.com/pytest-dev/cookiecutter-pytest-plugin.git', checkout=None, clone_to_dir='/tmp/pytest-of-root/pytest-0/user_dir0/cookiecutters', no_input=True, password=None),
E        call(repo_url='https://github.com/pytest-dev/cookiecutter-pytest-plugin.git', checkout=None, clone_to_dir='/tmp/pytest-of-root/pytest-0/user_dir0/cookiecutters', no_input=True, password=None)].
E       
E       pytest introspection follows:
E       
E       Kwargs:
E       assert {'repo_url': 'https://github.com/pytest-dev/cookiecutter-pytest-plugin.git', 'checkout': None, 'clone_to_dir': '/tmp/pytest-of-root/pytest-0/user_dir0/cookiecutters', 'no_input': True, 'password': None} == {'repo_url': 'https://github.com/pytest-dev/cookiecutter-pytest-plugin.git', 'checkout': None, 'clone_to_dir': '/tmp/pytest-of-root/pytest-0/user_dir0/cookiecutters', 'no_input': True}
E         
E         Common items:
E         {'checkout': None,
E          'clone_to_dir': '/tmp/pytest-of-root/pytest-0/user_dir0/cookiecutters',
E          'no_input': True,
E          'repo_url': 'https://github.com/pytest-dev/cookiecutter-pytest-plugin.git'}
E         Left contains 1 more item:
E         {'password': None}
E         
E         Full diff:
E           {
E               'checkout': None,
E               'clone_to_dir': '/tmp/pytest-of-root/pytest-0/user_dir0/cookiecutters',
E               'no_input': True,
E         +     'password': None,
E               'repo_url': 'https://github.com/pytest-dev/cookiecutter-pytest-plugin.git',
E           }

/usr/lib/python3.10/unittest/mock.py:213: 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) == (
            'The repository tests/fake-repo-bad does not contain a cookiecutter.json file'
        )
E       AssertionError: assert 'The repository The repository tests/fake-repo-bad does not contain a cookiecutter.json file does not contain a cookiecutter.json file' == 'The repository tests/fake-repo-bad does not contain a cookiecutter.json file'
E         
E         - The repository tests/fake-repo-bad does not contain a cookiecutter.json file
E         + The repository The repository tests/fake-repo-bad does not contain a cookiecutter.json file does not contain a cookiecutter.json file

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', 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.
        """
        logger.debug(f"Determining repo directory for template: {template}")
        template = expand_abbreviations(template, abbreviations)
        logger.debug(f"Expanded template: {template}")

        try:
>           repo_type, repo_url = identify_repo(template)

cookiecutter/repository.py:91: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

repo_url = 'cookiecutter-pytest-plugin'

    def identify_repo(repo_url):
        """Determine if `repo_url` should be treated as a URL to a git, hg repo, or zip file.

        Repos can be identified by prepending "hg+" or "git+" to the repo URL.

        :param repo_url: Repo URL of unknown type.
        :returns: ('git', repo_url), ('hg', repo_url), ('zip', repo_url), or ('file', repo_url).
        :raises: UnknownRepoType if the repo type cannot be determined.
        """
        logger.debug(f"identify_repo called with repo_url: {repo_url}")

        if repo_url is None:
            logger.error("repo_url is None")
            raise ValueError("repo_url cannot be None")

        if not repo_url:
            logger.debug("Empty repo_url, returning ('file', '')")
            return 'file', ''

        logger.debug(f"Identifying repo type for URL: {repo_url}")
        repo_url = str(repo_url)

        if repo_url.lower().startswith('git+'):
            logger.debug("Identified as git repo")
            return 'git', repo_url[4:]
        elif repo_url.lower().startswith('hg+'):
            logger.debug("Identified as hg repo")
            return 'hg', repo_url[3:]
        elif repo_url.lower().endswith('.git') or 'github.com' in repo_url.lower() or repo_url.startswith('git@'):
            logger.debug("Identified as git repo")
            return 'git', repo_url
        elif 'bitbucket.org' in repo_url.lower():
            logger.debug("Identified as hg repo")
            return 'hg', repo_url
        elif repo_url.lower().endswith('.zip') or '/zipball/' in repo_url.lower():
            logger.debug("Identified as zip file")
            return 'zip', repo_url
        elif os.path.exists(repo_url):
            if os.path.isdir(repo_url):
                logger.debug(f"Identified as local directory: {repo_url}")
            else:
                logger.debug(f"Identified as local file: {repo_url}")
            return 'file', repo_url
        else:
            logger.warning(f"Unable to identify repo type for: {repo_url}")
>           raise exceptions.UnknownRepoType(f"Unable to determine repository type for {repo_url}")
E           cookiecutter.exceptions.UnknownRepoType: Unable to determine repository type for cookiecutter-pytest-plugin

cookiecutter/vcs.py:61: UnknownRepoType

During handling of the above exception, another exception occurred:

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.
        """
        logger.debug(f"Determining repo directory for template: {template}")
        template = expand_abbreviations(template, abbreviations)
        logger.debug(f"Expanded template: {template}")

        try:
            repo_type, repo_url = identify_repo(template)
            logger.debug(f"Identified repo_type: {repo_type}, repo_url: {repo_url}")
        except Exception as e:
            logger.error(f"Error identifying repo: {e}")
>           raise RepositoryNotFound(f"Could not identify a repository for {template}")
E           cookiecutter.exceptions.RepositoryNotFound: The repository Could not identify a repository for cookiecutter-pytest-plugin does not contain a cookiecutter.json file

cookiecutter/repository.py:95: 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', 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.
        """
        logger.debug(f"Determining repo directory for template: {template}")
        template = expand_abbreviations(template, abbreviations)
        logger.debug(f"Expanded template: {template}")

        try:
>           repo_type, repo_url = identify_repo(template)

cookiecutter/repository.py:91: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

repo_url = 'cookiecutter-pytest-plugin'

    def identify_repo(repo_url):
        """Determine if `repo_url` should be treated as a URL to a git, hg repo, or zip file.

        Repos can be identified by prepending "hg+" or "git+" to the repo URL.

        :param repo_url: Repo URL of unknown type.
        :returns: ('git', repo_url), ('hg', repo_url), ('zip', repo_url), or ('file', repo_url).
        :raises: UnknownRepoType if the repo type cannot be determined.
        """
        logger.debug(f"identify_repo called with repo_url: {repo_url}")

        if repo_url is None:
            logger.error("repo_url is None")
            raise ValueError("repo_url cannot be None")

        if not repo_url:
            logger.debug("Empty repo_url, returning ('file', '')")
            return 'file', ''

        logger.debug(f"Identifying repo type for URL: {repo_url}")
        repo_url = str(repo_url)

        if repo_url.lower().startswith('git+'):
            logger.debug("Identified as git repo")
            return 'git', repo_url[4:]
        elif repo_url.lower().startswith('hg+'):
            logger.debug("Identified as hg repo")
            return 'hg', repo_url[3:]
        elif repo_url.lower().endswith('.git') or 'github.com' in repo_url.lower() or repo_url.startswith('git@'):
            logger.debug("Identified as git repo")
            return 'git', repo_url
        elif 'bitbucket.org' in repo_url.lower():
            logger.debug("Identified as hg repo")
            return 'hg', repo_url
        elif repo_url.lower().endswith('.zip') or '/zipball/' in repo_url.lower():
            logger.debug("Identified as zip file")
            return 'zip', repo_url
        elif os.path.exists(repo_url):
            if os.path.isdir(repo_url):
                logger.debug(f"Identified as local directory: {repo_url}")
            else:
                logger.debug(f"Identified as local file: {repo_url}")
            return 'file', repo_url
        else:
            logger.warning(f"Unable to identify repo type for: {repo_url}")
>           raise exceptions.UnknownRepoType(f"Unable to determine repository type for {repo_url}")
E           cookiecutter.exceptions.UnknownRepoType: Unable to determine repository type for cookiecutter-pytest-plugin

cookiecutter/vcs.py:61: UnknownRepoType

During handling of the above exception, another exception occurred:

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.
        """
        logger.debug(f"Determining repo directory for template: {template}")
        template = expand_abbreviations(template, abbreviations)
        logger.debug(f"Expanded template: {template}")

        try:
            repo_type, repo_url = identify_repo(template)
            logger.debug(f"Identified repo_type: {repo_type}, repo_url: {repo_url}")
        except Exception as e:
            logger.error(f"Error identifying repo: {e}")
>           raise RepositoryNotFound(f"Could not identify a repository for {template}")
E           cookiecutter.exceptions.RepositoryNotFound: The repository Could not identify a repository for cookiecutter-pytest-plugin does not contain a cookiecutter.json file

cookiecutter/repository.py:95: 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 Could not identify a repository for cookiecutter-pytest-plugin 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 Could not identify a repository for cookiecutter-pytest-plugin 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_finds_local_repo

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

    def test_finds_local_repo(tmp_path):
        """A valid local repository should be returned."""
        project_dir, cleanup = repository.determine_repo_dir(
            'tests/fake-repo',
            abbreviations={},
            clone_to_dir=str(tmp_path),
            checkout=None,
            no_input=True,
        )

>       assert 'tests/fake-repo' == project_dir
E       AssertionError: assert 'tests/fake-repo' == '/testbed/tests/fake-repo'
E         
E         - /testbed/tests/fake-repo
E         ? ---------
E         + tests/fake-repo

tests/repository/test_determine_repository_should_use_local_repo.py:20: 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 The repository /testbed/tests/fake-repo-bad does not contain a cookiecutter.json file 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 The repository /testbed/tests/fake-repo-bad does not contain a cookiecutter.json file 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 Could not identify a repository for 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 Could not identify a repository for 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_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),
            )
>           assert error.value.code == 5

tests/test_abort_generate_on_hook_error.py:39: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = 

    @property
    def value(self) -> E:
        """The exception value."""
        assert (
>           self._excinfo is not None
        ), ".value can only be used after the context manager exits"
E       AssertionError: .value can only be used after the context manager exits

.venv/lib/python3.10/site-packages/_pytest/_code/code.py:548: AssertionError

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),
            )
>           assert error.value.code == 5

tests/test_abort_generate_on_hook_error.py:39: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = 

    @property
    def value(self) -> E:
        """The exception value."""
        assert (
>           self._excinfo is not None
        ), ".value can only be used after the context manager exits"
E       AssertionError: .value can only be used after the context manager exits

.venv/lib/python3.10/site-packages/_pytest/_code/code.py:548: AssertionError

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 0x7f92d207eef0>

    @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 'Invoking cookiecutter with template: tests/fake-repo-pre/\nINFO: Starting cookiecutter invocation with template: tests/fake-repo-pre/\nINFO: Template directory determined: /testbed/tests/fake-repo-pre\nINFO: Running pre-prompt hook\nINFO: Generating context with no input\nERROR: Error during cookiecutter invocation: choose_nested_template() missing 1 required positional argument: \'repo_dir\'\nTraceback (most recent call last):\n  File "/testbed/cookiecutter/main.py", line 120, in cookiecutter_invocation\n    nested_template = choose_nested_template(context)\nTypeError: choose_nested_template() missing 1 required positional argument: \'repo_dir\'\nError: choose_nested_template() missing 1 required positional argument: \'repo_dir\'\nError type: TypeError\n' == 'Error: "fake-project" directory already exists\n'
E         
E         - Error: "fake-project" directory already exists
E         + Invoking cookiecutter with template: tests/fake-repo-pre/
E         + INFO: Starting cookiecutter invocation with template: tests/fake-repo-pre/
E         + INFO: Template directory determined: /testbed/tests/fake-repo-pre
E         + INFO: Running pre-prompt hook
E         + INFO: Generating context with no input
E         + ERROR: Error during cookiecutter invocation: choose_nested_template() missing 1 required positional argument: 'repo_dir'
E         + Traceback (most recent call last):
E         +   File "/testbed/cookiecutter/main.py", line 120, in cookiecutter_invocation
E         +     nested_template = choose_nested_template(context)
E         + TypeError: choose_nested_template() missing 1 required positional argument: 'repo_dir'
E         + Error: choose_nested_template() missing 1 required positional argument: 'repo_dir'
E         + Error type: TypeError

tests/test_cli.py:81: AssertionError

test_cli.py::test_cli

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

    @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 0x7f92d207eef0>

    @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
mocker = 
cli_runner = .cli_main at 0x7f92d207eef0>

    @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
E       assert 1 == 0
E        +  where 1 = .exit_code

tests/test_cli.py:112: AssertionError

test_cli.py::test_cli_replay_file

test_cli.py::test_cli_replay_file
mocker = 
cli_runner = .cli_main at 0x7f92d207eef0>

    @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
E       assert 1 == 0
E        +  where 1 = .exit_code

tests/test_cli.py:139: AssertionError

test_cli.py::test_cli_replay_generated

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

    @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 0x7f92d207eef0>

    @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 'Invoking cookiecutter with template: tests/fake-repo-pre/\nINFO cookiecutter.main: Starting cookiecutter invocation with template: tests/fake-repo-pre/\nDEBUG cookiecutter.main: User configuration: {\'cookiecutters_dir\': \'/tmp/pytest-of-root/pytest-0/test_cli_exit_on_noinput_and_r0/home/.cookiecutters\', \'replay_dir\': \'/tmp/pytest-of-root/pytest-0/test_cli_exit_on_noinput_and_r0/home/.cookiecutter_replay\', \'default_context\': OrderedDict(), \'abbreviations\': {\'gh\': \'https://github.com/{0}.git\', \'gl\': \'https://gitlab.com/{0}.git\', \'bb\': \'https://bitbucket.org/{0}\'}}\nDEBUG cookiecutter.repository: Determining repo directory for template: tests/fake-repo-pre/\nDEBUG cookiecutter.repository: Expanded template: tests/fake-repo-pre/\nDEBUG cookiecutter.vcs: identify_repo called with repo_url: tests/fake-repo-pre/\nDEBUG cookiecutter.vcs: Identifying repo type for URL: tests/fake-repo-pre/\nDEBUG cookiecutter.vcs: Identified as local directory: tests/fake-repo-pre/\nDEBUG cookiecutter.repository: Identified repo_type: file, repo_url: tests/fake-repo-pre/\nDEBUG cookiecutter.repository: Identified repo_type: file, repo_url: tests/fake-repo-pre/\nINFO cookiecutter.main: Template directory determined: /testbed/tests/fake-repo-pre\nINFO cookiecutter.main: Running pre-prompt hook\nDEBUG cookiecutter.hooks: No pre_prompt hook found\nDEBUG cookiecutter.main: Context file: /testbed/tests/fake-repo-pre/cookiecutter.json\nINFO cookiecutter.main: Loading context from replay\nERROR cookiecutter.main: Error during cookiecutter invocation: [Errno 2] No such file or directory: \'/tmp/pytest-of-root/pytest-0/test_cli_exit_on_noinput_and_r0/home/.cookiecutter_replay/tests/fake-repo-pre/.json\'\nTraceback (most recent call last):\n  File "/testbed/cookiecutter/main.py", line 98, in cookiecutter_invocation\n    context = load(config_dict[\'replay_dir\'], template)\n  File "/testbed/cookiecutter/replay.py", line 37, in load\n    with open(file_path, \'r\') as f:\nFileNotFoundError: [Errno 2] No such file or directory: \'/tmp/pytest-of-root/pytest-0/test_cli_exit_on_noinput_and_r0/home/.cookiecutter_replay/tests/fake-repo-pre/.json\'\nError: [Errno 2] No such file or directory: \'/tmp/pytest-of-root/pytest-0/test_cli_exit_on_noinput_and_r0/home/.cookiecutter_replay/tests/fake-repo-pre/.json\'\nError type: FileNotFoundError\nTraceback (most recent call last):\n  File "/testbed/cookiecutter/cli.py", line 112, in main\n    result = cookiecutter_invocation(\n  File "/testbed/cookiecutter/main.py", line 98, in cookiecutter_invocation\n    context = load(config_dict[\'replay_dir\'], template)\n  File "/testbed/cookiecutter/replay.py", line 37, in load\n    with open(file_path, \'r\') as f:\nFileNotFoundError: [Errno 2] No such file or directory: \'/tmp/pytest-of-root/pytest-0/test_cli_exit_on_noinput_and_r0/home/.cookiecutter_replay/tests/fake-repo-pre/.json\'\n\n'
E        +  where 'Invoking cookiecutter with template: tests/fake-repo-pre/\nINFO cookiecutter.main: Starting cookiecutter invocation with template: tests/fake-repo-pre/\nDEBUG cookiecutter.main: User configuration: {\'cookiecutters_dir\': \'/tmp/pytest-of-root/pytest-0/test_cli_exit_on_noinput_and_r0/home/.cookiecutters\', \'replay_dir\': \'/tmp/pytest-of-root/pytest-0/test_cli_exit_on_noinput_and_r0/home/.cookiecutter_replay\', \'default_context\': OrderedDict(), \'abbreviations\': {\'gh\': \'https://github.com/{0}.git\', \'gl\': \'https://gitlab.com/{0}.git\', \'bb\': \'https://bitbucket.org/{0}\'}}\nDEBUG cookiecutter.repository: Determining repo directory for template: tests/fake-repo-pre/\nDEBUG cookiecutter.repository: Expanded template: tests/fake-repo-pre/\nDEBUG cookiecutter.vcs: identify_repo called with repo_url: tests/fake-repo-pre/\nDEBUG cookiecutter.vcs: Identifying repo type for URL: tests/fake-repo-pre/\nDEBUG cookiecutter.vcs: Identified as local directory: tests/fake-repo-pre/\nDEBUG cookiecutter.repository: Identified repo_type: file, repo_url: tests/fake-repo-pre/\nDEBUG cookiecutter.repository: Identified repo_type: file, repo_url: tests/fake-repo-pre/\nINFO cookiecutter.main: Template directory determined: /testbed/tests/fake-repo-pre\nINFO cookiecutter.main: Running pre-prompt hook\nDEBUG cookiecutter.hooks: No pre_prompt hook found\nDEBUG cookiecutter.main: Context file: /testbed/tests/fake-repo-pre/cookiecutter.json\nINFO cookiecutter.main: Loading context from replay\nERROR cookiecutter.main: Error during cookiecutter invocation: [Errno 2] No such file or directory: \'/tmp/pytest-of-root/pytest-0/test_cli_exit_on_noinput_and_r0/home/.cookiecutter_replay/tests/fake-repo-pre/.json\'\nTraceback (most recent call last):\n  File "/testbed/cookiecutter/main.py", line 98, in cookiecutter_invocation\n    context = load(config_dict[\'replay_dir\'], template)\n  File "/testbed/cookiecutter/replay.py", line 37, in load\n    with open(file_path, \'r\') as f:\nFileNotFoundError: [Errno 2] No such file or directory: \'/tmp/pytest-of-root/pytest-0/test_cli_exit_on_noinput_and_r0/home/.cookiecutter_replay/tests/fake-repo-pre/.json\'\nError: [Errno 2] No such file or directory: \'/tmp/pytest-of-root/pytest-0/test_cli_exit_on_noinput_and_r0/home/.cookiecutter_replay/tests/fake-repo-pre/.json\'\nError type: FileNotFoundError\nTraceback (most recent call last):\n  File "/testbed/cookiecutter/cli.py", line 112, in main\n    result = cookiecutter_invocation(\n  File "/testbed/cookiecutter/main.py", line 98, in cookiecutter_invocation\n    context = load(config_dict[\'replay_dir\'], template)\n  File "/testbed/cookiecutter/replay.py", line 37, in load\n    with open(file_path, \'r\') as f:\nFileNotFoundError: [Errno 2] No such file or directory: \'/tmp/pytest-of-root/pytest-0/test_cli_exit_on_noinput_and_r0/home/.cookiecutter_replay/tests/fake-repo-pre/.json\'\n\n' = .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]
mocker = 
cli_runner = .cli_main at 0x7f92d207eef0>
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
E       assert 1 == 0
E        +  where 1 = .exit_code

tests/test_cli.py:226: 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]
mocker = 
cli_runner = .cli_main at 0x7f92d207eef0>
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
E       assert 1 == 0
E        +  where 1 = .exit_code

tests/test_cli.py:226: 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 0x7f92d207eef0>
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 0x7f92d207eef0>
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 0x7f92d207eef0>
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 0x7f92d207eef0>
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]
mocker = 
cli_runner = .cli_main at 0x7f92d207eef0>
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
E       assert 1 == 0
E        +  where 1 = .exit_code

tests/test_cli.py:284: AssertionError

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

test_cli.py::test_cli_output_dir[--output-dir]
mocker = 
cli_runner = .cli_main at 0x7f92d207eef0>
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
E       assert 1 == 0
E        +  where 1 = .exit_code

tests/test_cli.py:284: AssertionError

test_cli.py::test_cli_help[help]

test_cli.py::test_cli_help[help]
cli_runner = .cli_main at 0x7f92d207eef0>
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
mocker = 
cli_runner = .cli_main at 0x7f92d207eef0>
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
E       assert 1 == 0
E        +  where 1 = .exit_code

tests/test_cli.py:329: AssertionError

test_cli.py::test_default_user_config_overwrite

test_cli.py::test_default_user_config_overwrite
mocker = 
cli_runner = .cli_main at 0x7f92d207eef0>
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
E       assert 1 == 0
E        +  where 1 = .exit_code

tests/test_cli.py:360: AssertionError

test_cli.py::test_default_user_config

test_cli.py::test_default_user_config
mocker = 
cli_runner = .cli_main at 0x7f92d207eef0>

    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
E       assert 1 == 0
E        +  where 1 = .exit_code

tests/test_cli.py:386: 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 0x7f92d207eef0>

    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 'Invoking cookiecutter with template: tests/undefined-variable/file-name/\nINFO: Starting cookiecutter invocation with template: tests/undefined-variable/file-name/\nINFO: Template directory determined: /testbed/tests/undefined-variable/file-name\nINFO: Running pre-prompt hook\nINFO: Generating context with no input\nERROR: Error during cookiecutter invocation: choose_nested_template() missing 1 required positional argument: \'repo_dir\'\nTraceback (most recent call last):\n  File "/testbed/cookiecutter/main.py", line 120, in cookiecutter_invocation\n    nested_template = choose_nested_template(context)\nTypeError: choose_nested_template() missing 1 required positional argument: \'repo_dir\'\nError: choose_nested_template() missing 1 required positional argument: \'repo_dir\'\nError type: TypeError\n'
E        +  where 'Invoking cookiecutter with template: tests/undefined-variable/file-name/\nINFO: Starting cookiecutter invocation with template: tests/undefined-variable/file-name/\nINFO: Template directory determined: /testbed/tests/undefined-variable/file-name\nINFO: Running pre-prompt hook\nINFO: Generating context with no input\nERROR: Error during cookiecutter invocation: choose_nested_template() missing 1 required positional argument: \'repo_dir\'\nTraceback (most recent call last):\n  File "/testbed/cookiecutter/main.py", line 120, in cookiecutter_invocation\n    nested_template = choose_nested_template(context)\nTypeError: choose_nested_template() missing 1 required positional argument: \'repo_dir\'\nError: choose_nested_template() missing 1 required positional argument: \'repo_dir\'\nError type: TypeError\n' = .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 0x7f92d207eef0>

    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 'Invoking cookiecutter with template: tests/test-extensions/unknown/\nINFO: Starting cookiecutter invocation with template: tests/test-extensions/unknown/\nINFO: Template directory determined: /testbed/tests/test-extensions/unknown\nINFO: Running pre-prompt hook\nINFO: Generating context with no input\nERROR: Error during cookiecutter invocation: choose_nested_template() missing 1 required positional argument: \'repo_dir\'\nTraceback (most recent call last):\n  File "/testbed/cookiecutter/main.py", line 120, in cookiecutter_invocation\n    nested_template = choose_nested_template(context)\nTypeError: choose_nested_template() missing 1 required positional argument: \'repo_dir\'\nError: choose_nested_template() missing 1 required positional argument: \'repo_dir\'\nError type: TypeError\n'
E        +  where 'Invoking cookiecutter with template: tests/test-extensions/unknown/\nINFO: Starting cookiecutter invocation with template: tests/test-extensions/unknown/\nINFO: Template directory determined: /testbed/tests/test-extensions/unknown\nINFO: Running pre-prompt hook\nINFO: Generating context with no input\nERROR: Error during cookiecutter invocation: choose_nested_template() missing 1 required positional argument: \'repo_dir\'\nTraceback (most recent call last):\n  File "/testbed/cookiecutter/main.py", line 120, in cookiecutter_invocation\n    nested_template = choose_nested_template(context)\nTypeError: choose_nested_template() missing 1 required positional argument: \'repo_dir\'\nError: choose_nested_template() missing 1 required positional argument: \'repo_dir\'\nError type: TypeError\n' = .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 0x7f92d207eef0>

    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 0x7f92d207eef0>

    @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 0x7f92d207eef0>

    @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 0x7f92d207eef0>
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 0x7f92d207eef0>
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 0x7f92d207eef0>
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  .git\n  tests\n  cookiecutter\n  .venv\n  cookiecutter.egg-info\n  .github\n  logo\n  docs\n  fake-project\n'
E        +  where 'Installed templates:\n  .git\n  tests\n  cookiecutter\n  .venv\n  cookiecutter.egg-info\n  .github\n  logo\n  docs\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 0x7f92d207eef0>
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 0x7f92d207eef0>

    @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]
mocker = 
cli_runner = .cli_main at 0x7f92d207eef0>
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
E       assert 1 == 0
E        +  where 1 = .exit_code

tests/test_cli.py:656: 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]
mocker = 
cli_runner = .cli_main at 0x7f92d207eef0>
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
E       assert 1 == 0
E        +  where 1 = .exit_code

tests/test_cli.py:656: 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]
mocker = 
cli_runner = .cli_main at 0x7f92d207eef0>
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
E       assert 1 == 0
E        +  where 1 = .exit_code

tests/test_cli.py:656: 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]
mocker = 
cli_runner = .cli_main at 0x7f92d207eef0>
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
E       assert 1 == 0
E        +  where 1 = .exit_code

tests/test_cli.py:656: 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]
mocker = 
cli_runner = .cli_main at 0x7f92d207eef0>
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
E       assert 1 == 0
E        +  where 1 = .exit_code

tests/test_cli.py:656: 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]
mocker = 
cli_runner = .cli_main at 0x7f92d207eef0>
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
E       assert 1 == 0
E        +  where 1 = .exit_code

tests/test_cli.py:656: 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]
mocker = 
cli_runner = .cli_main at 0x7f92d207eef0>
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
E       assert 1 == 0
E        +  where 1 = .exit_code

tests/test_cli.py:656: 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]
mocker = 
cli_runner = .cli_main at 0x7f92d207eef0>
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
E       assert 1 == 0
E        +  where 1 = .exit_code

tests/test_cli.py:656: AssertionError

test_cli.py::test_cli_with_pre_prompt_hook

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

    @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 0x7f92d1dce4a0>
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: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
cookiecutter/main.py:55: in cookiecutter
    return cookiecutter_invocation(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

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_invocation(
        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
    ):
        if template is None:
            raise ValueError("Template argument cannot be None")
        try:
            logger.info(f"Starting cookiecutter invocation with template: {template}")
            # Get user configuration
            config_dict = get_user_config(config_file=config_file, default_config=default_config)
            logger.debug(f"User configuration: {config_dict}")

            # 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,
                abbreviations=config_dict.get('abbreviations', {})
            )
            logger.info(f"Template directory determined: {repo_dir}")

            # Run pre-prompt hook if accept_hooks is True
            if accept_hooks:
                logger.info("Running pre-prompt hook")
                run_pre_prompt_hook(repo_dir, config_dict)

            # Prompt for template configuration
            context_file = os.path.join(repo_dir, 'cookiecutter.json')
            logger.debug(f"Context file: {context_file}")
            if replay:
                logger.info("Loading context from replay")
                context = load(config_dict['replay_dir'], template)
            elif no_input:
                logger.info("Generating context with no input")
                context = generate_context(
                    context_file=context_file,
                    default_context=config_dict['default_context'],
                    extra_context=extra_context,
                )
            else:
                logger.info("Prompting for config")
                context = prompt_for_config(context_file, extra_context)
            logger.debug(f"Context: {context}")

            # Apply any overwrites to the context
            if 'cookiecutter' not in context:
                context['cookiecutter'] = {}
            context['cookiecutter'] = apply_overwrites_to_context(
                context['cookiecutter'], config_dict.get('overwrite_context', {})
            )
            logger.debug(f"Context after overwrites: {context}")

            # Choose nested template if applicable
>           nested_template = choose_nested_template(context)
E           TypeError: choose_nested_template() missing 1 required positional argument: 'repo_dir'

cookiecutter/main.py:120: 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: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
cookiecutter/main.py:55: in cookiecutter
    return cookiecutter_invocation(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

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_invocation(
        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
    ):
        if template is None:
            raise ValueError("Template argument cannot be None")
        try:
            logger.info(f"Starting cookiecutter invocation with template: {template}")
            # Get user configuration
            config_dict = get_user_config(config_file=config_file, default_config=default_config)
            logger.debug(f"User configuration: {config_dict}")

            # 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,
                abbreviations=config_dict.get('abbreviations', {})
            )
            logger.info(f"Template directory determined: {repo_dir}")

            # Run pre-prompt hook if accept_hooks is True
            if accept_hooks:
                logger.info("Running pre-prompt hook")
                run_pre_prompt_hook(repo_dir, config_dict)

            # Prompt for template configuration
            context_file = os.path.join(repo_dir, 'cookiecutter.json')
            logger.debug(f"Context file: {context_file}")
            if replay:
                logger.info("Loading context from replay")
                context = load(config_dict['replay_dir'], template)
            elif no_input:
                logger.info("Generating context with no input")
                context = generate_context(
                    context_file=context_file,
                    default_context=config_dict['default_context'],
                    extra_context=extra_context,
                )
            else:
                logger.info("Prompting for config")
                context = prompt_for_config(context_file, extra_context)
            logger.debug(f"Context: {context}")

            # Apply any overwrites to the context
            if 'cookiecutter' not in context:
                context['cookiecutter'] = {}
            context['cookiecutter'] = apply_overwrites_to_context(
                context['cookiecutter'], config_dict.get('overwrite_context', {})
            )
            logger.debug(f"Context after overwrites: {context}")

            # Choose nested template if applicable
>           nested_template = choose_nested_template(context)
E           TypeError: choose_nested_template() missing 1 required positional argument: 'repo_dir'

cookiecutter/main.py:120: 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: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
cookiecutter/main.py:55: in cookiecutter
    return cookiecutter_invocation(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

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_invocation(
        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
    ):
        if template is None:
            raise ValueError("Template argument cannot be None")
        try:
            logger.info(f"Starting cookiecutter invocation with template: {template}")
            # Get user configuration
            config_dict = get_user_config(config_file=config_file, default_config=default_config)
            logger.debug(f"User configuration: {config_dict}")

            # 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,
                abbreviations=config_dict.get('abbreviations', {})
            )
            logger.info(f"Template directory determined: {repo_dir}")

            # Run pre-prompt hook if accept_hooks is True
            if accept_hooks:
                logger.info("Running pre-prompt hook")
                run_pre_prompt_hook(repo_dir, config_dict)

            # Prompt for template configuration
            context_file = os.path.join(repo_dir, 'cookiecutter.json')
            logger.debug(f"Context file: {context_file}")
            if replay:
                logger.info("Loading context from replay")
                context = load(config_dict['replay_dir'], template)
            elif no_input:
                logger.info("Generating context with no input")
                context = generate_context(
                    context_file=context_file,
                    default_context=config_dict['default_context'],
                    extra_context=extra_context,
                )
            else:
                logger.info("Prompting for config")
                context = prompt_for_config(context_file, extra_context)
            logger.debug(f"Context: {context}")

            # Apply any overwrites to the context
            if 'cookiecutter' not in context:
                context['cookiecutter'] = {}
            context['cookiecutter'] = apply_overwrites_to_context(
                context['cookiecutter'], config_dict.get('overwrite_context', {})
            )
            logger.debug(f"Context after overwrites: {context}")

            # Choose nested template if applicable
>           nested_template = choose_nested_template(context)
E           TypeError: choose_nested_template() missing 1 required positional argument: 'repo_dir'

cookiecutter/main.py:120: 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: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
cookiecutter/main.py:55: in cookiecutter
    return cookiecutter_invocation(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

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_invocation(
        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
    ):
        if template is None:
            raise ValueError("Template argument cannot be None")
        try:
            logger.info(f"Starting cookiecutter invocation with template: {template}")
            # Get user configuration
            config_dict = get_user_config(config_file=config_file, default_config=default_config)
            logger.debug(f"User configuration: {config_dict}")

            # 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,
                abbreviations=config_dict.get('abbreviations', {})
            )
            logger.info(f"Template directory determined: {repo_dir}")

            # Run pre-prompt hook if accept_hooks is True
            if accept_hooks:
                logger.info("Running pre-prompt hook")
                run_pre_prompt_hook(repo_dir, config_dict)

            # Prompt for template configuration
            context_file = os.path.join(repo_dir, 'cookiecutter.json')
            logger.debug(f"Context file: {context_file}")
            if replay:
                logger.info("Loading context from replay")
                context = load(config_dict['replay_dir'], template)
            elif no_input:
                logger.info("Generating context with no input")
                context = generate_context(
                    context_file=context_file,
                    default_context=config_dict['default_context'],
                    extra_context=extra_context,
                )
            else:
                logger.info("Prompting for config")
                context = prompt_for_config(context_file, extra_context)
            logger.debug(f"Context: {context}")

            # Apply any overwrites to the context
            if 'cookiecutter' not in context:
                context['cookiecutter'] = {}
            context['cookiecutter'] = apply_overwrites_to_context(
                context['cookiecutter'], config_dict.get('overwrite_context', {})
            )
            logger.debug(f"Context after overwrites: {context}")

            # Choose nested template if applicable
>           nested_template = choose_nested_template(context)
E           TypeError: choose_nested_template() missing 1 required positional argument: 'repo_dir'

cookiecutter/main.py:120: 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: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
cookiecutter/main.py:55: in cookiecutter
    return cookiecutter_invocation(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

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_invocation(
        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
    ):
        if template is None:
            raise ValueError("Template argument cannot be None")
        try:
            logger.info(f"Starting cookiecutter invocation with template: {template}")
            # Get user configuration
            config_dict = get_user_config(config_file=config_file, default_config=default_config)
            logger.debug(f"User configuration: {config_dict}")

            # 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,
                abbreviations=config_dict.get('abbreviations', {})
            )
            logger.info(f"Template directory determined: {repo_dir}")

            # Run pre-prompt hook if accept_hooks is True
            if accept_hooks:
                logger.info("Running pre-prompt hook")
                run_pre_prompt_hook(repo_dir, config_dict)

            # Prompt for template configuration
            context_file = os.path.join(repo_dir, 'cookiecutter.json')
            logger.debug(f"Context file: {context_file}")
            if replay:
                logger.info("Loading context from replay")
                context = load(config_dict['replay_dir'], template)
            elif no_input:
                logger.info("Generating context with no input")
                context = generate_context(
                    context_file=context_file,
                    default_context=config_dict['default_context'],
                    extra_context=extra_context,
                )
            else:
                logger.info("Prompting for config")
                context = prompt_for_config(context_file, extra_context)
            logger.debug(f"Context: {context}")

            # Apply any overwrites to the context
            if 'cookiecutter' not in context:
                context['cookiecutter'] = {}
            context['cookiecutter'] = apply_overwrites_to_context(
                context['cookiecutter'], config_dict.get('overwrite_context', {})
            )
            logger.debug(f"Context after overwrites: {context}")

            # Choose nested template if applicable
>           nested_template = choose_nested_template(context)
E           TypeError: choose_nested_template() missing 1 required positional argument: 'repo_dir'

cookiecutter/main.py:120: 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: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
cookiecutter/main.py:55: in cookiecutter
    return cookiecutter_invocation(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

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_invocation(
        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
    ):
        if template is None:
            raise ValueError("Template argument cannot be None")
        try:
            logger.info(f"Starting cookiecutter invocation with template: {template}")
            # Get user configuration
            config_dict = get_user_config(config_file=config_file, default_config=default_config)
            logger.debug(f"User configuration: {config_dict}")

            # 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,
                abbreviations=config_dict.get('abbreviations', {})
            )
            logger.info(f"Template directory determined: {repo_dir}")

            # Run pre-prompt hook if accept_hooks is True
            if accept_hooks:
                logger.info("Running pre-prompt hook")
                run_pre_prompt_hook(repo_dir, config_dict)

            # Prompt for template configuration
            context_file = os.path.join(repo_dir, 'cookiecutter.json')
            logger.debug(f"Context file: {context_file}")
            if replay:
                logger.info("Loading context from replay")
                context = load(config_dict['replay_dir'], template)
            elif no_input:
                logger.info("Generating context with no input")
                context = generate_context(
                    context_file=context_file,
                    default_context=config_dict['default_context'],
                    extra_context=extra_context,
                )
            else:
                logger.info("Prompting for config")
                context = prompt_for_config(context_file, extra_context)
            logger.debug(f"Context: {context}")

            # Apply any overwrites to the context
            if 'cookiecutter' not in context:
                context['cookiecutter'] = {}
            context['cookiecutter'] = apply_overwrites_to_context(
                context['cookiecutter'], config_dict.get('overwrite_context', {})
            )
            logger.debug(f"Context after overwrites: {context}")

            # Choose nested template if applicable
>           nested_template = choose_nested_template(context)
E           TypeError: choose_nested_template() missing 1 required positional argument: 'repo_dir'

cookiecutter/main.py:120: 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: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
cookiecutter/main.py:55: in cookiecutter
    return cookiecutter_invocation(
cookiecutter/main.py:77: in cookiecutter_invocation
    repo_dir, cleanup = determine_repo_dir(
cookiecutter/repository.py:105: in determine_repo_dir
    repo_dir = clone(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

repo_url = 'tests/files/fake-repo-tmpl.zip', checkout = None
clone_to_dir = '/tmp/pytest-of-root/pytest-0/test_cookiecutter_template_cle0/home/.cookiecutters'
no_input = True, password = None

    def clone(repo_url: str, checkout: Optional[str]=None, clone_to_dir:
        'os.PathLike[str]'='.', no_input: bool=False, password: Optional[str]=None):
        """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.")
E           cookiecutter.exceptions.VCSNotInstalled: zip is not installed.

cookiecutter/vcs.py:94: VCSNotInstalled

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 0x7f92d2bf8700>

    @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: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
cookiecutter/main.py:55: in cookiecutter
    return cookiecutter_invocation(
cookiecutter/main.py:108: in cookiecutter_invocation
    context = prompt_for_config(context_file, extra_context)
cookiecutter/prompt.py:238: in prompt_for_config
    env = create_env_with_context(context)
cookiecutter/utils.py:88: in create_env_with_context
    env = StrictEnvironment(context=context)
cookiecutter/environment.py:56: in __init__
    super().__init__(undefined=StrictUndefined, **kwargs)
cookiecutter/environment.py:28: in __init__
    extensions = default_extensions + self._read_extensions(context)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = 
context = '/testbed/tests/fake-repo-pre/cookiecutter.json'

    def _read_extensions(self, context):
        """Return list of extensions as str to be passed on to the Jinja2 env.

        If context does not contain the relevant info, return an empty
        list instead.
        """
>       extensions = context.get('cookiecutter', {}).get('_extensions', [])
E       AttributeError: 'str' object has no attribute 'get'

cookiecutter/environment.py:40: AttributeError

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 0x7f92d2ce8130>

    @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: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
cookiecutter/main.py:55: in cookiecutter
    return cookiecutter_invocation(
cookiecutter/main.py:108: in cookiecutter_invocation
    context = prompt_for_config(context_file, extra_context)
cookiecutter/prompt.py:238: in prompt_for_config
    env = create_env_with_context(context)
cookiecutter/utils.py:88: in create_env_with_context
    env = StrictEnvironment(context=context)
cookiecutter/environment.py:56: in __init__
    super().__init__(undefined=StrictUndefined, **kwargs)
cookiecutter/environment.py:28: in __init__
    extensions = default_extensions + self._read_extensions(context)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = 
context = '/testbed/tests/fake-repo-pre/cookiecutter.json'

    def _read_extensions(self, context):
        """Return list of extensions as str to be passed on to the Jinja2 env.

        If context does not contain the relevant info, return an empty
        list instead.
        """
>       extensions = context.get('cookiecutter', {}).get('_extensions', [])
E       AttributeError: 'str' object has no attribute 'get'

cookiecutter/environment.py:40: AttributeError

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: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
cookiecutter/main.py:55: in cookiecutter
    return cookiecutter_invocation(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

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_invocation(
        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
    ):
        if template is None:
            raise ValueError("Template argument cannot be None")
        try:
            logger.info(f"Starting cookiecutter invocation with template: {template}")
            # Get user configuration
            config_dict = get_user_config(config_file=config_file, default_config=default_config)
            logger.debug(f"User configuration: {config_dict}")

            # 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,
                abbreviations=config_dict.get('abbreviations', {})
            )
            logger.info(f"Template directory determined: {repo_dir}")

            # Run pre-prompt hook if accept_hooks is True
            if accept_hooks:
                logger.info("Running pre-prompt hook")
                run_pre_prompt_hook(repo_dir, config_dict)

            # Prompt for template configuration
            context_file = os.path.join(repo_dir, 'cookiecutter.json')
            logger.debug(f"Context file: {context_file}")
            if replay:
                logger.info("Loading context from replay")
                context = load(config_dict['replay_dir'], template)
            elif no_input:
                logger.info("Generating context with no input")
                context = generate_context(
                    context_file=context_file,
                    default_context=config_dict['default_context'],
                    extra_context=extra_context,
                )
            else:
                logger.info("Prompting for config")
                context = prompt_for_config(context_file, extra_context)
            logger.debug(f"Context: {context}")

            # Apply any overwrites to the context
            if 'cookiecutter' not in context:
                context['cookiecutter'] = {}
            context['cookiecutter'] = apply_overwrites_to_context(
                context['cookiecutter'], config_dict.get('overwrite_context', {})
            )
            logger.debug(f"Context after overwrites: {context}")

            # Choose nested template if applicable
>           nested_template = choose_nested_template(context)
E           TypeError: choose_nested_template() missing 1 required positional argument: 'repo_dir'

cookiecutter/main.py:120: 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: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
cookiecutter/main.py:55: in cookiecutter
    return cookiecutter_invocation(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

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_invocation(
        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
    ):
        if template is None:
            raise ValueError("Template argument cannot be None")
        try:
            logger.info(f"Starting cookiecutter invocation with template: {template}")
            # Get user configuration
            config_dict = get_user_config(config_file=config_file, default_config=default_config)
            logger.debug(f"User configuration: {config_dict}")

            # 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,
                abbreviations=config_dict.get('abbreviations', {})
            )
            logger.info(f"Template directory determined: {repo_dir}")

            # Run pre-prompt hook if accept_hooks is True
            if accept_hooks:
                logger.info("Running pre-prompt hook")
                run_pre_prompt_hook(repo_dir, config_dict)

            # Prompt for template configuration
            context_file = os.path.join(repo_dir, 'cookiecutter.json')
            logger.debug(f"Context file: {context_file}")
            if replay:
                logger.info("Loading context from replay")
                context = load(config_dict['replay_dir'], template)
            elif no_input:
                logger.info("Generating context with no input")
                context = generate_context(
                    context_file=context_file,
                    default_context=config_dict['default_context'],
                    extra_context=extra_context,
                )
            else:
                logger.info("Prompting for config")
                context = prompt_for_config(context_file, extra_context)
            logger.debug(f"Context: {context}")

            # Apply any overwrites to the context
            if 'cookiecutter' not in context:
                context['cookiecutter'] = {}
            context['cookiecutter'] = apply_overwrites_to_context(
                context['cookiecutter'], config_dict.get('overwrite_context', {})
            )
            logger.debug(f"Context after overwrites: {context}")

            # Choose nested template if applicable
>           nested_template = choose_nested_template(context)
E           TypeError: choose_nested_template() missing 1 required positional argument: 'repo_dir'

cookiecutter/main.py:120: 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: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
cookiecutter/main.py:55: in cookiecutter
    return cookiecutter_invocation(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

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_invocation(
        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
    ):
        if template is None:
            raise ValueError("Template argument cannot be None")
        try:
            logger.info(f"Starting cookiecutter invocation with template: {template}")
            # Get user configuration
            config_dict = get_user_config(config_file=config_file, default_config=default_config)
            logger.debug(f"User configuration: {config_dict}")

            # 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,
                abbreviations=config_dict.get('abbreviations', {})
            )
            logger.info(f"Template directory determined: {repo_dir}")

            # Run pre-prompt hook if accept_hooks is True
            if accept_hooks:
                logger.info("Running pre-prompt hook")
                run_pre_prompt_hook(repo_dir, config_dict)

            # Prompt for template configuration
            context_file = os.path.join(repo_dir, 'cookiecutter.json')
            logger.debug(f"Context file: {context_file}")
            if replay:
                logger.info("Loading context from replay")
                context = load(config_dict['replay_dir'], template)
            elif no_input:
                logger.info("Generating context with no input")
                context = generate_context(
                    context_file=context_file,
                    default_context=config_dict['default_context'],
                    extra_context=extra_context,
                )
            else:
                logger.info("Prompting for config")
                context = prompt_for_config(context_file, extra_context)
            logger.debug(f"Context: {context}")

            # Apply any overwrites to the context
            if 'cookiecutter' not in context:
                context['cookiecutter'] = {}
            context['cookiecutter'] = apply_overwrites_to_context(
                context['cookiecutter'], config_dict.get('overwrite_context', {})
            )
            logger.debug(f"Context after overwrites: {context}")

            # Choose nested template if applicable
>           nested_template = choose_nested_template(context)
E           TypeError: choose_nested_template() missing 1 required positional argument: 'repo_dir'

cookiecutter/main.py:120: 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: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
cookiecutter/main.py:55: in cookiecutter
    return cookiecutter_invocation(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

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_invocation(
        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
    ):
        if template is None:
            raise ValueError("Template argument cannot be None")
        try:
            logger.info(f"Starting cookiecutter invocation with template: {template}")
            # Get user configuration
            config_dict = get_user_config(config_file=config_file, default_config=default_config)
            logger.debug(f"User configuration: {config_dict}")

            # 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,
                abbreviations=config_dict.get('abbreviations', {})
            )
            logger.info(f"Template directory determined: {repo_dir}")

            # Run pre-prompt hook if accept_hooks is True
            if accept_hooks:
                logger.info("Running pre-prompt hook")
                run_pre_prompt_hook(repo_dir, config_dict)

            # Prompt for template configuration
            context_file = os.path.join(repo_dir, 'cookiecutter.json')
            logger.debug(f"Context file: {context_file}")
            if replay:
                logger.info("Loading context from replay")
                context = load(config_dict['replay_dir'], template)
            elif no_input:
                logger.info("Generating context with no input")
                context = generate_context(
                    context_file=context_file,
                    default_context=config_dict['default_context'],
                    extra_context=extra_context,
                )
            else:
                logger.info("Prompting for config")
                context = prompt_for_config(context_file, extra_context)
            logger.debug(f"Context: {context}")

            # Apply any overwrites to the context
            if 'cookiecutter' not in context:
                context['cookiecutter'] = {}
            context['cookiecutter'] = apply_overwrites_to_context(
                context['cookiecutter'], config_dict.get('overwrite_context', {})
            )
            logger.debug(f"Context after overwrites: {context}")

            # Choose nested template if applicable
>           nested_template = choose_nested_template(context)
E           TypeError: choose_nested_template() missing 1 required positional argument: 'repo_dir'

cookiecutter/main.py:120: 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: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
cookiecutter/main.py:55: in cookiecutter
    return cookiecutter_invocation(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

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_invocation(
        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
    ):
        if template is None:
            raise ValueError("Template argument cannot be None")
        try:
            logger.info(f"Starting cookiecutter invocation with template: {template}")
            # Get user configuration
            config_dict = get_user_config(config_file=config_file, default_config=default_config)
            logger.debug(f"User configuration: {config_dict}")

            # 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,
                abbreviations=config_dict.get('abbreviations', {})
            )
            logger.info(f"Template directory determined: {repo_dir}")

            # Run pre-prompt hook if accept_hooks is True
            if accept_hooks:
                logger.info("Running pre-prompt hook")
                run_pre_prompt_hook(repo_dir, config_dict)

            # Prompt for template configuration
            context_file = os.path.join(repo_dir, 'cookiecutter.json')
            logger.debug(f"Context file: {context_file}")
            if replay:
                logger.info("Loading context from replay")
                context = load(config_dict['replay_dir'], template)
            elif no_input:
                logger.info("Generating context with no input")
                context = generate_context(
                    context_file=context_file,
                    default_context=config_dict['default_context'],
                    extra_context=extra_context,
                )
            else:
                logger.info("Prompting for config")
                context = prompt_for_config(context_file, extra_context)
            logger.debug(f"Context: {context}")

            # Apply any overwrites to the context
            if 'cookiecutter' not in context:
                context['cookiecutter'] = {}
            context['cookiecutter'] = apply_overwrites_to_context(
                context['cookiecutter'], config_dict.get('overwrite_context', {})
            )
            logger.debug(f"Context after overwrites: {context}")

            # Choose nested template if applicable
>           nested_template = choose_nested_template(context)
E           TypeError: choose_nested_template() missing 1 required positional argument: 'repo_dir'

cookiecutter/main.py:120: 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: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
cookiecutter/main.py:55: in cookiecutter
    return cookiecutter_invocation(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

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_invocation(
        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
    ):
        if template is None:
            raise ValueError("Template argument cannot be None")
        try:
            logger.info(f"Starting cookiecutter invocation with template: {template}")
            # Get user configuration
            config_dict = get_user_config(config_file=config_file, default_config=default_config)
            logger.debug(f"User configuration: {config_dict}")

            # 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,
                abbreviations=config_dict.get('abbreviations', {})
            )
            logger.info(f"Template directory determined: {repo_dir}")

            # Run pre-prompt hook if accept_hooks is True
            if accept_hooks:
                logger.info("Running pre-prompt hook")
                run_pre_prompt_hook(repo_dir, config_dict)

            # Prompt for template configuration
            context_file = os.path.join(repo_dir, 'cookiecutter.json')
            logger.debug(f"Context file: {context_file}")
            if replay:
                logger.info("Loading context from replay")
                context = load(config_dict['replay_dir'], template)
            elif no_input:
                logger.info("Generating context with no input")
                context = generate_context(
                    context_file=context_file,
                    default_context=config_dict['default_context'],
                    extra_context=extra_context,
                )
            else:
                logger.info("Prompting for config")
                context = prompt_for_config(context_file, extra_context)
            logger.debug(f"Context: {context}")

            # Apply any overwrites to the context
            if 'cookiecutter' not in context:
                context['cookiecutter'] = {}
            context['cookiecutter'] = apply_overwrites_to_context(
                context['cookiecutter'], config_dict.get('overwrite_context', {})
            )
            logger.debug(f"Context after overwrites: {context}")

            # Choose nested template if applicable
>           nested_template = choose_nested_template(context)
E           TypeError: choose_nested_template() missing 1 required positional argument: 'repo_dir'

cookiecutter/main.py:120: 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: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
cookiecutter/main.py:55: in cookiecutter
    return cookiecutter_invocation(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

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_invocation(
        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
    ):
        if template is None:
            raise ValueError("Template argument cannot be None")
        try:
            logger.info(f"Starting cookiecutter invocation with template: {template}")
            # Get user configuration
            config_dict = get_user_config(config_file=config_file, default_config=default_config)
            logger.debug(f"User configuration: {config_dict}")

            # 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,
                abbreviations=config_dict.get('abbreviations', {})
            )
            logger.info(f"Template directory determined: {repo_dir}")

            # Run pre-prompt hook if accept_hooks is True
            if accept_hooks:
                logger.info("Running pre-prompt hook")
                run_pre_prompt_hook(repo_dir, config_dict)

            # Prompt for template configuration
            context_file = os.path.join(repo_dir, 'cookiecutter.json')
            logger.debug(f"Context file: {context_file}")
            if replay:
                logger.info("Loading context from replay")
                context = load(config_dict['replay_dir'], template)
            elif no_input:
                logger.info("Generating context with no input")
                context = generate_context(
                    context_file=context_file,
                    default_context=config_dict['default_context'],
                    extra_context=extra_context,
                )
            else:
                logger.info("Prompting for config")
                context = prompt_for_config(context_file, extra_context)
            logger.debug(f"Context: {context}")

            # Apply any overwrites to the context
            if 'cookiecutter' not in context:
                context['cookiecutter'] = {}
            context['cookiecutter'] = apply_overwrites_to_context(
                context['cookiecutter'], config_dict.get('overwrite_context', {})
            )
            logger.debug(f"Context after overwrites: {context}")

            # Choose nested template if applicable
>           nested_template = choose_nested_template(context)
E           TypeError: choose_nested_template() missing 1 required positional argument: 'repo_dir'

cookiecutter/main.py:120: TypeError

test_exceptions.py::test_undefined_variable_to_str

test_exceptions.py::test_undefined_variable_to_str
def test_undefined_variable_to_str():
        """Verify string representation of errors formatted in expected form."""
        undefined_var_error = exceptions.UndefinedVariableInTemplate(
            'Beautiful is better than ugly',
            UndefinedError('Errors should never pass silently'),
            {'cookiecutter': {'foo': 'bar'}},
        )

        expected_str = (
            "Beautiful is better than ugly. "
            "Error message: Errors should never pass silently. "
            "Context: {'cookiecutter': {'foo': 'bar'}}"
        )

>       assert str(undefined_var_error) == expected_str
E       assert "Beautiful is better than ugly. Error message: Errors should never pass silently. Context: {'cookiecutter': {'foo': 'bar'}}. Template: None" == "Beautiful is better than ugly. Error message: Errors should never pass silently. Context: {'cookiecutter': {'foo': 'bar'}}"
E         
E         - Beautiful is better than ugly. Error message: Errors should never pass silently. Context: {'cookiecutter': {'foo': 'bar'}}
E         + Beautiful is better than ugly. Error message: Errors should never pass silently. Context: {'cookiecutter': {'foo': 'bar'}}. Template: None
E         ?                                                                                                                           ++++++++++++++++

tests/test_exceptions.py:22: AssertionError

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 0x7f92d25e5990>
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_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',
        )

        dir_contents = os.listdir('test_copy_without_render')

>       assert 'test_copy_without_render-not-rendered' in dir_contents
E       AssertionError: assert 'test_copy_without_render-not-rendered' in []

tests/test_generate_copy_without_render.py:44: AssertionError

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.
        """
        # Create necessary files for the test
        repo_dir = 'tests/test-generate-copy-without-render-override'
        os.makedirs(repo_dir, exist_ok=True)
        with open(os.path.join(repo_dir, 'README.txt'), 'w') as f:
            f.write('{{cookiecutter.render_test}}')
        with open(os.path.join(repo_dir, 'README.rst'), 'w') as f:
            f.write('{{cookiecutter.render_test}}')

        # 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=repo_dir,
        )

        # second run with override flag to True
        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',
                    ],
                }
            },
            overwrite_if_exists=True,
            repo_dir='tests/test-generate-copy-without-render',
        )

        dir_contents = os.listdir('test_copy_without_render')

>       assert 'test_copy_without_render-not-rendered' in dir_contents
E       AssertionError: assert 'test_copy_without_render-not-rendered' in []

tests/test_generate_copy_without_render_override.py:75: AssertionError

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\n  File "tests/files/syntax_error.txt", line 1')
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\n  File "tests/files/syntax_error.txt", line 1' = 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_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,
        )

        # assert 'Overwritting endline character with %s' in caplog.messages
        newline_file = Path(tmp_path, 'inputpizzä/simple-with-newline.txt')
        assert newline_file.is_file()
        assert newline_file.exists()

        with Path(newline_file).open(encoding='utf-8', newline='') as f:
            simple_text = f.readline()
>       assert simple_text == 'newline is LF\r\n'
E       AssertionError: assert 'newline is LF\n' == 'newline is LF\r\n'
E         
E         - newline is LF
E         ?              -
E         + newline is LF

tests/test_generate_files.py:99: AssertionError

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,
        )

        newline_file = Path(tmp_path, 'inputpizzä/simple-with-newline-crlf.txt')
        assert newline_file.is_file()
        assert newline_file.exists()

        with Path(newline_file).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_files.py:117: AssertionError

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,
        )

        assert Path(tmp_path, 'inputpermissions/simple.txt').is_file()

        # Verify source simple.txt should still be 0o644
        tests_simple_file = Path(
            'tests',
            'test-generate-files-permissions',
            'input{{cookiecutter.permissions}}',
            'simple.txt',
        )
        tests_simple_file_mode = tests_simple_file.stat().st_mode

        input_simple_file = Path(tmp_path, 'inputpermissions', 'simple.txt')
        input_simple_file_mode = input_simple_file.stat().st_mode
        assert tests_simple_file_mode == input_simple_file_mode

        assert Path(tmp_path, 'inputpermissions/script.sh').exists()
        assert Path(tmp_path, 'inputpermissions/script.sh').is_file()

        # Verify source script.sh should still be 0o755
        tests_script_file = Path(
            'tests',
            'test-generate-files-permissions',
            'input{{cookiecutter.permissions}}',
            'script.sh',
        )
        tests_script_file_mode = tests_script_file.stat().st_mode

        input_script_file = Path(tmp_path, 'inputpermissions', 'script.sh')
        input_script_file_mode = input_script_file.stat().st_mode
>       assert tests_script_file_mode == input_script_file_mode
E       assert 33261 == 33188

tests/test_generate_files.py:228: AssertionError

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,
        )

        assert Path(simple_file).is_file()
        assert Path(simple_file).exists()
        assert Path(simple_with_new_line_file).is_file()
        assert Path(simple_with_new_line_file).exists()

        simple_text = Path(simple_file).read_text(encoding='utf-8')
>       assert simple_text == 'temp'
E       AssertionError: assert 'I eat pizzä\n' == 'temp'
E         
E         - temp
E         + I eat pizzä

tests/test_generate_files.py:254: AssertionError

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):
E       Failed: DID NOT RAISE 

tests/test_generate_files.py:265: Failed

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:
E       Failed: DID NOT RAISE 

tests/test_generate_files.py:315: Failed

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:
E       Failed: DID NOT RAISE 

tests/test_generate_files.py:335: Failed

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:
E       Failed: DID NOT RAISE 

tests/test_generate_files.py:351: Failed

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:
E       Failed: DID NOT RAISE 

tests/test_generate_files.py:366: Failed

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):
E       Failed: DID NOT RAISE 

tests/test_generate_files.py:385: Failed

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:
E       Failed: DID NOT RAISE 

tests/test_generate_files.py:402: Failed

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: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
cookiecutter/generate.py:291: in generate_files
    project_dir = render_and_create_dir(
cookiecutter/generate.py:204: in render_and_create_dir
    rendered_dirname = name_tmpl.render(**context)
.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)