remove Python 2 from docs
diff --git a/docs/api.rst b/docs/api.rst
index 871b326..501a2c6 100644
--- a/docs/api.rst
+++ b/docs/api.rst
@@ -60,63 +60,6 @@
    configure autoescaping now instead of relying on the default.
 
 
-Unicode
--------
-
-Jinja is using Unicode internally which means that you have to pass Unicode
-objects to the render function or bytestrings that only consist of ASCII
-characters.  Additionally newlines are normalized to one end of line
-sequence which is per default UNIX style (``\n``).
-
-Python 2.x supports two ways of representing string objects.  One is the
-`str` type and the other is the `unicode` type, both of which extend a type
-called `basestring`.  Unfortunately the default is `str` which should not
-be used to store text based information unless only ASCII characters are
-used.  With Python 2.6 it is possible to make `unicode` the default on a per
-module level and with Python 3 it will be the default.
-
-To explicitly use a Unicode string you have to prefix the string literal
-with a `u`: ``u'Hänsel und Gretel sagen Hallo'``.  That way Python will
-store the string as Unicode by decoding the string with the character
-encoding from the current Python module.  If no encoding is specified this
-defaults to 'ASCII' which means that you can't use any non ASCII identifier.
-
-To set a better module encoding add the following comment to the first or
-second line of the Python module using the Unicode literal::
-
-    # -*- coding: utf-8 -*-
-
-We recommend utf-8 as Encoding for Python modules and templates as it's
-possible to represent every Unicode character in utf-8 and because it's
-backwards compatible to ASCII.  For Jinja the default encoding of templates
-is assumed to be utf-8.
-
-It is not possible to use Jinja to process non-Unicode data.  The reason
-for this is that Jinja uses Unicode already on the language level.  For
-example Jinja treats the non-breaking space as valid whitespace inside
-expressions which requires knowledge of the encoding or operating on an
-Unicode string.
-
-For more details about Unicode in Python have a look at the excellent
-`Unicode documentation`_.
-
-Another important thing is how Jinja is handling string literals in
-templates.  A naive implementation would be using Unicode strings for
-all string literals but it turned out in the past that this is problematic
-as some libraries are typechecking against `str` explicitly.  For example
-`datetime.strftime` does not accept Unicode arguments.  To not break it
-completely Jinja is returning `str` for strings that fit into ASCII and
-for everything else `unicode`:
-
->>> m = Template(u"{% set a, b = 'foo', 'föö' %}").module
->>> m.a
-'foo'
->>> m.b
-u'f\xf6\xf6'
-
-
-.. _Unicode documentation: https://docs.python.org/3/howto/unicode.html
-
 High Level API
 --------------
 
@@ -301,12 +244,12 @@
 --------------------
 
 Jinja uses Python naming rules. Valid identifiers can be any combination
-of Unicode characters accepted by Python.
+of characters accepted by Python.
 
 Filters and tests are looked up in separate namespaces and have slightly
 modified identifier syntax.  Filters and tests may contain dots to group
 filters and tests by topic.  For example it's perfectly valid to add a
