.. code-block:: python
import asyncio
-
- import tornado.web
+ import tornado
class MainHandler(tornado.web.RequestHandler):
def get(self):
import os.path
import psycopg2
import re
-import tornado.escape
-import tornado.httpserver
-import tornado.ioloop
-import tornado.locks
-import tornado.options
-import tornado.web
+import tornado
import unicodedata
from tornado.options import define, options
# under the License.
import asyncio
-import tornado.escape
-import tornado.locks
-import tornado.web
+import tornado
import os.path
import uuid
import asyncio
import os.path
-import tornado.auth
-import tornado.escape
-import tornado.httpserver
-import tornado.options
-import tornado.web
+import tornado
from tornado.options import define, options
import logging
from urllib.parse import unquote
-import tornado.web
+import tornado
from tornado import options
# under the License.
import asyncio
-import tornado.httpserver
-import tornado.options
-import tornado.web
+import tornado
from tornado.options import define, options
import asyncio
import logging
-import tornado.escape
-import tornado.options
-import tornado.web
-import tornado.websocket
+import tornado
import os.path
import uuid
.. testsetup::
- import tornado.auth, tornado.gen, tornado.web
+ import tornado
.. automodule:: tornado.auth
.. testsetup::
- import tornado.auth
- import tornado.web
+ import tornado
Cookies and secure cookies
~~~~~~~~~~~~~~~~~~~~~~~~~~
.. testsetup::
- import tornado.web
+ import tornado
Structure of a Tornado web application
======================================
.. testcode::
import asyncio
-
- import tornado.web
+ import tornado
class MainHandler(tornado.web.RequestHandler):
def get(self):
.. testsetup::
- import tornado.web
+ import tornado
Tornado includes a simple, fast, and flexible templating language.
This section describes that language as well as related issues
Here is a simple "Hello, world" example web app for Tornado::
import asyncio
-
- import tornado.web
+ import tornado
class MainHandler(tornado.web.RequestHandler):
def get(self):
.. testsetup::
- import tornado.websocket
+ import tornado
.. automodule:: tornado.websocket
# number has been incremented)
version = "6.3.dev1"
version_info = (6, 3, 0, -100)
+
+import importlib
+import typing
+
+__all__ = [
+ "auth",
+ "autoreload",
+ "concurrent",
+ "curl_httpclient",
+ "escape",
+ "gen",
+ "http1connection",
+ "httpclient",
+ "httpserver",
+ "httputil",
+ "ioloop",
+ "iostream",
+ "locale",
+ "locks",
+ "log",
+ "netutil",
+ "options",
+ "platform",
+ "process",
+ "queues",
+ "routing",
+ "simple_httpclient",
+ "tcpclient",
+ "tcpserver",
+ "template",
+ "testing",
+ "util",
+ "web",
+]
+
+
+# Copied from https://peps.python.org/pep-0562/
+def __getattr__(name: str) -> typing.Any:
+ if name in __all__:
+ return importlib.import_module("." + name, __name__)
+ raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
import functools
import socket
- import tornado.ioloop
+ import tornado
from tornado.iostream import IOStream
async def handle_connection(connection, address):
.. testcode::
- import tornado.ioloop
- import tornado.iostream
import socket
+ import tornado
async def main():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
either `parse_command_line` or `parse_config_file`::
import myapp.db, myapp.server
- import tornado.options
+ import tornado
if __name__ == '__main__':
tornado.options.parse_command_line()
import unittest
-import tornado.escape
+import tornado
from tornado.escape import (
utf8,
xhtml_escape,
import asyncio
asyncio.set_event_loop(None)
-import tornado.auth
-import tornado.autoreload
-import tornado.concurrent
-import tornado.escape
-import tornado.gen
-import tornado.http1connection
-import tornado.httpclient
-import tornado.httpserver
-import tornado.httputil
-import tornado.ioloop
-import tornado.iostream
-import tornado.locale
-import tornado.log
-import tornado.netutil
-import tornado.options
-import tornado.process
-import tornado.simple_httpclient
-import tornado.tcpserver
-import tornado.tcpclient
-import tornado.template
-import tornado.testing
-import tornado.util
-import tornado.web
-import tornado.websocket
-import tornado.wsgi
+import importlib
+import tornado
-try:
- import pycurl
-except ImportError:
- pass
-else:
- import tornado.curl_httpclient
+for mod in tornado.__all__:
+ if mod == "curl_httpclient":
+ # This module has extra dependencies; skip it if they're not installed.
+ try:
+ import pycurl
+ except ImportError:
+ continue
+ importlib.import_module(f"tornado.{mod}")
+"""
+
+_import_lazy = b"""
+import sys
+import tornado
+
+if "tornado.web" in sys.modules:
+ raise Exception("unexpected eager import")
+
+# Trigger a lazy import by referring to something in a submodule.
+tornado.web.RequestHandler
+
+if "tornado.web" not in sys.modules:
+ raise Exception("lazy import did not update sys.modules")
"""
proc.communicate(_import_everything)
self.assertEqual(proc.returncode, 0)
+ def test_lazy_import(self):
+ # Test that submodules can be referenced lazily after "import tornado"
+ proc = subprocess.Popen([sys.executable], stdin=subprocess.PIPE)
+ proc.communicate(_import_lazy)
+ self.assertEqual(proc.returncode, 0)
+
def test_import_aliases(self):
# Ensure we don't delete formerly-documented aliases accidentally.
import tornado.ioloop
import datetime
import unittest
-import tornado.escape
+import tornado
from tornado.escape import utf8
from tornado.util import (
raise_exc_info,
.. testcode::
import asyncio
- import tornado.web
+ import tornado
class MainHandler(tornado.web.RequestHandler):
def get(self):
import os
import sys
import struct
-import tornado.escape
import tornado.web
from urllib.parse import urlparse
import zlib