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

Commit 21bf376

Browse files
committed
Merge pull request #89 from Nurdok/count
Added `--count` flag.
2 parents 6e3d7dd + 315e9a8 commit 21bf376

File tree

3 files changed

+99
-39
lines changed

3 files changed

+99
-39
lines changed

README.rst

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,20 +31,23 @@ Example
3131
Usage: pep257 [options] [<file|dir>...]
3232
3333
Options:
34-
--version show program's version number and exit
35-
-h, --help show this help message and exit
36-
-e, --explain show explanation of each error
37-
-s, --source show source for each error
38-
--ignore=<codes> ignore a list comma-separated error codes, for
34+
--version show program's version number and exit
35+
-h, --help show this help message and exit
36+
-e, --explain show explanation of each error
37+
-s, --source show source for each error
38+
--ignore=<codes> ignore a list comma-separated error codes, for
3939
example: --ignore=D101,D202
40-
--match=<pattern> check only files that exactly match <pattern> regular
40+
--match=<pattern> check only files that exactly match <pattern> regular
4141
expression; default is --match='(?!test_).*\.py' which
4242
matches files that don't start with 'test_' but end
4343
with '.py'
44-
--match-dir=<pattern>
44+
--match-dir=<pattern>
4545
search only dirs that exactly match <pattern> regular
4646
expression; default is --match-dir='[^\.].*', which
4747
matches all dirs that don't start with a dot
48+
-d, --debug print debug information
49+
-v, --verbose print status information
50+
--count print total number of errors to stdout
4851
4952
$ pep257 test.py
5053
test.py:18 in private nested class `meta`:
@@ -75,6 +78,15 @@ Example
7578
16:
7679
...
7780
81+
$ pep257 test.py --count
82+
test.py:18 in private nested class `meta`:
83+
D101: Docstring missing
84+
test.py:22 in public method `method`:
85+
D102: Docstring missing
86+
...
87+
33
88+
89+
7890
Error codes
7991
-----------------------------------------------------------
8092

pep257.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -412,7 +412,7 @@ def get_option_parser():
412412
parser = OptionParser(version=__version__,
413413
usage='Usage: pep257 [options] [<file|dir>...]')
414414
parser.config_options = ('explain', 'source', 'ignore', 'match',
415-
'match-dir', 'debug', 'verbose')
415+
'match-dir', 'debug', 'verbose', 'count')
416416
option = parser.add_option
417417
option('-e', '--explain', action='store_true',
418418
help='show explanation of each error')
@@ -434,6 +434,8 @@ def get_option_parser():
434434
help='print debug information')
435435
option('-v', '--verbose', action='store_true',
436436
help='print status information')
437+
option('--count', action='store_true',
438+
help='print total number of errors to stdout')
437439
return parser
438440

439441

@@ -564,10 +566,15 @@ def main():
564566
Error.explain = options.explain
565567
Error.source = options.source
566568
collected = list(collected)
569+
errors = check(collected, ignore=options.ignore.split(','))
567570
code = 0
568-
for error in check(collected, ignore=options.ignore.split(',')):
571+
count = 0
572+
for error in errors:
569573
sys.stderr.write('%s\n' % error)
570574
code = 1
575+
count += 1
576+
if options.count:
577+
print(count)
571578
return code
572579

573580

test_pep257.py

Lines changed: 71 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,55 @@
1515
__all__ = ()
1616

1717