-function into the filter dict and call it `to.unicode`.  The regular
+function into the filter dict and call it `to.str`.  The regular
 expression for filter and test identifiers is
 ``[a-zA-Z_][a-zA-Z0-9_]*(\.[a-zA-Z_][a-zA-Z0-9_]*)*```.
 
@@ -328,8 +271,8 @@
 
     .. attribute:: _undefined_hint
 
-        Either `None` or an unicode string with the error message for
-        the undefined object.
+        Either `None` or a string with the error message for the
+        undefined object.
 
     .. attribute:: _undefined_obj
 
@@ -367,27 +310,32 @@
 
 .. admonition:: Implementation
 
-    :class:`Undefined` objects are implemented by overriding the special
-    `__underscore__` methods.  For example the default :class:`Undefined`
-    class implements `__unicode__` in a way that it returns an empty
-    string, however `__int__` and others still fail with an exception.  To
-    allow conversion to int by returning ``0`` you can implement your own::
+    :class:`Undefined` is implemented by overriding the special
+    ``__underscore__`` methods. For example the default
+    :class:`Undefined` class implements ``__str__`` to returns an empty
+    string, while ``__int__`` and others fail with an exception. To
+    allow conversion to int by returning ``0`` you can implement your
+    own subclass.
+
+    .. code-block:: python
 
         class NullUndefined(Undefined):
             def __int__(self):
                 return 0
+
             def __float__(self):
                 return 0.0
 
-    To disallow a method, just override it and raise
-    :attr:`~Undefined._undefined_exception`.  Because this is a very common
-    idiom in undefined objects there is the helper method
-    :meth:`~Undefined._fail_with_undefined_error` that does the error raising
-    automatically.  Here a class that works like the regular :class:`Undefined`
-    but chokes on iteration::
+    To disallow a method, override it and raise
+    :attr:`~Undefined._undefined_exception`.  Because this is very
+    common there is the helper method
+    :meth:`~Undefined._fail_with_undefined_error` that raises the error
+    with the correct information. Here's a class that works like the
+    regular :class:`Undefined` but fails on iteration::
 
         class NonIterableUndefined(Undefined):
-            __iter__ = Undefined._fail_with_undefined_error
+            def __iter__(self):
+                self._fail_with_undefined_error()
 
 
 The Context
@@ -575,16 +523,6 @@
 
     env.policies['urlize.rel'] = 'nofollow noopener'
 
-``compiler.ascii_str``:
-    This boolean controls on Python 2 if Jinja should store ASCII only
-    literals as bytestring instead of unicode strings.  This used to be
-    always enabled for Jinja versions below 2.9 and now can be changed.
-    Traditionally it was done this way since some APIs in Python 2 failed
-    badly for unicode strings (for instance the datetime strftime API).
-    Now however sometimes the inverse is true (for instance str.format).
-    If this is set to False then all strings are stored as unicode
-    internally.
-
 ``truncate.leeway``:
     Configures the leeway default for the `truncate` filter.  Leeway as
     introduced in 2.9 but to restore compatibility with older templates
@@ -676,24 +614,20 @@
 
     .. attribute:: message
 
-        The error message as utf-8 bytestring.
+        The error message.
 
     .. attribute:: lineno
 
-        The line number where the error occurred
+        The line number where the error occurred.
 
     .. attribute:: name
 
-        The load name for the template as unicode string.
+        The load name for the template.
 
     .. attribute:: filename
 
-        The filename that loaded the template as bytestring in the encoding
-        of the file system (most likely utf-8 or mbcs on Windows systems).
-
-    The reason why the filename and error message are bytestrings and not
-    unicode strings is that Python 2.x is not using unicode for exceptions
-    and tracebacks as well as the compiler.  This will change with Python 3.
+        The filename that loaded the template in the encoding of the
+        file system (most likely utf-8, or mbcs on Windows systems).
 
 .. autoexception:: jinja2.TemplateRuntimeError
 
@@ -894,7 +828,7 @@
     that has to be created by :meth:`new_context` of the same template or
     a compatible template.  This render function is generated by the
     compiler from the template code and returns a generator that yields
-    unicode strings.
+    strings.
 
     If an exception in the template code happens the template engine will
     not rewrite the exception but pass through the original one.  As a
diff --git a/docs/extensions.rst b/docs/extensions.rst
index 7abed65..bb81f21 100644
--- a/docs/extensions.rst
+++ b/docs/extensions.rst
@@ -44,8 +44,7 @@
 .. method:: jinja2.Environment.install_gettext_translations(translations, newstyle=False)
 
     Installs a translation globally for the environment. The
-    ``translations`` object must implement ``gettext`` and ``ngettext``
-    (or ``ugettext`` and ``ungettext`` for Python 2).
+    ``translations`` object must implement ``gettext`` and ``ngettext``.
     :class:`gettext.NullTranslations`, :class:`gettext.GNUTranslations`,
     and `Babel`_\s ``Translations`` are supported.
 
@@ -63,8 +62,7 @@
 
     Install the given ``gettext`` and ``ngettext`` callables into the
     environment. They should behave exactly like
-    :func:`gettext.gettext` and :func:`gettext.ngettext` (or
-    ``ugettext`` and ``ungettext`` for Python 2).
+    :func:`gettext.gettext` and :func:`gettext.ngettext`.
 
     If ``newstyle`` is activated, the callables are wrapped to work like
     newstyle callables.  See :ref:`newstyle-gettext` for more information.
@@ -86,8 +84,8 @@
         found.
     -   ``function`` is the name of the ``gettext`` function used (if
         the string was extracted from embedded Python code).
-    -   ``message`` is the string itself (``unicode`` on Python 2), or a
-        tuple of strings for functions with multiple arguments.
+    -   ``message`` is the string itself, or a tuple of strings for
+        functions with multiple arguments.
 
     If `Babel`_ is installed, see :ref:`babel-integration` to extract
     the strings.
diff --git a/docs/faq.rst b/docs/faq.rst
index 294fef1..1e29e12 100644
--- a/docs/faq.rst
+++ b/docs/faq.rst
@@ -125,19 +125,18 @@
 
     {% set comments = get_latest_comments() %}
 
-My tracebacks look weird.  What's happening?
---------------------------------------------
+My tracebacks look weird. What's happening?
+-------------------------------------------
 
-If the debugsupport module is not compiled and you are using a Python
-installation without ctypes (Python 2.4 without ctypes, Jython or Google's
-AppEngine) Jinja is unable to provide correct debugging information and
-the traceback may be incomplete.  There is currently no good workaround
-for Jython or the AppEngine as ctypes is unavailable there and it's not
-possible to use the debugsupport extension.
+Jinja can rewrite tracebacks so they show the template lines numbers and
+source rather than the underlying compiled code, but this requires
+special Python support. CPython <3.7 requires ``ctypes``, and PyPy
+requires transparent proxy support.
 
-If you are working in the Google AppEngine development server you can
-whitelist the ctypes module to restore the tracebacks.  This however won't
-work in production environments::
+If you are using Google App Engine, ``ctypes`` is not available. You can
+make it available in development, but not in production.
+
+.. code-block:: python
 
     import os
     if os.environ.get('SERVER_SOFTWARE', '').startswith('Dev'):
@@ -147,25 +146,6 @@
 Credit for this snippet goes to `Thomas Johansson
 <https://stackoverflow.com/questions/3086091/debug-jinja2-in-google-app-engine/3694434#3694434>`_
 
