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..01c9397 100644 --- twisted/python/dist.py +++ twisted/python/dist.py @@ -49,6 +49,70 @@ twisted_subprojects = ["conch", "lore", "mail", "names", "news", "pair", "runner", "web", "words"] +# These are the actual package names and versions that will +# be used by extras_require. This is not passed setup +# directly so that combinations of the packages can be created +# without needed to copy package names multiple times. +_extra_options = 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', + 'PyCrypto'], + conch = ['gmpy', + 'pyasn1'], + subunit = ['python-subunit'], + soap = ['soappy'], + serial = ['pyserial'], + pam = ['pam'], + ## the following are platform or graphics specific libraries + gtk = ['PyGTK'], + windows = ['pywin32'], + osx = ['pyobjc'] +) + +_platform_independent = [ + _extra_options['docs'], + _extra_options['dev'], + _extra_options['tls'], + _extra_options['conch'], + _extra_options['subunit'], + _extra_options['soap'], + _extra_options['serial'], + _extra_options['pam'] +] + +# 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 = _extra_options['docs'], + dev = _extra_options['dev'], + tls = _extra_options['tls'], + conch = _extra_options['conch'], + subunit = _extra_options['subunit'], + soap = _extra_options['soap'], + serial = _extra_options['serial'], + gtk = _extra_options['gtk'], + pam = _extra_options['pam'], + non_plat = _platform_independent, + windows_plat = [ + _extra_options['windows'], + _platform_independent + ], + osx_plat = [ + _extra_options['osx'], + _platform_independent + ], + linux_plat = [ + _extra_options['gtk'], + _platform_independent + ] +) class ConditionalExtension(Extension): diff --git twisted/python/test/test_dist.py twisted/python/test/test_dist.py index d2288ee..7b36a52 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,40 @@ 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('non_plat', EXTRAS_REQUIRE) + self.assertIn('windows_plat', EXTRAS_REQUIRE) + self.assertIn('osx_plat', EXTRAS_REQUIRE) + self.assertIn('linux_plat', 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