]> git.ipfire.org Git - thirdparty/tornado.git/commitdiff
Allow unicode strings in import_object in python 2.
authorBen Darnell <ben@bendarnell.com>
Sun, 8 Feb 2015 18:26:56 +0000 (13:26 -0500)
committerBen Darnell <ben@bendarnell.com>
Sun, 8 Feb 2015 18:26:56 +0000 (13:26 -0500)
Fixes #1316.

tornado/test/util_test.py
tornado/util.py

index 1cd78fe46f3b5672e52940e91240e32b929fd102..a0fbae43c4f1eb44475fca6ba1e04c80be52b313 100644 (file)
@@ -3,8 +3,9 @@ from __future__ import absolute_import, division, print_function, with_statement
 import sys
 import datetime
 
+import tornado.escape
 from tornado.escape import utf8
-from tornado.util import raise_exc_info, Configurable, u, exec_in, ArgReplacer, timedelta_to_seconds
+from tornado.util import raise_exc_info, Configurable, u, exec_in, ArgReplacer, timedelta_to_seconds, import_object
 from tornado.test.util import unittest
 
 try:
@@ -177,3 +178,20 @@ 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(u('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(u('tornado.escape')), tornado.escape)
index 34c4b072c49bb83cc80e38e00dcaca16174ab12d..cac4e3aaea48addd9d051886bd319efd3b6b282c 100644 (file)
@@ -78,6 +78,23 @@ class GzipDecompressor(object):
         return self.decompressobj.flush()
 
 
+# Fake unicode literal support:  Python 3.2 doesn't have the u'' marker for
+# literal strings, and alternative solutions like "from __future__ import
+# unicode_literals" have other problems (see PEP 414).  u() can be applied
+# to ascii strings that include \u escapes (but they must not contain
+# literal non-ascii characters).
+if type('') is not type(b''):
+    def u(s):
+        return s
+    unicode_type = str
+    basestring_type = str
+else:
+    def u(s):
+        return s.decode('unicode_escape')
+    unicode_type = unicode
+    basestring_type = basestring
+
+
 def import_object(name):
     """Imports an object by name.
 
@@ -96,6 +113,9 @@ def import_object(name):
         ...
     ImportError: No module named missing_module
     """
+    if isinstance(name, unicode_type) and str is not unicode_type:
+        # On python 2 a byte string is required.
+        name = name.encode('utf-8')
     if name.count('.') == 0:
         return __import__(name, None, None)
 
@@ -107,22 +127,6 @@ def import_object(name):
         raise ImportError("No module named %s" % parts[-1])
 
 
-# Fake unicode literal support:  Python 3.2 doesn't have the u'' marker for
-# literal strings, and alternative solutions like "from __future__ import
-# unicode_literals" have other problems (see PEP 414).  u() can be applied
-# to ascii strings that include \u escapes (but they must not contain
-# literal non-ascii characters).
-if type('') is not type(b''):
-    def u(s):
-        return s
-    unicode_type = str
-    basestring_type = str
-else:
-    def u(s):
-        return s.decode('unicode_escape')
-    unicode_type = unicode
-    basestring_type = basestring
-
 # Deprecated alias that was used before we dropped py25 support.
 # Left here in case anyone outside Tornado is using it.
 bytes_type = bytes