18+
class Pep257Env():
19+
20+
"""An isolated environment where pep257.py can be run.
21+
22+
Since running pep257.py as a script is affected by local config files, it's
23+
important that tests will run in an isolated environment. This class should
24+
be used as a context manager and offers utility methods for adding files
25+
to the environment and changing the environment's configuration.
26+
27+
"""
28+
29+
def __init__(self):
30+
self.tempdir = None
31+
32+
def write_config(self, ignore, verbose):
33+
"""Change the environment's config file."""
34+
with open(os.path.join(self.tempdir, 'tox.ini'), 'wt') as conf:
35+
conf.write(textwrap.dedent("""\
36+
[pep257]
37+
ignore = {0}
38+
verbose = {1}
39+
""".format(ignore, verbose)))
40+
41+
def open(self, path, *args, **kwargs):
42+
"""Open a file in the environment.
43+
44+
The file path should be relative to the base of the environment.
45+
46+
"""
47+
return open(os.path.join(self.tempdir, path), *args, **kwargs)
48+
49+
def invoke_pep257(self, args=""):
50+
"""Run pep257.py on the environment base folder with the given args."""
51+
pep257_location = os.path.join(os.path.dirname(__file__), 'pep257.py')
52+
cmd = shlex.split("python {0} {1} {2}"
53+
.format(pep257_location, self.tempdir, args))
54+
p = subprocess.Popen(cmd, stdout=subprocess.PIPE,
55+
stderr=subprocess.PIPE)
56+
out, err = p.communicate()
57+
return out.decode('utf-8'), err.decode('utf-8')
58+
59+
def __enter__(self):
60+
self.tempdir = tempfile.mkdtemp()
61+
return self
62+
63+
def __exit__(self, *args, **kwargs):
64+
shutil.rmtree(self.tempdir)
65+
66+
1867
def test_pep257_conformance():
1968
errors = list(pep257.check(['pep257.py', 'test_pep257.py']))
2069
print(errors)
@@ -48,54 +97,46 @@ def test_config_file():
4897
that pep257 gives the correct output.
4998
5099
"""
51-
tempdir = tempfile.mkdtemp()
52-
53-
def write_config(ignore, verbose):
54-
with open(os.path.join(tempdir, 'tox.ini'), 'wt') as conf:
55-
conf.write(textwrap.dedent("""\
56-
[pep257]
57-
ignore = {0}
58-
verbose = {1}
59-
""".format(ignore, verbose)))
60-
61-
def invoke_pep257():
62-
pep257_location = os.path.join(os.path.dirname(__file__), 'pep257.py')
63-
cmd = shlex.split("python {0} {1}".format(pep257_location, tempdir))
64-
p = subprocess.Popen(cmd, stdout=subprocess.PIPE,
65-
stderr=subprocess.PIPE)
66-
out, err = p.communicate()
67-
return out.decode('utf-8'), err.decode('utf-8')
68-
69-
try:
70-
with open(os.path.join(tempdir, 'example.py'), 'wt') as example:
100+
with Pep257Env() as env:
101+
with env.open('example.py', 'wt') as example:
71102
example.write(textwrap.dedent("""\
72103
def foo():
73104
pass
74105
"""))
75106

76-
write_config(ignore='D100', verbose=True)
77-
out, err = invoke_pep257()
107+
env.write_config(ignore='D100', verbose=True)
108+
out, err = env.invoke_pep257()
78109
assert 'D100' not in err
79110
assert 'D103' in err
80111
assert 'example.py' in out
81112

82-
write_config(ignore='', verbose=True)
83-
out, err = invoke_pep257()
113+
env.write_config(ignore='', verbose=True)
114+
out, err = env.invoke_pep257()
84115
assert 'D100' in err
85116
assert 'D103' in err
86117
assert 'example.py' in out
87118

88-
write_config(ignore='D100,D103', verbose=False)
89-
out, err = invoke_pep257()
119+
env.write_config(ignore='D100,D103', verbose=False)
120+
out, err = env.invoke_pep257()
90121
assert 'D100' not in err
91122
assert 'D103' not in err
92123
assert 'example.py' not in out
93124

94-
write_config(ignore='', verbose=False)
95-
out, err = invoke_pep257()
125+
env.write_config(ignore='', verbose=False)
126+
out, err = env.invoke_pep257()
96127
assert 'D100' in err
97128
assert 'D103' in err
98129
assert 'example.py' not in out
99130

100-
finally:
101-
shutil.rmtree(tempdir)
131+
132+
def test_count():
133+
"""Test that passing --count to pep257 correctly prints the error num."""
134+
with Pep257Env() as env:
135+
with env.open('example.py', 'wt') as example:
136+
example.write(textwrap.dedent("""\
137+
def foo():
138+
pass
139+
"""))
140+
141+
out, err = env.invoke_pep257(args='--count')
142+
assert out == '2\n'

0 commit comments

Comments
 (0)