-Why is there no Python 2.3/2.4/2.5/2.6/3.1/3.2/3.3 support?
------------------------------------------------------------
-
-Python 2.3 is missing a lot of features that are used heavily in Jinja.  This
-decision was made as with the upcoming Python 2.6 and 3.0 versions it becomes
-harder to maintain the code for older Python versions.  If you really need
-Python 2.3 support you either have to use Jinja 1 or other templating
-engines that still support 2.3.
-
-Python 2.4/2.5/3.1/3.2 support was removed when we switched to supporting
-Python 2 and 3 by the same sourcecode (without using 2to3). It was required to
-drop support because only Python 2.6/2.7 and >=3.3 support byte and unicode
-literals in a way compatible to each other version. If you really need support
-for older Python 2 (or 3) versions, you can just use Jinja 2.6.
-
-Python 2.6/3.3 support was dropped because it got dropped in various upstream
-projects (such as wheel or pytest), which would make it difficult to continue
-supporting it. Jinja 2.10 was the last version supporting Python 2.6/3.3.
-
 My Macros are overridden by something
 -------------------------------------
 
diff --git a/docs/index.rst b/docs/index.rst
index 65d5d3d..dcaa9ff 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -7,29 +7,9 @@
     :align: center
     :target: https://palletsprojects.com/p/jinja/
 
-Jinja is a modern and designer-friendly templating language for Python,
-modelled after Django's templates.  It is fast, widely used and secure
-with the optional sandboxed template execution environment:
-
-.. sourcecode:: html+jinja
-
-   <title>{% block title %}{% endblock %}</title>
-   <ul>
-   {% for user in users %}
-     <li><a href="{{ user.url }}">{{ user.username }}</a></li>
-   {% endfor %}
-   </ul>
-
-Features:
-
--   sandboxed execution
--   powerful automatic HTML escaping system for XSS prevention
--   template inheritance
--   compiles down to the optimal python code just in time
--   optional ahead-of-time template compilation
--   easy to debug.  Line numbers of exceptions directly point to
-    the correct line in the template.
--   configurable syntax
+Jinja is a fast, expressive, extensible templating engine. Special
+placeholders in the template allow writing code similar to Python
+syntax. Then the template is passed data to render the final document.
 
 .. toctree::
     :maxdepth: 2
@@ -46,6 +26,3 @@
     tricks
     faq
     changelog
-
-* :ref:`genindex`
-* :ref:`search`
diff --git a/docs/intro.rst b/docs/intro.rst
index c20c5e9..25c2b58 100644
--- a/docs/intro.rst
+++ b/docs/intro.rst
@@ -1,82 +1,63 @@
 Introduction
 ============
 
