Skip to content

Commit 6d3648b

Browse files
committed
Add support for Pip's extra dependencies in YAML config.
Closes #173.
1 parent bf922cf commit 6d3648b

File tree

4 files changed

+89
-2
lines changed

4 files changed

+89
-2
lines changed

docs/yaml-config.rst

+52
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,58 @@ documentation.
144144
145145
conf_file: project2/docs/conf.py
146146
147+
python.extra_requirements
148+
`````````````````````````
149+
150+
* Default: ``[]``
151+
* Type: List
152+
153+
List of `extra requirements`_ sections to install, additionnaly to the
154+
`package default dependencies`_. Only works if `python.pip_install` option
155+
above is set to `True`.
156+
157+
Let's say your Python package has a ``setup.py`` which looks like this:
158+
159+
.. code-block:: python
160+
161+
from setuptools import setup
162+
163+
setup(
164+
name="my_package",
165+
166+
# (...)
167+
168+
install_requires=[
169+
'requests',
170+
'simplejson'],
171+
extras_require={
172+
'tests': [
173+
'nose',
174+
'pycodestyle >= 2.1.0'],
175+
'docs': [
176+
'sphinx >= 1.4',
177+
'sphinx_rtd_theme']}
178+
)
179+
180+
Then to have all dependencies from the ``tests`` and ``docs`` sections
181+
installed in addition to the default ``requests`` and ``simplejson``, use the
182+
``extra_requirements`` as such:
183+
184+
.. code-block:: yaml
185+
186+
python:
187+
extra_requirements:
188+
- tests
189+
- docs
190+
191+
Behind the scene the following Pip command will be run:
192+
193+
.. code-block:: shell
194+
195+
$ pip install -e .[tests,docs]
196+
147197
148198
.. _issue: https://github.com/rtfd/readthedocs.org/issues
149199
.. _environment file: http://conda.pydata.org/docs/using/envs.html#share-an-environment
200+
.. _extra requirements: http://setuptools.readthedocs.io/en/latest/setuptools.html#declaring-extras-optional-features-with-their-own-dependencies
201+
.. _package default dependencies: http://setuptools.readthedocs.io/en/latest/setuptools.html#declaring-dependencies

readthedocs/doc_builder/config.py

+8
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,14 @@ def install_project(self):
3939
else:
4040
return self._project.install_project
4141

42+
@property
43+
def extra_requirements(self):
44+
if self.pip_install and 'extra_requirements' in self._yaml_config.get(
45+
'python', {}):
46+
return self._yaml_config['python']['extra_requirements']
47+
else:
48+
return []
49+
4250
@property
4351
def python_interpreter(self):
4452
if 'version' in self._yaml_config.get('python', {}):

readthedocs/doc_builder/python_environments.py

+7-2
Original file line numberDiff line numberDiff line change
@@ -43,15 +43,20 @@ def delete_existing_build_dir(self):
4343
def install_package(self):
4444
setup_path = os.path.join(self.checkout_path, 'setup.py')
4545
if os.path.isfile(setup_path) and self.config.install_project:
46-
if self.config.pip_install or getattr(settings, 'USE_PIP_INSTALL', False):
46+
if self.config.pip_install or getattr(
47+
settings, 'USE_PIP_INSTALL', False):
48+
extra_req_param = ''
49+
if self.config.extra_requirements:
50+
extra_req_param = '[{0}]'.format(
51+
','.join(self.config.extra_requirements))
4752
self.build_env.run(
4853
'python',
4954
self.venv_bin(filename='pip'),
5055
'install',
5156
'--ignore-installed',
5257
'--cache-dir',
5358
self.project.pip_cache_path,
54-
'.',
59+
'.{0}'.format(extra_req_param),
5560
cwd=self.checkout_path,
5661
bin_path=self.venv_bin()
5762
)

readthedocs/rtd_tests/tests/test_config_wrapper.py

+22
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,28 @@ def test_install_project(self):
5555
config = ConfigWrapper(version=self.version, yaml_config=yaml_config)
5656
self.assertEqual(config.install_project, False)
5757

58+
def test_extra_requirements(self):
59+
yaml_config = get_build_config({'python': {
60+
'pip_install': True,
61+
'extra_requirements': ['tests', 'docs']}})
62+
config = ConfigWrapper(version=self.version, yaml_config=yaml_config)
63+
self.assertEqual(config.extra_requirements, ['tests', 'docs'])
64+
65+
yaml_config = get_build_config({'python': {
66+
'extra_requirements': ['tests', 'docs']}})
67+
config = ConfigWrapper(version=self.version, yaml_config=yaml_config)
68+
self.assertEqual(config.extra_requirements, [])
69+
70+
yaml_config = get_build_config({})
71+
config = ConfigWrapper(version=self.version, yaml_config=yaml_config)
72+
self.assertEqual(config.extra_requirements, [])
73+
74+
yaml_config = get_build_config({'python': {
75+
'setup_py_install': True,
76+
'extra_requirements': ['tests', 'docs']}})
77+
config = ConfigWrapper(version=self.version, yaml_config=yaml_config)
78+
self.assertEqual(config.extra_requirements, [])
79+
5880
def test_conda(self):
5981
to_find = 'urls.py'
6082
yaml_config = get_build_config({'conda': {'file': to_find}})

0 commit comments

Comments
 (0)