We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
passing list to template
I would like to be able to pass a list to the templates. See the two code blocks at the end of this post for an example. Right now it appears that if you pass a list in the config object, it's read as a list of options for that key.

I know that you can use `str.split()` in the jinja2 template, but that's not a real solution, since it's impossible to "escape" the character that's used as the delimiter. What's the best solution here? I would prefer to be able to pass a list in the json object and call it a day, but obviously that doesn't work for the user input prompts.
- `cookiecutter.json`:

``` json
{
  "build_steps": [
     "do_something",
     "do_something_else"
  ]
}
```
- `Dockerfile`:

``` jinja2
FROM something

{% for step in cookiecutter.build_steps %}
RUN {{ step }}
{% endfor %}
```


--- 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 # -*- coding: utf-8 -*-
2 
3 """
4 cookiecutter.prompt
5 ---------------------
6 
7 Functions for prompting the user for project info.
8 """
9 
10 from collections import OrderedDict
11 
12 import click
13 from past.builtins import basestring
14 
15 from future.utils import iteritems
16 
17 from jinja2.exceptions import UndefinedError
18 
19 from .exceptions import UndefinedVariableInTemplate
20 from .environment import StrictEnvironment
21 
22 
23 def read_user_variable(var_name, default_value):
24     """Prompt the user for the given variable and return the entered value
25     or the given default.
26 
27     :param str var_name: Variable of the context to query the user
28     :param default_value: Value that will be returned if no input happens
29     """
30     # Please see http://click.pocoo.org/4/api/#click.prompt
31     return click.prompt(var_name, default=default_value)
32 
33 
34 def read_user_yes_no(question, default_value):
35     """Prompt the user to reply with 'yes' or 'no' (or equivalent values).
36 
37     Note:
38       Possible choices are 'true', '1', 'yes', 'y' or 'false', '0', 'no', 'n'
39 
40     :param str question: Question to the user
41     :param default_value: Value that will be returned if no input happens
42     """
43     # Please see http://click.pocoo.org/4/api/#click.prompt
44     return click.prompt(
45         question,
46         default=default_value,
47         type=click.BOOL
48     )
49 
50 
51 def read_user_choice(var_name, options):
52     """Prompt the user to choose from several options for the given variable.
53 
54     The first item will be returned if no input happens.
55 
56     :param str var_name: Variable as specified in the context
57     :param list options: Sequence of options that are available to select from
58     :return: Exactly one item of ``options`` that has been chosen by the user
59     """
60     # Please see http://click.pocoo.org/4/api/#click.prompt
61     if not isinstance(options, list):
62         raise TypeError
63 
64     if not options:
65         raise ValueError
66 
67     choice_map = OrderedDict(
68         (u'{}'.format(i), value) for i, value in enumerate(options, 1)
69     )
70     choices = choice_map.keys()
71     default = u'1'
72 
73     choice_lines = [u'{} - {}'.format(*c) for c in choice_map.items()]
74     prompt = u'\n'.join((
75         u'Select {}:'.format(var_name),
76         u'\n'.join(choice_lines),
77         u'Choose from {}'.format(u', '.join(choices))
78     ))
79 
80     user_choice = click.prompt(
81         prompt, type=click.Choice(choices), default=default
82     )
83     return choice_map[user_choice]
84 
85 
86 def render_variable(env, raw, cookiecutter_dict):
87     if raw is None:
88         return None
89     if not isinstance(raw, basestring):
90         raw = str(raw)
91     template = env.from_string(raw)
92 
93     rendered_template = template.render(cookiecutter=cookiecutter_dict)
94     return rendered_template
95 
96 
97 def prompt_choice_for_config(cookiecutter_dict, env, key, options, no_input):
98     """Prompt the user which option to choose from the given. Each of the
99     possible choices is rendered beforehand.
100     """
101     rendered_options = [
102         render_variable(env, raw, cookiecutter_dict) for raw in options
103     ]
104 
105     if no_input:
106         return rendered_options[0]
107     return read_user_choice(key, rendered_options)
108 
109 
110 def prompt_for_config(context, no_input=False):
111     """
112     Prompts the user to enter new config, using context as a source for the
113     field names and sample values.
114 
115     :param no_input: Prompt the user at command line for manual configuration?
116     """
117     cookiecutter_dict = {}
118     env = StrictEnvironment(context=context)
119 
120     for key, raw in iteritems(context[u'cookiecutter']):
121         if key.startswith(u'_'):
122             cookiecutter_dict[key] = raw
123             continue
124 
125         try:
126             if isinstance(raw, list):
127                 # We are dealing with a choice variable
128                 val = prompt_choice_for_config(
129                     cookiecutter_dict, env, key, raw, no_input
130                 )
131             else:
132                 # We are dealing with a regular variable
133                 val = render_variable(env, raw, cookiecutter_dict)
134 
135                 if not no_input:
136                     val = read_user_variable(key, val)
137         except UndefinedError as err:
138             msg = "Unable to render variable '{}'".format(key)
139             raise UndefinedVariableInTemplate(msg, err, context)
140 
141         cookiecutter_dict[key] = val
142     return cookiecutter_dict
143
```
--- 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
@@ -8,6 +8,7 @@
 """
 
 from collections import OrderedDict
+import json
 
 import click
 from past.builtins import basestring
@@ -83,11 +84,43 @@
     return choice_map[user_choice]
 
 
+def read_user_dict(var_name, default_value):
+    """Prompt the user to provide a dictionary of data.
+
+    :param str var_name: Variable as specified in the context
+    :param default_value: Value that will be returned if no input is provided
+    :return: A Python dictionary to use in the context.
+    """
+    # Please see http://click.pocoo.org/4/api/#click.prompt
+    if not isinstance(default_value, dict):
+        raise TypeError
+
+    raw = click.prompt(var_name, default='default')
+    if raw != 'default':
+        value = json.loads(raw, object_hook=OrderedDict)
+    else:
+        value = default_value
+
+    return value
+
+
 def render_variable(env, raw, cookiecutter_dict):
     if raw is None:
         return None
-    if not isinstance(raw, basestring):
+    elif isinstance(raw, dict):
+        return {
+            render_variable(env, k, cookiecutter_dict):
+                render_variable(env, v, cookiecutter_dict)
+            for k, v in raw.items()
+        }
+    elif isinstance(raw, list):
+        return [
+            render_variable(env, v, cookiecutter_dict)
+            for v in raw
+        ]
+    elif not isinstance(raw, basestring):
         raw = str(raw)
+
     template = env.from_string(raw)
 
     rendered_template = template.render(cookiecutter=cookiecutter_dict)
@@ -117,6 +150,9 @@
     cookiecutter_dict = {}
     env = StrictEnvironment(context=context)
 
+    # First pass: Handle simple and raw variables, plus choices.
+    # These must be done first because the dictionaries keys and
+    # values might refer to them.
     for key, raw in iteritems(context[u'cookiecutter']):
         if key.startswith(u'_'):
             cookiecutter_dict[key] = raw
@@ -128,15 +164,33 @@
                 val = prompt_choice_for_config(
                     cookiecutter_dict, env, key, raw, no_input
                 )
-            else:
+                cookiecutter_dict[key] = val
+            elif not isinstance(raw, dict):
                 # We are dealing with a regular variable
                 val = render_variable(env, raw, cookiecutter_dict)
 
                 if not no_input:
                     val = read_user_variable(key, val)
+
+                cookiecutter_dict[key] = val
+        except UndefinedError as err:
+            msg = "Unable to render variable '{}'".format(key)
+            raise UndefinedVariableInTemplate(msg, err, context)
+
+    # Second pass; handle the dictionaries.
+    for key, raw in iteritems(context[u'cookiecutter']):
+
+        try:
+            if isinstance(raw, dict):
+                # We are dealing with a dict variable
+                val = render_variable(env, raw, cookiecutter_dict)
+
+                if not no_input:
+                    val = read_user_dict(key, val)
+
+                cookiecutter_dict[key] = val
         except UndefinedError as err:
             msg = "Unable to render variable '{}'".format(key)
             raise UndefinedVariableInTemplate(msg, err, context)
 
-        cookiecutter_dict[key] = val
     return cookiecutter_dict

{"golden_diff": "diff --git a/cookiecutter/prompt.py b/cookiecutter/prompt.py\n--- a/cookiecutter/prompt.py\n+++ b/cookiecutter/prompt.py\n@@ -8,6 +8,7 @@\n \"\"\"\n \n from collections import OrderedDict\n+import json\n \n import click\n from past.builtins import basestring\n@@ -83,11 +84,43 @@\n     return choice_map[user_choice]\n \n \n+def 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 http://click.pocoo.org/4/api/#click.prompt\n+    if not isinstance(default_value, dict):\n+        raise TypeError\n+\n+    raw = click.prompt(var_name, default='default')\n+    if raw != 'default':\n+        value = json.loads(raw, object_hook=OrderedDict)\n+    else:\n+        value = default_value\n+\n+    return value\n+\n+\n def render_variable(env, raw, cookiecutter_dict):\n     if raw is None:\n         return None\n-    if not isinstance(raw, basestring):\n+    elif isinstance(raw, dict):\n+        return {\n+            render_variable(env, k, cookiecutter_dict):\n+                render_variable(env, v, cookiecutter_dict)\n+            for k, v in raw.items()\n+        }\n+    elif isinstance(raw, list):\n+        return [\n+            render_variable(env, v, cookiecutter_dict)\n+            for v in raw\n+        ]\n+    elif not isinstance(raw, basestring):\n         raw = str(raw)\n+\n     template = env.from_string(raw)\n \n     rendered_template = template.render(cookiecutter=cookiecutter_dict)\n@@ -117,6 +150,9 @@\n     cookiecutter_dict = {}\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 iteritems(context[u'cookiecutter']):\n         if key.startswith(u'_'):\n             cookiecutter_dict[key] = raw\n@@ -128,15 +164,33 @@\n                 val = prompt_choice_for_config(\n                     cookiecutter_dict, env, key, raw, no_input\n                 )\n-            else:\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 iteritems(context[u'cookiecutter']):\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:\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-        cookiecutter_dict[key] = val\n     return cookiecutter_dict\n", "issue": "passing list to template\nI would like to be able to pass a list to the templates. See the two code blocks at the end of this post for an example. Right now it appears that if you pass a list in the config object, it's read as a list of options for that key.\n\nI know that you can use `str.split()` in the jinja2 template, but that's not a real solution, since it's impossible to \"escape\" the character that's used as the delimiter. What's the best solution here? I would prefer to be able to pass a list in the json object and call it a day, but obviously that doesn't work for the user input prompts.\n- `cookiecutter.json`:\n\n``` json\n{\n  \"build_steps\": [\n     \"do_something\",\n     \"do_something_else\"\n  ]\n}\n```\n- `Dockerfile`:\n\n``` jinja2\nFROM something\n\n{% for step in cookiecutter.build_steps %}\nRUN {{ step }}\n{% endfor %}\n```\n\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\n\n\"\"\"\ncookiecutter.prompt\n---------------------\n\nFunctions for prompting the user for project info.\n\"\"\"\n\nfrom collections import OrderedDict\n\nimport click\nfrom past.builtins import basestring\n\nfrom future.utils import iteritems\n\nfrom jinja2.exceptions import UndefinedError\n\nfrom .exceptions import UndefinedVariableInTemplate\nfrom .environment import StrictEnvironment\n\n\ndef read_user_variable(var_name, default_value):\n    \"\"\"Prompt the user for the given variable and return the entered value\n    or the 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 http://click.pocoo.org/4/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 http://click.pocoo.org/4/api/#click.prompt\n    return click.prompt(\n        question,\n        default=default_value,\n        type=click.BOOL\n    )\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 http://click.pocoo.org/4/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        (u'{}'.format(i), value) for i, value in enumerate(options, 1)\n    )\n    choices = choice_map.keys()\n    default = u'1'\n\n    choice_lines = [u'{} - {}'.format(*c) for c in choice_map.items()]\n    prompt = u'\\n'.join((\n        u'Select {}:'.format(var_name),\n        u'\\n'.join(choice_lines),\n        u'Choose from {}'.format(u', '.join(choices))\n    ))\n\n    user_choice = click.prompt(\n        prompt, type=click.Choice(choices), default=default\n    )\n    return choice_map[user_choice]\n\n\ndef render_variable(env, raw, cookiecutter_dict):\n    if raw is None:\n        return None\n    if not isinstance(raw, basestring):\n        raw = str(raw)\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 the user which option to choose from the given. Each of the\n    possible choices is rendered beforehand.\n    \"\"\"\n    rendered_options = [\n        render_variable(env, raw, cookiecutter_dict) for raw in options\n    ]\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    \"\"\"\n    Prompts the user to enter new config, using context as a source for the\n    field names and sample values.\n\n    :param no_input: Prompt the user at command line for manual configuration?\n    \"\"\"\n    cookiecutter_dict = {}\n    env = StrictEnvironment(context=context)\n\n    for key, raw in iteritems(context[u'cookiecutter']):\n        if key.startswith(u'_'):\n            cookiecutter_dict[key] = raw\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            else:\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        except UndefinedError as err:\n            msg = \"Unable to render variable '{}'\".format(key)\n            raise UndefinedVariableInTemplate(msg, err, context)\n\n        cookiecutter_dict[key] = val\n    return cookiecutter_dict\n", "path": "cookiecutter/prompt.py"}], "after_files": [{"content": "# -*- coding: utf-8 -*-\n\n\"\"\"\ncookiecutter.prompt\n---------------------\n\nFunctions for prompting the user for project info.\n\"\"\"\n\nfrom collections import OrderedDict\nimport json\n\nimport click\nfrom past.builtins import basestring\n\nfrom future.utils import iteritems\n\nfrom jinja2.exceptions import UndefinedError\n\nfrom .exceptions import UndefinedVariableInTemplate\nfrom .environment import StrictEnvironment\n\n\ndef read_user_variable(var_name, default_value):\n    \"\"\"Prompt the user for the given variable and return the entered value\n    or the 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 http://click.pocoo.org/4/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 http://click.pocoo.org/4/api/#click.prompt\n    return click.prompt(\n        question,\n        default=default_value,\n        type=click.BOOL\n    )\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 http://click.pocoo.org/4/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        (u'{}'.format(i), value) for i, value in enumerate(options, 1)\n    )\n    choices = choice_map.keys()\n    default = u'1'\n\n    choice_lines = [u'{} - {}'.format(*c) for c in choice_map.items()]\n    prompt = u'\\n'.join((\n        u'Select {}:'.format(var_name),\n        u'\\n'.join(choice_lines),\n        u'Choose from {}'.format(u', '.join(choices))\n    ))\n\n    user_choice = click.prompt(\n        prompt, type=click.Choice(choices), default=default\n    )\n    return choice_map[user_choice]\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 http://click.pocoo.org/4/api/#click.prompt\n    if not isinstance(default_value, dict):\n        raise TypeError\n\n    raw = click.prompt(var_name, default='default')\n    if raw != 'default':\n        value = json.loads(raw, object_hook=OrderedDict)\n    else:\n        value = default_value\n\n    return value\n\n\ndef render_variable(env, raw, cookiecutter_dict):\n    if raw is None:\n        return None\n    elif isinstance(raw, dict):\n        return {\n            render_variable(env, k, cookiecutter_dict):\n                render_variable(env, v, cookiecutter_dict)\n            for k, v in raw.items()\n        }\n    elif isinstance(raw, list):\n        return [\n            render_variable(env, v, cookiecutter_dict)\n            for v in raw\n        ]\n    elif not isinstance(raw, basestring):\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 the user which option to choose from the given. Each of the\n    possible choices is rendered beforehand.\n    \"\"\"\n    rendered_options = [\n        render_variable(env, raw, cookiecutter_dict) for raw in options\n    ]\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    \"\"\"\n    Prompts the user to enter new config, using context as a source for the\n    field names and sample values.\n\n    :param no_input: Prompt the user at command line for manual configuration?\n    \"\"\"\n    cookiecutter_dict = {}\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 iteritems(context[u'cookiecutter']):\n        if key.startswith(u'_'):\n            cookiecutter_dict[key] = raw\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 iteritems(context[u'cookiecutter']):\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:\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"}]}