Skip to content

Commit

Permalink
Make singledispatch and backports_abc mandatory dependencies.
Browse files Browse the repository at this point in the history
I anticipate confusion around the differing behavior based on whether or
not these packages are installed, so it's better to just make them
mandatory (except on app engine).
  • Loading branch information
bdarnell committed Oct 18, 2015
1 parent b9d8e00 commit 7b3e31b
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 28 deletions.
5 changes: 2 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,11 @@ install:
# always install unittest2 on py26 even if $DEPS is unset
- if [[ $TRAVIS_PYTHON_VERSION == '2.6' ]]; then travis_retry pip install unittest2; fi
- if [[ $TRAVIS_PYTHON_VERSION == 2* && $DEPS == true ]]; then travis_retry pip install futures mock Monotime trollius; fi
- if [[ $TRAVIS_PYTHON_VERSION == '2.7' ]]; then travis_retry pip install singledispatch; fi
- if [[ $TRAVIS_PYTHON_VERSION == 'pypy' && $DEPS == true ]]; then travis_retry pip install futures mock singledispatch; fi
- if [[ $TRAVIS_PYTHON_VERSION == 'pypy' && $DEPS == true ]]; then travis_retry pip install futures mock; fi
# TODO(bdarnell): pycares tests are currently disabled on travis due to ipv6 issues.
#- if [[ $TRAVIS_PYTHON_VERSION != 'pypy'* && $DEPS == true ]]; then travis_retry pip install pycares; fi
- if [[ $TRAVIS_PYTHON_VERSION != 'pypy'* && $DEPS == true ]]; then travis_retry pip install pycurl; fi
- if [[ $TRAVIS_PYTHON_VERSION == '3.2' && $DEPS == true ]]; then travis_retry pip install mock singledispatch; fi
- if [[ $TRAVIS_PYTHON_VERSION == '3.2' && $DEPS == true ]]; then travis_retry pip install mock; fi
# Twisted runs on 2.x and 3.3+, but is flaky on pypy.
- if [[ $TRAVIS_PYTHON_VERSION != '3.2' && $TRAVIS_PYTHON_VERSION != 'pypy'* && $DEPS == true ]]; then travis_retry pip install Twisted; fi
- if [[ $TRAVIS_PYTHON_VERSION == '2.7' && $DEPS == true ]]; then travis_retry pip install sphinx sphinx_rtd_theme; fi
Expand Down
3 changes: 3 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,10 +125,13 @@ def build_extension(self, ext):
if sys.version_info < (3, 2):
install_requires.append('backports.ssl_match_hostname')
if sys.version_info < (3, 4):
install_requires.append('singledispatch')
# Certifi is also optional on 2.7.9+, although making our dependencies
# conditional on micro version numbers seems like a bad idea
# until we have more declarative metadata.
install_requires.append('certifi')
if sys.version_info < (3, 5):
install_requires.append('backports_abc>=0.4')
kwargs['install_requires'] = install_requires

setup(
Expand Down
39 changes: 24 additions & 15 deletions tornado/gen.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ def get(self):
import collections
import functools
import itertools
import os
import sys
import textwrap
import types
Expand All @@ -90,30 +91,38 @@ def get(self):
from tornado.util import raise_exc_info

try:
from functools import singledispatch # py34+
except ImportError as e:
try:
from singledispatch import singledispatch # backport
from functools import singledispatch # py34+
except ImportError:
singledispatch = None

from singledispatch import singledispatch # backport
except ImportError:
# In most cases, singledispatch is required (to avoid
# difficult-to-diagnose problems in which the functionality
# available differs depending on which invisble packages are
# installed). However, in Google App Engine third-party
# dependencies are more trouble so we allow this module to be
# imported without it.
if 'APPENGINE_RUNTIME' not in os.environ:
raise
singledispatch = None

try:
from collections.abc import Generator as GeneratorType # py35+
except ImportError:
try:
from backports_abc import Generator as GeneratorType
from collections.abc import Generator as GeneratorType # py35+
except ImportError:
from types import GeneratorType
from backports_abc import Generator as GeneratorType

try:
from inspect import isawaitable # py35+
except ImportError:
try:
from backports_abc import isawaitable
from inspect import isawaitable # py35+
except ImportError:
def isawaitable(x):
return False
from backports_abc import isawaitable
except ImportError:
if 'APPENGINE_RUNTIME' not in os.environ:
raise
from types import GeneratorType

def isawaitable(x):
return False

try:
import builtins # py3
Expand Down
5 changes: 0 additions & 5 deletions tornado/test/asyncio_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,6 @@
# This is used in dynamically-evaluated code, so silence pyflakes.
to_asyncio_future

skipIfNoSingleDispatch = unittest.skipIf(
gen.singledispatch is None, "singledispatch module not present")


@unittest.skipIf(asyncio is None, "asyncio module not present")
class AsyncIOLoopTest(AsyncTestCase):
Expand All @@ -41,7 +38,6 @@ def test_asyncio_callback(self):
asyncio.get_event_loop().call_soon(self.stop)
self.wait()

@skipIfNoSingleDispatch
@gen_test
def test_asyncio_future(self):
# Test that we can yield an asyncio future from a tornado coroutine.
Expand All @@ -51,7 +47,6 @@ def test_asyncio_future(self):
self.assertEqual(x, 42)

@skipBefore33
@skipIfNoSingleDispatch
@gen_test
def test_asyncio_yield_from(self):
# Test that we can use asyncio coroutines with 'yield from'
Expand Down
5 changes: 0 additions & 5 deletions tornado/test/twisted_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,6 @@
skipIfNoTwisted = unittest.skipUnless(have_twisted,
"twisted module not present")

skipIfNoSingleDispatch = unittest.skipIf(
gen.singledispatch is None, "singledispatch module not present")


def save_signal_handlers():
saved = {}
Expand Down Expand Up @@ -495,7 +492,6 @@ def testTornadoServerTwistedClientReactor(self):
'http://127.0.0.1:%d' % self.tornado_port, self.run_reactor)
self.assertEqual(response, 'Hello from tornado!')

@skipIfNoSingleDispatch
def testTornadoServerTwistedCoroutineClientIOLoop(self):
self.start_tornado_server()
response = self.twisted_coroutine_fetch(
Expand All @@ -504,7 +500,6 @@ def testTornadoServerTwistedCoroutineClientIOLoop(self):


@skipIfNoTwisted
@skipIfNoSingleDispatch
class ConvertDeferredTest(unittest.TestCase):
def test_success(self):
@inlineCallbacks
Expand Down

0 comments on commit 7b3e31b

Please sign in to comment.