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

Commit ccd9a73

Browse files
committed
All tests pass for now.
1 parent 1c88e4d commit ccd9a73

File tree

16 files changed

+142
-38
lines changed

16 files changed

+142
-38
lines changed

README.rst

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,6 @@ docstring conventions.
1010
`PEP 257 <http://www.python.org/dev/peps/pep-0257/>`_ out of the box, but it
1111
should not be considered a reference implementation.
1212

13-
The framework for checking docstring style is flexible, and
14-
custom checks can be easily added, for example to cover
15-
NumPy `docstring conventions
16-
<https://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt>`_.
17-
1813
**pydocstyle** supports Python 2.6, 2.7, 3.3, 3.4, 3.5, pypy and pypy3.
1914

2015
Quick Start
@@ -27,16 +22,19 @@ Install
2722
2823
pip install pydocstyle
2924
25+
3026
Run
31-
^^^
27+
^^^^
3228

3329
.. code::
3430
3531
$ pydocstyle test.py
3632
test.py:18 in private nested class `meta`:
3733
D101: Docstring missing
38-
test.py:22 in public method `method`:
39-
D102: Docstring missing
34+
test.py:27 in public function `get_user`:
35+
D300: Use """triple double quotes""" (found '''-quotes)
36+
test:75 in public function `init_database`:
37+
D201: No blank lines allowed before function docstring (found 1)
4038
...
4139
4240
@@ -50,7 +48,7 @@ Links
5048
:target: https://readthedocs.org/projects/pydocstyle/?badge=latest
5149
:alt: Documentation Status
5250

53-
* `Read the full documentation here <https://pydocstyle.readthedocs.io>`_.
51+
* `Read the full documentation here <https://pydocstyle.org>`_.
5452

5553
* `Fork pydocstyle on GitHub <http://github.com/PyCQA/pydocstyle>`_.
5654

requirements/tests.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
pytest==2.7.3
22
pytest-pep8
33
mock
4-
tox
4+
tox
5+
pathlib

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from setuptools import setup
44

55

6-
with open(os.path.join('src', 'pydocstyle', 'pydocstyle.py')) as f:
6+
with open(os.path.join('src', 'pydocstyle', 'utils.py')) as f:
77
for line in f:
88
if line.startswith('__version__'):
99
version = eval(line.split('=')[-1])

src/__init__.py

Whitespace-only changes.

src/pydocstyle/pydocstyle.py renamed to src/main.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,15 @@
55
http://github.com/PyCQA/pydocstyle
66
77
"""
8-
from __future__ import with_statement
98

10-
import logging
119

12-
log = logging.getLogger(__name__)
10+
__all__ = ()
1311

1412

15-
__version__ = '1.1.0-rc1'
16-
__all__ = ()
13+
def main():
14+
from pydocstyle import cli
15+
cli.main()
16+
17+
18+
if __name__ == '__main__':
19+
main()

src/pydocstyle/checker.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,20 @@
1+
"""Parsed source code checkers for docstring violations."""
2+
13
import ast
24
import string
35
import sys
46
import tokenize as tk
57
from itertools import takewhile
68
from re import compile as re
79

8-
import violations
9-
from config import IllegalConfiguration
10+
from . import violations
11+
from .config import IllegalConfiguration
1012
# TODO: handle
11-
from parser import *
12-
from pydocstyle import log
13-
from utils import is_blank
13+
from .parser import *
14+
from .utils import log, is_blank
15+
16+
17+
__all__ = ('check', )
1418

1519

1620
# If possible (python >= 3.2) use tokenize.open to open files, so PEP 263
@@ -386,7 +390,7 @@ def check(filenames, select=None, ignore=None):
386390
387391
Example
388392
-------
389-
>>> check([ppydocstyle.py.py], checked_codes=['D100'])
393+
>>> check(['pydocstyle.py'], checked_codes=['D100'])
390394
<generator object check at 0x...>
391395
392396
"""

src/pydocstyle/cli.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
1+
"""Command line interface for pydocstyle."""
12
import logging
23
import sys
34

4-
from pydocstyle import log
5-
from violations import Error
6-
from config import ConfigurationParser, IllegalConfiguration
7-
from checker import check
5+
from .utils import log
6+
from .violations import Error
7+
from .config import ConfigurationParser, IllegalConfiguration
8+
from .checker import check
9+
10+
11+
__all__ = ('main', )
812

913

1014
class ReturnCode(object):
@@ -59,6 +63,12 @@ def run_pydocstyle(use_pep257=False):
5963

6064

6165
def main(use_pep257=False):
66+
"""Run pydocstyle as a script.
67+
68+
`use_pep257` is True if the script was invoked with the deprecated script
69+
name `pep257`, in which case a deprecation warning will be printed.
70+
71+
"""
6272
try:
6373
sys.exit(run_pydocstyle(use_pep257))
6474
except KeyboardInterrupt:

src/pydocstyle/config.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
"""Configuration file parsing and utilities."""
2+
13
import copy
24
import itertools
35
import os
@@ -11,8 +13,8 @@
1113
from configparser import RawConfigParser
1214

1315

14-
from pydocstyle import __version__, log
15-
from violations import ErrorRegistry, conventions
16+
from .utils import __version__, log
17+
from .violations import ErrorRegistry, conventions
1618

1719

1820
def check_initialized(method):

src/pydocstyle/parser.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
"""Python code parser."""
2+
13
import logging
24
import sys
35
import textwrap
@@ -36,6 +38,8 @@ def humanize(string):
3638

3739

3840
class Value(object):
41+
"""A generic object with a list of preset fields."""
42+
3943
def __init__(self, *args):
4044
vars(self).update(zip(self._fields, args))
4145

@@ -52,6 +56,8 @@ def __repr__(self):
5256

5357

5458
class Definition(Value):
59+
"""A Python source code definition (could be class, function, etc)."""
60+
5561
_fields = ('name', '_source', 'start', 'end', 'decorators', 'docstring',
5662
'children', 'parent')
5763

@@ -85,6 +91,8 @@ def __str__(self):
8591

8692

8793
class Module(Definition):
94+
"""A Python source code module."""
95+
8896
_fields = ('name', '_source', 'start', 'end', 'decorators', 'docstring',
8997
'children', 'parent', '_all', 'future_imports')
9098
is_public = True
@@ -101,30 +109,39 @@ class Package(Module):
101109

102110

103111
class Function(Definition):
112+
"""A Python source code function."""
113+
104114
_nest = staticmethod(lambda s: {'def': NestedFunction,
105115
'class': NestedClass}[s])
106116

107117
@property
108118
def is_public(self):
119+
"""Return True iff this function should be considered public."""
109120
if self.all is not None:
110121
return self.name in self.all
111122
else:
112123
return not self.name.startswith('_')
113124

114125

115126
class NestedFunction(Function):
127+
"""A Python source code nested function."""
128+
116129
is_public = False
117130

118131

119132
class Method(Function):
133+
"""A Python source code method."""
134+
120135
@property
121136
def is_magic(self):
137+
"""Return True iff this method is a magic method (e.g., `__str__`)."""
122138
return (self.name.startswith('__') and
123139
self.name.endswith('__') and
124140
self.name not in VARIADIC_MAGIC_METHODS)
125141

126142
@property
127143
def is_public(self):
144+
"""Return True iff this method should be considered public."""
128145
# Check if we are a setter/deleter method, and mark as private if so.
129146
for decorator in self.decorators:
130147
# Given 'foo', match 'foo.bar' but not 'foobar' or 'sfoo'
@@ -137,14 +154,19 @@ def is_public(self):
137154

138155

139156
class Class(Definition):
157+
"""A Python source code class."""
158+
140159
_nest = staticmethod(lambda s: {'def': Method, 'class': NestedClass}[s])
141160
is_public = Function.is_public
142161
is_class = True
143162

144163

145164
class NestedClass(Class):
165+
"""A Python source code nested class."""
166+
146167
@property
147168
def is_public(self):
169+
"""Return True iff this class should be considered public."""
148170
return (not self.name.startswith('_') and
149171
self.parent.is_class and
150172
self.parent.is_public)
@@ -160,7 +182,10 @@ class Decorator(Value):
160182

161183

162184
class AllError(Exception):
185+
"""Raised when there is a problem with __all__ when parsing."""
186+
163187
def __init__(self, message):
188+
"""Initialize the error with a more specific message."""
164189
Exception.__init__(
165190
self, message + textwrap.dedent("""
166191
That means pydocstyle cannot decide which definitions are
@@ -207,7 +232,10 @@ def __init__(self, *args):
207232

208233

209234
class Parser(object):
235+
"""A Python source code parser."""
236+
210237
def parse(self, filelike, filename):
238+
"""Parse the given file-like object and return its Module object."""
211239
# TODO: fix log
212240
self.log = logging.getLogger()
213241
self.source = filelike.readlines()
@@ -221,6 +249,7 @@ def parse(self, filelike, filename):
221249

222250
# TODO: remove
223251
def __call__(self, *args, **kwargs):
252+
"""Call the parse method."""
224253
return self.parse(*args, **kwargs)
225254

226255
current = property(lambda self: self.stream.current)
@@ -437,6 +466,7 @@ def parse_definition(self, class_):
437466
return definition
438467

439468
def check_current(self, kind=None, value=None):
469+
"""Verify the current token is of type `kind` and equals `value`."""
440470
msg = textwrap.dedent("""
441471
Unexpected token at line {self.line}:
442472

src/pydocstyle/tests/parser_test.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,19 @@
1+
"""Parser tests."""
2+
13
import six
24
import textwrap
35
from pydocstyle.parser import Parser
46

57

68
class CodeSnippet(six.StringIO):
9+
"""A code snippet.
10+
11+
Automatically wraps snippet as a file-like object and handles line wraps.
12+
13+
"""
14+
715
def __init__(self, code_string):
16+
"""Initialize the object."""
817
six.StringIO.__init__(self, textwrap.dedent(code_string))
918

1019

0 commit comments

Comments
 (0)