We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Add support for click 8.0.0
### Description:

We should add support to click 8.0.0, there are some breaking changes like #1558 


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `cookiecutter/prompt.py`
Content:
```
1 """Functions for prompting the user for project info."""
2 import json
3 from collections import OrderedDict
4 
5 import click
6 from jinja2.exceptions import UndefinedError
7 
8 from cookiecutter.environment import StrictEnvironment
9 from cookiecutter.exceptions import UndefinedVariableInTemplate
10 
11 
12 def read_user_variable(var_name, default_value):
13     """Prompt user for variable and return the entered value or given default.
14 
15     :param str var_name: Variable of the context to query the user
16     :param default_value: Value that will be returned if no input happens
17     """
18     # Please see https://click.palletsprojects.com/en/7.x/api/#click.prompt
19     return click.prompt(var_name, default=default_value)
20 
21 
22 def read_user_yes_no(question, default_value):
23     """Prompt the user to reply with 'yes' or 'no' (or equivalent values).
24 
25     Note:
26       Possible choices are 'true', '1', 'yes', 'y' or 'false', '0', 'no', 'n'
27 
28     :param str question: Question to the user
29     :param default_value: Value that will be returned if no input happens
30     """
31     # Please see https://click.palletsprojects.com/en/7.x/api/#click.prompt
32     return click.prompt(question, default=default_value, type=click.BOOL)
33 
34 
35 def read_repo_password(question):
36     """Prompt the user to enter a password.
37 
38     :param str question: Question to the user
39     """
40     # Please see https://click.palletsprojects.com/en/7.x/api/#click.prompt
41     return click.prompt(question, hide_input=True)
42 
43 
44 def read_user_choice(var_name, options):
45     """Prompt the user to choose from several options for the given variable.
46 
47     The first item will be returned if no input happens.
48 
49     :param str var_name: Variable as specified in the context
50     :param list options: Sequence of options that are available to select from
51     :return: Exactly one item of ``options`` that has been chosen by the user
52     """
53     # Please see https://click.palletsprojects.com/en/7.x/api/#click.prompt
54     if not isinstance(options, list):
55         raise TypeError
56 
57     if not options:
58         raise ValueError
59 
60     choice_map = OrderedDict(
61         ('{}'.format(i), value) for i, value in enumerate(options, 1)
62     )
63     choices = choice_map.keys()
64     default = '1'
65 
66     choice_lines = ['{} - {}'.format(*c) for c in choice_map.items()]
67     prompt = '\n'.join(
68         (
69             'Select {}:'.format(var_name),
70             '\n'.join(choice_lines),
71             'Choose from {}'.format(', '.join(choices)),
72         )
73     )
74 
75     user_choice = click.prompt(
76         prompt, type=click.Choice(choices), default=default, show_choices=False
77     )
78     return choice_map[user_choice]
79 
80 
81 def process_json(user_value):
82     """Load user-supplied value as a JSON dict.
83 
84     :param str user_value: User-supplied value to load as a JSON dict
85     """
86     try:
87         user_dict = json.loads(user_value, object_pairs_hook=OrderedDict)
88     except Exception:
89         # Leave it up to click to ask the user again
90         raise click.UsageError('Unable to decode to JSON.')
91 
92     if not isinstance(user_dict, dict):
93         # Leave it up to click to ask the user again
94         raise click.UsageError('Requires JSON dict.')
95 
96     return user_dict
97 
98 
99 def read_user_dict(var_name, default_value):
100     """Prompt the user to provide a dictionary of data.
101 
102     :param str var_name: Variable as specified in the context
103     :param default_value: Value that will be returned if no input is provided
104     :return: A Python dictionary to use in the context.
105     """
106     # Please see https://click.palletsprojects.com/en/7.x/api/#click.prompt
107     if not isinstance(default_value, dict):
108         raise TypeError
109 
110     default_display = 'default'
111 
112     user_value = click.prompt(
113         var_name, default=default_display, type=click.STRING, value_proc=process_json
114     )
115 
116     if user_value == default_display:
117         # Return the given default w/o any processing
118         return default_value
119     return user_value
120 
121 
122 def render_variable(env, raw, cookiecutter_dict):
123     """Render the next variable to be displayed in the user prompt.
124 
125     Inside the prompting taken from the cookiecutter.json file, this renders
126     the next variable. For example, if a project_name is "Peanut Butter
127     Cookie", the repo_name could be be rendered with:
128 
129         `{{ cookiecutter.project_name.replace(" ", "_") }}`.
130 
131     This is then presented to the user as the default.
132 
133     :param Environment env: A Jinja2 Environment object.
134     :param raw: The next value to be prompted for by the user.
135     :param dict cookiecutter_dict: The current context as it's gradually
136         being populated with variables.
137     :return: The rendered value for the default variable.
138     """
139     if raw is None:
140         return None
141     elif isinstance(raw, dict):
142         return {
143             render_variable(env, k, cookiecutter_dict): render_variable(
144                 env, v, cookiecutter_dict
145             )
146             for k, v in raw.items()
147         }
148     elif isinstance(raw, list):
149         return [render_variable(env, v, cookiecutter_dict) for v in raw]
150     elif not isinstance(raw, str):
151         raw = str(raw)
152 
153     template = env.from_string(raw)
154 
155     rendered_template = template.render(cookiecutter=cookiecutter_dict)
156     return rendered_template
157 
158 
159 def prompt_choice_for_config(cookiecutter_dict, env, key, options, no_input):
160     """Prompt user with a set of options to choose from.
161 
162     Each of the possible choices is rendered beforehand.
163     """
164     rendered_options = [render_variable(env, raw, cookiecutter_dict) for raw in options]
165 
166     if no_input:
167         return rendered_options[0]
168     return read_user_choice(key, rendered_options)
169 
170 
171 def prompt_for_config(context, no_input=False):
172     """Prompt user to enter a new config.
173 
174     :param dict context: Source for field names and sample values.
175     :param no_input: Prompt the user at command line for manual configuration?
176     """
177     cookiecutter_dict = OrderedDict([])
178     env = StrictEnvironment(context=context)
179 
180     # First pass: Handle simple and raw variables, plus choices.
181     # These must be done first because the dictionaries keys and
182     # values might refer to them.
183     for key, raw in context['cookiecutter'].items():
184         if key.startswith('_') and not key.startswith('__'):
185             cookiecutter_dict[key] = raw
186             continue
187         elif key.startswith('__'):
188             cookiecutter_dict[key] = render_variable(env, raw, cookiecutter_dict)
189             continue
190 
191         try:
192             if isinstance(raw, list):
193                 # We are dealing with a choice variable
194                 val = prompt_choice_for_config(
195                     cookiecutter_dict, env, key, raw, no_input
196                 )
197                 cookiecutter_dict[key] = val
198             elif not isinstance(raw, dict):
199                 # We are dealing with a regular variable
200                 val = render_variable(env, raw, cookiecutter_dict)
201 
202                 if not no_input:
203                     val = read_user_variable(key, val)
204 
205                 cookiecutter_dict[key] = val
206         except UndefinedError as err:
207             msg = "Unable to render variable '{}'".format(key)
208             raise UndefinedVariableInTemplate(msg, err, context)
209 
210     # Second pass; handle the dictionaries.
211     for key, raw in context['cookiecutter'].items():
212         # Skip private type dicts not ot be rendered.
213         if key.startswith('_') and not key.startswith('__'):
214             continue
215 
216         try:
217             if isinstance(raw, dict):
218                 # We are dealing with a dict variable
219                 val = render_variable(env, raw, cookiecutter_dict)
220 
221                 if not no_input and not key.startswith('__'):
222                     val = read_user_dict(key, val)
223 
224                 cookiecutter_dict[key] = val
225         except UndefinedError as err:
226             msg = "Unable to render variable '{}'".format(key)
227             raise UndefinedVariableInTemplate(msg, err, context)
228 
229     return cookiecutter_dict
230
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/cookiecutter/prompt.py b/cookiecutter/prompt.py
--- a/cookiecutter/prompt.py
+++ b/cookiecutter/prompt.py
@@ -1,4 +1,5 @@
 """Functions for prompting the user for project info."""
+import functools
 import json
 from collections import OrderedDict
 
@@ -78,11 +79,18 @@
     return choice_map[user_choice]
 
 
-def process_json(user_value):
+DEFAULT_DISPLAY = 'default'
+
+
+def process_json(user_value, default_value=None):
     """Load user-supplied value as a JSON dict.
 
     :param str user_value: User-supplied value to load as a JSON dict
     """
+    if user_value == DEFAULT_DISPLAY:
+        # Return the given default w/o any processing
+        return default_value
+
     try:
         user_dict = json.loads(user_value, object_pairs_hook=OrderedDict)
     except Exception:
@@ -107,15 +115,16 @@
     if not isinstance(default_value, dict):
         raise TypeError
 
-    default_display = 'default'
-
     user_value = click.prompt(
-        var_name, default=default_display, type=click.STRING, value_proc=process_json
+        var_name,
+        default=DEFAULT_DISPLAY,
+        type=click.STRING,
+        value_proc=functools.partial(process_json, default_value=default_value),
     )
 
-    if user_value == default_display:
-        # Return the given default w/o any processing
-        return default_value
+    if click.__version__.startswith("7.") and user_value == DEFAULT_DISPLAY:
+        # click 7.x does not invoke value_proc on the default value.
+        return default_value  # pragma: no cover
     return user_value

{"golden_diff": "diff --git a/cookiecutter/prompt.py b/cookiecutter/prompt.py\n--- a/cookiecutter/prompt.py\n+++ b/cookiecutter/prompt.py\n@@ -1,4 +1,5 @@\n \"\"\"Functions for prompting the user for project info.\"\"\"\n+import functools\n import json\n from collections import OrderedDict\n \n@@ -78,11 +79,18 @@\n     return choice_map[user_choice]\n \n \n-def process_json(user_value):\n+DEFAULT_DISPLAY = 'default'\n+\n+\n+def process_json(user_value, default_value=None):\n     \"\"\"Load user-supplied value as a JSON dict.\n \n     :param str user_value: User-supplied value to load as a JSON dict\n     \"\"\"\n+    if user_value == DEFAULT_DISPLAY:\n+        # Return the given default w/o any processing\n+        return default_value\n+\n     try:\n         user_dict = json.loads(user_value, object_pairs_hook=OrderedDict)\n     except Exception:\n@@ -107,15 +115,16 @@\n     if not isinstance(default_value, dict):\n         raise TypeError\n \n-    default_display = 'default'\n-\n     user_value = click.prompt(\n-        var_name, default=default_display, type=click.STRING, value_proc=process_json\n+        var_name,\n+        default=DEFAULT_DISPLAY,\n+        type=click.STRING,\n+        value_proc=functools.partial(process_json, default_value=default_value),\n     )\n \n-    if user_value == default_display:\n-        # Return the given default w/o any processing\n-        return default_value\n+    if click.__version__.startswith(\"7.\") and user_value == DEFAULT_DISPLAY:\n+        # click 7.x does not invoke value_proc on the default value.\n+        return default_value  # pragma: no cover\n     return user_value\n", "issue": "Add support for click 8.0.0\n### Description:\r\n\r\nWe should add support to click 8.0.0, there are some breaking changes like #1558 \r\n\n", "before_files": [{"content": "\"\"\"Functions for prompting the user for project info.\"\"\"\nimport json\nfrom collections import OrderedDict\n\nimport click\nfrom jinja2.exceptions import UndefinedError\n\nfrom cookiecutter.environment import StrictEnvironment\nfrom cookiecutter.exceptions import UndefinedVariableInTemplate\n\n\ndef read_user_variable(var_name, default_value):\n    \"\"\"Prompt user for variable and return the entered value or given default.\n\n    :param str var_name: Variable of the context to query the user\n    :param default_value: Value that will be returned if no input happens\n    \"\"\"\n    # Please see https://click.palletsprojects.com/en/7.x/api/#click.prompt\n    return click.prompt(var_name, default=default_value)\n\n\ndef read_user_yes_no(question, default_value):\n    \"\"\"Prompt the user to reply with 'yes' or 'no' (or equivalent values).\n\n    Note:\n      Possible choices are 'true', '1', 'yes', 'y' or 'false', '0', 'no', 'n'\n\n    :param str question: Question to the user\n    :param default_value: Value that will be returned if no input happens\n    \"\"\"\n    # Please see https://click.palletsprojects.com/en/7.x/api/#click.prompt\n    return click.prompt(question, default=default_value, type=click.BOOL)\n\n\ndef read_repo_password(question):\n    \"\"\"Prompt the user to enter a password.\n\n    :param str question: Question to the user\n    \"\"\"\n    # Please see https://click.palletsprojects.com/en/7.x/api/#click.prompt\n    return click.prompt(question, hide_input=True)\n\n\ndef read_user_choice(var_name, options):\n    \"\"\"Prompt the user to choose from several options for the given variable.\n\n    The first item will be returned if no input happens.\n\n    :param str var_name: Variable as specified in the context\n    :param list options: Sequence of options that are available to select from\n    :return: Exactly one item of ``options`` that has been chosen by the user\n    \"\"\"\n    # Please see https://click.palletsprojects.com/en/7.x/api/#click.prompt\n    if not isinstance(options, list):\n        raise TypeError\n\n    if not options:\n        raise ValueError\n\n    choice_map = OrderedDict(\n        ('{}'.format(i), value) for i, value in enumerate(options, 1)\n    )\n    choices = choice_map.keys()\n    default = '1'\n\n    choice_lines = ['{} - {}'.format(*c) for c in choice_map.items()]\n    prompt = '\\n'.join(\n        (\n            'Select {}:'.format(var_name),\n            '\\n'.join(choice_lines),\n            'Choose from {}'.format(', '.join(choices)),\n        )\n    )\n\n    user_choice = click.prompt(\n        prompt, type=click.Choice(choices), default=default, show_choices=False\n    )\n    return choice_map[user_choice]\n\n\ndef process_json(user_value):\n    \"\"\"Load user-supplied value as a JSON dict.\n\n    :param str user_value: User-supplied value to load as a JSON dict\n    \"\"\"\n    try:\n        user_dict = json.loads(user_value, object_pairs_hook=OrderedDict)\n    except Exception:\n        # Leave it up to click to ask the user again\n        raise click.UsageError('Unable to decode to JSON.')\n\n    if not isinstance(user_dict, dict):\n        # Leave it up to click to ask the user again\n        raise click.UsageError('Requires JSON dict.')\n\n    return user_dict\n\n\ndef read_user_dict(var_name, default_value):\n    \"\"\"Prompt the user to provide a dictionary of data.\n\n    :param str var_name: Variable as specified in the context\n    :param default_value: Value that will be returned if no input is provided\n    :return: A Python dictionary to use in the context.\n    \"\"\"\n    # Please see https://click.palletsprojects.com/en/7.x/api/#click.prompt\n    if not isinstance(default_value, dict):\n        raise TypeError\n\n    default_display = 'default'\n\n    user_value = click.prompt(\n        var_name, default=default_display, type=click.STRING, value_proc=process_json\n    )\n\n    if user_value == default_display:\n        # Return the given default w/o any processing\n        return default_value\n    return user_value\n\n\ndef render_variable(env, raw, cookiecutter_dict):\n    \"\"\"Render the next variable to be displayed in the user prompt.\n\n    Inside the prompting taken from the cookiecutter.json file, this renders\n    the next variable. For example, if a project_name is \"Peanut Butter\n    Cookie\", the repo_name could be be rendered with:\n\n        `{{ cookiecutter.project_name.replace(\" \", \"_\") }}`.\n\n    This is then presented to the user as the default.\n\n    :param Environment env: A Jinja2 Environment object.\n    :param raw: The next value to be prompted for by the user.\n    :param dict cookiecutter_dict: The current context as it's gradually\n        being populated with variables.\n    :return: The rendered value for the default variable.\n    \"\"\"\n    if raw is None:\n        return None\n    elif isinstance(raw, dict):\n        return {\n            render_variable(env, k, cookiecutter_dict): render_variable(\n                env, v, cookiecutter_dict\n            )\n            for k, v in raw.items()\n        }\n    elif isinstance(raw, list):\n        return [render_variable(env, v, cookiecutter_dict) for v in raw]\n    elif not isinstance(raw, str):\n        raw = str(raw)\n\n    template = env.from_string(raw)\n\n    rendered_template = template.render(cookiecutter=cookiecutter_dict)\n    return rendered_template\n\n\ndef prompt_choice_for_config(cookiecutter_dict, env, key, options, no_input):\n    \"\"\"Prompt user with a set of options to choose from.\n\n    Each of the possible choices is rendered beforehand.\n    \"\"\"\n    rendered_options = [render_variable(env, raw, cookiecutter_dict) for raw in options]\n\n    if no_input:\n        return rendered_options[0]\n    return read_user_choice(key, rendered_options)\n\n\ndef prompt_for_config(context, no_input=False):\n    \"\"\"Prompt user to enter a new config.\n\n    :param dict context: Source for field names and sample values.\n    :param no_input: Prompt the user at command line for manual configuration?\n    \"\"\"\n    cookiecutter_dict = OrderedDict([])\n    env = StrictEnvironment(context=context)\n\n    # First pass: Handle simple and raw variables, plus choices.\n    # These must be done first because the dictionaries keys and\n    # values might refer to them.\n    for key, raw in context['cookiecutter'].items():\n        if key.startswith('_') and not key.startswith('__'):\n            cookiecutter_dict[key] = raw\n            continue\n        elif key.startswith('__'):\n            cookiecutter_dict[key] = render_variable(env, raw, cookiecutter_dict)\n            continue\n\n        try:\n            if isinstance(raw, list):\n                # We are dealing with a choice variable\n                val = prompt_choice_for_config(\n                    cookiecutter_dict, env, key, raw, no_input\n                )\n                cookiecutter_dict[key] = val\n            elif not isinstance(raw, dict):\n                # We are dealing with a regular variable\n                val = render_variable(env, raw, cookiecutter_dict)\n\n                if not no_input:\n                    val = read_user_variable(key, val)\n\n                cookiecutter_dict[key] = val\n        except UndefinedError as err:\n            msg = \"Unable to render variable '{}'\".format(key)\n            raise UndefinedVariableInTemplate(msg, err, context)\n\n    # Second pass; handle the dictionaries.\n    for key, raw in context['cookiecutter'].items():\n        # Skip private type dicts not ot be rendered.\n        if key.startswith('_') and not key.startswith('__'):\n            continue\n\n        try:\n            if isinstance(raw, dict):\n                # We are dealing with a dict variable\n                val = render_variable(env, raw, cookiecutter_dict)\n\n                if not no_input and not key.startswith('__'):\n                    val = read_user_dict(key, val)\n\n                cookiecutter_dict[key] = val\n        except UndefinedError as err:\n            msg = \"Unable to render variable '{}'\".format(key)\n            raise UndefinedVariableInTemplate(msg, err, context)\n\n    return cookiecutter_dict\n", "path": "cookiecutter/prompt.py"}], "after_files": [{"content": "\"\"\"Functions for prompting the user for project info.\"\"\"\nimport functools\nimport json\nfrom collections import OrderedDict\n\nimport click\nfrom jinja2.exceptions import UndefinedError\n\nfrom cookiecutter.environment import StrictEnvironment\nfrom cookiecutter.exceptions import UndefinedVariableInTemplate\n\n\ndef read_user_variable(var_name, default_value):\n    \"\"\"Prompt user for variable and return the entered value or given default.\n\n    :param str var_name: Variable of the context to query the user\n    :param default_value: Value that will be returned if no input happens\n    \"\"\"\n    # Please see https://click.palletsprojects.com/en/7.x/api/#click.prompt\n    return click.prompt(var_name, default=default_value)\n\n\ndef read_user_yes_no(question, default_value):\n    \"\"\"Prompt the user to reply with 'yes' or 'no' (or equivalent values).\n\n    Note:\n      Possible choices are 'true', '1', 'yes', 'y' or 'false', '0', 'no', 'n'\n\n    :param str question: Question to the user\n    :param default_value: Value that will be returned if no input happens\n    \"\"\"\n    # Please see https://click.palletsprojects.com/en/7.x/api/#click.prompt\n    return click.prompt(question, default=default_value, type=click.BOOL)\n\n\ndef read_repo_password(question):\n    \"\"\"Prompt the user to enter a password.\n\n    :param str question: Question to the user\n    \"\"\"\n    # Please see https://click.palletsprojects.com/en/7.x/api/#click.prompt\n    return click.prompt(question, hide_input=True)\n\n\ndef read_user_choice(var_name, options):\n    \"\"\"Prompt the user to choose from several options for the given variable.\n\n    The first item will be returned if no input happens.\n\n    :param str var_name: Variable as specified in the context\n    :param list options: Sequence of options that are available to select from\n    :return: Exactly one item of ``options`` that has been chosen by the user\n    \"\"\"\n    # Please see https://click.palletsprojects.com/en/7.x/api/#click.prompt\n    if not isinstance(options, list):\n        raise TypeError\n\n    if not options:\n        raise ValueError\n\n    choice_map = OrderedDict(\n        ('{}'.format(i), value) for i, value in enumerate(options, 1)\n    )\n    choices = choice_map.keys()\n    default = '1'\n\n    choice_lines = ['{} - {}'.format(*c) for c in choice_map.items()]\n    prompt = '\\n'.join(\n        (\n            'Select {}:'.format(var_name),\n            '\\n'.join(choice_lines),\n            'Choose from {}'.format(', '.join(choices)),\n        )\n    )\n\n    user_choice = click.prompt(\n        prompt, type=click.Choice(choices), default=default, show_choices=False\n    )\n    return choice_map[user_choice]\n\n\nDEFAULT_DISPLAY = 'default'\n\n\ndef process_json(user_value, default_value=None):\n    \"\"\"Load user-supplied value as a JSON dict.\n\n    :param str user_value: User-supplied value to load as a JSON dict\n    \"\"\"\n    if user_value == DEFAULT_DISPLAY:\n        # Return the given default w/o any processing\n        return default_value\n\n    try:\n        user_dict = json.loads(user_value, object_pairs_hook=OrderedDict)\n    except Exception:\n        # Leave it up to click to ask the user again\n        raise click.UsageError('Unable to decode to JSON.')\n\n    if not isinstance(user_dict, dict):\n        # Leave it up to click to ask the user again\n        raise click.UsageError('Requires JSON dict.')\n\n    return user_dict\n\n\ndef read_user_dict(var_name, default_value):\n    \"\"\"Prompt the user to provide a dictionary of data.\n\n    :param str var_name: Variable as specified in the context\n    :param default_value: Value that will be returned if no input is provided\n    :return: A Python dictionary to use in the context.\n    \"\"\"\n    # Please see https://click.palletsprojects.com/en/7.x/api/#click.prompt\n    if not isinstance(default_value, dict):\n        raise TypeError\n\n    user_value = click.prompt(\n        var_name,\n        default=DEFAULT_DISPLAY,\n        type=click.STRING,\n        value_proc=functools.partial(process_json, default_value=default_value),\n    )\n\n    if click.__version__.startswith(\"7.\") and user_value == DEFAULT_DISPLAY:\n        # click 7.x does not invoke value_proc on the default value.\n        return default_value  # pragma: no cover\n    return user_value\n\n\ndef render_variable(env, raw, cookiecutter_dict):\n    \"\"\"Render the next variable to be displayed in the user prompt.\n\n    Inside the prompting taken from the cookiecutter.json file, this renders\n    the next variable. For example, if a project_name is \"Peanut Butter\n    Cookie\", the repo_name could be be rendered with:\n\n        `{{ cookiecutter.project_name.replace(\" \", \"_\") }}`.\n\n    This is then presented to the user as the default.\n\n    :param Environment env: A Jinja2 Environment object.\n    :param raw: The next value to be prompted for by the user.\n    :param dict cookiecutter_dict: The current context as it's gradually\n        being populated with variables.\n    :return: The rendered value for the default variable.\n    \"\"\"\n    if raw is None:\n        return None\n    elif isinstance(raw, dict):\n        return {\n            render_variable(env, k, cookiecutter_dict): render_variable(\n                env, v, cookiecutter_dict\n            )\n            for k, v in raw.items()\n        }\n    elif isinstance(raw, list):\n        return [render_variable(env, v, cookiecutter_dict) for v in raw]\n    elif not isinstance(raw, str):\n        raw = str(raw)\n\n    template = env.from_string(raw)\n\n    rendered_template = template.render(cookiecutter=cookiecutter_dict)\n    return rendered_template\n\n\ndef prompt_choice_for_config(cookiecutter_dict, env, key, options, no_input):\n    \"\"\"Prompt user with a set of options to choose from.\n\n    Each of the possible choices is rendered beforehand.\n    \"\"\"\n    rendered_options = [render_variable(env, raw, cookiecutter_dict) for raw in options]\n\n    if no_input:\n        return rendered_options[0]\n    return read_user_choice(key, rendered_options)\n\n\ndef prompt_for_config(context, no_input=False):\n    \"\"\"Prompt user to enter a new config.\n\n    :param dict context: Source for field names and sample values.\n    :param no_input: Prompt the user at command line for manual configuration?\n    \"\"\"\n    cookiecutter_dict = OrderedDict([])\n    env = StrictEnvironment(context=context)\n\n    # First pass: Handle simple and raw variables, plus choices.\n    # These must be done first because the dictionaries keys and\n    # values might refer to them.\n    for key, raw in context['cookiecutter'].items():\n        if key.startswith('_') and not key.startswith('__'):\n            cookiecutter_dict[key] = raw\n            continue\n        elif key.startswith('__'):\n            cookiecutter_dict[key] = render_variable(env, raw, cookiecutter_dict)\n            continue\n\n        try:\n            if isinstance(raw, list):\n                # We are dealing with a choice variable\n                val = prompt_choice_for_config(\n                    cookiecutter_dict, env, key, raw, no_input\n                )\n                cookiecutter_dict[key] = val\n            elif not isinstance(raw, dict):\n                # We are dealing with a regular variable\n                val = render_variable(env, raw, cookiecutter_dict)\n\n                if not no_input:\n                    val = read_user_variable(key, val)\n\n                cookiecutter_dict[key] = val\n        except UndefinedError as err:\n            msg = \"Unable to render variable '{}'\".format(key)\n            raise UndefinedVariableInTemplate(msg, err, context)\n\n    # Second pass; handle the dictionaries.\n    for key, raw in context['cookiecutter'].items():\n        # Skip private type dicts not ot be rendered.\n        if key.startswith('_') and not key.startswith('__'):\n            continue\n\n        try:\n            if isinstance(raw, dict):\n                # We are dealing with a dict variable\n                val = render_variable(env, raw, cookiecutter_dict)\n\n                if not no_input and not key.startswith('__'):\n                    val = read_user_dict(key, val)\n\n                cookiecutter_dict[key] = val\n        except UndefinedError as err:\n            msg = \"Unable to render variable '{}'\".format(key)\n            raise UndefinedVariableInTemplate(msg, err, context)\n\n    return cookiecutter_dict\n", "path": "cookiecutter/prompt.py"}]}