]> git.ipfire.org Git - thirdparty/tornado.git/commitdiff
Fix importability on python 3.5.2 2605/head
authorBen Darnell <ben@bendarnell.com>
Fri, 1 Mar 2019 20:03:31 +0000 (15:03 -0500)
committerBen Darnell <ben@bendarnell.com>
Fri, 1 Mar 2019 20:57:41 +0000 (15:57 -0500)
The "provisional" typing module in 3.5.2 is kind of broken/incomplete
so we need to use more forward references to avoid confusing it. The
significance of this version in particular is that it was the one
included in ubuntu 16.04.

Fixes #2604

13 files changed:
.travis.yml
tornado/concurrent.py
tornado/gen.py
tornado/http1connection.py
tornado/httpclient.py
tornado/ioloop.py
tornado/iostream.py
tornado/locks.py
tornado/simple_httpclient.py
tornado/testing.py
tornado/web.py
tornado/websocket.py
tornado/wsgi.py

index f39bb765734a527e190b9bf6dedb91584f1179bd..dd808b97c0f34d166b2aecfea0ab54cf0d3437c9 100644 (file)
@@ -27,6 +27,10 @@ language: python
         - libgnutls-dev
 jobs:
   include:
+    # 3.5.2 is interesting because it's the version in ubuntu 16.04, and due to python's
+    # "provisional feature" rules there are significant differences between patch
+    # versions for asyncio and typing.
+    - python: 3.5.2
     - python: 3.5
     - python: 3.6
     - python: pypy3.5-5.10.1
@@ -85,7 +89,7 @@ script:
     - if [[ $TRAVIS_PYTHON_VERSION != nightly && $TRAVIS_PYTHON_VERSION != 'pypy'* ]]; then export RUN_COVERAGE=1; fi
     - if [[ "$RUN_COVERAGE" == 1 ]]; then export TARGET="-m coverage run $TARGET"; fi
     # See comments in tox.ini. Disabled on py35 because ResourceWarnings are too noisy there.
-    - if [[ $TRAVIS_PYTHON_VERSION != '3.5' ]]; then export PYTHONWARNINGS=error,ignore:::site; fi
+    - if [[ $TRAVIS_PYTHON_VERSION != '3.5'* ]]; then export PYTHONWARNINGS=error,ignore:::site; fi
     - python -bb $TARGET
     - python -O $TARGET
     - LANG=C python $TARGET
index 9d77170c8256c8dd75e3b54280e562cc235af202..3a49940dfab5cb6423741b978b9093f42a2fb547 100644 (file)
@@ -172,7 +172,7 @@ def chain_future(a: "Future[_T]", b: "Future[_T]") -> None:
 
 
 def future_set_result_unless_cancelled(
-    future: Union["futures.Future[_T]", "Future[_T]"], value: _T
+    future: "Union[futures.Future[_T], Future[_T]]", value: _T
 ) -> None:
     """Set the given ``value`` as the `Future`'s result, if not cancelled.
 
@@ -186,7 +186,7 @@ def future_set_result_unless_cancelled(
 
 
 def future_set_exception_unless_cancelled(
-    future: Union["futures.Future[_T]", "Future[_T]"], exc: BaseException
+    future: "Union[futures.Future[_T], Future[_T]]", exc: BaseException
 ) -> None:
     """Set the given ``exc`` as the `Future`'s exception.
 