-This is the documentation for the Jinja general purpose templating language.
-Jinja is a library for Python that is designed to be flexible, fast and secure.
+Jinja is a fast, expressive, extensible templating engine. Special
+placeholders in the template allow writing code similar to Python
+syntax. Then the template is passed data to render the final document.
 
-If you have any exposure to other text-based template languages, such as Smarty or
-Django, you should feel right at home with Jinja.  It's both designer and
-developer friendly by sticking to Python's principles and adding functionality
-useful for templating environments.
+It includes:
 
-Prerequisites
--------------
+-   Template inheritance and inclusion.
+-   Define and import macros within templates.
+-   HTML templates can use autoescaping to prevent XSS from untrusted
+    user input.
+-   A sandboxed environment can safely render untrusted templates.
+-   AsyncIO support for generating templates and calling async
+    functions.
+-   I18N support with Babel.
+-   Templates are compiled to optimized Python code just-in-time and
+    cached, or can be compiled ahead-of-time.
+-   Exceptions point to the correct line in templates to make debugging
+    easier.
+-   Extensible filters, tests, functions, and even syntax.
 
-Jinja works with Python 2.7.x and >= 3.5.  If you are using Python
-3.2 you can use an older release of Jinja (2.6) as support for Python 3.2
-was dropped in Jinja version 2.7. The last release which supported Python 2.6
-and 3.3 was Jinja 2.10.
+Jinja's philosophy is that while application logic belongs in Python if
+possible, it shouldn't make the template designer's job difficult by
+restricting functionality too much.
 
-If you wish to use the :class:`~jinja2.PackageLoader` class, you will also
-need `setuptools`_ or `distribute`_ installed at runtime.
 
 Installation
 ------------
 
-You can install the most recent Jinja version using `pip`_::
+We recommend using the latest version of Python. Jinja supports Python
+3.6 and newer. We also recommend using a `virtual environment`_ in order
+to isolate your project dependencies from other projects and the system.
 
-    pip install Jinja2
+.. _virtual environment: https://packaging.python.org/tutorials/installing-packages/#creating-virtual-environments
 
-This will install Jinja in your Python installation's site-packages directory.
+Install the most recent Jinja version using pip:
 
-Installing the development version
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.. code-block:: text
 
-1.  Install `git`_
-2.  ``git clone git://github.com/pallets/jinja.git``
-3.  ``cd jinja2``
-4.  ``ln -s jinja2 /usr/lib/python2.X/site-packages``
-
-As an alternative to steps 4 you can also do ``python setup.py develop``
-which will install the package via `distribute` in development mode.  This also
-has the advantage that the C extensions are compiled.
-
-.. _distribute: https://pypi.org/project/distribute/
-.. _setuptools: https://pypi.org/project/setuptools/
-.. _pip: https://pypi.org/project/pip/
-.. _git: https://git-scm.com/
+    $ pip install Jinja2
 
 
-MarkupSafe Dependency
-~~~~~~~~~~~~~~~~~~~~~
+Dependencies
+~~~~~~~~~~~~
 
-As of version 2.7 Jinja depends on the `MarkupSafe`_ module. If you install
-Jinja via ``pip`` it will be installed automatically for you.
+These will be installed automatically when installing Jinja.
+
+-   `MarkupSafe`_ escapes untrusted input when rendering templates to
+    avoid injection attacks.
 
 .. _MarkupSafe: https://markupsafe.palletsprojects.com/
 
-Basic API Usage
----------------
 
-This section gives you a brief introduction to the Python API for Jinja
-templates.
+Optional Dependencies
+~~~~~~~~~~~~~~~~~~~~~
 
-The most basic way to create a template and render it is through
-:class:`~jinja2.Template`.  This however is not the recommended way to
-work with it if your templates are not loaded from strings but the file
-system or another data source:
+These distributions will not be installed automatically.
 
->>> from jinja2 import Template
->>> template = Template('Hello {{ name }}!')
->>> template.render(name='John Doe')
-u'Hello John Doe!'
+-   `Babel`_ provides translation support in templates.
 
-By creating an instance of :class:`~jinja2.Template` you get back a new template
-object that provides a method called :meth:`~jinja2.Template.render` which when
-called with a dict or keyword arguments expands the template.  The dict
-or keywords arguments passed to the template are the so-called "context"
-of the template.
-
-What you can see here is that Jinja is using unicode internally and the
-return value is an unicode string.  So make sure that your application is
-indeed using unicode internally.
+.. _Babel: http://babel.pocoo.org/
diff --git a/docs/switching.rst b/docs/switching.rst
index 8225b2e..b9ff954 100644
--- a/docs/switching.rst
+++ b/docs/switching.rst
@@ -32,12 +32,12 @@
     with optional additional configuration.
 
 Automatic unicode conversion
