Skip to content
This repository has been archived by the owner on Nov 3, 2023. It is now read-only.

Print a warning where error code (/prefix) doesn't exist, e.g., --select=D9 #279

Merged
merged 3 commits into from
Sep 2, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/release_notes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ New Features
* ``__init__`` methods missing a docstring are now reported as D107 instead of
D102 (#273, #277).
* Added support for Python 3.6 (#270).
* Specifying an invalid error code prefix (e.g., ``--select=D9``) will print
a warning message to ``stderr`` (#253, #279).

Bug Fixes

Expand Down
2 changes: 2 additions & 0 deletions src/pydocstyle/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,5 +90,7 @@ def filter(self, record):
log.addHandler(stdout_handler)

stderr_handler = logging.StreamHandler(sys.stderr)
msg_format = "%(levelname)s: %(message)s"
stderr_handler.setFormatter(logging.Formatter(fmt=msg_format))
stderr_handler.setLevel(logging.WARNING)
log.addHandler(stderr_handler)
26 changes: 14 additions & 12 deletions src/pydocstyle/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ def get_user_run_configuration(self):
def get_files_to_check(self):
"""Generate files and error codes to check on each one.

Walk dir trees under `self._arguments` and generate yield filnames
Walk dir trees under `self._arguments` and yield file names
that `match` under each directory that `match_dir`.
The method locates the configuration for each file name and yields a
tuple of (filename, [error_codes]).
Expand All @@ -155,7 +155,7 @@ def _get_ignore_decorators(config):
for name in self._arguments:
if os.path.isdir(name):
for root, dirs, filenames in os.walk(name):
config = self._get_config(root)
config = self._get_config(os.path.abspath(root))
match, match_dir = _get_matches(config)
ignore_decorators = _get_ignore_decorators(config)

Expand All @@ -168,7 +168,7 @@ def _get_ignore_decorators(config):
yield (full_path, list(config.checked_codes),
ignore_decorators)
else:
config = self._get_config(name)
config = self._get_config(os.path.abspath(name))
match, _ = _get_matches(config)
ignore_decorators = _get_ignore_decorators(config)
if match(name):
Expand Down Expand Up @@ -446,12 +446,12 @@ def _expand_error_codes(code_parts):

try:
for part in code_parts:
if len(part) < 4:
for code in codes:
if code.startswith(part):
expanded_codes.add(code)
else:
expanded_codes.add(part)
codes_to_add = {code for code in codes
if code.startswith(part)}
if not codes_to_add:
log.warn('Error code passed is not a prefix of any known '
'errors: %s', part)
expanded_codes.update(codes_to_add)
except TypeError as e:
raise IllegalConfiguration(e)

Expand Down Expand Up @@ -496,8 +496,8 @@ def _has_exclusive_option(cls, options):
return any([getattr(options, opt) is not None for opt in
cls.BASE_ERROR_SELECTION_OPTIONS])

@staticmethod
def _fix_set_options(options):
@classmethod
def _fix_set_options(cls, options):
"""Alter the set options from None/strings to sets in place."""
optional_set_options = ('ignore', 'select')
mandatory_set_options = ('add_ignore', 'add_select')
Expand All @@ -506,9 +506,11 @@ def _get_set(value_str):
"""Split `value_str` by the delimiter `,` and return a set.

Removes any occurrences of '' in the set.
Also expand error code prefixes, to avoid doing this for every
file.

"""
return set(value_str.split(',')) - {''}
return cls._expand_error_codes(set(value_str.split(',')) - {''})

for opt in optional_set_options:
value = getattr(options, opt)
Expand Down
4 changes: 3 additions & 1 deletion src/tests/test_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,9 @@ def foo():
assert code == 1
assert 'D203' in out
assert 'D300' in out
assert 'D3034' not in out
assert 'D3004' not in out
assert ('Error code passed is not a prefix of any known errors: D3004'
in err)


def test_conflicting_select_ignore_config(env):
Expand Down