#3583·tornado

Support for __html__ method and marking variables as safe to use in templates to avoid escaping

Author: bhchCreated Mar 8, 2026Updated Mar 8, 2026

Feature

Something like Django's safestring or the markupsafe library.

A lot of libraries (wtforms, django, jinja, etc.) follow a convention for autoescaping that if an object implements a special method called __html__, the value returned by this method should be assumed as safe to use in templates and not be escaped.

e.g.:

class SafeString(str): 
    def __html__(self):
        return self

# escape function
def escape(value):
    if hasattr(value, "__html__"):
        return value.__html__()
    else:
        # escape normally
        ...

Obstacle

Although Tornado makes it easy to use a a custom autoescape function, the trouble is that tornado's template system converts str (and its subclass) instances to bytes. And during this conversion the information that it is a safe-marked variable (i.e. it has the __html__ method) is lost and the escape function has no way of knowing.

Possible solutions

1. Preserve the __html__ method during conversion

Can be done possibly in template.py or in escape.utf8 function.

This will allow interoperability with third party libs that inherit their SafeString class from str.

2. Provide a custom implementation of SafeString that inherits from bytes instead of str

This is what I'm currently doing in my project.

But to work with 3rd party libs I have to explicitly convert their safe str to my custom safe bytes, something like this:

{{ mark_safe(third_party_safe_str) }}

I think it's an essential feature for any template system. I don't see a reason why Tornado shouldn't have it built-in.