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

Commit 717f672

Browse files
committed
Merge remote-tracking branch 'PyCQA/master'
2 parents 389964b + dc797d4 commit 717f672

File tree

4 files changed

+96
-20
lines changed

4 files changed

+96
-20
lines changed

docs/release_notes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ Major Updates
1616
New Features
1717

1818
* Decorator-based skipping via ``--ignore-decorators`` has been added (#204).
19+
* Support for using pycodestyle style wildcards has been added (#72, #209).
1920

2021
Bug Fixes
2122

docs/snippets/cli.rst

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,12 @@ Usage
1717
--count print total number of errors to stdout
1818
--select=<codes> choose the basic list of checked errors by specifying
1919
which errors to check for (with a list of comma-
20-
separated error codes). for example:
21-
--select=D101,D202
20+
separated error codes or prefixes). for example:
21+
--select=D101,D2
2222
--ignore=<codes> choose the basic list of checked errors by specifying
2323
which errors to ignore (with a list of comma-separated
24-
error codes). for example: --ignore=D101,D202
24+
error codes or prefixes). for example:
25+
--ignore=D101,D2
2526
--convention=<name> choose the basic list of checked errors by specifying
2627
an existing convention. Possible conventions: pep257
2728
--add-select=<codes> amend the list of errors to check for by specifying
@@ -42,6 +43,14 @@ Usage
4243
regular expression; default is --ignore-decorators=''
4344
which does not ignore any decorated functions.
4445
46+
.. note::
47+
48+
When using any of the ``--select``, ``--ignore``, ``--add-select``, or
49+
``--add-ignore`` command line flags, it is possible to pass a prefix for an
50+
error code. It will be expanded so that any code begining with that prefix
51+
will match. For example, running the command ``pydocstyle --ignore=D4``
52+
will ignore all docstring content issues as their error codes begining with
53+
"D4" (i.e. D400, D401, D402, D403, and D404).
4554

4655
Return Code
4756
^^^^^^^^^^^

src/pydocstyle/config.py

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -375,27 +375,47 @@ def _get_config_file_in_folder(cls, path):
375375
if config.read(full_path) and cls._get_section_name(config):
376376
return full_path
377377

378-
@staticmethod
379-
def _get_exclusive_error_codes(options):
378+
@classmethod
379+
def _get_exclusive_error_codes(cls, options):
380380
"""Extract the error codes from the selected exclusive option."""
381381
codes = set(ErrorRegistry.get_error_codes())
382382
checked_codes = None
383383

384384
if options.ignore is not None:
385-
checked_codes = codes - options.ignore
385+
ignored = cls._expand_error_codes(options.ignore)
386+
checked_codes = codes - ignored
386387
elif options.select is not None:
387-
checked_codes = options.select
388+
checked_codes = cls._expand_error_codes(options.select)
388389
elif options.convention is not None:
389390
checked_codes = getattr(conventions, options.convention)
390391

391392
# To not override the conventions nor the options - copy them.
392393
return copy.deepcopy(checked_codes)
393394

394-
@staticmethod
395-
def _set_add_options(checked_codes, options):
395+
@classmethod
396+
def _set_add_options(cls, checked_codes, options):
396397
"""Set `checked_codes` by the `add_ignore` or `add_select` options."""
397-
checked_codes |= options.add_select
398-
checked_codes -= options.add_ignore
398+
checked_codes |= cls._expand_error_codes(options.add_select)
399+
checked_codes -= cls._expand_error_codes(options.add_ignore)
400+
401+
@staticmethod
402+
def _expand_error_codes(code_parts):
403+
"""Return an expanded set of error codes to ignore."""
404+
codes = set(ErrorRegistry.get_error_codes())
405+
expanded_codes = set()
406+
407+
try:
408+
for part in code_parts:
409+
if len(part) < 4:
410+
for code in codes:
411+
if code.startswith(part):
412+
expanded_codes.add(code)
413+
else:
414+
expanded_codes.add(part)
415+
except TypeError as e:
416+
raise IllegalConfiguration(e)
417+
418+
return expanded_codes
399419