-    Jinja 1 performed automatic conversion of bytestrings in a given encoding
-    into unicode objects.  This conversion is no longer implemented as it
-    was inconsistent as most libraries are using the regular Python ASCII
-    bytestring to Unicode conversion.  An application powered by Jinja 2
-    *has to* use unicode internally everywhere or make sure that Jinja 2 only
-    gets unicode strings passed.
+    Jinja 1 performed automatic conversion of bytes in a given encoding
+    into unicode objects. This conversion is no longer implemented as it
+    was inconsistent as most libraries are using the regular Python
+    ASCII bytes to Unicode conversion. An application powered by Jinja 2
+    *has to* use unicode internally everywhere or make sure that Jinja 2
+    only gets unicode strings passed.
 
 i18n
     Jinja 1 used custom translators for internationalization.  i18n is now
diff --git a/docs/templates.rst b/docs/templates.rst
index 89c2a50..c08ce4b 100644
--- a/docs/templates.rst
+++ b/docs/templates.rst
@@ -602,9 +602,8 @@
 Jinja functions (macros, `super`, `self.BLOCKNAME`) always return template
 data that is marked as safe.
 
-String literals in templates with automatic escaping are considered unsafe
-because native Python strings (``str``, ``unicode``, ``basestring``) are not
-`MarkupSafe.Markup` strings with an ``__html__`` attribute.
+String literals in templates with automatic escaping are considered
+unsafe because native Python strings are not safe.
 
 .. _list-of-control-structures:
 
diff --git a/src/jinja2/bccache.py b/src/jinja2/bccache.py
index 9c06610..ff4d606 100644
--- a/src/jinja2/bccache.py
+++ b/src/jinja2/bccache.py
@@ -284,7 +284,7 @@
     -   `python-memcached <https://pypi.org/project/python-memcached/>`_
 
     (Unfortunately the django cache interface is not compatible because it
-    does not support storing binary data, only unicode.  You can however pass
+    does not support storing binary data, only text. You can however pass
     the underlying cache client to the bytecode cache which is available
     as `django.core.cache.cache._client`.)
 
diff --git a/src/jinja2/environment.py b/src/jinja2/environment.py
index 8430390..3f75816 100644
--- a/src/jinja2/environment.py
+++ b/src/jinja2/environment.py
@@ -1081,7 +1081,7 @@
             template.render(knights='that say nih')
             template.render({'knights': 'that say nih'})
 
-        This will return the rendered template as unicode string.
+        This will return the rendered template as a string.
         """
         vars = dict(*args, **kwargs)
         try:
@@ -1113,7 +1113,7 @@
         """For very large templates it can be useful to not render the whole
         template at once but evaluate each statement after another and yield
         piece for piece.  This method basically does exactly that and returns
-        a generator that yields one item after another as unicode strings.
+        a generator that yields one item after another as strings.
 
         It accepts the same arguments as :meth:`render`.
         """
@@ -1223,7 +1223,7 @@
 class TemplateModule(object):
     """Represents an imported template.  All the exported names of the
     template are available as attributes on this object.  Additionally
-    converting it into an unicode- or bytestrings renders the contents.
+    converting it into a string renders the contents.
     """
 
     def __init__(self, template, context, body_stream=None):
@@ -1278,10 +1278,10 @@
     """A template stream works pretty much like an ordinary python generator
     but it can buffer multiple items to reduce the number of total iterations.
     Per default the output is unbuffered which means that for every unbuffered
-    instruction in the template one unicode string is yielded.
+    instruction in the template one string is yielded.
 
     If buffering is enabled with a buffer size of 5, five items are combined
-    into a new unicode string.  This is mainly useful if you are streaming
+    into a new string.  This is mainly useful if you are streaming
     big templates to a client via WSGI which flushes after each iteration.
     """
 
@@ -1291,7 +1291,7 @@
 
     def dump(self, fp, encoding=None, errors="strict"):
         """Dump the complete stream into a file or file-like object.
-        Per default unicode strings are written, if you want to encode
+        Per default strings are written, if you want to encode
         before writing specify an `encoding`.
 
         Example usage::
