8000 Don't prettify HTML in PEP pages · python/pythondotorg@cbb14fc · GitHub
[go: up one dir, main page]

Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit cbb14fc

Browse files
committed
Don't prettify HTML in PEP pages
Fixes #825
1 parent de4e5d3 commit cbb14fc

File tree

4 files changed

+85
-21
lines changed

4 files changed

+85
-21
lines changed

peps/converters.py

Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import functools
12
import re
23
import os
34

@@ -13,22 +14,24 @@
1314
pep_url = lambda num: 'dev/peps/pep-{}/'.format(num)
1415

1516

16-
def check_paths():
17-
""" Checks to ensure our PEP_REPO_PATH is setup correctly """
18-
if not hasattr(settings, 'PEP_REPO_PATH'):
19-
raise ImproperlyConfigured("No PEP_REPO_PATH in settings")
20-
21-
if not os.path.exists(settings.PEP_REPO_PATH):
22-
raise ImproperlyConfigured("PEP_REPO_PATH in settings does not exist")
17+
def check_paths(func):
18+
"""Ensure that our PEP_REPO_PATH is setup correctly."""
19+
@functools.wraps(func)
20+
def wrapped(*args, **kwargs):
21+
if not hasattr(settings, 'PEP_REPO_PATH'):
22+
raise ImproperlyConfigured('No PEP_REPO_PATH in settings')
23+
if not os.path.exists(settings.PEP_REPO_PATH):
24+
raise ImproperlyConfigured('Path set as PEP_REPO_PATH does not exist')
25+
return func(*args, **kwargs)
26+
return wrapped
2327

2428

29+
@check_paths
2530
def convert_pep0():
2631
"""
2732
Take existing generated pep-0000.html and convert to something suitable
2833
for a Python.org Page returns the core body HTML necessary only
2934
"""
30-
check_paths()
31-
3235
pep0_path = os.path.join(settings.PEP_REPO_PATH, 'pep-0000.html')
3336
pep0_content = open(pep0_path).read()
3437

@@ -60,7 +63,7 @@ def convert_pep0():
6063
if 'Version:' in t.text and 'N/A' in t.next_sibling.text:
6164
t.parent.extract()
6265

63-
return ''.join([header.prettify(), pep_content.prettify< 8000 /span>()])
66+
return ''.join([str(header), str(pep_content)])
6467

6568

6669
def get_pep0_page(commit=True):
@@ -109,11 +112,11 @@ def fix_headers(soup, data):
109112
return soup, data
110113

111114

115+
@check_paths
112116
def convert_pep_page(pep_number, content):
113117
"""
114118
Handle different formats that pep2html.py outputs
115119
"""
116-
check_paths()
117120
data = {
118121
'title': None,
119122
}
@@ -132,11 +135,11 @@ def convert_pep_page(pep_number, content):
132135

133136
header = soup.body.find('div', class_="header")
134137
header, data = fix_headers(header, data)
135-
data['header'] = header.prettify()
138+
data['header'] = str(header)
136139

137140
main_content = soup.body.find('div', class_="content")
138141

