- use inlined getargspec
- The "output encoding" now defaults
  to "ascii", whereas previously
  it was set to None.  This has the effect
  of FastEncodingBuffer being used internally
  by default when render() is called, instead
  of cStringIO or StringIO, which are
  slower, but allow bytestrings with
  unknown encoding to pass right through.
  It is of course not recommended to use
  bytestrings of unknown encoding. Usage of
  the "disable_unicode" mode also requires
  that output_encoding be set to None.
diff --git a/CHANGES b/CHANGES
index c993ad6..51189eb 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,21 @@
+0.4.0
+- The "output encoding" now defaults
+  to "ascii", whereas previously
+  it was set to None.  This has the effect
+  of FastEncodingBuffer being used internally
+  by default when render() is called, instead 
+  of cStringIO or StringIO, which are 
+  slower, but allow bytestrings with 
+  unknown encoding to pass right through.  
+  It is of course not recommended to use 
+  bytestrings of unknown encoding. Usage of
+  the "disable_unicode" mode also requires
+  that output_encoding be set to None.
+
+- the <%namespace> tag raises an error
+  if the 'template' and 'module' attributes
+  are specified at the same time.
+
 0.3.6
 - Documentation is on Sphinx.
   [ticket:126]
diff --git a/mako/__init__.py b/mako/__init__.py
index b61cb80..78b4191 100644
--- a/mako/__init__.py
+++ b/mako/__init__.py
@@ -5,5 +5,5 @@
 # the MIT License: http://www.opensource.org/licenses/mit-license.php
 
 
-__version__ = '0.3.6'
+__version__ = '0.4.0'
 
diff --git a/mako/filters.py b/mako/filters.py
index a5e414e..30c792f 100644
--- a/mako/filters.py
+++ b/mako/filters.py
@@ -27,8 +27,7 @@
 
 try:
     import markupsafe
-    def html_escape(string):
-        return markupsafe.escape(string)
+    html_escape = markupsafe.escape
 except ImportError:
     html_escape = legacy_html_escape
 
diff --git a/mako/lookup.py b/mako/lookup.py
index a8fd6c0..7450700 100644
--- a/mako/lookup.py
+++ b/mako/lookup.py
@@ -148,7 +148,7 @@
                         format_exceptions=False, 
                         error_handler=None, 
                         disable_unicode=False, 
-                        output_encoding=None, 
+                        output_encoding='ascii', 
                         encoding_errors='strict', 
                         cache_type=None, 
                         cache_dir=None, cache_url=None,
diff --git a/mako/runtime.py b/mako/runtime.py
index e0df124..c13de21 100644
--- a/mako/runtime.py
+++ b/mako/runtime.py
@@ -662,7 +662,7 @@
     return context._pop_buffer().getvalue()
 
 def _kwargs_for_callable(callable_, data):
-    argspec = inspect.getargspec(callable_)
+    argspec = util.inspect_func_args(callable_)
     # for normal pages, **pageargs is usually present
     if argspec[2]:
         return data
@@ -676,7 +676,7 @@
     return kwargs
 
 def _kwargs_for_include(callable_, data, **kwargs):
-    argspec = inspect.getargspec(callable_)
+    argspec = util.inspect_func_args(callable_)
     namedargs = argspec[0] + [v for v in argspec[1:3] if v is not None]
     for arg in namedargs:
         if arg != 'context' and arg in data and arg not in kwargs:
diff --git a/mako/template.py b/mako/template.py
index 5c67b14..f93be79 100644
--- a/mako/template.py
+++ b/mako/template.py
@@ -127,7 +127,7 @@
                     format_exceptions=False, 
                     error_handler=None, 
                     lookup=None, 
-                    output_encoding=None, 
+                    output_encoding='ascii', 
                     encoding_errors='strict', 
                     module_directory=None, 
                     cache_type=None, 
@@ -164,7 +164,10 @@
             raise exceptions.UnsupportedError(
                                     "Mako for Python 3 does not "
                                     "support disabling Unicode")
- 
+        elif output_encoding and disable_unicode:
+            raise exceptions.UnsupportedError(
+                                    "output_encoding must be set to "
+                                    "None when disable_unicode is used.")
         if default_filters is None:
             if util.py3k or self.disable_unicode:
                 self.default_filters = ['str']
