# Create temporary test application
os.mkdir(os.path.join(self.path, "testapp"))
- open(os.path.join(self.path, "testapp/__init__.py"), "w").close()
- with open(os.path.join(self.path, "testapp/__main__.py"), "w") as f:
+ open(
+ os.path.join(self.path, "testapp/__init__.py"), "w", encoding="utf-8"
+ ).close()
+ with open(
+ os.path.join(self.path, "testapp/__main__.py"), "w", encoding="utf-8"
+ ) as f:
f.write(main)
# Make sure the tornado module under test is available to the test
cwd=self.path,
env=dict(os.environ, PYTHONPATH=pythonpath),
universal_newlines=True,
+ encoding="utf-8",
)
out = p.communicate()[0]
self.assertEqual(out, "Starting\nStarting\n")
# Create temporary test application
os.mkdir(os.path.join(self.path, "testapp"))
init_file = os.path.join(self.path, "testapp", "__init__.py")
- open(init_file, "w").close()
+ open(init_file, "w", encoding="utf-8").close()
main_file = os.path.join(self.path, "testapp", "__main__.py")
- with open(main_file, "w") as f:
+ with open(main_file, "w", encoding="utf-8") as f:
f.write(main)
# Make sure the tornado module under test is available to the test
cwd=self.path,
env=dict(os.environ, PYTHONPATH=pythonpath),
universal_newlines=True,
+ encoding="utf-8",
)
# This timeout needs to be fairly generous for pypy due to jit
os.rmdir(self.tempdir)
def make_handler(self, filename):
- # Base case: default setup without explicit encoding.
- # In python 2, supports arbitrary byte strings and unicode objects
- # that contain only ascii. In python 3, supports ascii-only unicode
- # strings (but byte strings will be repr'd automatically).
- return logging.FileHandler(filename)
+ return logging.FileHandler(filename, encoding="utf-8")
def get_output(self):
with open(self.filename, "rb") as f:
# The traceback contains newlines, which should not have been escaped.
self.assertNotIn(rb"\n", output)
-
-class UnicodeLogFormatterTest(LogFormatterTest):
- def make_handler(self, filename):
- # Adding an explicit encoding configuration allows non-ascii unicode
- # strings in both python 2 and 3, without changing the behavior
- # for byte strings.
- return logging.FileHandler(filename, encoding="utf8")
-
def test_unicode_logging(self):
self.logger.error("\u00e9")
self.assertEqual(self.get_output(), utf8("\u00e9"))
self.logger.handlers[0].flush()
filenames = glob.glob(tmpdir + "/test_log*")
self.assertEqual(1, len(filenames))
- with open(filenames[0]) as f:
+ with open(filenames[0], encoding="utf-8") as f:
self.assertRegex(f.read(), r"^\[E [^]]*\] hello$")
finally:
for handler in self.logger.handlers:
self.logger.handlers[0].flush()
filenames = glob.glob(tmpdir + "/test_log*")
self.assertEqual(1, len(filenames))
- with open(filenames[0]) as f:
+ with open(filenames[0], encoding="utf-8") as f:
self.assertRegex(f.read(), r"^\[E [^]]*\] hello$")
finally:
for handler in self.logger.handlers:
warnings.filterwarnings(
"error", category=PendingDeprecationWarning, module=r"tornado\..*"
)
- # The unittest module is aggressive about deprecating redundant methods,
- # leaving some without non-deprecated spellings that work on both
- # 2.7 and 3.2
- warnings.filterwarnings(
- "ignore", category=DeprecationWarning, message="Please use assert.* instead"
- )
- warnings.filterwarnings(
- "ignore",
- category=PendingDeprecationWarning,
- message="Please use assert.* instead",
- )
- # Twisted 15.0.0 triggers some warnings on py3 with -bb.
- warnings.filterwarnings("ignore", category=BytesWarning, module=r"twisted\..*")
- if (3,) < sys.version_info < (3, 6):
- # Prior to 3.6, async ResourceWarnings were rather noisy
- # and even
- # `python3.4 -W error -c 'import asyncio; asyncio.get_event_loop()'`
- # would generate a warning.
- warnings.filterwarnings(
- "ignore", category=ResourceWarning, module=r"asyncio\..*"
- )
- # This deprecation warning is introduced in Python 3.8 and is
- # triggered by pycurl. Unforunately, because it is raised in the C
- # layer it can't be filtered by module and we must match the
- # message text instead (Tornado's C module uses PY_SSIZE_T_CLEAN
- # so it's not at risk of running into this issue).
- warnings.filterwarnings(
- "ignore",
- category=DeprecationWarning,
- message="PY_SSIZE_T_CLEAN will be required",
- )
logging.getLogger("tornado.access").setLevel(logging.CRITICAL)
# to ``Range: bytes=0-`` :(
self.assertEqual(response.code, 200)
robots_file_path = os.path.join(self.static_dir, "robots.txt")
- with open(robots_file_path) as f:
+ with open(robots_file_path, encoding="utf-8") as f:
self.assertEqual(response.body, utf8(f.read()))
self.assertEqual(response.headers.get("Content-Length"), "26")
self.assertEqual(response.headers.get("Content-Range"), None)
)
self.assertEqual(response.code, 200)
robots_file_path = os.path.join(self.static_dir, "robots.txt")
- with open(robots_file_path) as f:
+ with open(robots_file_path, encoding="utf-8") as f:
self.assertEqual(response.body, utf8(f.read()))
self.assertEqual(response.headers.get("Content-Length"), "26")
self.assertEqual(response.headers.get("Content-Range"), None)
)
self.assertEqual(response.code, 206)
robots_file_path = os.path.join(self.static_dir, "robots.txt")
- with open(robots_file_path) as f:
+ with open(robots_file_path, encoding="utf-8") as f:
self.assertEqual(response.body, utf8(f.read()[1:]))
self.assertEqual(response.headers.get("Content-Length"), "25")
self.assertEqual(response.headers.get("Content-Range"), "bytes 1-25/26")
)
self.assertEqual(response.code, 200)
robots_file_path = os.path.join(self.static_dir, "robots.txt")
- with open(robots_file_path) as f:
+ with open(robots_file_path, encoding="utf-8") as f:
self.assertEqual(response.body, utf8(f.read()))
self.assertEqual(response.headers.get("Content-Length"), "26")
self.assertEqual(response.headers.get("Content-Range"), None)
setenv =
# Treat the extension as mandatory in testing (but not on pypy)
- {py3,py38,py39,py310,py311}: TORNADO_EXTENSION=1
+ {py3,py38,py39,py310,py311,py312}: TORNADO_EXTENSION=1
# CI workers are often overloaded and can cause our tests to exceed
# the default timeout of 5s.
ASYNC_TEST_TIMEOUT=25
# possible to set environment variables during that phase of
# tox).
{py3,py38,py39,py310,py311,pypy3}: PYTHONWARNINGS=error:::tornado
-
+ # Warn if we try to open a file with an unspecified encoding.
+ # (New in python 3.10, becomes obsolete when utf8 becomes the
+ # default in 3.15)
+ PYTHONWARNDEFAULTENCODING=1
# Allow shell commands in tests
allowlist_externals = sh
# the trap of relying on an assertion's side effects or using
# them for things that should be runtime errors.
full: python -O -m tornado.test
- # In python 3, opening files in text mode uses a
- # system-dependent encoding by default. Run the tests with "C"
- # (ascii) and "utf-8" locales to ensure we don't have hidden
- # dependencies on this setting.
- full: sh -c 'LANG=C python -m tornado.test'
- full: sh -c 'LANG=en_US.utf-8 python -m tornado.test'
# Note that httpclient_test is always run with both client
# implementations; this flag controls which client all the
# other tests use.
full: python -m tornado.test --httpclient=tornado.curl_httpclient.CurlAsyncHTTPClient
full: python -m tornado.test --resolver=tornado.platform.caresresolver.CaresResolver
- # Run the tests once from the source directory to detect issues
- # involving relative __file__ paths; see
- # https://github.com/tornadoweb/tornado/issues/1780
- full: sh -c '(cd {toxinidir} && unset TORNADO_EXTENSION && python -m tornado.test)'
-
# python will import relative to the current working directory by default,
# so cd into the tox working directory to avoid picking up the working
# copy of the files (especially important for the speedups module).
changedir = {toxworkdir}
-# tox 1.6 passes --pre to pip by default, which currently has problems
-# installing pycurl (https://github.com/pypa/pip/issues/1405).
-# Remove it (it's not a part of {opts}) to only install real releases.
-install_command = pip install {opts} {packages}
-
[testenv:docs]
changedir = docs
# For some reason the extension fails to load in this configuration,