MarkupSafe

3.0.3 · active · verified Sat Mar 28

MarkupSafe implements a text object (Markup, a str subclass) that escapes characters so it is safe to use in HTML and XML. Characters with special meanings are replaced so they display as literal characters, mitigating injection attacks. It is the escaping backbone for Jinja2 and Flask. Current version is 3.0.3 (released Sep 2025); the project follows a feature-release + fix-branch cadence under the Pallets organization, with the 3.0.x branch as the active supported line.

Warnings

Install

Imports

Quickstart

Escape untrusted user input, build safe HTML with Markup.format(), and check idempotency of escape().

from markupsafe import Markup, escape

# Escape untrusted input — returns a Markup (str subclass)
user_input = "<script>alert('xss')</script>"
safe = escape(user_input)
print(safe)  # &lt;script&gt;alert(&#39;xss&#39;)&lt;/script&gt;

# escape() is idempotent: escaping a Markup object is a no-op
assert escape(safe) == safe

# Build HTML safely: use Markup.format() so arguments are auto-escaped
template = Markup("<p>Hello, <em>{name}</em>!</p>")
html = template.format(name='<World>')
print(html)  # <p>Hello, <em>&lt;World&gt;</em>!</p>

# Join a mixed list safely — use Markup.join(), NOT str.join()
lines = [Markup("<b>Title</b>"), "user & data"]
result = Markup("<br>").join(lines)
print(result)  # <b>Title</b><br>user &amp; data

# Check the version correctly (markupsafe.__version__ is deprecated)
import importlib.metadata
version = importlib.metadata.version("markupsafe")
print(version)

view raw JSON →