400420
@classmethod
401421
def _get_checked_errors(cls, options):
@@ -494,13 +514,13 @@ def _create_option_parser(cls):
494514
option('--select', metavar='<codes>', default=None,
495515
help='choose the basic list of checked errors by '
496516
'specifying which errors to check for (with a list of '
497-
'comma-separated error codes). '
498-
'for example: --select=D101,D202')
517+
'comma-separated error codes or prefixes). '
518+
'for example: --select=D101,D2')
499519
option('--ignore', metavar='<codes>', default=None,
500520
help='choose the basic list of checked errors by '
501521
'specifying which errors to ignore (with a list of '
502-
'comma-separated error codes). '
503-
'for example: --ignore=D101,D202')
522+
'comma-separated error codes or prefixes). '
523+
'for example: --ignore=D101,D2')
504524
option('--convention', metavar='<name>', default=None,
505525
help='choose the basic list of checked errors by specifying an '
506526
'existing convention. Possible conventions: {}'

src/tests/test_integration.py

Lines changed: 51 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,12 @@ def foo():
233233
assert 'D100' not in out
234234
assert 'D103' not in out
235235

236+
env.write_config(ignore='D10')
237+
_, err, code = env.invoke()
238+
assert code == 0
239+
assert 'D100' not in err
240+
assert 'D103' not in err
241+
236242

237243
def test_verbose(env):
238244
"""Test that passing --verbose prints more information."""
@@ -282,14 +288,17 @@ def test_select_config(env):
282288
"""Test choosing error codes with `select` in the config file."""
283289
with env.open('example.py', 'wt') as example:
284290
example.write(textwrap.dedent("""\
285-
def foo():
286-
pass
291+
class Foo(object):
292+
"Doc string"
293+
def foo():
294+
pass
287295
"""))
288296

289-
env.write_config(select="D100")
297+
env.write_config(select="D100,D3")
290298
out, err, code = env.invoke()
291299
assert code == 1
292300
assert 'D100' in out
301+
assert 'D300' in out
293302
assert 'D103' not in out
294303

295304

@@ -298,15 +307,17 @@ def test_add_select_cli(env):
298307
with env.open('example.py', 'wt') as example:
299308
example.write(textwrap.dedent("""\
300309
class Foo(object):
310+
"Doc string"
301311
def foo():
302312
pass
303313
"""))
304314

305315
env.write_config(select="D100")
306-
out, err, code = env.invoke(args="--add-select=D101")
316+
out, err, code = env.invoke(args="--add-select=D204,D3")
307317
assert code == 1
308318
assert 'D100' in out
309-
assert 'D101' in out
319+
assert 'D204' in out
320+
assert 'D300' in out
310321
assert 'D103' not in out
311322

312323

@@ -327,6 +338,41 @@ def foo():
327338
assert 'D103' not in out
328339

329340

341+
def test_wildcard_add_ignore_cli(env):
342+
"""Test choosing error codes with --add-ignore in the CLI."""
343+
with env.open('example.py', 'wt') as example:
344+
example.write(textwrap.dedent("""\
345+
class Foo(object):
346+
"Doc string"
347+
def foo():
348+
pass
349+
"""))
350+
351+
env.write_config(select="D203,D300")
352+
out, err, code = env.invoke(args="--add-ignore=D30")
353+
assert code == 1
354+
assert 'D203' in out
355+
assert 'D300' not in out
356+
357+
358+
def test_bad_wildcard_add_ignore_cli(env):
359+
"""Test adding a non-existent error codes with --add-ignore."""
360+
with env.open('example.py', 'wt') as example:
361+
example.write(textwrap.dedent("""\
362+
class Foo(object):
363+
"Doc string"
364+
def foo():
365+
pass
366+
"""))
367+
368+
env.write_config(select="D203,D300")
369+
out, err, code = env.invoke(args="--add-ignore=D3004")
370+
assert code == 1
371+
assert 'D203' in out
372+
assert 'D300' in out
373+
assert 'D3034' not in out
374+
375+
330376
def test_conflicting_select_ignore_config(env):
331377
"""Test that select and ignore are mutually exclusive."""
332378
env.write_config(select="D100", ignore="D101")

0 commit comments

Comments
 (0)