Spaces:
Sleeping
Sleeping
from io import StringIO | |
import re | |
import sys | |
import datetime | |
import unittest | |
import tornado | |
from tornado.escape import utf8 | |
from tornado.util import ( | |
raise_exc_info, | |
Configurable, | |
exec_in, | |
ArgReplacer, | |
timedelta_to_seconds, | |
import_object, | |
re_unescape, | |
is_finalizing, | |
) | |
import typing | |
from typing import cast | |
if typing.TYPE_CHECKING: | |
from typing import Dict, Any # noqa: F401 | |
class RaiseExcInfoTest(unittest.TestCase): | |
def test_two_arg_exception(self): | |
# This test would fail on python 3 if raise_exc_info were simply | |
# a three-argument raise statement, because TwoArgException | |
# doesn't have a "copy constructor" | |
class TwoArgException(Exception): | |
def __init__(self, a, b): | |
super().__init__() | |
self.a, self.b = a, b | |
try: | |
raise TwoArgException(1, 2) | |
except TwoArgException: | |
exc_info = sys.exc_info() | |
try: | |
raise_exc_info(exc_info) | |
self.fail("didn't get expected exception") | |
except TwoArgException as e: | |
self.assertIs(e, exc_info[1]) | |
class TestConfigurable(Configurable): | |
def configurable_base(cls): | |
return TestConfigurable | |
def configurable_default(cls): | |
return TestConfig1 | |
class TestConfig1(TestConfigurable): | |
def initialize(self, pos_arg=None, a=None): | |
self.a = a | |
self.pos_arg = pos_arg | |
class TestConfig2(TestConfigurable): | |
def initialize(self, pos_arg=None, b=None): | |
self.b = b | |
self.pos_arg = pos_arg | |
class TestConfig3(TestConfigurable): | |
# TestConfig3 is a configuration option that is itself configurable. | |
def configurable_base(cls): | |
return TestConfig3 | |
def configurable_default(cls): | |
return TestConfig3A | |
class TestConfig3A(TestConfig3): | |
def initialize(self, a=None): | |
self.a = a | |
class TestConfig3B(TestConfig3): | |
def initialize(self, b=None): | |
self.b = b | |
class ConfigurableTest(unittest.TestCase): | |
def setUp(self): | |
self.saved = TestConfigurable._save_configuration() | |
self.saved3 = TestConfig3._save_configuration() | |
def tearDown(self): | |
TestConfigurable._restore_configuration(self.saved) | |
TestConfig3._restore_configuration(self.saved3) | |
def checkSubclasses(self): | |
# no matter how the class is configured, it should always be | |
# possible to instantiate the subclasses directly | |
self.assertIsInstance(TestConfig1(), TestConfig1) | |
self.assertIsInstance(TestConfig2(), TestConfig2) | |
obj = TestConfig1(a=1) | |
self.assertEqual(obj.a, 1) | |
obj2 = TestConfig2(b=2) | |
self.assertEqual(obj2.b, 2) | |
def test_default(self): | |
# In these tests we combine a typing.cast to satisfy mypy with | |
# a runtime type-assertion. Without the cast, mypy would only | |
# let us access attributes of the base class. | |
obj = cast(TestConfig1, TestConfigurable()) | |
self.assertIsInstance(obj, TestConfig1) | |
self.assertIs(obj.a, None) | |
obj = cast(TestConfig1, TestConfigurable(a=1)) | |
self.assertIsInstance(obj, TestConfig1) | |
self.assertEqual(obj.a, 1) | |
self.checkSubclasses() | |
def test_config_class(self): | |
TestConfigurable.configure(TestConfig2) | |
obj = cast(TestConfig2, TestConfigurable()) | |
self.assertIsInstance(obj, TestConfig2) | |
self.assertIs(obj.b, None) | |
obj = cast(TestConfig2, TestConfigurable(b=2)) | |
self.assertIsInstance(obj, TestConfig2) | |
self.assertEqual(obj.b, 2) | |
self.checkSubclasses() | |
def test_config_str(self): | |
TestConfigurable.configure("tornado.test.util_test.TestConfig2") | |
obj = cast(TestConfig2, TestConfigurable()) | |
self.assertIsInstance(obj, TestConfig2) | |
self.assertIs(obj.b, None) | |
obj = cast(TestConfig2, TestConfigurable(b=2)) | |
self.assertIsInstance(obj, TestConfig2) | |
self.assertEqual(obj.b, 2) | |
self.checkSubclasses() | |
def test_config_args(self): | |
TestConfigurable.configure(None, a=3) | |
obj = cast(TestConfig1, TestConfigurable()) | |
self.assertIsInstance(obj, TestConfig1) | |
self.assertEqual(obj.a, 3) | |
obj = cast(TestConfig1, TestConfigurable(42, a=4)) | |
self.assertIsInstance(obj, TestConfig1) | |
self.assertEqual(obj.a, 4) | |
self.assertEqual(obj.pos_arg, 42) | |
self.checkSubclasses() | |
# args bound in configure don't apply when using the subclass directly | |
obj = TestConfig1() | |
self.assertIs(obj.a, None) | |
def test_config_class_args(self): | |
TestConfigurable.configure(TestConfig2, b=5) | |
obj = cast(TestConfig2, TestConfigurable()) | |
self.assertIsInstance(obj, TestConfig2) | |
self.assertEqual(obj.b, 5) | |
obj = cast(TestConfig2, TestConfigurable(42, b=6)) | |
self.assertIsInstance(obj, TestConfig2) | |
self.assertEqual(obj.b, 6) | |
self.assertEqual(obj.pos_arg, 42) | |
self.checkSubclasses() | |
# args bound in configure don't apply when using the subclass directly | |
obj = TestConfig2() | |
self.assertIs(obj.b, None) | |
def test_config_multi_level(self): | |
TestConfigurable.configure(TestConfig3, a=1) | |
obj = cast(TestConfig3A, TestConfigurable()) | |
self.assertIsInstance(obj, TestConfig3A) | |
self.assertEqual(obj.a, 1) | |
TestConfigurable.configure(TestConfig3) | |
TestConfig3.configure(TestConfig3B, b=2) | |
obj2 = cast(TestConfig3B, TestConfigurable()) | |
self.assertIsInstance(obj2, TestConfig3B) | |
self.assertEqual(obj2.b, 2) | |
def test_config_inner_level(self): | |
# The inner level can be used even when the outer level | |
# doesn't point to it. | |
obj = TestConfig3() | |
self.assertIsInstance(obj, TestConfig3A) | |
TestConfig3.configure(TestConfig3B) | |
obj = TestConfig3() | |
self.assertIsInstance(obj, TestConfig3B) | |
# Configuring the base doesn't configure the inner. | |
obj2 = TestConfigurable() | |
self.assertIsInstance(obj2, TestConfig1) | |
TestConfigurable.configure(TestConfig2) | |
obj3 = TestConfigurable() | |
self.assertIsInstance(obj3, TestConfig2) | |
obj = TestConfig3() | |
self.assertIsInstance(obj, TestConfig3B) | |
class UnicodeLiteralTest(unittest.TestCase): | |
def test_unicode_escapes(self): | |
self.assertEqual(utf8("\u00e9"), b"\xc3\xa9") | |
class ExecInTest(unittest.TestCase): | |
# TODO(bdarnell): make a version of this test for one of the new | |
# future imports available in python 3. | |
def test_no_inherit_future(self): | |
# This file has from __future__ import print_function... | |
f = StringIO() | |
print("hello", file=f) | |
# ...but the template doesn't | |
exec_in('print >> f, "world"', dict(f=f)) | |
self.assertEqual(f.getvalue(), "hello\nworld\n") | |
class ArgReplacerTest(unittest.TestCase): | |
def setUp(self): | |
def function(x, y, callback=None, z=None): | |
pass | |
self.replacer = ArgReplacer(function, "callback") | |
def test_omitted(self): | |
args = (1, 2) | |
kwargs = dict() # type: Dict[str, Any] | |
self.assertIs(self.replacer.get_old_value(args, kwargs), None) | |
self.assertEqual( | |
self.replacer.replace("new", args, kwargs), | |
(None, (1, 2), dict(callback="new")), | |
) | |
def test_position(self): | |
args = (1, 2, "old", 3) | |
kwargs = dict() # type: Dict[str, Any] | |
self.assertEqual(self.replacer.get_old_value(args, kwargs), "old") | |
self.assertEqual( | |
self.replacer.replace("new", args, kwargs), | |
("old", [1, 2, "new", 3], dict()), | |
) | |
def test_keyword(self): | |
args = (1,) | |
kwargs = dict(y=2, callback="old", z=3) | |
self.assertEqual(self.replacer.get_old_value(args, kwargs), "old") | |
self.assertEqual( | |
self.replacer.replace("new", args, kwargs), | |
("old", (1,), dict(y=2, callback="new", z=3)), | |
) | |
class TimedeltaToSecondsTest(unittest.TestCase): | |
def test_timedelta_to_seconds(self): | |
time_delta = datetime.timedelta(hours=1) | |
self.assertEqual(timedelta_to_seconds(time_delta), 3600.0) | |
class ImportObjectTest(unittest.TestCase): | |
def test_import_member(self): | |
self.assertIs(import_object("tornado.escape.utf8"), utf8) | |
def test_import_member_unicode(self): | |
self.assertIs(import_object("tornado.escape.utf8"), utf8) | |
def test_import_module(self): | |
self.assertIs(import_object("tornado.escape"), tornado.escape) | |
def test_import_module_unicode(self): | |
# The internal implementation of __import__ differs depending on | |
# whether the thing being imported is a module or not. | |
# This variant requires a byte string in python 2. | |
self.assertIs(import_object("tornado.escape"), tornado.escape) | |
class ReUnescapeTest(unittest.TestCase): | |
def test_re_unescape(self): | |
test_strings = ("/favicon.ico", "index.html", "Hello, World!", "!$@#%;") | |
for string in test_strings: | |
self.assertEqual(string, re_unescape(re.escape(string))) | |
def test_re_unescape_raises_error_on_invalid_input(self): | |
with self.assertRaises(ValueError): | |
re_unescape("\\d") | |
with self.assertRaises(ValueError): | |
re_unescape("\\b") | |
with self.assertRaises(ValueError): | |
re_unescape("\\Z") | |
class IsFinalizingTest(unittest.TestCase): | |
def test_basic(self): | |
self.assertFalse(is_finalizing()) | |