Merge branch 'master' into w_json_metadata

Conflicts:
	doc/build/changelog.rst
diff --git a/doc/build/changelog.rst b/doc/build/changelog.rst
index 7664284..27c12e5 100644
--- a/doc/build/changelog.rst
+++ b/doc/build/changelog.rst
@@ -21,6 +21,22 @@
       here is to allow integration with coverage tools.
 
     .. change::
+        :tags: bug, py3k
+        :tickets: 227
+
+      Fixed bug in Python parsing logic which would fail on Python 3
+      when a "try/except" targeted a tuple of exception types, rather
+      than a single exception.
+
+    .. change::
+        :tags: feature
+        :pullreq: bitbucket:4
+
+      The mako-render script will now catch exceptions and run them
+      into the text error handler, and exit with a non-zero exit code.
+      Pull request courtesy Derek Harland.
+
+    .. change::
         :tags: feature, py3k
         :pullreq: github:7
 
diff --git a/doc/build/inheritance.rst b/doc/build/inheritance.rst
index 9eba053..5b29574 100644
--- a/doc/build/inheritance.rst
+++ b/doc/build/inheritance.rst
@@ -192,6 +192,8 @@
 Where above an inheriting template can define ``<%block name="title">`` just once, and it will be
 used in the base template both in the ``<title>`` section as well as the ``<h2>``.
 
+
+
 But what about Defs?
 ====================
 
@@ -494,6 +496,111 @@
 
 and you're now a template inheritance ninja!
 
+Using ``<%include>`` with Template Inheritance
+==============================================
+
+A common source of confusion is the behavior of the ``<%include>`` tag,
+often in conjunction with its interaction within template inheritance.
+Key to understanding the ``<%include>`` tag is that it is a *dynamic*, e.g.
+runtime, include, and not a static include.   The ``<%include>`` is only processed
+as the template renders, and not at inheritance setup time.   When encountered,
+the referenced template is run fully as an entirely separate template with no
+linkage to any current inheritance structure.
+
+If the tag were on the other hand a *static* include, this would allow source
+within the included template to interact within the same inheritance context
+as the calling template, but currently Mako has no static include facility.
+
+In practice, this means that ``<%block>`` elements defined in an ``<%include>``
+file will not interact with corresponding ``<%block>`` elements in the calling
+template.
+
+A common mistake is along these lines:
+
+.. sourcecode:: mako
+
+    ## partials.mako
+    <%block name="header">
+        Global Header
+    </%block>
+
+    ## parent.mako
+    <%include file="partials.mako">
+
+    ## child.mako
+    <%inherit file="parent.mako">
+    <%block name="header">
+        Custom Header
+    </%block>
+
+Above, one might expect that the ``"header"`` block declared in ``child.mako``
+might be invoked, as a result of it overriding the same block present in
+``parent.mako`` via the include for ``partials.mako``.  But this is not the case.
+Instead, ``parent.mako`` will invoke ``partials.mako``, which then invokes
+``"header"`` in ``partials.mako``, and then is finished rendering.  Nothing
+from ``child.mako`` will render; there is no interaction between the ``"header"``
+block in ``child.mako`` and the ``"header"`` block in ``partials.mako``.
+
+Instead, ``parent.mako`` must explicitly state the inheritance structure.
+In order to call upon specific elements of ``partials.mako``, we will call upon
+it as a namespace:
+
+.. sourcecode:: mako
+
+    ## partials.mako
+    <%block name="header">
+        Global Header
+    </%block>
+
+    ## parent.mako
+    <%namespace name="partials" file="partials.mako"/>
+    <%block name="header">
+        ${partials.header()}
+    </%block>
+
+    ## child.mako
+    <%inherit file="parent.mako">
+    <%block name="header">
+        Custom Header
+    </%block>
+
+Where above, ``parent.mako`` states the inheritance structure that ``child.mako``
+is to participate within.  ``partials.mako`` only defines defs/blocks that can be
+used on a per-name basis.
+
+Another scenario is below, which results in both ``"SectionA"`` blocks being rendered for the ``child.mako`` document:
+
+.. sourcecode:: mako
+
+    ## base.mako
+    ${self.body()}
+    <%block name="SectionA">
+        base.mako
+    </%block>
+
+    ## parent.mako
+    <%inherit file="base.mako">
+    <%include file="child.mako">
+
+    ## child.mako
+    <%block name="SectionA">
+        child.mako
+    </%block>
+
+The resolution is similar; instead of using ``<%include>``, we call upon the blocks
+of ``child.mako`` using a namespace:
+
+.. sourcecode:: mako
+
+    ## parent.mako
+    <%inherit file="base.mako">
+    <%namespace name="child" file="child.mako">
+
+    <%block name="SectionA">
+        ${child.SectionA()}
+    </%block>
+
+
 .. _inheritance_attr:
 
 Inheritable Attributes
