- We use
blackas code formatter and recommend configuring your editor to run this automatically (using the version specified inrequirements.txt). Commits that are not properly formatted byblackwill be rejected in CI. - We update
requirements.txtinfrequently. It is important to install the versions of tools likeblackandmypyfromrequirements.txtinstead of running their latest versions (don't just useuvx). Older release branches likebranch6.5have their ownrequirements.txtso reinstall these tools (or switch virtualenvs) when switching branches. - The
types-pycurlpackage should be installed when runningmypy. - Run
flake8from the project root directory so it can see.flake8, this prevents spurious warnings. - Before committing, it is recommended to run
tox -e lint,docs,py3. This will verify that the code is formatted correctly, type checking withmypypasses, thesphinxbuild for docs has no errors, and the main test suite passes with the current version of python. - Nearly all code changes should have new or updated tests covering the changed behavior. Red/green TDD is encouraged.
- We use
toxas a test runner to run tests in various configurations with the correct dependencies.tox -e py3runs most of the tests, whiletox -e py3-fullcan be used to run a more extensive version of the test suite which as extra dependencies. The-fullconfigurations are necessary when working on certain modules, includingcurl_httpclient.py,twisted.py, orpycares.py. - The fastest way to run the tests is to bypass
toxand runpython3 -m tornado.test. To run a subset of tests, add a module, class, or method name to the command line:python3 -m tornado.test.httputil_test. - Tests can also be run with the standard library's
unittestpackage CLI. This is useful for integration with some editors. However, this mode skips a few checks, notably the requirement that tests do not generate any log output without corresponding ExpectLog assertions. - Tornado does not use
pytest. Some effort has been made to make the tests work with thepytestrunner, but this is not maintained. - Tests must run on Linux, macOS, and Windows (unless they are testing platform-dependent functionality, in which case they should be skipped on other platforms).
- Use mocks sparingly. Prefer to use real sockets, servers, etc as much as possible. It is rarely appropriate to use mocks just to speed up a test. The most common reason to use mocks in Tornado tests is to simulate error conditions that cannot be reproduced without mocks.
- Most tests are covered by a default 5 second timeout. This can be changed during
development with the env var
ASYNC_TEST_TIMEOUT, or with thetimeoutargument to@gen_test(although most tests should be made fast instead of given an increased timeout)
We use Sphinx with the autodoc extension to build our docs. To build the docs run
tox -e docs and find the output in ./.tox/docs/tmp/html/index.html
Tornado has a neutral stance towards AI-generated code. All pull requests, whether human or machine-generated, are subject to strict code review standards. However, PRs that appear to be AI-generated and contain clear flaws (such as failing CI) may be closed without detailed review.
- Older versions of pycurl bundled specific versions of libcurl. This can be an easy way
to test with old versions of libcurl. Specifically,
pycurl==7.45.4installs libcurl 8.11.1, which is not the oldest version of libcurl we support but is the oldest one that is easy to install. - Easy handles are pooled and reused (_free_list, reset in _finish), so per-request state leaking into the following request is a live bug class: test_reuse_proxy_credentials and test_reuse_certs both exist because of it. New per-request state deserves a reuse test with max_clients=1.
- That state is smuggled in a dict attached to the handle (curl.info, rebuilt in _process_queue). There is a standing TODO about the approach; until it is addressed, this is where such state goes.
- Run
tox -e lint,docs,py3locally and make sure it passes - If you modify
curl_httpclient.py, also runtox -e py3-full - Review your changes for any backwards incompatibilities that may affect downstream applications using Tornado