Merge "Allow ignore specific error codes in files"

This commit is contained in:
Jenkins 2015-04-09 15:08:02 +00:00 committed by Gerrit Code Review
commit 24a3c9642a
2 changed files with 62 additions and 24 deletions

View File

@ -27,7 +27,8 @@ Command line usage
$ doc8 -h
usage: doc8 [-h] [--config path] [--allow-long-titles] [--ignore code]
[--no-sphinx] [--ignore-path path] [--default-extension extension]
[--no-sphinx] [--ignore-path path] [--ignore-path-errors path]
[--default-extension extension] [--file-encoding encoding]
[--max-line-length int] [-e extension] [-v] [--version]
[path [path ...]]
@ -46,17 +47,20 @@ Command line usage
- no newline at end of file - D005
positional arguments:
path path to scan for doc files (default: os.getcwd())
path Path to scan for doc files (default: current
directory).
optional arguments:
-h, --help show this help message and exit
--config path user config file location (default: doc8.ini, tox.ini,
pep8.ini, setup.cfg)
--allow-long-titles allow long section titles (default: False)
--ignore code ignore the given errors code/codes
--no-sphinx do not ignore sphinx specific false positives
--ignore-path path ignore the given directory or file (globs are
supported)
--config path User config file location (default: doc8.ini, tox.ini,
pep8.ini, setup.cfg).
--allow-long-titles Allow long section titles (default: False).
--ignore code Ignore the given error code(s).
--no-sphinx Do not ignore sphinx specific false positives.
--ignore-path path Ignore the given directory or file (globs are
supported).
--ignore-path-errors path
Ignore the given specific errors in the provided file.
--default-extension extension
Default file extension to use when a file is found
without a file extension.
@ -65,11 +69,11 @@ Command line usage
an input files text encoding (providing this avoids
using `chardet` to automatically detect encoding/s)
--max-line-length int
maximum allowed line length (default: 79)
Maximum allowed line length (default: 79).
-e extension, --extension extension
check file extensions of the given type (default:
.rst, .txt)
-v, --verbose run in verbose mode
Check file extensions of the given type (default:
.rst, .txt).
-v, --verbose Run in verbose mode.
--version Show the version and exit.
Ini file usage
@ -90,14 +94,14 @@ An example section that can be placed into one of these files::
[doc8]
ignore_path=/tmp/stuff,/tmp/other_stuff
max_line_length=99
ignore-path=/tmp/stuff,/tmp/other_stuff
max-line-length=99
verbose=1
ignore-path-errors=/tmp/other_thing.rst;D001;D002
**Note:** The option names are the same as the command line ones but instead
of dashes underscores are used instead (with the only variation of this being
the ``no-sphinx`` option which from configuration file will be ``sphinx``
instead).
**Note:** The option names are the same as the command line ones (with the
only variation of this being the ``no-sphinx`` option which from
configuration file will be ``sphinx`` instead).
Option conflict resolution
**************************
@ -110,6 +114,7 @@ of conflicts.
Option Overrides Merges
===================== =========== ========
``allow-long-titles`` Yes No
``ignore-path-errors`` No Yes
``default-extension`` Yes No
``extension`` No Yes
``ignore-path`` No Yes

View File

@ -60,8 +60,8 @@ CONFIG_FILENAMES = [
]
def split_set_type(text):
return set([i.strip() for i in text.split(",") if i.strip()])
def split_set_type(text, delimiter=","):
return set([i.strip() for i in text.split(delimiter) if i.strip()])
def merge_sets(sets):
@ -71,6 +71,16 @@ def merge_sets(sets):
return m
def parse_ignore_path_errors(entries):
ignore_path_errors = collections.defaultdict(set)
for path in entries:
path, ignored_errors = path.split(";", 1)
path = os.path.abspath(path.strip())
ignored_errors = split_set_type(ignored_errors, delimiter=";")
ignore_path_errors[path].update(ignored_errors)
return dict(ignore_path_errors)
def extract_config(args):
parser = configparser.RawConfigParser()
read_files = []
@ -97,6 +107,13 @@ def extract_config(args):
"ignore-path"))
except (configparser.NoSectionError, configparser.NoOptionError):
pass
try:
ignore_path_errors = parser.get("doc8", "ignore-path-errors")
ignore_path_errors = split_set_type(ignore_path_errors)
ignore_path_errors = parse_ignore_path_errors(ignore_path_errors)
cfg['ignore_path_errors'] = ignore_path_errors
except (configparser.NoSectionError, configparser.NoOptionError):
pass
try:
cfg['allow_long_titles'] = parser.getboolean("doc8",
"allow-long-titles")
@ -186,10 +203,13 @@ def validate(cfg, files):
print("Validating...")
error_counts = {}
ignoreables = frozenset(cfg.get('ignore', []))
ignore_targeted = cfg.get('ignore_path_errors', {})
while files:
f = files.popleft()
if cfg.get('verbose'):
print("Validating %s" % f)
targeted_ignoreables = set(ignore_targeted.get(f.filename, set()))
targeted_ignoreables.update(ignoreables)
for c in fetch_checks(cfg):
try:
# http://legacy.python.org/dev/peps/pep-3155/
@ -214,7 +234,7 @@ def validate(cfg, files):
except AttributeError:
pass
else:
reports = reports - ignoreables
reports = reports - targeted_ignoreables
if not reports:
if cfg.get('verbose'):
print(" Skipping check '%s', determined to only"
@ -224,7 +244,7 @@ def validate(cfg, files):
print(" Running check '%s'" % check_name)
if isinstance(c, checks.ContentCheck):
for line_num, code, message in c.report_iter(f):
if code in ignoreables:
if code in targeted_ignoreables:
continue
if not isinstance(line_num, (float, int)):
line_num = "?"
@ -238,7 +258,7 @@ def validate(cfg, files):
elif isinstance(c, checks.LineCheck):
for line_num, line in enumerate(f.lines_iter(), 1):
for code, message in c.report_iter(line):
if code in ignoreables:
if code in targeted_ignoreables:
continue
if cfg.get('verbose'):
print(' - %s:%s: %s %s'
@ -280,6 +300,9 @@ def main():
parser.add_argument("--ignore-path", action="append", default=[],
help="Ignore the given directory or file (globs"
" are supported).", metavar='path')
parser.add_argument("--ignore-path-errors", action="append", default=[],
help="Ignore the given specific errors in the"
" provided file.", metavar='path')
parser.add_argument("--default-extension", action="store",
help="Default file extension to use when a file is"
" found without a file extension.",
@ -317,6 +340,16 @@ def main():
args['sphinx'] = cfg.pop("sphinx")
args['extension'].extend(cfg.pop('extension', []))
args['ignore_path'].extend(cfg.pop('ignore_path', []))
cfg.setdefault('ignore_path_errors', {})
for tmp_ignore_path_error in args.pop('ignore_path_errors', []):
tmp_ignores = parse_ignore_path_errors(tmp_ignore_path_error)
for path, ignores in six.iteritems(tmp_ignores):
if path in cfg['ignore_path_errors']:
cfg['ignore_path_errors'][path].update(ignores)
else:
cfg['ignore_path_errors'][path] = set(ignores)
args.update(cfg)
setup_logging(args.get('verbose'))