39b3942048
Left hand side slicing is confusing and slower but maybe more memory efficient in some circumstances. There is one case where it adds to code safety: when it's used to substitute a different list in place of a slice of the original list and the original list could have been bound to a different variable in some other code. (The most likely case of this is when it's a global variable and some other code might import that variable name). Because of the confusion factor we think it should only be used for the safety case or where it's been benchmarked and shown to have some sort of documentatble improvement. At the moment, only one piece of code falls into those categories so this PR removes all the other instances of left hand side slicing.
135 lines
4.4 KiB
Python
Executable file
135 lines
4.4 KiB
Python
Executable file
#!/usr/bin/env python
|
|
from __future__ import (absolute_import, division, print_function)
|
|
__metaclass__ = type
|
|
|
|
import os
|
|
import re
|
|
import subprocess
|
|
import sys
|
|
|
|
|
|
def main():
|
|
base_dir = os.getcwd() + os.path.sep
|
|
docs_dir = os.path.abspath('docs/docsite')
|
|
cmd = ['make', 'singlehtmldocs']
|
|
|
|
sphinx = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=docs_dir)
|
|
stdout, stderr = sphinx.communicate()
|
|
|
|
stdout = stdout.decode('utf-8')
|
|
stderr = stderr.decode('utf-8')
|
|
|
|
if sphinx.returncode != 0:
|
|
sys.stderr.write("Command '%s' failed with status code: %d\n" % (' '.join(cmd), sphinx.returncode))
|
|
|
|
if stdout.strip():
|
|
stdout = simplify_stdout(stdout)
|
|
|
|
sys.stderr.write("--> Standard Output\n")
|
|
sys.stderr.write("%s\n" % stdout.strip())
|
|
|
|
if stderr.strip():
|
|
sys.stderr.write("--> Standard Error\n")
|
|
sys.stderr.write("%s\n" % stderr.strip())
|
|
|
|
sys.exit(1)
|
|
|
|
with open('docs/docsite/rst_warnings', 'r') as warnings_fd:
|
|
output = warnings_fd.read().strip()
|
|
lines = output.splitlines()
|
|
|
|
known_warnings = {
|
|
'block-quote-missing-blank-line': r'^Block quote ends without a blank line; unexpected unindent.$',
|
|
'literal-block-lex-error': r'^Could not lex literal_block as "[^"]*". Highlighting skipped.$',
|
|
'duplicate-label': r'^duplicate label ',
|
|
'undefined-label': r'undefined label: ',
|
|
'unknown-document': r'unknown document: ',
|
|
'toc-tree-missing-document': r'toctree contains reference to nonexisting document ',
|
|
'reference-target-not-found': r'[^ ]* reference target not found: ',
|
|
'not-in-toc-tree': r"document isn't included in any toctree$",
|
|
'unexpected-indentation': r'^Unexpected indentation.$',
|
|
'definition-list-missing-blank-line': r'^Definition list ends without a blank line; unexpected unindent.$',
|
|
'explicit-markup-missing-blank-line': r'Explicit markup ends without a blank line; unexpected unindent.$',
|
|
'toc-tree-glob-pattern-no-match': r"^toctree glob pattern '[^']*' didn't match any documents$",
|
|
'unknown-interpreted-text-role': '^Unknown interpreted text role "[^"]*".$',
|
|
}
|
|
|
|
for line in lines:
|
|
match = re.search('^(?P<path>[^:]+):((?P<line>[0-9]+):)?((?P<column>[0-9]+):)? (?P<level>WARNING|ERROR): (?P<message>.*)$', line)
|
|
|
|
if not match:
|
|
path = 'docs/docsite/rst/index.rst'
|
|
lineno = 0
|
|
column = 0
|
|
code = 'unknown'
|
|
message = line
|
|
|
|
# surface unknown lines while filtering out known lines to avoid excessive output
|
|
print('%s:%d:%d: %s: %s' % (path, lineno, column, code, message))
|
|
continue
|
|
|
|
path = match.group('path')
|
|
lineno = int(match.group('line') or 0)
|
|
column = int(match.group('column') or 0)
|
|
level = match.group('level').lower()
|
|
message = match.group('message')
|
|
|
|
path = os.path.abspath(path)
|
|
|
|
if path.startswith(base_dir):
|
|
path = path[len(base_dir):]
|
|
|
|
if path.startswith('rst/'):
|
|
path = 'docs/docsite/' + path # fix up paths reported relative to `docs/docsite/`
|
|
|
|
if level == 'warning':
|
|
code = 'warning'
|
|
|
|
for label, pattern in known_warnings.items():
|
|
if re.search(pattern, message):
|
|
code = label
|
|
break
|
|
else:
|
|
code = 'error'
|
|
|
|
print('%s:%d:%d: %s: %s' % (path, lineno, column, code, message))
|
|
|
|
|
|
def simplify_stdout(value):
|
|
"""Simplify output by omitting earlier 'rendering: ...' messages."""
|
|
lines = value.strip().splitlines()
|
|
|
|
rendering = []
|
|
keep = []
|
|
|
|
def truncate_rendering():
|
|
"""Keep last rendering line (if any) with a message about omitted lines as needed."""
|
|
if not rendering:
|
|
return
|
|
|
|
notice = rendering[-1]
|
|
|
|
if len(rendering) > 1:
|
|
notice += ' (%d previous rendering line(s) omitted)' % (len(rendering) - 1)
|
|
|
|
keep.append(notice)
|
|
# Could change to rendering.clear() if we do not support python2
|
|
rendering[:] = []
|
|
|
|
for line in lines:
|
|
if line.startswith('rendering: '):
|
|
rendering.append(line)
|
|
continue
|
|
|
|
truncate_rendering()
|
|
keep.append(line)
|
|
|
|
truncate_rendering()
|
|
|
|
result = '\n'.join(keep)
|
|
|
|
return result
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|