diff --git a/mako/pyparser.py b/mako/pyparser.py
index aa2d882..db5c295 100644
--- a/mako/pyparser.py
+++ b/mako/pyparser.py
@@ -102,7 +102,7 @@
                 if node.name is not None:
                     self._add_declared(node.name)
                 if node.type is not None:
-                    self.listener.undeclared_identifiers.add(node.type.id)
+                    self.visit(node.type)
                 for statement in node.body:
                     self.visit(statement)
 
diff --git a/mako/util.py b/mako/util.py
index 0108109..48e3a23 100644
--- a/mako/util.py
+++ b/mako/util.py
@@ -11,15 +11,10 @@
 from mako import compat
 import operator
 
-def function_named(fn, name):
-    """Return a function with a given __name__.
-
-    Will assign to __name__ and return the original function if possible on
-    the Python implementation, otherwise a new function will be constructed.
-
-    """
-    fn.__name__ = name
-    return fn
+def update_wrapper(decorated, fn):
+    decorated.__wrapped__ = fn
+    decorated.__name__ = fn.__name__
+    return decorated
 
 
 class PluginLoader(object):
diff --git a/setup.cfg b/setup.cfg
index c933a4d..6a03440 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -5,6 +5,11 @@
 [wheel]
 universal = 1
 
+[pytest]
+addopts= --tb native -v -r fxX
+python_files=test/*test_*.py
+
+
 [upload]
 sign = 1
 identity = C4DAFEE1
diff --git a/test/__init__.py b/test/__init__.py
index f114f64..64dde8e 100644
--- a/test/__init__.py
+++ b/test/__init__.py
@@ -2,7 +2,7 @@
 import unittest
 import os
 from mako.compat import py3k, py26, py25
-from mako.util import function_named
+from mako.util import update_wrapper
 import re
 from mako.cache import CacheImpl, register_plugin
 from nose import SkipTest
@@ -93,7 +93,7 @@
                 raise SkipTest(msg)
             else:
                 return fn(*args, **kw)
-        return function_named(maybe, fn_name)
+        return update_wrapper(maybe, fn)
     return decorate
 
 def requires_python_3(fn):
@@ -124,7 +124,7 @@
             return fn(*arg, **kw)
         finally:
             exceptions._install_highlighting()
-    return function_named(go, fn.__name__)
+    return update_wrapper(go, fn)
 
 class PlainCacheImpl(CacheImpl):
     """Simple memory cache impl so that tests which
diff --git a/test/test_ast.py b/test/test_ast.py
index 9f9ec10..32a1d74 100644
--- a/test/test_ast.py
+++ b/test/test_ast.py
@@ -1,7 +1,8 @@
 import unittest
 
 from mako import ast, exceptions, pyparser, util, compat
-from test import eq_, requires_python_2, requires_python_3
+from test import eq_, requires_python_2, requires_python_3, \
+            requires_python_26_or_greater
 
 exception_kwargs = {
     'source': '',
@@ -222,6 +223,28 @@
         eq_(parsed.declared_identifiers, set(['t1', 't2']))
         eq_(parsed.undeclared_identifiers, set())
 
+    @requires_python_26_or_greater
+    def test_locate_identifiers_16(self):
+        code = """
+try:
+    print(x)
+except Exception as e:
+    print(y)
+"""
+        parsed = ast.PythonCode(code, **exception_kwargs)
+        eq_(parsed.undeclared_identifiers, set(['x', 'y', 'Exception']))
+
+    @requires_python_26_or_greater
+    def test_locate_identifiers_17(self):
+        code = """
+try:
+    print(x)
+except (Foo, Bar) as e:
+    print(y)
+"""
+        parsed = ast.PythonCode(code, **exception_kwargs)
+        eq_(parsed.undeclared_identifiers, set(['x', 'y', 'Foo', 'Bar']))
+
     def test_no_global_imports(self):
         code = """
 from foo import *