Repository: cookiecutter/cookiecutter

Issue:
AttributeError in Jinja2 call
I'm fairly certain this is a Jinja2 bug (submitted [here](https://github.com/mitsuhiko/jinja2/issues/396)), but the ultimate impact is that `cookiecutter==0.9.0` is broken for me (on Python 2 and Python 3).

Steps to reproduce:

```
 $ pip2 install cookiecutter==0.9.0 && cookiecutter gh:jacebrowning/template-python --no-input
```

```
Traceback (most recent call last):
  File "/opt/boxen/homebrew/bin/cookiecutter", line 9, in <module>
    load_entry_point('cookiecutter==0.9.0', 'console_scripts', 'cookiecutter')()
  File "/opt/boxen/homebrew/lib/python2.7/site-packages/cookiecutter/main.py", line 169, in main
    cookiecutter(args.input_dir, args.checkout, args.no_input)
  File "/opt/boxen/homebrew/lib/python2.7/site-packages/cookiecutter/main.py", line 100, in cookiecutter
    context['cookiecutter'] = prompt_for_config(context, no_input)
  File "/opt/boxen/homebrew/lib/python2.7/site-packages/cookiecutter/prompt.py", line 29, in prompt_for_config
    val = env.from_string(raw).render(cookiecutter=cookiecutter_dict)
  File "/opt/boxen/homebrew/lib/python2.7/site-packages/jinja2/environment.py", line 841, in from_string
    return cls.from_code(self, self.compile(source), globals, None)
  File "/opt/boxen/homebrew/lib/python2.7/site-packages/jinja2/environment.py", line 542, in compile
    source = optimize(source, self)
  File "/opt/boxen/homebrew/lib/python2.7/site-packages/jinja2/optimizer.py", line 27, in optimize
    return optimizer.visit(node)
  File "/opt/boxen/homebrew/lib/python2.7/site-packages/jinja2/visitor.py", line 39, in visit
    return self.generic_visit(node, *args, **kwargs)
  File "/opt/boxen/homebrew/lib/python2.7/site-packages/jinja2/visitor.py", line 59, in generic_visit
    for field, old_value in node.iter_fields():
AttributeError: 'int' object has no attribute 'iter_fields'
```

This still works with `cookiecutter==0.8.0`:

```
 $ pip2 install cookiecutter==0.8.0 && cookiecutter gh:jacebrowning/template-python --no-input
```

My environment:
- OS X 10.10.1
- Python 2.7.9
- pip 1.5.6



Discussion:
@jacebrowning #291 assumes that the values in `cookiecutter.json` are strings: https://github.com/audreyr/cookiecutter/pull/291/files#diff-3caa474d33f1a49fd4fcfc9c4154d651R29
And your template contains ints: https://github.com/jacebrowning/template-python/blob/master/cookiecutter.json#L10-L11

Do you think you could :scissors:  a PR to fix this? (`str` casting and a test case is probably sufficient)
Thanks for the feedback :)

@michaeljoseph Yeah, I can work on that.

@jacebrowning awesome, thanks :heart_eyes: 

@jacebrowning Thank you for the catch! Once you get that in place I'll back-port it and release it as 0.9.1.


Resolving patch:
diff --git a/cookiecutter/compat.py b/cookiecutter/compat.py
--- a/cookiecutter/compat.py
+++ b/cookiecutter/compat.py
@@ -131,4 +131,10 @@ def _access_check(fn, mode):
                         return name
         return None
 
+
+def is_string(obj):
+    """Determine if an object is a string."""
+    return isinstance(obj, str if PY3 else basestring)
+
+
 _hush_pyflakes = (patch, StringIO, which)
diff --git a/cookiecutter/prompt.py b/cookiecutter/prompt.py
--- a/cookiecutter/prompt.py
+++ b/cookiecutter/prompt.py
@@ -11,7 +11,7 @@
 from __future__ import unicode_literals
 import sys
 
-from .compat import iteritems, read_response
+from .compat import iteritems, read_response, is_string
 from jinja2.environment import Environment
 
 
@@ -26,6 +26,7 @@ def prompt_for_config(context, no_input=False):
     env = Environment()
 
     for key, raw in iteritems(context['cookiecutter']):
+        raw = raw if is_string(raw) else str(raw)
         val = env.from_string(raw).render(cookiecutter=cookiecutter_dict)
 
         if not no_input:


Test patch:
diff --git a/tests/test_prompt.py b/tests/test_prompt.py
--- a/tests/test_prompt.py
+++ b/tests/test_prompt.py
@@ -66,6 +66,13 @@ def test_unicode_prompt_for_templated_config(self):
         self.assertEqual(cookiecutter_dict, {"project_name": u"A New Project",
              "pkg_name": u"anewproject"})
 
+    @patch('cookiecutter.prompt.read_response', lambda x=u'': u'2')
+    def test_prompt_for_config_nonstring(self):
+        context = {"cookiecutter": {"python_major_version": 3}}
+
+        cookiecutter_dict = prompt.prompt_for_config(context)
+        self.assertEqual(cookiecutter_dict, {"python_major_version": u"2"})
+
 
 class TestQueryAnswers(unittest.TestCase):