139-
data['main_content'] = main_content.prettify()
142+
data['main_content'] = str(main_content)
140143
data['content'] = ''.join([
141144
data['header'],
142145
data['main_content']
@@ -155,7 +158,7 @@ def convert_pep_page(pep_number, content):
155158
data['title'],
156159
)
157160

158-
data['content'] = soup.prettify()
161+
data['content'] = str(soup)
159162

160163
# Fix PEP links
161164
pep_content = BeautifulSoup(data['content'])
@@ -172,7 +175,7 @@ def convert_pep_page(pep_number, content):
172175

173176
b.attrs['href'] = '/dev/peps/pep-{}/'.format(m.group(1))
174177

175-
data['content'] = pep_content.prettify()
178+
data['content'] = str(pep_content)
176179

177180
source_link = "https://github.com/python/peps/blob/master/pep-{0}.txt".format(pep_number)
178181
data['content'] += """Source: <a href="{0}">{0}</a>""".format(source_link)
@@ -187,6 +190,7 @@ def get_pep_page(pep_number, commit=True):
187190
pep_path = os.path.join(settings.PEP_REPO_PATH, 'pep-{}.html'.format(pep_number))
188191
if not os.path.exists(pep_path):
189192
print("PEP Path '{}' does not exist, skipping".format(pep_path))
193+
return
190194

191195
pep_content = convert_pep_page(pep_number, open(pep_path).read())
192196

@@ -208,6 +212,7 @@ def add_pep_image(pep_number, path):
208212
image_path = os.path.join(settings.PEP_REPO_PATH, path)
209213
if not os.path.exists(image_path):
210214
print("Image Path '{}' does not exist, skipping".format(image_path))
215+
return
211216

212217
try:
213218
page = Page.objects.get(path=pep_url(pep_number))
@@ -250,12 +255,13 @@ def add_pep_image(pep_number, path):
250255
if img_tag['src'] == path:
251256
img_tag['src'] = os.path.join(settings.MEDIA_URL, page.path, path)
252257

253-
page.content.raw = soup.prettify()
258+
page.content.raw = str(soup)
254259
page.save()
255260

256261
return image
257262

258263

264+
@check_paths
259265
def get_peps_rss():
260266
rss_feed = os.path.join(settings.PEP_REPO_PATH, 'peps.rss')
261267
if not os.path.exists(rss_feed):

peps/tests/test_commands.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,12 @@ class PEPManagementCommandTests(TestCase):
1515

1616
@override_settings(PEP_REPO_PATH='/path/that/does/not/exist')
1717
def test_generate_pep_pages(self):
18+
with self.assertRaises(ImproperlyConfigured):
19+
call_command('generate_pep_pages')
1820

21+
@override_settings()
22+
def test_generate_pep_pages_without_setting(self):
23+
del settings.PEP_REPO_PATH
1924
with self.assertRaises(ImproperlyConfigured):
2025
call_command('generate_pep_pages')
2126

peps/tests/test_converters.py

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
from django.core.exceptions import ImproperlyConfigured
33
from django.test.utils import override_settings
44

5-
from peps.converters import check_paths, get_pep0_page, get_pep_page
5+
from peps.converters import get_pep0_page, get_pep_page, add_pep_image
6+
from pydotorg.test_utils import captured_stdout
67

78
from . import FAKE_PEP_REPO
89

@@ -11,10 +12,6 @@ class PEPConverterTests(TestCase):
1112

1213
@override_settings(PEP_REPO_PATH='/path/that/does/not/exist')
1314
def test_converter_path_checks(self):
14-
15-
with self.assertRaises(ImproperlyConfigured):
16-
check_paths()
17-
1815
with self.assertRaises(ImproperlyConfigured):
1916
get_pep0_page()
2017

@@ -27,3 +24,35 @@ def test_source_link(self):
2724
'pep-0525.txt">https://github.com/python/peps/blob/master/pep-0525.txt</a>',
2825
pep.content.rendered
2926
)
27+
28+
@override_settings(PEP_REPO_PATH=FAKE_PEP_REPO)
29+
def test_invalid_pep_number(self):
30+
with captured_stdout() as stdout:
31+
get_pep_page('9999999')
32+
self.assertRegex(
33+
stdout.getvalue(),
34+
r"PEP Path '(.*)9999999(.*)' does not exist, skipping"
35+
)
36+
37+
@override_settings(PEP_REPO_PATH=FAKE_PEP_REPO)
38+
def test_add_image_not_found(self):
39+
with captured_stdout() as stdout:
40+
add_pep_image('0525', '/path/that/does/not/exist')
41+
self.assertRegex(
42+
stdout.getvalue(),
43+
r"Image Path '(.*)/path/that/does/not/exist(.*)' does not exist, skipping"
44+
)
45+
46+
@override_settings(PEP_REPO_PATH=FAKE_PEP_REPO)
47+
def test_html_do_not_prettify(self):
48+
pep = get_pep_page('3001')
49+
self.assertEqual(
50+
pep.title,
51+
'PEP 3001 -- Procedure for reviewing and improving standard library modules'
52+
)
53+
self.assertIn(
54+
'<tr class="field"><th class="field-name">Title:</th>'
55+
'< A93C ;td class="field-body">Procedure for reviewing and improving '
56+
'standard library modules</td>\n</tr>',
57+
pep.content.rendered
58+
)

pydotorg/test_utils.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# TODO: Remove this when we switched to Django 1.8
2+
3+
import contextlib
4+
import sys
5+
6+
from django.utils import six
7+
8+
9+
@contextlib.contextmanager
10+
def captured_output(stream_name):
11+
"""Return a context manager used by captured_stdout/stdin/stderr
12+
that temporarily replaces the sys stream *stream_name* with a StringIO.
13+
Note: This function and the following ``captured_std*`` are copied
14+
from CPython's ``test.support`` module."""
15+
orig_stdout = getattr(sys, stream_name)
16+
setattr(sys, stream_name, six.StringIO())
17+
try:
18+
yield getattr(sys, stream_name)
19+
finally:
20+
setattr(sys, stream_name, orig_stdout)
21+
22+
23+
def captured_stdout():
24+
return captured_output("stdout")

0 commit comments

Comments
 (0)
0