Repository: Pylons/pyramid

Issue:
Pyramid app frozen with py2exe fails because of Chameleon imports
If I freeze a Pyramid application with py2exe and try to run it, it fails during the startup, with the following traceback:

```
Traceback (most recent call last):
  File "web_server.py", line 2, in <module>
  File "pyramid\config\__init__.pyc", line 66, in <module>
  File "pyramid\config\rendering.pyc", line 11, in <module>
  File "pyramid\chameleon_text.pyc", line 3, in <module>
  File "chameleon\__init__.pyc", line 1, in <module>
  File "chameleon\zpt\template.pyc", line 10, in <module>
  File "chameleon\tales.pyc", line 19, in <module>
  File "chameleon\compiler.pyc", line 145, in <module>
  File "chameleon\codegen.pyc", line 93, in template
  File "inspect.pyc", line 701, in getsource
  File "inspect.pyc", line 690, in getsourcelines
  File "inspect.pyc", line 538, in findsource
IOError: could not get source code
```

My application doesn't use Chameleon, but the Pyramid modules still import it, which ultimately causes the .exe to fail to run.



Discussion:
I've [read that there's a project to remove templating dependencies](http://stackoverflow.com/a/14950809/58099) from Pyramid, but in the mean time I have a very short and simple solution for this particular bug. Would you be open to reviewing a pull request?

The problem with the pull request is that there is a lot more to do than just rip out  code for currently-supported templates (Chameleon, Mako):
- We would need to get the equivalent code launched in new packages ('pyramid_chameleon', 'pyramid_mako').
- We would need to have maintainers identified for those packages, set them up for CI, etc.
- We would have to upload a metric tonne of tutorials, scaffolds, etc., to call out the new pacakges as requirements, in addition to fixing code samples, etc.:  inevitably, this involves breaking existing docs not under our control (think StackOverflow, mailing list archives, etc).

Yes, the task of removing the dependencies is huge. But the fix for this specific bug does not require removing the dependencies, just making sure the imports don't mess things up. Specifically, the fix I'm proposing would touch only two modules.

The first is `pyramid.chameleon_text`, in which I would move the import on the line 3 into the method `template` defined on the line 22.

The second is `pyramid.chameleon_zpt`, in which I would move the import on the line 3 into the method `template` defined on the line 20.

This is enough to avoid importing Chameleon unless the user is actually using it in their project. I can have a pull request for this ready quickly, which is why I was whether you would be open to taking a look at it.


Resolving patch:
diff --git a/pyramid/chameleon_text.py b/pyramid/chameleon_text.py
--- a/pyramid/chameleon_text.py
+++ b/pyramid/chameleon_text.py
@@ -1,7 +1,5 @@
 from zope.interface import implementer
 
-from chameleon.zpt.template import PageTextTemplateFile
-
 from pyramid.interfaces import ITemplateRenderer
 
 from pyramid.decorator import reify
@@ -20,6 +18,7 @@ def __init__(self, path, lookup, macro=None):
 
     @reify # avoid looking up reload_templates before manager pushed
     def template(self):
+        from chameleon.zpt.template import PageTextTemplateFile
         return PageTextTemplateFile(self.path,
                                     auto_reload=self.lookup.auto_reload,
                                     debug=self.lookup.debug,
diff --git a/pyramid/chameleon_zpt.py b/pyramid/chameleon_zpt.py
--- a/pyramid/chameleon_zpt.py
+++ b/pyramid/chameleon_zpt.py
@@ -1,7 +1,5 @@
 from zope.interface import implementer
 
-from chameleon.zpt.template import PageTemplateFile
-
 from pyramid.interfaces import ITemplateRenderer
 from pyramid.decorator import reify
 from pyramid import renderers
@@ -18,6 +16,7 @@ def __init__(self, path, lookup, macro=None):
 
     @reify # avoid looking up reload_templates before manager pushed
     def template(self):
+        from chameleon.zpt.template import PageTemplateFile
         tf = PageTemplateFile(
             self.path,
             auto_reload=self.lookup.auto_reload,


Test patch: