Skip to content

Commit ded401e

Browse files
humitosagjohnson
authored andcommitted
Auto-generate conf.py compatible with Py2 and Py3 (#3745)
* Test to call BaseSphinx.append_conf() without a conf.py * Fix open.write incompatibility between Py2 and Py3 * Small typo * Small lint error * Add docstring and mark test as failed when Exception raised * Spaces cleanup in conf.py.conf (template) * Improve test to check content of generated conf.py * Remove unused import * Increase in one the number of imported files because of new conf.py * Fix test to return a valid temporal file as conf.py
1 parent da56a7d commit ded401e

File tree

5 files changed

+109
-9
lines changed

5 files changed

+109
-9
lines changed

readthedocs/projects/utils.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
import redis
1212
import six
13-
from builtins import object
13+
from builtins import object, open
1414
from django.conf import settings
1515
from django.core.cache import cache
1616
from httplib2 import Http
@@ -121,8 +121,9 @@ def safe_write(filename, contents):
121121
dirname = os.path.dirname(filename)
122122
if not os.path.exists(dirname):
123123
os.makedirs(dirname)
124-
with open(filename, 'w') as fh:
125-
fh.write(contents.encode('utf-8', 'ignore'))
124+
125+
with open(filename, 'w', encoding='utf-8', errors='ignore') as fh:
126+
fh.write(contents)
126127
fh.close()
127128

128129

readthedocs/rtd_tests/files/conf.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# -*- coding: utf-8 -*-
2+
3+
from __future__ import division, print_function, unicode_literals
4+
5+
from datetime import datetime
6+
7+
from recommonmark.parser import CommonMarkParser
8+
9+
extensions = []
10+
templates_path = ['/tmp/sphinx-template-dir', 'templates', '_templates', '.templates']
11+
source_suffix = ['.rst', '.md']
12+
source_parsers = {
13+
'.md': CommonMarkParser,
14+
}
15+
master_doc = 'index'
16+
project = u'Pip'
17+
copyright = str(datetime.now().year)
18+
version = '0.8.1'
19+
release = '0.8.1'
20+
exclude_patterns = ['_build']
21+
pygments_style = 'sphinx'
22+
htmlhelp_basename = 'pip'
23+
html_theme = 'sphinx_rtd_theme'
24+
file_insertion_enabled = False
25+
latex_documents = [
26+
('index', 'pip.tex', u'Pip Documentation',
27+
u'', 'manual'),
28+
]
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
# -*- coding: utf-8 -*-
2+
from __future__ import (
3+
absolute_import, division, print_function, unicode_literals)
4+
5+
from collections import namedtuple
6+
import os
7+
import tempfile
8+
9+
from django.test import TestCase
10+
from mock import patch, Mock
11+
import pytest
12+
13+
from readthedocs.doc_builder.backends.sphinx import BaseSphinx
14+
from readthedocs.projects.exceptions import ProjectConfigurationError
15+
from readthedocs.projects.models import Project
16+
17+
18+
class SphinxBuilderTest(TestCase):
19+
20+
fixtures = ['test_data']
21+
22+
def setUp(self):
23+
self.project = Project.objects.get(slug='pip')
24+
self.version = self.project.versions.first()
25+
26+
build_env = namedtuple('project', 'version')
27+
build_env.project = self.project
28+
build_env.version = self.version
29+
30+
BaseSphinx.type = 'base'
31+
BaseSphinx.sphinx_build_dir = tempfile.mkdtemp()
32+
self.base_sphinx = BaseSphinx(build_env=build_env, python_env=None)
33+
34+
@patch(
35+
'readthedocs.doc_builder.backends.sphinx.SPHINX_TEMPLATE_DIR',
36+
'/tmp/sphinx-template-dir',
37+
)
38+
@patch('readthedocs.doc_builder.backends.sphinx.BaseSphinx.docs_dir')
39+
@patch('readthedocs.doc_builder.backends.sphinx.BaseSphinx.create_index')
40+
@patch('readthedocs.doc_builder.backends.sphinx.BaseSphinx.get_config_params')
41+
@patch('readthedocs.doc_builder.backends.sphinx.BaseSphinx.run')
42+
@patch('readthedocs.builds.models.Version.get_conf_py_path')
43+
@patch('readthedocs.builds.models.Project.conf_file')
44+
def test_create_conf_py(self, conf_file, get_conf_py_path, _, get_config_params, create_index, docs_dir):
45+
"""
46+
Test for a project without ``conf.py`` file.
47+
48+
When this happen, the ``get_conf_py_path`` raises a
49+
``ProjectConfigurationError`` which is captured by our own code and
50+
generates a conf.py file based using our own template.
51+
52+
This template should be properly rendered in Python2 and Python3 without
53+
any kind of exception raised by ``append_conf`` (we were originally
54+
having a ``TypeError`` because of an encoding problem in Python3)
55+
"""
56+
docs_dir.return_value = tempfile.mkdtemp()
57+
create_index.return_value = 'README.rst'
58+
get_config_params.return_value = {}
59+
get_conf_py_path.side_effect = ProjectConfigurationError
60+
conf_file.return_value = tempfile.mktemp()
61+
try:
62+
self.base_sphinx.append_conf()
63+
except Exception:
64+
pytest.fail('Exception was generated when append_conf called.')
65+
66+
# Check the content generated by our method is the same than what we
67+
# expects from a pre-generated file
68+
generated_conf_py = os.path.join(self.base_sphinx.docs_dir(), 'conf.py')
69+
expected_conf_py = os.path.join(os.path.dirname(__file__), '..', 'files', 'conf.py')
70+
with open(generated_conf_py) as gf, open(expected_conf_py) as ef:
71+
self.assertEqual(gf.read(), ef.read())

readthedocs/rtd_tests/tests/test_imported_file.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@ def test_properly_created(self):
1919
test_dir = os.path.join(base_dir, 'files')
2020
self.assertEqual(ImportedFile.objects.count(), 0)
2121
_manage_imported_files(self.version, test_dir, 'commit01')
22-
self.assertEqual(ImportedFile.objects.count(), 2)
22+
self.assertEqual(ImportedFile.objects.count(), 3)
2323
_manage_imported_files(self.version, test_dir, 'commit01')
24-
self.assertEqual(ImportedFile.objects.count(), 2)
24+
self.assertEqual(ImportedFile.objects.count(), 3)
2525

2626
def test_update_commit(self):
2727
test_dir = os.path.join(base_dir, 'files')
@@ -47,4 +47,4 @@ def test_update_content(self):
4747
_manage_imported_files(self.version, test_dir, 'commit02')
4848
self.assertNotEqual(ImportedFile.objects.get(name='test.html').md5, 'c7532f22a052d716f7b2310fb52ad981')
4949

50-
self.assertEqual(ImportedFile.objects.count(), 2)
50+
self.assertEqual(ImportedFile.objects.count(), 3)

readthedocs/templates/sphinx/conf.py.conf

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ from recommonmark.parser import CommonMarkParser
88

99
extensions = []
1010
templates_path = ['{{ template_dir }}', 'templates', '_templates', '.templates']
11-
source_suffix = ['.rst', '.md']
12-
source_parsers = {
13-
'.md': CommonMarkParser,
11+
source_suffix = ['.rst', '.md']
12+
source_parsers = {
13+
'.md': CommonMarkParser,
1414
}
1515
master_doc = 'index'
1616
project = u'{{ project.name }}'

0 commit comments

Comments
 (0)