diff --git a/src/jinja2/ext.py b/src/jinja2/ext.py
index 9141be4..99ecb34 100644
--- a/src/jinja2/ext.py
+++ b/src/jinja2/ext.py
@@ -538,8 +538,8 @@
     * ``lineno`` is the number of the line on which the string was found,
     * ``function`` is the name of the ``gettext`` function used (if the
       string was extracted from embedded Python code), and
-    *  ``message`` is the string itself (a ``unicode`` object, or a tuple
-       of ``unicode`` objects for functions with multiple string arguments).
+    *   ``message`` is the string, or a tuple of strings for functions
+         with multiple string arguments.
 
     This extraction function operates on the AST and is because of that unable
     to extract any comments.  For comment support you have to use the babel
diff --git a/src/jinja2/lexer.py b/src/jinja2/lexer.py
index a2b44e9..8e73be8 100644
--- a/src/jinja2/lexer.py
+++ b/src/jinja2/lexer.py
@@ -607,7 +607,9 @@
         }
 
     def _normalize_newlines(self, value):
-        """Called for strings and template data to normalize it to unicode."""
+        """Replace all newlines with the configured sequence in strings
+        and template data.
+        """
         return newline_re.sub(self.newline_sequence, value)
 
     def tokenize(self, source, name=None, filename=None, state=None):
diff --git a/src/jinja2/loaders.py b/src/jinja2/loaders.py
index ce5537a..0a5538a 100644
--- a/src/jinja2/loaders.py
+++ b/src/jinja2/loaders.py
@@ -77,9 +77,9 @@
         `TemplateNotFound` error if it can't locate the template.
 
         The source part of the returned tuple must be the source of the
-        template as unicode string or a ASCII bytestring.  The filename should
-        be the name of the file on the filesystem if it was loaded from there,
-        otherwise `None`.  The filename is used by python for the tracebacks
+        template as a string. The filename should be the name of the
+        file on the filesystem if it was loaded from there, otherwise
+        ``None``. The filename is used by Python for the tracebacks
         if no loader extension is used.
 
         The last item in the tuple is the `uptodate` function.  If auto
@@ -357,8 +357,8 @@
 
 
 class DictLoader(BaseLoader):
-    """Loads a template from a python dict.  It's passed a dict of unicode
-    strings bound to template names.  This loader is useful for unittesting:
+    """Loads a template from a Python dict mapping template names to
+    template source.  This loader is useful for unittesting:
 
     >>> loader = DictLoader({'index.html': 'source here'})
 
@@ -381,7 +381,7 @@
 class FunctionLoader(BaseLoader):
     """A loader that is passed a function which does the loading.  The
     function receives the name of the template and has to return either
-    an unicode string with the template source, a tuple in the form ``(source,
+    a string with the template source, a tuple in the form ``(source,
     filename, uptodatefunc)`` or `None` if the template does not exist.
 
     >>> def load_template(name):
diff --git a/src/jinja2/nodes.py b/src/jinja2/nodes.py
index 95bd614..c0b6d77 100644
--- a/src/jinja2/nodes.py
+++ b/src/jinja2/nodes.py
@@ -788,8 +788,8 @@
 
 
 class Concat(Expr):
-    """Concatenates the list of expressions provided after converting them to
-    unicode.
+    """Concatenates the list of expressions provided after converting
+    them to strings.
     """
 
     fields = ("nodes",)
diff --git a/src/jinja2/runtime.py b/src/jinja2/runtime.py
index 3ad7968..8df42c5 100644
--- a/src/jinja2/runtime.py
+++ b/src/jinja2/runtime.py
@@ -60,7 +60,7 @@
 
 
 def markup_join(seq):
-    """Concatenation that escapes if necessary and converts to unicode."""
+    """Concatenation that escapes if necessary and converts to string."""
     buf = []
     iterator = imap(soft_unicode, seq)
     for arg in iterator:
@@ -71,7 +71,7 @@
 
 
 def unicode_join(seq):
-    """Simple args to unicode conversion and concatenation."""
+    """Simple args to string conversion and concatenation."""
     return concat(imap(text_type, seq))
 
 
diff --git a/src/jinja2/sandbox.py b/src/jinja2/sandbox.py
index cfd7993..3bb0145 100644
--- a/src/jinja2/sandbox.py
+++ b/src/jinja2/sandbox.py
@@ -244,8 +244,7 @@
     >>> modifies_known_mutable([], "index")
     False
 
-    If called with an unsupported object (such as unicode) `False` is
-    returned.
+    If called with an unsupported object, ``False`` is returned.
 
     >>> modifies_known_mutable("foo", "upper")
     False