Skip to content
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
1 change: 1 addition & 0 deletions CONTRIBUTORS.txt
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,7 @@ contributors:
- Made C0412 (ungrouped import) compatible with isort
- Made multiple message with the same old name possible
- Made Pylint a little faster by refactoring the message store
- Broke down "missing-docstrings" between "module", "class" and "function"

* Nathan Marrow

Expand Down
7 changes: 7 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -1076,6 +1076,13 @@ Release date: 2018-07-15

Close 1992

* Broke down "missing-docstrings" between "module", "class" and "function"

For this to work we had to make multiple messages with the same old name
possible.

Closes #1164

What's New in Pylint 1.9?
=========================

Expand Down
42 changes: 31 additions & 11 deletions pylint/checkers/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -1942,18 +1942,34 @@ def _name_became_keyword_in_version(name, rules):

class DocStringChecker(_BasicChecker):
msgs = {
"C0111": (
"Missing %s docstring", # W0131
"missing-docstring",
"Used when a module, function, class or method has no docstring. "
"Some special methods like __init__ don't necessarily require a "
"docstring.",
),
"C0112": (
"Empty %s docstring", # W0132
"Empty %s docstring",
"empty-docstring",
"Used when a module, function, class or method has an empty "
"docstring (it would be too easy ;).",
{"old_names": [("W0132", "old-empty-docstring")]},
),
"C0114": (
"Missing module docstring",
"missing-module-docstring",
"Used when a module has no docstring."
"Empty modules do not require a docstring.",
{"old_names": [("C0111", "missing-docstring")]},
),
"C0115": (
"Missing class docstring",
"missing-class-docstring",
"Used when a class has no docstring."
"Even an empty class must have a docstring.",
{"old_names": [("C0111", "missing-docstring")]},
),
"C0116": (
"Missing function or method docstring",
"missing-function-docstring",
"Used when a function or method has no docstring."
"Some special methods like __init__ do not require a "
"docstring.",
{"old_names": [("C0111", "missing-docstring")]},
),
}
options = (
Expand Down Expand Up @@ -2064,9 +2080,13 @@ def _check_docstring(
return
if func.bound.name in ("str", "unicode", "bytes"):
return
self.add_message(
"missing-docstring", node=node, args=(node_type,), confidence=confidence
)
if node_type == "module":
message = "missing-module-docstring"
elif node_type == "class":
message = "missing-class-docstring"
else:
message = "missing-function-docstring"
self.add_message(message, node=node, confidence=confidence)
elif not docstring.strip():
self.stats["undocumented_" + node_type] += 1
self.add_message(
Expand Down
10 changes: 5 additions & 5 deletions tests/functional/d/docstrings.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# pylint: disable=R0201, useless-object-inheritance, unnecessary-pass
# -1: [missing-docstring]
# -1: [missing-module-docstring]
from __future__ import print_function

# +1: [empty-docstring]
def function0():
""""""

# +1: [missing-docstring]
# +1: [missing-function-docstring]
def function1(value):
# missing docstring
print(value)
Expand All @@ -19,7 +19,7 @@ def function3(value):
"""docstring"""
print(value)

# +1: [missing-docstring]
# +1: [missing-class-docstring]
class AAAA(object):
# missing docstring

Expand All @@ -36,7 +36,7 @@ class AAAA(object):
## """ yeah !"""
## pass

# +1: [missing-docstring]
# +1: [missing-function-docstring]
def method1(self):
pass

Expand Down Expand Up @@ -66,7 +66,7 @@ def method2(self):
def method3(self):
pass

# +1: [missing-docstring]
# +1: [missing-function-docstring]
def method4(self):
pass

Expand Down
10 changes: 5 additions & 5 deletions tests/functional/d/docstrings.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
missing-docstring:1::Missing module docstring
missing-module-docstring:1::Missing module docstring
empty-docstring:6:function0:Empty function docstring
missing-docstring:10:function1:Missing function docstring
missing-docstring:23:AAAA:Missing class docstring
missing-docstring:40:AAAA.method1:Missing method docstring:INFERENCE
missing-function-docstring:10:function1:Missing function or method docstring
missing-class-docstring:23:AAAA:Missing class docstring
missing-function-docstring:40:AAAA.method1:Missing function or method docstring:INFERENCE
empty-docstring:48:AAAA.method3:Empty method docstring:INFERENCE
empty-docstring:62:DDDD.method2:Empty method docstring:INFERENCE
missing-docstring:70:DDDD.method4:Missing method docstring:INFERENCE
missing-function-docstring:70:DDDD.method4:Missing function or method docstring:INFERENCE
2 changes: 1 addition & 1 deletion tests/functional/m/messages_managed_by_id.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ def foo(): #pylint: disable=C0102
def toto(): #pylint: disable=C0102,R1711
return

# +1: [missing-docstring]
# +1: [missing-function-docstring]
def test_enabled_by_id_msg(): #pylint: enable=C0111
pass
2 changes: 1 addition & 1 deletion tests/functional/m/messages_managed_by_id.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ use-symbolic-message-instead:3::"Id 'C0102' is used to disable 'blacklisted-name
use-symbolic-message-instead:6::"Id 'C0102' is used to disable 'blacklisted-name' message emission"
use-symbolic-message-instead:6::"Id 'R1711' is used to disable 'useless-return' message emission"
use-symbolic-message-instead:10::"Id 'C0111' is used to enable 'missing-docstring' message emission"
missing-docstring:10:test_enabled_by_id_msg:"Missing function docstring"
missing-function-docstring:10:test_enabled_by_id_msg:"Missing function or method docstring"
6 changes: 3 additions & 3 deletions tests/functional/m/missing_docstring.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# [missing-docstring]
# [missing-module-docstring]
# pylint: disable=too-few-public-methods, useless-object-inheritance

def public_documented():
Expand All @@ -18,11 +18,11 @@ class ClassDocumented(object):
"""It has a docstring."""


class ClassUndocumented(object): # [missing-docstring]
class ClassUndocumented(object): # [missing-class-docstring]
pass


def public_undocumented(): # [missing-docstring]
def public_undocumented(): # [missing-function-docstring]
pass


Expand Down
6 changes: 3 additions & 3 deletions tests/functional/m/missing_docstring.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
missing-docstring:1::Missing module docstring
missing-docstring:21:ClassUndocumented:Missing class docstring
missing-docstring:25:public_undocumented:Missing function docstring
missing-module-docstring:1::Missing module docstring
missing-class-docstring:21:ClassUndocumented:Missing class docstring
missing-function-docstring:25:public_undocumented:Missing function or method docstring
47 changes: 47 additions & 0 deletions tests/functional/m/missing_docstring_new_style.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# [missing-module-docstring]
# pylint: disable=too-few-public-methods


class ClassDocumented:
"""It has a docstring."""


class UndocumentedClass: # [missing-class-docstring]
pass


# pylint: disable=missing-class-docstring
class ClassUndocumented:
pass


# pylint: enable=missing-class-docstring
class OtherClassUndocumented: # [missing-class-docstring]
pass


def public_documented():
"""It has a docstring."""


def _private_undocumented():
# Doesn't need a docstring
pass


def _private_documented():
"""It has a docstring."""


def public_undocumented(): # [missing-function-docstring]
pass


# pylint: disable=missing-function-docstring
def undocumented_function():
pass


# pylint: enable=missing-function-docstring
def undocumented_other_function(): # [missing-function-docstring]
pass
5 changes: 5 additions & 0 deletions tests/functional/m/missing_docstring_new_style.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
missing-module-docstring:1::Missing module docstring
missing-class-docstring:9:UndocumentedClass:Missing class docstring
missing-class-docstring:19:OtherClassUndocumented:Missing class docstring
missing-function-docstring:36:public_undocumented:Missing function or method docstring
missing-function-docstring:46:undocumented_other_function:Missing function or method docstring
5 changes: 5 additions & 0 deletions tests/functional/m/missing_module_docstring_disabled.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# pylint: disable=missing-module-docstring, too-few-public-methods


class Documented:
"Something."
Empty file.
8 changes: 4 additions & 4 deletions tests/test_self.py
Original file line number Diff line number Diff line change
Expand Up @@ -344,8 +344,8 @@ def test_enable_all_works(self):
"""
************* Module data.clientmodule_test
{0}:10:8: W0612: Unused variable 'local_variable' (unused-variable)
{0}:18:4: C0111: Missing method docstring (missing-docstring)
{0}:22:0: C0111: Missing class docstring (missing-docstring)
{0}:18:4: C0116: Missing function or method docstring (missing-function-docstring)
{0}:22:0: C0115: Missing class docstring (missing-class-docstring)
""".format(
module
)
Expand Down Expand Up @@ -542,8 +542,8 @@ def test_pylintrc_comments_in_values(self):
"""
************* Module test_pylintrc_comments
{0}:2:0: W0311: Bad indentation. Found 1 spaces, expected 4 (bad-indentation)
{0}:1:0: C0111: Missing module docstring (missing-docstring)
{0}:1:0: C0111: Missing function docstring (missing-docstring)
{0}:1:0: C0114: Missing module docstring (missing-module-docstring)
{0}:1:0: C0116: Missing function or method docstring (missing-function-docstring)
""".format(
path
)
Expand Down
10 changes: 5 additions & 5 deletions tests/unittest_checker_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class TestDocstring(CheckerTestCase):

def test_missing_docstring_module(self):
module = astroid.parse("something")
message = Message("missing-docstring", node=module, args=("module",))
message = Message("missing-module-docstring", node=module)
with self.assertAddsMessages(message):
self.checker.visit_module(module)

Expand All @@ -53,7 +53,7 @@ def test_empty_docstring_function(self):
def func(tion):
pass"""
)
message = Message("missing-docstring", node=func, args=("function",))
message = Message("missing-function-docstring", node=func)
with self.assertAddsMessages(message):
self.checker.visit_functiondef(func)

Expand All @@ -76,7 +76,7 @@ def func(tion):
pass
"""
)
message = Message("missing-docstring", node=func, args=("function",))
message = Message("missing-function-docstring", node=func)
with self.assertAddsMessages(message):
self.checker.visit_functiondef(func)

Expand All @@ -91,7 +91,7 @@ def func(tion):
pass
"""
)
message = Message("missing-docstring", node=func, args=("function",))
message = Message("missing-function-docstring", node=func)
with self.assertAddsMessages(message):
self.checker.visit_functiondef(func)

Expand All @@ -111,7 +111,7 @@ def test_class_no_docstring(self):
class Klass(object):
pass"""
)
message = Message("missing-docstring", node=klass, args=("class",))
message = Message("missing-class-docstring", node=klass)
with self.assertAddsMessages(message):
self.checker.visit_classdef(klass)

Expand Down