Inconsistent type hinting for UIModule methods
UIModule.render is typed to return a string whereas UIModule.render_string is typed to return bytes. The naming of render_string is probably a holdover from the Python 2 days and does in fact return bytes. I think the only thing strictly required to do here is to update render to indicate Union[str, bytes] as the return type since returning HTML as a str works in practice.
In general I think Union returns are ugly and it's usually better to standardize on one type or the other. I wish we could change render to return bytes, but I guess that has a lot of downstream impact on anyone using UIModules and type checking. So I guess introducing the Union is the less-bad option. I think the _ui_module helper function will need some small updates and maybe elsewhere but it shouldn't need too many changes.
And yes, the name render_string with return type bytes is leftover from the python 2 days. I think I'd use str for all template stuff if I were starting over in python 3, but as it is, tornado is pretty bytes-oriented.