title: Using re.sub with jinja2.Markup escaping in Python 3.6?
body: <p>So I have the following function in my Flask app.</p>
  
  <pre><code>def markup_abbreviations(txt, match_map, match_regex):
      html = Markup.escape(txt)
      sub_template = Markup('&lt;abbr title="%s"&gt;%s&lt;/abbr&gt;')
  
      def replace_callback(m):
          return sub_template % (match_map[m.group(0)], m.group(0))
  
      return match_regex.sub(replace_callback, html)
  </code></pre>
  
  <p>Example arguments:</p>
  
  <pre><code>txt = 'blah blah blah etc., blah blah'
  
  match_map = {
      'etc.': 'et cetera',
      'usu.': 'usually',
  }
  
  match_regex = re.compile(
      '|'.join(r'\b' + re.escape(k) for k in match_map)
  )
  </code></pre>
  
  <p>This was working very well and turning <code>"etc."</code> into <code>"&lt;abbr title=\"et cetera\"&gt;etc.&lt;/abbr&gt;"</code> and so on in my local Python 3.3 machine.</p>
  
  <p>Then I figure I want to deploy to Heroku, and it says it only supports the latest python, which is Python 3.6.1. It's different from the one I got locally, but, eh, whatever. It works... mostly.</p>
  
  <p>Except my function above gives me <code>"&amp;lt;abbr title=&amp;quot;et cetera&amp;quot;&amp;gt;etc.&amp;lt;/abbr&amp;gt;"</code> now.</p>
  
  <p>I assume between Python 3.3 and Python 3.6 the <code>re.sub</code> implementation must have changed somehow and now it no longer uses the passed string methods to create the output. So <code>Markup</code>'s auto-escaping methods aren't used. Instead a new <code>str</code> is built from scratch. Which is why <code>re.sub</code> only returns <code>str</code> now, and not <code>Markup</code> anymore.</p>
  
  <p>How can I use <code>re.sub</code> with <code>jinja2.Markup</code> in Python 3.6 and make my function work once again?</p>