diff --git a/mako/util.py b/mako/util.py
index f6ef125..23a3277 100644
--- a/mako/util.py
+++ b/mako/util.py
@@ -324,3 +324,27 @@
 
     _ast.In = type(m.body[12].value.ops[0])
     _ast.NotIn = type(m.body[12].value.ops[1])
+
+
+try:
+    from inspect import CO_VARKEYWORDS, CO_VARARGS
+    def inspect_func_args(fn):
+        co = fn.func_code
+
+        nargs = co.co_argcount
+        names = co.co_varnames
+        args = list(names[:nargs])
+
+        varargs = None
+        if co.co_flags & CO_VARARGS:
+            varargs = co.co_varnames[nargs]
+            nargs = nargs + 1
+        varkw = None
+        if co.co_flags & CO_VARKEYWORDS:
+            varkw = co.co_varnames[nargs]
+
+        return args, varargs, varkw, fn.func_defaults
+except ImportError:
+    import inspect
+    def inspect_func_args(fn):
+        return inspect.getargspec(fn)
diff --git a/test/test_filters.py b/test/test_filters.py
index 2958711..13492d8 100644
--- a/test/test_filters.py
+++ b/test/test_filters.py
@@ -43,7 +43,8 @@
     def test_quoting_non_unicode(self):
         t = Template("""
             foo ${bar | h}
-        """, disable_unicode=True)
+        """, disable_unicode=True,
+        output_encoding=None)
 
         eq_(
             flatten_result(t.render(bar="<'привет'>")),
diff --git a/test/test_template.py b/test/test_template.py
index 3d489f7..ba47885 100644
--- a/test/test_template.py
+++ b/test/test_template.py
@@ -288,7 +288,8 @@
             "hello śląsk",
             default_filters=[],
             template_args={'x':'śląsk'},
-            unicode_=False
+            unicode_=False,
+            output_encoding=None #'ascii'
         )
 
         # now, the way you *should* be doing it....
@@ -330,6 +331,7 @@
             '毛泽东 是 新中国的主席<br/> Welcome 你 to 北京. Welcome 你 to 北京.',
             default_filters=[],
             disable_unicode=True,
+            output_encoding=None,
             template_args={'name':'毛泽东'},
             filters=flatten_result, 
             unicode_=False
@@ -339,18 +341,37 @@
             'chs_utf8.html',
             '毛泽东 是 新中国的主席<br/> Welcome 你 to 北京. Welcome 你 to 北京.',
             disable_unicode=True,
+            output_encoding=None,
             template_args={'name':'毛泽东'},
             filters=flatten_result,
             unicode_=False
         )
 
-        template = self._file_template('chs_utf8.html', disable_unicode=True)
+        template = self._file_template('chs_utf8.html', 
+                    output_encoding=None,
+                    disable_unicode=True)
         self.assertRaises(UnicodeDecodeError, template.render_unicode, name='毛泽东')
 
-        template = Template("""${'Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »'}""", disable_unicode=True, input_encoding='utf-8')
-        assert template.render() == """Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »"""
-        template = Template("""${'Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »'}""", input_encoding='utf8', output_encoding='utf8', disable_unicode=False, default_filters=[])
-        self.assertRaises(UnicodeDecodeError, template.render)  # raises because expression contains an encoded bytestring which cannot be decoded
+        template = Template(
+            "${'Alors vous imaginez ma surprise, au lever"
+            " du jour, quand une drôle de petite voix m’a "
+            "réveillé. Elle disait: « S’il vous plaît… "
+            "dessine-moi un mouton! »'}", 
+            output_encoding=None,
+            disable_unicode=True, input_encoding='utf-8')
+        assert template.render() == "Alors vous imaginez ma surprise, "\
+                "au lever du jour, quand une drôle de petite "\
+                "voix m’a réveillé. Elle disait: « S’il vous "\
+                "plaît… dessine-moi un mouton! »"
+        template = Template(
+                "${'Alors vous imaginez ma surprise, au "
+                "lever du jour, quand une drôle de petite "
+                "voix m’a réveillé. Elle disait: « S’il "
+                "vous plaît… dessine-moi un mouton! »'}", 
+                input_encoding='utf8', output_encoding='utf8', 
+                disable_unicode=False, default_filters=[])
+        # raises because expression contains an encoded bytestring which cannot be decoded
+        self.assertRaises(UnicodeDecodeError, template.render)
 
 
 class PageArgsTest(TemplateTest):