diff --git setup.py setup.py index 26f052b..e63f1b5 100755 --- setup.py +++ setup.py @@ -54,7 +54,7 @@ dependency resolution is disabled. from twisted.python.dist import ( STATIC_PACKAGE_METADATA, getDataFiles, getExtensions, getAllScripts, - getPackages, setup) + getPackages, setup, EXTRAS_REQUIRE) scripts = getAllScripts() @@ -62,6 +62,7 @@ dependency resolution is disabled. packages=getPackages('twisted'), conditionalExtensions=getExtensions(), scripts=scripts, + extras_require=EXTRAS_REQUIRE, data_files=getDataFiles('twisted'), **STATIC_PACKAGE_METADATA)) diff --git twisted/python/dist.py twisted/python/dist.py index 9566039..eae91b3 100644 --- twisted/python/dist.py +++ twisted/python/dist.py @@ -49,6 +49,29 @@ twisted_subprojects = ["conch", "lore", "mail", "names", "news", "pair", "runner", "web", "words"] +# extras_require is a dictionary of items that can be passed to setup.py +# to install optional dependencies. For example, to install the optional +# dev dependencies one would type `pip install -e . "twisted[dev]"` +# This has been supported by setuptools since 0.5a4 +EXTRAS_REQUIRE = dict( + docs = ['sphinx >= 1.2.2', + 'pydoctor >= 0.5'], + dev = ['twistedchecker >= 0.2.0', + 'pyflakes >= 0.8.1', + 'twisted-dev-tools >= 0.0.2'], + tls = ['pyopenssl >= 0.11', + 'service_identity'], + conch = ['gmpy', + 'pyasn1' + 'PyCrypto'], + subunit = ['python-subunit'], + soap = ['soappy'], + serial = ['pyserial'], + pam = ['pam'], + gtk = ['PyGTK'], + windows = ['pywin32'], + osx = ['pyobjc'] +) class ConditionalExtension(Extension): diff --git twisted/python/test/test_dist.py twisted/python/test/test_dist.py index d2288ee..d6ea244 100644 --- twisted/python/test/test_dist.py +++ twisted/python/test/test_dist.py @@ -9,13 +9,13 @@ Tests for parts of our release automation system. import os import sys -from distutils.core import Distribution +from setuptools.dist import Distribution from twisted.trial.unittest import TestCase from twisted.python import dist from twisted.python.dist import (get_setup_args, ConditionalExtension, - build_scripts_twisted) + build_scripts_twisted, EXTRAS_REQUIRE) from twisted.python.filepath import FilePath @@ -58,6 +58,39 @@ class SetupTest(TestCase): self.assertEqual(ext.define_macros, [("whatever", 2), ("WIN32", 1)]) +class OptionalDependenciesTests(TestCase): + """ + Tests for L{dist.EXTRA_REQUIRES} + + Test whether or not the setuptools generates the correct Distribution + object when extra_requires are passed to it. As long as the distribution + object looks correct, it *should* generate the correct egg_info. + """ + def test_distributeTakesExtrasRequire(self): + """ + Test that setuptools' Distribution object can use extra_requires. + """ + attrs = dict(extras_require=EXTRAS_REQUIRE) + dist = Distribution(attrs) + self.assertEqual(dist.extras_require, EXTRAS_REQUIRE) + + def test_extrasRequireDictContainsKeys(self): + """ + Test that the L{dist.EXTRA_REQUIRES} dictionary contains all of the + expected keys. + """ + self.assertIn('docs', EXTRAS_REQUIRE) + self.assertIn('dev', EXTRAS_REQUIRE) + self.assertIn('tls', EXTRAS_REQUIRE) + self.assertIn('conch', EXTRAS_REQUIRE) + self.assertIn('subunit', EXTRAS_REQUIRE) + self.assertIn('soap', EXTRAS_REQUIRE) + self.assertIn('serial', EXTRAS_REQUIRE) + self.assertIn('gtk', EXTRAS_REQUIRE) + self.assertIn('pam', EXTRAS_REQUIRE) + self.assertIn('windows', EXTRAS_REQUIRE) + self.assertIn('osx', EXTRAS_REQUIRE) + class GetExtensionsTest(TestCase): """ diff --git twisted/topfiles/3696.misc twisted/topfiles/3696.misc new file mode 100644 index 0000000..78e79d4 --- /dev/null +++ twisted/topfiles/3696.misc @@ -0,0 +1 @@ +Optional dependencies can be installed using the extra_requires facility provided by setuptools \ No newline at end of file