@@ -208,7 +208,7 @@ def future_set_exception_unless_cancelled(
 
 
 def future_set_exc_info(
-    future: Union["futures.Future[_T]", "Future[_T]"],
+    future: "Union[futures.Future[_T], Future[_T]]",
     exc_info: Tuple[
         Optional[type], Optional[BaseException], Optional[types.TracebackType]
     ],
@@ -246,7 +246,7 @@ def future_add_done_callback(
 
 
 def future_add_done_callback(  # noqa: F811
-    future: Union["futures.Future[_T]", "Future[_T]"], callback: Callable[..., None]
+    future: "Union[futures.Future[_T], Future[_T]]", callback: Callable[..., None]
 ) -> None:
     """Arrange to call ``callback`` when ``future`` is complete.
 
index 3c1deeae3dd136ca0beeae4e85c6a76a80401a68..51f2a4f0388a21edbb37d9d4ba8fe77fb55de025 100644 (file)
@@ -408,8 +408,8 @@ class WaitIterator(object):
 
 def multi(
     children: Union[List[_Yieldable], Dict[Any, _Yieldable]],
-    quiet_exceptions: Union[Type[Exception], Tuple[Type[Exception], ...]] = (),
-) -> Union["Future[List]", "Future[Dict]"]:
+    quiet_exceptions: "Union[Type[Exception], Tuple[Type[Exception], ...]]" = (),
+) -> "Union[Future[List], Future[Dict]]":
     """Runs multiple asynchronous operations in parallel.
 
     ``children`` may either be a list or a dict whose values are
@@ -462,8 +462,8 @@ Multi = multi
 
 def multi_future(
     children: Union[List[_Yieldable], Dict[Any, _Yieldable]],
-    quiet_exceptions: Union[Type[Exception], Tuple[Type[Exception], ...]] = (),
-) -> Union["Future[List]", "Future[Dict]"]:
+    quiet_exceptions: "Union[Type[Exception], Tuple[Type[Exception], ...]]" = (),
+) -> "Union[Future[List], Future[Dict]]":
     """Wait for multiple asynchronous futures in parallel.
 
     Since Tornado 6.0, this function is exactly the same as `multi`.
@@ -547,7 +547,7 @@ def maybe_future(x: Any) -> Future:
 def with_timeout(
     timeout: Union[float, datetime.timedelta],
     future: _Yieldable,
-    quiet_exceptions: Union[Type[Exception], Tuple[Type[Exception], ...]] = (),
+    quiet_exceptions: "Union[Type[Exception], Tuple[Type[Exception], ...]]" = (),
 ) -> Future:
     """Wraps a `.Future` (or other yieldable object) in a timeout.
 
index fd63be62759efa8dc7a34b3d10a1546820bff011..434f16a09dcb417b8b59f80096cc581bd72492b4 100644 (file)
@@ -58,7 +58,7 @@ class _ExceptionLoggingContext(object):
 
     def __exit__(
         self,
-        typ: Optional[Type[BaseException]],
+        typ: "Optional[Type[BaseException]]",
         value: Optional[BaseException],
         tb: types.TracebackType,
     ) -> None:
@@ -563,7 +563,7 @@ class HTTP1Connection(httputil.HTTPConnection):
             return connection_header == "keep-alive"
         return False
 
-    def _finish_request(self, future: Optional["Future[None]"]) -> None:
+    def _finish_request(self, future: "Optional[Future[None]]") -> None:
         self._clear_callbacks()
         if not self.is_client and self._disconnect_on_finish:
             self.close()
index 73c9e7b5717df8c00dcdbd5bc367d5bcbe6c0c3a..33abe2e16e943df6bdb2a9d4b15c96e335ac2824 100644 (file)
@@ -311,7 +311,7 @@ class AsyncHTTPClient(Configurable):
 
     @classmethod
     def configure(
-        cls, impl: Union[None, str, Type[Configurable]], **kwargs: Any
+        cls, impl: "Union[None, str, Type[Configurable]]", **kwargs: Any
     ) -> None:
         """Configures the `AsyncHTTPClient` subclass to use.
 
index 0ed1fb61cbf258a769c370b5a4b78818335b87d2..02794cb9d338c4a558e59cd0fbe2390a330987a8 100644 (file)
@@ -165,7 +165,7 @@ class IOLoop(Configurable):
 
     @classmethod
     def configure(
-        cls, impl: Union[None, str, Type[Configurable]], **kwargs: Any
+        cls, impl: "Union[None, str, Type[Configurable]]", **kwargs: Any
     ) -> None:
         if asyncio is not None:
             from tornado.platform.asyncio import BaseAsyncIOLoop
@@ -664,7 +664,7 @@ class IOLoop(Configurable):
 
     def add_future(
         self,
-        future: Union["Future[_T]", "concurrent.futures.Future[_T]"],
+        future: "Union[Future[_T], concurrent.futures.Future[_T]]",
         callback: Callable[["Future[_T]"], None],
     ) -> None:
         """Schedules a callback on the ``IOLoop`` when the given
index 8c01cb5e9b6f9a87e037b5b725ea138700b5f037..6ea748a541d16068634d581c444b8468e667d45e 100644 (file)
@@ -46,7 +46,6 @@ from typing import (
     Optional,
     Awaitable,
     Callable,
-    Type,
     Pattern,
     Any,
     Dict,
@@ -56,7 +55,7 @@ from typing import (
 from types import TracebackType
 
 if typing.TYPE_CHECKING:
-    from typing import Deque, List  # noqa: F401
+    from typing import Deque, List, Type  # noqa: F401
 
 _IOStreamType = TypeVar("_IOStreamType", bound="IOStream")
 
@@ -585,7 +584,7 @@ class BaseIOStream(object):
             bool,
             BaseException,
             Tuple[
-                Optional[Type[BaseException]],
+                "Optional[Type[BaseException]]",
                 Optional[BaseException],
                 Optional[TracebackType],
             ],
index 8b1a5341091d1cb86bd7657f228327cb40059c80..699bb30152c3218f2540c9acf45dd135cd50d7dd 100644 (file)
@@ -275,7 +275,7 @@ class _ReleasingContextManager(object):
 
     def __exit__(
         self,
-        exc_type: Optional[Type[BaseException]],
+        exc_type: "Optional[Type[BaseException]]",
         exc_val: Optional[BaseException],
         exc_tb: Optional[types.TracebackType],
     ) -> None:
@@ -444,7 +444,7 @@ class Semaphore(_TimeoutGarbageCollector):
 
     def __exit__(
         self,
-        typ: Optional[Type[BaseException]],
+        typ: "Optional[Type[BaseException]]",
         value: Optional[BaseException],
         traceback: Optional[types.TracebackType],
     ) -> None:
@@ -455,7 +455,7 @@ class Semaphore(_TimeoutGarbageCollector):
 
     async def __aexit__(
         self,
-        typ: Optional[Type[BaseException]],
+        typ: "Optional[Type[BaseException]]",
         value: Optional[BaseException],
         tb: Optional[types.TracebackType],
     ) -> None:
@@ -552,7 +552,7 @@ class Lock(object):
 
     def __exit__(
         self,
-        typ: Optional[Type[BaseException]],
+        typ: "Optional[Type[BaseException]]",
         value: Optional[BaseException],
         tb: Optional[types.TracebackType],
     ) -> None:
@@ -563,7 +563,7 @@ class Lock(object):
 
     async def __aexit__(
         self,
-        typ: Optional[Type[BaseException]],
+        typ: "Optional[Type[BaseException]]",
         value: Optional[BaseException],
         tb: Optional[types.TracebackType],
     ) -> None:
index 6e075aa639d23fef03fedebcd1e7256d1362be29..1d82890bcc476ad11d3c3716a3749fb2ee6bdb38 100644 (file)
@@ -535,7 +535,7 @@ class _HTTPConnection(httputil.HTTPMessageDelegate):
 
     def _handle_exception(
         self,
-        typ: Optional[Type[BaseException]],
+        typ: "Optional[Type[BaseException]]",
         value: Optional[BaseException],
         tb: Optional[TracebackType],
     ) -> bool:
index fdfda44ae226e798b8c30775b6e671b566da5d91..ba13a525eededae0a1f43733bea25dffe1435eea 100644 (file)
@@ -33,10 +33,14 @@ from tornado.util import raise_exc_info, basestring_type
 from tornado.web import Application
 
 import typing
-from typing import Tuple, Any, Callable, Type, Dict, Union, Coroutine, Optional
+from typing import Tuple, Any, Callable, Type, Dict, Union, Optional
 from types import TracebackType
 
 if typing.TYPE_CHECKING:
+    # Coroutine wasn't added to typing until 3.5.3, so only import it
+    # when mypy is running and use forward references.
+    from typing import Coroutine  # noqa: F401
+
     _ExcInfoTuple = Tuple[
         Optional[Type[BaseException]], Optional[BaseException], Optional[TracebackType]
     ]
@@ -505,20 +509,20 @@ class AsyncHTTPSTestCase(AsyncHTTPTestCase):
 @typing.overload
 def gen_test(
     *, timeout: float = None
-) -> Callable[[Callable[..., Union[Generator, Coroutine]]], Callable[..., None]]:
+) -> Callable[[Callable[..., Union[Generator, "Coroutine"]]], Callable[..., None]]:
     pass
 
 
 @typing.overload  # noqa: F811
-def gen_test(func: Callable[..., Union[Generator, Coroutine]]) -> Callable[..., None]:
+def gen_test(func: Callable[..., Union[Generator, "Coroutine"]]) -> Callable[..., None]:
     pass
 
 
 def gen_test(  # noqa: F811
-    func: Callable[..., Union[Generator, Coroutine]] = None, timeout: float = None
+    func: Callable[..., Union[Generator, "Coroutine"]] = None, timeout: float = None
 ) -> Union[
     Callable[..., None],
-    Callable[[Callable[..., Union[Generator, Coroutine]]], Callable[..., None]],
+    Callable[[Callable[..., Union[Generator, "Coroutine"]]], Callable[..., None]],
 ]:
     """Testing equivalent of ``@gen.coroutine``, to be applied to test methods.
 
@@ -558,7 +562,7 @@ def gen_test(  # noqa: F811
     if timeout is None:
         timeout = get_async_test_timeout()
 
-    def wrap(f: Callable[..., Union[Generator, Coroutine]]) -> Callable[..., None]:
+    def wrap(f: Callable[..., Union[Generator, "Coroutine"]]) -> Callable[..., None]:
         # Stack up several decorators to allow us to access the generator
         # object itself.  In the innermost wrapper, we capture the generator
         # and save it in an attribute of self.  Next, we run the wrapped
@@ -681,7 +685,7 @@ class ExpectLog(logging.Filter):
 
     def __exit__(
         self,
-        typ: Optional[Type[BaseException]],
+        typ: "Optional[Type[BaseException]]",
         value: Optional[BaseException],
         tb: Optional[TracebackType],
     ) -> None:
index 6545430e1882e2b2badf439edc5010c80a6868cf..6e6e9551a9f23052a12619998df617deced38328 100644 (file)
@@ -1762,7 +1762,7 @@ class RequestHandler(object):
 
     def log_exception(
         self,
-        typ: Optional[Type[BaseException]],
+        typ: "Optional[Type[BaseException]]",
         value: Optional[BaseException],
         tb: Optional[TracebackType],
     ) -> None:
index f1138e00dc0bcf3bb5a4d404379ef88a43ce664a..00d08bab2ec893494175a4dc8041563ef4729b0d 100644 (file)
@@ -639,7 +639,7 @@ class WebSocketProtocol(abc.ABC):
 
     def _run_callback(
         self, callback: Callable, *args: Any, **kwargs: Any
-    ) -> Optional["Future[Any]"]:
+    ) -> "Optional[Future[Any]]":
         """Runs the given callback with exception handling.
 
         If the callback is a coroutine, returns its Future. On error, aborts the
@@ -1204,7 +1204,7 @@ class WebSocketProtocol13(WebSocketProtocol):
             if handled_future is not None:
                 await handled_future
 
-    def _handle_message(self, opcode: int, data: bytes) -> Optional["Future[None]"]:
+    def _handle_message(self, opcode: int, data: bytes) -> "Optional[Future[None]]":
         """Execute on_message, returning its Future if it is a coroutine."""
         if self.client_terminated:
             return None
@@ -1567,7 +1567,7 @@ class WebSocketClientConnection(simple_httpclient._HTTPConnection):
 
     def log_exception(
         self,
-        typ: Optional[Type[BaseException]],
+        typ: "Optional[Type[BaseException]]",
         value: Optional[BaseException],
         tb: Optional[TracebackType],
     ) -> None:
index 55e0da201362a663cba638af6058df8534c2e46e..77124aaa309f58e14b8d4521ad5cc6daf75b3643 100644 (file)
@@ -35,11 +35,12 @@ from tornado import escape
 from tornado import httputil
 from tornado.log import access_log
 
-from typing import List, Tuple, Optional, Type, Callable, Any, Dict, Text
+from typing import List, Tuple, Optional, Callable, Any, Dict, Text
 from types import TracebackType
 import typing
 
 if typing.TYPE_CHECKING:
+    from typing import Type  # noqa: F401
     from wsgiref.types import WSGIApplication as WSGIAppType  # noqa: F401
 
 
@@ -99,7 +100,7 @@ class WSGIContainer(object):
             headers: List[Tuple[str, str]],
             exc_info: Optional[
                 Tuple[
-                    Optional[Type[BaseException]],
+                    "Optional[Type[BaseException]]",
                     Optional[BaseException],
                     Optional[TracebackType],
                 ]