Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 45f5337

Browse files
committed
Merged revisions 68214-68215,68217-68218 via svnmerge from
svn+ssh://[email protected]/python/trunk ........ r68214 | georg.brandl | 2009-01-03 20:44:48 +0100 (Sat, 03 Jan 2009) | 2 lines Make indentation consistent. ........ r68215 | georg.brandl | 2009-01-03 21:15:14 +0100 (Sat, 03 Jan 2009) | 2 lines Fix role name. ........ r68217 | georg.brandl | 2009-01-03 21:30:15 +0100 (Sat, 03 Jan 2009) | 2 lines Add rstlint, a little tool to find subtle markup problems and inconsistencies in the Doc sources. ........ r68218 | georg.brandl | 2009-01-03 21:38:59 +0100 (Sat, 03 Jan 2009) | 2 lines Recognize usage of the default role. ........
1 parent a9ecbda commit 45f5337

3 files changed

Lines changed: 241 additions & 13 deletions

File tree

Doc/Makefile

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ DISTVERSION = $(shell $(PYTHON) tools/sphinxext/patchlevel.py)
1414
ALLSPHINXOPTS = -b $(BUILDER) -d build/doctrees -D latex_paper_size=$(PAPER) \
1515
$(SPHINXOPTS) . build/$(BUILDER) $(SOURCES)
1616

17-
.PHONY: help checkout update build html htmlhelp clean coverage dist
17+
.PHONY: help checkout update build html htmlhelp clean coverage dist check
1818

1919
help:
2020
@echo "Please use \`make <target>' where <target> is one of"
@@ -141,3 +141,5 @@ dist:
141141
cp build/latex/docs-pdf.zip dist/python-$(DISTVERSION)-docs-pdf-letter.zip
142142
cp build/latex/docs-pdf.tar.bz2 dist/python-$(DISTVERSION)-docs-pdf-letter.tar.bz2
143143

144+
check:
145+
$(PYTHON) tools/rstlint.py -i tools -s 2

Doc/library/decimal.rst

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -474,7 +474,7 @@ Decimal objects
474474
>>> Decimal.from_float(float('-inf'))
475475
Decimal('-Infinity')
476476

477-
.. versionadded:: 2.7
477+
.. versionadded:: 3.1
478478

479479
.. method:: fma(other, third[, context])
480480

@@ -933,25 +933,25 @@ In addition to the three supplied contexts, new contexts can be created with the
933933
If the argument is a string, no leading or trailing whitespace is
934934
permitted.
935935

936-
.. method:: create_decimal_from_float(f)
936+
.. method:: create_decimal_from_float(f)
937937

938938
Creates a new Decimal instance from a float *f* but rounding using *self*
939-
as the context. Unlike the :method:`Decimal.from_float` class method,
939+
as the context. Unlike the :meth:`Decimal.from_float` class method,
940940
the context precision, rounding method, flags, and traps are applied to
941941
the conversion.
942942

943943
.. doctest::
944944

945-
>>> context = Context(prec=5, rounding=ROUND_DOWN)
946-
>>> context.create_decimal_from_float(math.pi)
947-
Decimal('3.1415')
948-
>>> context = Context(prec=5, traps=[Inexact])
949-
>>> context.create_decimal_from_float(math.pi)
950-
Traceback (most recent call last):
951-
...
952-
decimal.Inexact: None
945+
>>> context = Context(prec=5, rounding=ROUND_DOWN)
946+
>>> context.create_decimal_from_float(math.pi)
947+
Decimal('3.1415')
948+
>>> context = Context(prec=5, traps=[Inexact])
949+
>>> context.create_decimal_from_float(math.pi)
950+
Traceback (most recent call last):
951+
...
952+
decimal.Inexact: None
953953

954-
.. versionadded:: 2.7
954+
.. versionadded:: 3.1
955955

956956
.. method:: Etiny()
957957

Doc/tools/rstlint.py

