Ticket #3696: extras_require-3696-11.diff

File extras_require-3696-11.diff, 13.0 KB (added by Chris Wolfe, 5 years ago)

comments from adiroiban, thijs, tom.prince

  • docs/index.rst

    diff --git docs/index.rst docs/index.rst
    index 1172a49..a4eaf5f 100644
    Contents: 
    77    :maxdepth: 2
    88    :includehidden:
    99
     10    installation/index
    1011    core/index
    1112    conch/index
    1213    lore/index
  • new file docs/installation/howto/optional.rst

    diff --git docs/installation/howto/optional.rst docs/installation/howto/optional.rst
    new file mode 100644
    index 0000000..38f9d05
    - +  
     1
     2:LastChangedDate: $LastChangedDate$
     3:LastChangedRevision: $LastChangedRevision$
     4:LastChangedBy: $LastChangedBy$
     5
     6Installing Optional Dependencies
     7================================
     8
     9This document describes how to install optional dependencies that enhance Twisted.
     10These dependencies are python packages that Twisted's developers have found useful either for developing Twisted itself or for developing Twisted applications.
     11
     12The intended audience of this document is someone who is going to use `pip`_ to manage a Twisted installation.
     13
     14
     15What are optional dependencies?
     16----------------------------------
     17
     18Optional dependencies are python packages that are not strictly necessary for Twisted to function but provide some functionality that would otherwise be unavailable.
     19
     20
     21Why use optional dependencies?
     22------------------------------
     23
     24The optional dependencies that Twisted recommends are used regularly by Twisted developers.
     25While this is not a guarantee that each dependency combination works on every operating system and python interpreter, it is a good indication that the dependencies *should* work.
     26
     27
     28Which options are supported?
     29----------------------------
     30
     31* **dev** - packages that aid in the development of Twisted itself.
     32    * `TwistedChecker`_
     33    * `pyflakes`_
     34    * `twisted-dev-tools`_
     35    * `python-subunit`_
     36    * `Sphinx`_
     37    * `pydoctor`_
     38
     39* **tls** - packages that are needed to work with TLS.
     40    * `pyOpenSSL`_
     41    * `service_identity`_
     42
     43* **conch** - packages for working with conch/SSH.
     44    * `gmpy`_
     45    * `pyasn1`_
     46    * `pycrypto`_
     47
     48* **soap** - the `SOAPpy`_ package to work with SOAP.
     49
     50* **serial** - the `pyserial`_ package to work with serial data.
     51
     52* **all_non_platform** - installs **tls**, **conch**, **soap**, and **serial** options.
     53
     54* **osx_platform** - **all_non_platform** options and `pyobjc`_ to work with Objective-C apis.
     55
     56* **windows_platform** - **all_non_platform** options and `pypiwin32`_ to work with Windows's apis.
     57
     58
     59How do I install an optional dependency?
     60----------------------------------------
     61
     62To install optional dependencies one needs to use a slightly different syntax with `pip`_ than normal.
     63The following code snippet installs Twisted and its **dev** option.
     64
     65.. code-block:: shell
     66
     67   $ pip install "twisted[dev]"
     68
     69To install multiple options at the same time, one need only provide `pip`_ a comma seperated list of options.
     70For example, to install the **dev** and **tls** options, call `pip`_ like so:
     71
     72.. code-block:: shell
     73
     74   $ pip install "twisted[dev, tls]"
     75
     76Lastly, if you are developing Twisted and want to install your development source and an optional depency, use `pip`_ to create an `editable install`_:
     77
     78.. code-block:: shell
     79
     80   $ cd /into/directory/containing/Twisted/setup.py
     81   $ pip install -e ".[dev]"
     82
     83
     84Conclusion
     85----------
     86
     87In this document you've been shown:
     88
     89#. What optional dependences are.
     90#. Which optional dependencies are supported.
     91#. How to install optional dependencies using `pip`_.
     92
     93
     94.. _pip: https://pip.pypa.io/en/latest/quickstart.html
     95.. _TwistedChecker: https://pypi.python.org/pypi/TwistedChecker
     96.. _pyflakes: https://pypi.python.org/pypi/pyflakes
     97.. _twisted-dev-tools: https://pypi.python.org/pypi/twisted-dev-tools
     98.. _python-subunit: https://pypi.python.org/pypi/python-subunit
     99.. _Sphinx: https://pypi.python.org/pypi/Sphinx/1.3b1
     100.. _pydoctor: https://pypi.python.org/pypi/pydoctor
     101.. _pyOpenSSL: https://pypi.python.org/pypi/pyOpenSSL
     102.. _service_identity: https://pypi.python.org/pypi/service_identity
     103.. _gmpy: https://pypi.python.org/pypi/gmpy/1.17
     104.. _pyasn1: https://pypi.python.org/pypi/pyasn1
     105.. _pycrypto: https://pypi.python.org/pypi/pycrypto
     106.. _SOAPpy: https://pypi.python.org/pypi/SOAPpy
     107.. _pyserial: https://pypi.python.org/pypi/pyserial
     108.. _pyobjc: https://pypi.python.org/pypi/pyobjc
     109.. _pypiwin32: https://pypi.python.org/pypi/pypiwin32
     110.. _`editable install`: https://pip.pypa.io/en/latest/reference/pip_install.html#editable-installs
     111.. _`extras_require`: https://pythonhosted.org/setuptools/setuptools.html#declaring-extras-optional-features-with-their-own-dependencies
  • new file docs/installation/index.rst

    diff --git docs/installation/index.rst docs/installation/index.rst
    new file mode 100644
    index 0000000..d3e0360
    - +  
     1
     2:LastChangedDate: $LastChangedDate$
     3:LastChangedRevision: $LastChangedRevision$
     4:LastChangedBy: $LastChangedBy$
     5
     6Installing Twisted
     7==================
     8
     9.. toctree::
     10   :hidden:
     11
     12   howto/optional
     13
     14- :doc:`Installing Optional Dependencies <howto/optional>`: documentation
     15  on how to install Twisted's optional dependencies.
  • setup.py

    diff --git setup.py setup.py
    index 26f052b..e63f1b5 100755
    dependency resolution is disabled. 
    5454
    5555    from twisted.python.dist import (
    5656        STATIC_PACKAGE_METADATA, getDataFiles, getExtensions, getAllScripts,
    57         getPackages, setup)
     57        getPackages, setup, EXTRAS_REQUIRE)
    5858
    5959    scripts = getAllScripts()
    6060
    dependency resolution is disabled. 
    6262        packages=getPackages('twisted'),
    6363        conditionalExtensions=getExtensions(),
    6464        scripts=scripts,
     65        extras_require=EXTRAS_REQUIRE,
    6566        data_files=getDataFiles('twisted'),
    6667        **STATIC_PACKAGE_METADATA))
    6768
  • twisted/python/dist.py

    diff --git twisted/python/dist.py twisted/python/dist.py
    index 63b36b3..ae46d17 100644
    twisted_subprojects = ["conch", "lore", "mail", "names", 
    4949                       "news", "pair", "runner", "web",
    5050                       "words"]
    5151
     52# These are the actual package names and versions that will
     53# be used by extras_require. This is not passed to setup
     54# directly so that combinations of the packages can be created
     55# without the need to copy package names multiple times.
     56_extra_options = dict(
     57    dev=['twistedchecker >= 0.2.0',
     58         'pyflakes >= 0.8.1',
     59         'twisted-dev-tools >= 0.0.2',
     60         'python-subunit',
     61         'sphinx >= 1.2.2',
     62         'pydoctor >= 0.5'],
     63    tls=['pyopenssl >= 0.11',
     64         'service_identity'],
     65    conch=['gmpy',
     66           'pyasn1',
     67           'pycrypto'],
     68    soap=['soappy'],
     69    serial=['pyserial'],
     70    osx=['pyobjc'],
     71    windows=['pypiwin32']
     72)
     73
     74_platform_independent = (
     75    _extra_options['tls'] +
     76    _extra_options['conch'] +
     77    _extra_options['soap'] +
     78    _extra_options['serial']
     79)
     80
     81# extras_require is a dictionary of items that can be passed to setup.py
     82# to install optional dependencies. For example, to install the optional
     83# dev dependencies one would type `pip install -e ".[dev]"`
     84# This has been supported by setuptools since 0.5a4
     85EXTRAS_REQUIRE = {
     86    'dev': _extra_options['dev'],
     87    'tls': _extra_options['tls'],
     88    'conch': _extra_options['conch'],
     89    'soap': _extra_options['soap'],
     90    'serial': _extra_options['serial'],
     91    'all_non_platform': _platform_independent,
     92    'osx_platform': (
     93        _extra_options['osx'] + _platform_independent
     94    ),
     95    'windows_platform': (
     96        _extra_options['windows'] + _platform_independent
     97    ),
     98}
    5299
    53100
    54101class ConditionalExtension(Extension):
  • twisted/python/test/test_dist.py

    diff --git twisted/python/test/test_dist.py twisted/python/test/test_dist.py
    index d2288ee..5cfccd3 100644
    Tests for parts of our release automation system. 
    99import os
    1010import sys
    1111
    12 from distutils.core import Distribution
     12from setuptools.dist import Distribution
    1313
    1414from twisted.trial.unittest import TestCase
    1515
    1616from twisted.python import dist
    1717from twisted.python.dist import (get_setup_args, ConditionalExtension,
    18     build_scripts_twisted)
     18                                 build_scripts_twisted, EXTRAS_REQUIRE)
    1919from twisted.python.filepath import FilePath
    2020
    2121
    class SetupTest(TestCase): 
    5858        self.assertEqual(ext.define_macros, [("whatever", 2), ("WIN32", 1)])
    5959
    6060
     61class OptionalDependenciesTests(TestCase):
     62    """
     63    Tests for L{dist.EXTRA_REQUIRES}
     64    """
     65    def test_distributeTakesExtrasRequire(self):
     66        """
     67        Setuptools' Distribution object can use extra_requires.
     68        """
     69        extras = dict(im_an_extra_dependency="thing")
     70        attrs = dict(extras_require=extras)
     71        dist = Distribution(attrs)
     72        self.assertEqual(
     73            extras,
     74            dist.extras_require
     75        )
     76
     77
     78    def test_extrasRequireDictContainsKeys(self):
     79        """
     80        L{dist.EXTRA_REQUIRES} C{dev} option contains a valid
     81        list with correct dependecies.
     82        """
     83        self.assertIn('dev', EXTRAS_REQUIRE)
     84        self.assertIn('tls', EXTRAS_REQUIRE)
     85        self.assertIn('conch', EXTRAS_REQUIRE)
     86        self.assertIn('soap', EXTRAS_REQUIRE)
     87        self.assertIn('serial', EXTRAS_REQUIRE)
     88        self.assertIn('all_non_platform', EXTRAS_REQUIRE)
     89        self.assertIn('osx_platform', EXTRAS_REQUIRE)
     90        self.assertIn('windows_platform', EXTRAS_REQUIRE)
     91
     92
     93    def test_extrasRequiresDevDepsAreValid(self):
     94        """
     95        L{dist.EXTRA_REQUIRES} C{dev} option contains the correct
     96        dependencies.
     97        """
     98        deps = EXTRAS_REQUIRE['dev']
     99        self.assertIn('twistedchecker >= 0.2.0', deps)
     100        self.assertIn('pyflakes >= 0.8.1', deps)
     101        self.assertIn('twisted-dev-tools >= 0.0.2', deps)
     102        self.assertIn('python-subunit', deps)
     103        self.assertIn('sphinx >= 1.2.2', deps)
     104        self.assertIn('pydoctor >= 0.5', deps)
     105
     106
     107    def test_extrasRequiresTlsDepsAreValid(self):
     108        """
     109        L{dist.EXTRA_REQUIRES} C{tls} option contains the correct
     110        dependencies.
     111        """
     112        deps = EXTRAS_REQUIRE['tls']
     113        self.assertIn('pyopenssl >= 0.11', deps)
     114        self.assertIn('service_identity', deps)
     115
     116
     117    def test_extrasRequiresConchDepsAreValid(self):
     118        """
     119        L{dist.EXTRA_REQUIRES} C{conch} option contains the correct
     120        dependencies.
     121        """
     122        deps = EXTRAS_REQUIRE['conch']
     123        self.assertIn('gmpy', deps)
     124        self.assertIn('pyasn1', deps)
     125        self.assertIn('pycrypto', deps)
     126
     127
     128    def test_extrasRequiresSoapDepsAreValid(self):
     129        """
     130        L{dist.EXTRA_REQUIRES} C{soap} option contains the correct
     131        dependecies.
     132        """
     133        self.assertIn(
     134            'soappy',
     135            EXTRAS_REQUIRE['soap']
     136        )
     137
     138
     139    def test_extrasRequiresSerialDepsAreValid(self):
     140        """
     141        L{dist.EXTRA_REQUIRES} C{serial} option contains the correct
     142        dependencies.
     143        """
     144        self.assertIn(
     145            'pyserial',
     146            EXTRAS_REQUIRE['serial']
     147        )
     148
     149
     150    def test_extrasRequiresAllNonPlatformDepsAreValid(self):
     151        """
     152        L{dist.EXTRA_REQUIRES} C{all_non_platform} option contains the
     153        correct dependencies.
     154        """
     155        deps = EXTRAS_REQUIRE['all_non_platform']
     156        self.assertIn('pyopenssl >= 0.11', deps)
     157        self.assertIn('service_identity', deps)
     158        self.assertIn('gmpy', deps)
     159        self.assertIn('pyasn1', deps)
     160        self.assertIn('pycrypto', deps)
     161        self.assertIn('soappy', deps)
     162        self.assertIn('pyserial', deps)
     163
     164
     165    def test_extrasRequiresOsxPlatformDepsAreValid(self):
     166        """
     167        L{dist.EXTRA_REQUIRES} C{osx_platform} option contains the correct
     168        dependecies.
     169        """
     170        deps = EXTRAS_REQUIRE['osx_platform']
     171        self.assertIn('pyopenssl >= 0.11', deps)
     172        self.assertIn('service_identity', deps)
     173        self.assertIn('gmpy', deps)
     174        self.assertIn('pyasn1', deps)
     175        self.assertIn('pycrypto', deps)
     176        self.assertIn('soappy', deps)
     177        self.assertIn('pyserial', deps)
     178        self.assertIn('pyobjc', deps)
     179
     180
     181    def test_extrasRequiresWindowsPlatformDepsAreValid(self):
     182        """
     183        L{dist.EXTRA_REQUIRES} C{windows_platform} option contains the correct
     184        dependecies.
     185        """
     186        deps = EXTRAS_REQUIRE['windows_platform']
     187        self.assertIn('pyopenssl >= 0.11', deps)
     188        self.assertIn('service_identity', deps)
     189        self.assertIn('gmpy', deps)
     190        self.assertIn('pyasn1', deps)
     191        self.assertIn('pycrypto', deps)
     192        self.assertIn('soappy', deps)
     193        self.assertIn('pyserial', deps)
     194        self.assertIn('pypiwin32', deps)
     195
    61196
    62197class GetExtensionsTest(TestCase):
    63198    """
  • new file twisted/topfiles/3696.feature

    diff --git twisted/topfiles/3696.feature twisted/topfiles/3696.feature
    new file mode 100644
    index 0000000..24d3d09
    - +  
     1Optional dependencies can be installed using the extra_requires facility provided by setuptools.
     2 No newline at end of file