From: Ben Darnell Date: Sat, 17 May 2014 14:56:35 +0000 (-0400) Subject: Fix Tornado on Google App Engine. X-Git-Tag: v4.0.0b1~66 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4b6fc9cb9fe5d9b8018b1a32645b74c86f5576e1;p=thirdparty%2Ftornado.git Fix Tornado on Google App Engine. Imports of tornado.ioloop have crept into more places, so the old app engine policy of never importing these modules doesn't work. Instead, we add guards around imports of unavailable modules (fcntl, ssl, multiprocessing) so that everything is at least importable. Closes #1059. --- diff --git a/maint/test/appengine/common/cgi_runtests.py b/maint/test/appengine/common/cgi_runtests.py index f33c131bc..44ddf7ae8 100644 --- a/maint/test/appengine/common/cgi_runtests.py +++ b/maint/test/appengine/common/cgi_runtests.py @@ -2,65 +2,46 @@ import sys import unittest -# Most of our tests depend on IOLoop, which is not importable on app engine. -# Run the tests that work, and check that forbidden imports don't sneak -# in to modules that are supposed to work on app engine. +# Most of our tests depend on IOLoop, which is not usable on app engine. +# Run the tests that work, and check that everything else is at least +# importable (via tornado.test.import_test) TEST_MODULES = [ 'tornado.httputil.doctests', - #'tornado.iostream.doctests', + 'tornado.iostream.doctests', 'tornado.util.doctests', #'tornado.test.auth_test', + #'tornado.test.concurrent_test', #'tornado.test.curl_httpclient_test', 'tornado.test.escape_test', #'tornado.test.gen_test', #'tornado.test.httpclient_test', #'tornado.test.httpserver_test', 'tornado.test.httputil_test', - #'tornado.test.import_test', + 'tornado.test.import_test', #'tornado.test.ioloop_test', #'tornado.test.iostream_test', + 'tornado.test.locale_test', + #'tornado.test.netutil_test', + #'tornado.test.log_test', + 'tornado.test.options_test', #'tornado.test.process_test', #'tornado.test.simple_httpclient_test', #'tornado.test.stack_context_test', 'tornado.test.template_test', #'tornado.test.testing_test', #'tornado.test.twisted_test', + 'tornado.test.util_test', #'tornado.test.web_test', + #'tornado.test.websocket_test', #'tornado.test.wsgi_test', ] -def import_everything(): - # import tornado.auth - # import tornado.autoreload - # import tornado.curl_httpclient # depends on pycurl - import tornado.escape - # import tornado.httpclient - # import tornado.httpserver - import tornado.httputil - # import tornado.ioloop - # import tornado.iostream - import tornado.locale - import tornado.options - # import tornado.netutil - # import tornado.platform.twisted # depends on twisted - # import tornado.process - # import tornado.simple_httpclient - import tornado.stack_context - import tornado.template - import tornado.testing - import tornado.util - import tornado.web - # import tornado.websocket - import tornado.wsgi - def all(): return unittest.defaultTestLoader.loadTestsFromNames(TEST_MODULES) def main(): print "Content-Type: text/plain\r\n\r\n", - import_everything() - try: unittest.main(defaultTest='all', argv=sys.argv[:1]) except SystemExit, e: diff --git a/tornado/iostream.py b/tornado/iostream.py index 7f2e36499..c8c074943 100644 --- a/tornado/iostream.py +++ b/tornado/iostream.py @@ -31,7 +31,6 @@ import errno import numbers import os import socket -import ssl import sys import re @@ -47,6 +46,12 @@ try: except ImportError: _set_nonblocking = None +try: + import ssl +except ImportError: + # ssl is not available on Google App Engine + ssl = None + # These errnos indicate that a non-blocking operation must be retried # at a later time. On most platforms they're the same value, but on # some they differ. diff --git a/tornado/netutil.py b/tornado/netutil.py index 50e3a0b92..2042b91dd 100644 --- a/tornado/netutil.py +++ b/tornado/netutil.py @@ -21,7 +21,6 @@ from __future__ import absolute_import, division, print_function, with_statement import errno import os import socket -import ssl import stat from tornado.concurrent import dummy_executor, run_on_executor @@ -29,9 +28,17 @@ from tornado.ioloop import IOLoop from tornado.platform.auto import set_close_exec from tornado.util import u, Configurable, errno_from_exception +try: + import ssl +except ImportError: + # ssl is not available on Google App Engine + ssl = None + if hasattr(ssl, 'match_hostname') and hasattr(ssl, 'CertificateError'): # python 3.2+ ssl_match_hostname = ssl.match_hostname SSLCertificateError = ssl.CertificateError +elif ssl is None: + ssl_match_hostname = SSLCertificateError = None else: import backports.ssl_match_hostname ssl_match_hostname = backports.ssl_match_hostname.match_hostname diff --git a/tornado/platform/auto.py b/tornado/platform/auto.py index e55725b37..1dbb3f416 100644 --- a/tornado/platform/auto.py +++ b/tornado/platform/auto.py @@ -30,6 +30,9 @@ import os if os.name == 'nt': from tornado.platform.common import Waker from tornado.platform.windows import set_close_exec +elif 'APPENGINE_RUNTIME' in os.environ: + from tornado.platform.common import Waker + def set_close_exec(fd): pass else: from tornado.platform.posix import set_close_exec, Waker diff --git a/tornado/process.py b/tornado/process.py index 74575d05a..0f38b856d 100644 --- a/tornado/process.py +++ b/tornado/process.py @@ -21,7 +21,6 @@ the server into multiple processes and managing subprocesses. from __future__ import absolute_import, division, print_function, with_statement import errno -import multiprocessing import os import signal import subprocess @@ -37,6 +36,12 @@ from tornado.platform.auto import set_close_exec from tornado import stack_context from tornado.util import errno_from_exception +try: + import multiprocessing +except ImportError: + # Multiprocessing is not availble on Google App Engine. + multiprocessing = None + try: long # py2 except NameError: @@ -45,6 +50,8 @@ except NameError: def cpu_count(): """Returns the number of processors on this machine.""" + if multiprocessing is None: + return 1 try: return multiprocessing.cpu_count() except NotImplementedError: diff --git a/tornado/simple_httpclient.py b/tornado/simple_httpclient.py index d35ff1def..b7be7950f 100644 --- a/tornado/simple_httpclient.py +++ b/tornado/simple_httpclient.py @@ -17,7 +17,6 @@ import copy import functools import re import socket -import ssl import sys try: @@ -30,6 +29,12 @@ try: except ImportError: import urllib.parse as urlparse # py3 +try: + import ssl +except ImportError: + # ssl is not available on Google App Engine. + ssl = None + try: import certifi except ImportError: diff --git a/tornado/tcpserver.py b/tornado/tcpserver.py index 74326c1f1..d5e28df6e 100644 --- a/tornado/tcpserver.py +++ b/tornado/tcpserver.py @@ -20,7 +20,6 @@ from __future__ import absolute_import, division, print_function, with_statement import errno import os import socket -import ssl from tornado.log import app_log from tornado.ioloop import IOLoop @@ -29,6 +28,11 @@ from tornado.netutil import bind_sockets, add_accept_handler, ssl_wrap_socket from tornado import process from tornado.util import errno_from_exception +try: + import ssl +except ImportError: + # ssl is not available on Google App Engine. + ssl = None class TCPServer(object): r"""A non-blocking, single-threaded TCP server. diff --git a/tornado/test/import_test.py b/tornado/test/import_test.py index ccd6ef35f..de7cc0b9f 100644 --- a/tornado/test/import_test.py +++ b/tornado/test/import_test.py @@ -13,6 +13,7 @@ class ImportTest(unittest.TestCase): # import tornado.curl_httpclient # depends on pycurl import tornado.escape import tornado.gen + import tornado.http1connection import tornado.httpclient import tornado.httpserver import tornado.httputil