Lines changed: 226 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
1+
#!/usr/bin/env python
2+
# -*- coding: utf-8 -*-
3+
4+
# Check for stylistic and formal issues in .rst and .py
5+
# files included in the documentation.
6+
#
7+
# 01/2009, Georg Brandl
8+
9+
from __future__ import with_statement
10+
11+
import os
12+
import re
13+
import sys
14+
import getopt
15+
import subprocess
16+
from os.path import join, splitext, abspath, exists
17+
from collections import defaultdict
18+
19+
directives = [
20+
# standard docutils ones
21+
'admonition', 'attention', 'caution', 'class', 'compound', 'container',
22+
'contents', 'csv-table', 'danger', 'date', 'default-role', 'epigraph',
23+
'error', 'figure', 'footer', 'header', 'highlights', 'hint', 'image',
24+
'important', 'include', 'line-block', 'list-table', 'meta', 'note',
25+
'parsed-literal', 'pull-quote', 'raw', 'replace',
26+
'restructuredtext-test-directive', 'role', 'rubric', 'sectnum', 'sidebar',
27+
'table', 'target-notes', 'tip', 'title', 'topic', 'unicode', 'warning',
28+
# Sphinx custom ones
29+
'acks', 'attribute', 'autoattribute', 'autoclass', 'autodata',
30+
'autoexception', 'autofunction', 'automethod', 'automodule', 'centered',
31+
'cfunction', 'class', 'classmethod', 'cmacro', 'cmdoption', 'cmember',
32+
'code-block', 'confval', 'cssclass', 'ctype', 'currentmodule', 'cvar',
33+
'data', 'deprecated', 'describe', 'directive', 'doctest', 'envvar', 'event',
34+
'exception', 'function', 'glossary', 'highlight', 'highlightlang', 'index',
35+
'literalinclude', 'method', 'module', 'moduleauthor', 'productionlist',
36+
'program', 'role', 'sectionauthor', 'seealso', 'sourcecode', 'staticmethod',
37+
'tabularcolumns', 'testcode', 'testoutput', 'testsetup', 'toctree', 'todo',
38+
'todolist', 'versionadded', 'versionchanged'
39+
]
40+
41+
all_directives = '(' + '|'.join(directives) + ')'
42+
seems_directive_re = re.compile(r'\.\. %s([^a-z:]|:(?!:))' % all_directives)
43+
default_role_re = re.compile(r'(^| )`\w([^`]*?\w)?`($| )')
44+
leaked_markup_re = re.compile(r'[a-z]::[^=]|:[a-z]+:|`|\.\.\s*\w+:')
45+
46+
47+
checkers = {}
48+
49+
checker_props = {'severity': 1, 'falsepositives': False}
50+
51+
def checker(*suffixes, **kwds):
52+
"""Decorator to register a function as a checker."""
53+
def deco(func):
54+
for suffix in suffixes:
55+
checkers.setdefault(suffix, []).append(func)
56+
for prop in checker_props:
57+
setattr(func, prop, kwds.get(prop, checker_props[prop]))
58+
return func
59+
return deco
60+
61+
62+
@checker('.py', severity=4)
63+
def check_syntax(fn, lines):
64+
"""Check Python examples for valid syntax."""
65+
try:
66+
code = ''.join(lines)
67+
if '\r' in code:
68+
if os.name != 'nt':
69+
yield 0, '\\r in code file'
70+
code = code.replace('\r', '')
71+
compile(code, fn, 'exec')
72+
except SyntaxError as err:
73+
yield err.lineno, 'not compilable: %s' % err
74+
75+
76+
@checker('.rst', severity=2)
77+
def check_suspicious_constructs(fn, lines):
78+
"""Check for suspicious reST constructs."""
79+
inprod = False
80+
for lno, line in enumerate(lines):
81+
if seems_directive_re.match(line):
82+
yield lno+1, 'comment seems to be intended as a directive'
83+
if '.. productionlist::' in line:
84+
inprod = True
85+
elif not inprod and default_role_re.search(line):
86+
yield lno+1, 'default role used'
87+
elif inprod and not line.strip():
88+
inprod = False
89+
90+
91+
@checker('.py', '.rst')
92+
def check_whitespace(fn, lines):
93+
"""Check for whitespace and line length issues."""
94+
lasti = 0
95+
for lno, line in enumerate(lines):
96+
if '\r' in line:
97+
yield lno+1, '\\r in line'
98+
if '\t' in line:
99+
yield lno+1, 'OMG TABS!!!1'
100+
if line[:-1].rstrip(' \t') != line[:-1]:
101+
yield lno+1, 'trailing whitespace'
102+
if len(line) > 86:
103+
# don't complain about tables, links and function signatures
104+
if line.lstrip()[0] not in '+|' and \
105+
'http://' not in line and \
106+
not line.lstrip().startswith(('.. function',
107+
'.. method',
108+
'.. cfunction')):
109+
yield lno+1, "line too long"
110+
111+
112+
@checker('.html', severity=2, falsepositives=True)
113+
def check_leaked_markup(fn, lines):
114+
"""Check HTML files for leaked reST markup; this only works if
115+
the HTML files have been built.
116+
"""
117+
for lno, line in enumerate(lines):
118+
if leaked_markup_re.search(line):
119+
yield lno+1, 'possibly leaked markup: %r' % line
120+
121+
122+
def main(argv):
123+
usage = '''\
124+
Usage: %s [-v] [-f] [-s sev] [-i path]* [path]
125+
126+
Options: -v verbose (print all checked file names)
127+
-f enable checkers that yield many false positives
128+
-s sev only show problems with severity >= sev
129+
-i path ignore subdir or file path
130+
''' % argv[0]
131+
try:
132+
gopts, args = getopt.getopt(argv[1:], 'vfs:i:')
133+
except getopt.GetoptError:
134+
print(usage)
135+
return 2
136+
137+
verbose = False
138+
severity = 1
139+
ignore = []
140+
falsepos = False
141+
for opt, val in gopts:
142+
if opt == '-v':
143+
verbose = True
144+
elif opt == '-f':
145+
falsepos = True
146+
elif opt == '-s':
147+
severity = int(val)
148+
elif opt == '-i':
149+
ignore.append(abspath(val))
150+
151+
if len(args) == 0:
152+
path = '.'
153+
elif len(args) == 1:
154+
path = args[0]
155+
else:
156+
print(usage)
157+
return 2
158+
159+
if not exists(path):
160+
print('Error: path %s does not exist' % path)
161+
return 2
162+
163+
count = defaultdict(int)
164+
out = sys.stdout
165+
166+
for root, dirs, files in os.walk(path):
167+
# ignore subdirs controlled by svn
168+
if '.svn' in dirs:
169+
dirs.remove('.svn')
170+
171+
# ignore subdirs in ignore list
172+
if abspath(root) in ignore:
173+
del dirs[:]
174+
continue
175+
176+
for fn in files:
177+
fn = join(root, fn)
178+
if fn[:2] == './':
179+
fn = fn[2:]
180+
181+
# ignore files in ignore list
182+
if abspath(fn) in ignore:
183+
continue
184+
185+
ext = splitext(fn)[1]
186+
checkerlist = checkers.get(ext, None)
187+
if not checkerlist:
188+
continue
189+
190+
if verbose:
191+
print('Checking %s...' % fn)
192+
193+
try:
194+
with open(fn, 'r') as f:
195+
lines = list(f)
196+
except (IOError, OSError) as err:
197+
print('%s: cannot open: %s' % (fn, err))
198+
count[4] += 1
199+
continue
200+
201+
for checker in checkerlist:
202+
if checker.falsepositives and not falsepos:
203+
continue
204+
csev = checker.severity
205+
if csev >= severity:
206+
for lno, msg in checker(fn, lines):
207+
print('[%d] %s:%d: %s' % (csev, fn, lno, msg),
208+
file=out)
209+
count[csev] += 1
210+
if verbose:
211+
print()
212+
if not count:
213+
if severity > 1:
214+
print('No problems with severity >= %d found.' % severity)
215+
else:
216+
print('No problems found.')
217+
else:
218+
for severity in sorted(count):
219+
number = count[severity]
220+
print('%d problem%s with severity %d found.' %
221+
(number, number > 1 and 's' or '', severity))
222+
return int(bool(count))
223+
224+
225+
if __name__ == '__main__':
226+
sys.exit(main(sys.argv))

0 commit comments

Comments
 (0)