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..db337e2 100644 --- twisted/python/dist.py +++ twisted/python/dist.py @@ -49,6 +49,69 @@ 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 to setup +# directly so that combinations of the packages can be created +# without the need 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'], + 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 = { + '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'], + 'all_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..eb0c2e0 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,41 @@ 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('all_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