Merge lp:~adiroiban/pocket-lint/1237862-pep-257 into lp:pocket-lint

Proposed by Adi Roiban
Status: Merged
Merged at revision: 443
Proposed branch: lp:~adiroiban/pocket-lint/1237862-pep-257
Merge into: lp:pocket-lint
Diff against target: 180 lines (+120/-1)
2 files modified
pocketlint/formatcheck.py (+28/-1)
pocketlint/tests/test_python.py (+92/-0)
To merge this branch: bzr merge lp:~adiroiban/pocket-lint/1237862-pep-257
Reviewer Review Type Date Requested Status
Curtis Hovey code Approve
Adi Roiban (community) Needs Resubmitting
Review via email: mp+194239@code.launchpad.net

Description of the change

Why
---

pep257 looks like a nice effort in docstring format checking.

Changes
-------

Add optional pep257 check if module is present.

I added pep257 as setup.py dependency, but maybe we should remove it.

pep257 has no errror codes yet (wip: https://github.com/GreenSteam/pep257/pull/53) so the filtering is done on message string.

I also made a drive-by fix for pdb check.

Please let me know if changes make sense.

To post a comment you must log in.
Revision history for this message
Curtis Hovey (sinzui) wrote :

Hi Adi.

The tests don't pass when pep257 is not installed. We don't require the lib so I think the tests should skip.

I am not sure about the requires pep257. It is not packaged in Ubuntu. The dh will report an error when it calls setup to install during the package build. While I can copy the pep257 from someone-else's archive, pocket-lint will be removed from Ubuntu unless someone commits to creating python3-pep257 and possibly python2-pep257. I'd think removing pep257 from requires will prevent regressions.

pocket-lint now wrongly reports that a pdb is left in the code. Unless you know how to update the pdb check to know the string is not a function, this block needs to be restored.
- pdb_call = 'pdb.' + 'set_trace'
- if pdb_call in line:

review: Needs Information (code)
Revision history for this message
Adi Roiban (adiroiban) wrote :

Thanks for the review.

pep257 is still young and unstable so I don't think that it needs to be an Ubuntu package.

I will push a new change removing the install requirement and also skipping the tests when pep257 is not there.

I will also revert the pdb_call variable, but I think that it needs a comment. Otherwise is just triggers a WTF moment.

512. By Adi Roiban <email address hidden>

Fix after review.

Revision history for this message
Adi Roiban (adiroiban) wrote :

Please check latest changes.

Thanks!

review: Needs Resubmitting
Revision history for this message
Adi Roiban (adiroiban) wrote :

When you have time, please check latest changes. Thanks!

513. By Adi Roiban <email address hidden>

Merge branch 'master' into 1237862-pep-257

Revision history for this message
Curtis Hovey (sinzui) wrote :

Thank you Adi.

I am very sorry for ignoring your reviews. I saw you updated the reviews while I was travelling. I was so exhausted when I returned home, I forgot about them. I should have set a reminder.

review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'pocketlint/formatcheck.py'
--- pocketlint/formatcheck.py 2013-11-06 15:21:20 +0000
+++ pocketlint/formatcheck.py 2014-02-05 15:58:01 +0000
@@ -83,6 +83,13 @@
83except ImportError:83except ImportError:
84 closure_linter = None84 closure_linter = None
8585
86try:
87 import pep257
88 # Shut up the linter.
89 pep257
90except ImportError:
91 pep257 = None
92
8693
87IS_PY3 = True if sys.version_info >= (3,) else False94IS_PY3 = True if sys.version_info >= (3,) else False
8895
@@ -627,6 +634,7 @@
627 self.check_text()634 self.check_text()
628 self.check_flakes()635 self.check_flakes()
629 self.check_pep8()636 self.check_pep8()
637 self.check_pep257()
630 self.check_windows_endlines()638 self.check_windows_endlines()
631639
632 def check_flakes(self):640 def check_flakes(self):
@@ -665,6 +673,24 @@
665 message = "%s: %s" % (message, location[3].strip())673 message = "%s: %s" % (message, location[3].strip())
666 self.message(location[1], message, icon='error')674 self.message(location[1], message, icon='error')
667675
676 def check_pep257(self):
677 """PEP 257 docstring style checker."""
678 if not pep257:
679 # PEP257 is not available.
680 return
681
682 ignore_list = getattr(self.options, 'pep257_ignore', [])
683
684 results = pep257.check_source(self.text, self.file_path)
685
686 for error in results:
687 # PEP257 message contains the short error as first line from
688 # the long docstring explanation.
689 error_message = error.explanation.splitlines()[0]
690 if error_message in ignore_list:
691 continue
692 self.message(error.line, error_message, icon='error')
693
668 def check_text(self):694 def check_text(self):
669 """Call each line_method for each line in text."""695 """Call each line_method for each line in text."""
670 for line_no, line in enumerate(self.text.splitlines()):696 for line_no, line in enumerate(self.text.splitlines()):
@@ -678,7 +704,8 @@
678 self.check_ascii(line_no, line)704 self.check_ascii(line_no, line)
679705
680 def check_pdb(self, line_no, line):706 def check_pdb(self, line_no, line):
681 """Check the length of the line."""707 """Check for pdb breakpoints."""
708 # Set trace call is split so that this file will pass the linter.
682 pdb_call = 'pdb.' + 'set_trace'709 pdb_call = 'pdb.' + 'set_trace'
683 if pdb_call in line:710 if pdb_call in line:
684 self.message(711 self.message(
685712
=== modified file 'pocketlint/tests/test_python.py'
--- pocketlint/tests/test_python.py 2013-02-16 18:03:51 +0000
+++ pocketlint/tests/test_python.py 2014-02-05 15:58:01 +0000
@@ -7,10 +7,13 @@
7 unicode_literals,7 unicode_literals,
8)8)
99
10import unittest
10from tempfile import NamedTemporaryFile11from tempfile import NamedTemporaryFile
1112
12from pocketlint.formatcheck import (13from pocketlint.formatcheck import (
13 get_option_parser,14 get_option_parser,
15 # Imported via pocketlint to avoid duplication of conditional import.
16 pep257,
14 PythonChecker,17 PythonChecker,
15)18)
16from pocketlint.tests import CheckerTestCase19from pocketlint.tests import CheckerTestCase
@@ -82,6 +85,12 @@
82"""85"""
8386
8487
88class Bunch(object):
89 """Collector of a bunch of named stuff."""
90 def __init__(self, **kwds):
91 self.__dict__.update(kwds)
92
93
85class TestPyflakes(CheckerTestCase):94class TestPyflakes(CheckerTestCase):
86 """Verify pyflakes integration."""95 """Verify pyflakes integration."""
8796
@@ -233,6 +242,89 @@
233 self.reporter.messages)242 self.reporter.messages)
234243
235244
245@unittest.skipIf(pep257 is None, 'pep257 is not available.')
246class TestPEP257(CheckerTestCase):
247 """Verify PEP257 integration."""
248
249 def setUp(self):
250 super(TestPEP257, self).setUp()
251 self.file = NamedTemporaryFile(prefix='pocketlint_')
252
253 def tearDown(self):
254 self.file.close()
255
256 def makeChecker(self, content, options=None):
257 """Create a Python checker with file from `content`."""
258 # Don't know why multi-line text is interpreted as Unicode.
259 content = content.encode('utf-8')
260 return PythonChecker(
261 self.file.name, content, self.reporter, options=options)
262
263 def test_code_without_issues(self):
264 """No errors are reported if everything has a valid docstring."""
265 checker = self.makeChecker('''
266"""Module's docstring."""
267
268class SomeClass(object):
269
270 """Class with short docstring."""
271
272 def method(self):
273 """Method with short docstring."""
274
275 def otherMethod(self):
276 """
277 Method with multi.
278
279 Line docstring.
280
281 """
282 ''')
283
284 checker.check_pep257()
285
286 self.assertEqual([], self.reporter.messages)
287
288 pep257_without_docstrings = '''
289def some_function():
290 """Bad multi line without point"""
291 '''
292
293 def test_code_with_issues(self):
294 """Errors are reported when docstrings are missing or in bad format.
295
296 """
297 checker = self.makeChecker(self.pep257_without_docstrings)
298
299 checker.check_pep257()
300
301 self.assertEqual([
302 (1, 'All modules should have docstrings.'),
303 (3, 'First line should end with a period.'),
304 ],
305 self.reporter.messages,
306 )
307
308 def test_code_with_ignore(self):
309 """A list with error message which should be ignored can be
310 provided as `pep257_ignore` option.
311
312 Hope that pep257 will add error codes soon.
313 """
314 options = Bunch(
315 pep257_ignore=['First line should end with a period.'])
316 checker = self.makeChecker(
317 self.pep257_without_docstrings, options=options)
318
319 checker.check_pep257()
320
321 self.assertEqual([
322 (1, 'All modules should have docstrings.'),
323 ],
324 self.reporter.messages,
325 )
326
327
236class TestText(CheckerTestCase, TestAnyTextMixin):328class TestText(CheckerTestCase, TestAnyTextMixin):
237 """Verify text integration."""329 """Verify text integration."""
238330

Subscribers

People subscribed via source and target branches

to all changes: