mirror of
https://github.com/astral-sh/ruff.git
synced 2025-10-01 14:21:53 +00:00
Implement D205, D209, and D210 (#398)
This commit is contained in:
parent
b8dce8922d
commit
4e9fb9907a
15 changed files with 889 additions and 106 deletions
|
@ -217,7 +217,7 @@ ruff also implements some of the most popular Flake8 plugins natively, including
|
||||||
- [`flake8-print`](https://pypi.org/project/flake8-print/)
|
- [`flake8-print`](https://pypi.org/project/flake8-print/)
|
||||||
- [`flake8-comprehensions`](https://pypi.org/project/flake8-comprehensions/) (11/16)
|
- [`flake8-comprehensions`](https://pypi.org/project/flake8-comprehensions/) (11/16)
|
||||||
- [`flake8-bugbear`](https://pypi.org/project/flake8-bugbear/) (3/32)
|
- [`flake8-bugbear`](https://pypi.org/project/flake8-bugbear/) (3/32)
|
||||||
- [`flake8-docstrings`](https://pypi.org/project/flake8-docstrings/) (2/47)
|
- [`flake8-docstrings`](https://pypi.org/project/flake8-docstrings/) (6/47)
|
||||||
- [`pyupgrade`](https://pypi.org/project/pyupgrade/) (partial)
|
- [`pyupgrade`](https://pypi.org/project/pyupgrade/) (partial)
|
||||||
|
|
||||||
Beyond rule-set parity, ruff suffers from the following limitations vis-à-vis Flake8:
|
Beyond rule-set parity, ruff suffers from the following limitations vis-à-vis Flake8:
|
||||||
|
@ -304,6 +304,10 @@ The 🛠 emoji indicates that a rule is automatically fixable by the `--fix` com
|
||||||
| U006 | UsePEP585Annotation | Use `list` instead of `List` for type annotations | | 🛠 |
|
| U006 | UsePEP585Annotation | Use `list` instead of `List` for type annotations | | 🛠 |
|
||||||
| U007 | UsePEP604Annotation | Use `X \| Y` for type annotations | | 🛠 |
|
| U007 | UsePEP604Annotation | Use `X \| Y` for type annotations | | 🛠 |
|
||||||
| U008 | SuperCallWithParameters | Use `super()` instead of `super(__class__, self)` | | 🛠 |
|
| U008 | SuperCallWithParameters | Use `super()` instead of `super(__class__, self)` | | 🛠 |
|
||||||
|
| D200 | OneLinerDocstring | One-line docstring should fit on one line | | |
|
||||||
|
| D205 | BlankLineAfterSummary | 1 blank line required between summary line and description | | |
|
||||||
|
| D209 | NewLineAfterLastParagraph | Multi-line docstring closing quotes should be on a separate line | | |
|
||||||
|
| D210 | NoSurroundingWhitespace | No whitespaces allowed surrounding docstring text | | |
|
||||||
| D400 | DocstringEndsInNonPeriod | First line should end with a period | | |
|
| D400 | DocstringEndsInNonPeriod | First line should end with a period | | |
|
||||||
| D419 | EmptyDocstring | Docstring is empty | | |
|
| D419 | EmptyDocstring | Docstring is empty | | |
|
||||||
| M001 | UnusedNOQA | Unused `noqa` directive | | 🛠 |
|
| M001 | UnusedNOQA | Unused `noqa` directive | | 🛠 |
|
||||||
|
|
534
resources/test/fixtures/D.py
vendored
Normal file
534
resources/test/fixtures/D.py
vendored
Normal file
|
@ -0,0 +1,534 @@
|
||||||
|
# No docstring, so we can test D100
|
||||||
|
from functools import wraps
|
||||||
|
import os
|
||||||
|
from .expected import Expectation
|
||||||
|
from typing import overload
|
||||||
|
|
||||||
|
|
||||||
|
expectation = Expectation()
|
||||||
|
expect = expectation.expect
|
||||||
|
|
||||||
|
expect('class_', 'D101: Missing docstring in public class')
|
||||||
|
|
||||||
|
|
||||||
|
class class_:
|
||||||
|
|
||||||
|
expect('meta', 'D419: Docstring is empty')
|
||||||
|
|
||||||
|
class meta:
|
||||||
|
""""""
|
||||||
|
|
||||||
|
@expect('D102: Missing docstring in public method')
|
||||||
|
def method(self=None):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def _ok_since_private(self=None):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@overload
|
||||||
|
def overloaded_method(self, a: int) -> str:
|
||||||
|
...
|
||||||
|
|
||||||
|
@overload
|
||||||
|
def overloaded_method(self, a: str) -> str:
|
||||||
|
"""Foo bar documentation."""
|
||||||
|
...
|
||||||
|
|
||||||
|
def overloaded_method(a):
|
||||||
|
"""Foo bar documentation."""
|
||||||
|
return str(a)
|
||||||
|
|
||||||
|
expect('overloaded_method',
|
||||||
|
"D418: Function/ Method decorated with @overload"
|
||||||
|
" shouldn't contain a docstring")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def foo(self):
|
||||||
|
"""The foo of the thing, which isn't in imperitive mood."""
|
||||||
|
return "hello"
|
||||||
|
|
||||||
|
@expect('D102: Missing docstring in public method')
|
||||||
|
def __new__(self=None):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@expect('D107: Missing docstring in __init__')
|
||||||
|
def __init__(self=None):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@expect('D105: Missing docstring in magic method')
|
||||||
|
def __str__(self=None):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@expect('D102: Missing docstring in public method')
|
||||||
|
def __call__(self=None, x=None, y=None, z=None):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@expect('D419: Docstring is empty')
|
||||||
|
def function():
|
||||||
|
""" """
|
||||||
|
def ok_since_nested():
|
||||||
|
pass
|
||||||
|
|
||||||
|
@expect('D419: Docstring is empty')
|
||||||
|
def nested():
|
||||||
|
''
|
||||||
|
|
||||||
|
|
||||||
|
def function_with_nesting():
|
||||||
|
"""Foo bar documentation."""
|
||||||
|
@overload
|
||||||
|
def nested_overloaded_func(a: int) -> str:
|
||||||
|
...
|
||||||
|
|
||||||
|
@overload
|
||||||
|
def nested_overloaded_func(a: str) -> str:
|
||||||
|
"""Foo bar documentation."""
|
||||||
|
...
|
||||||
|
|
||||||
|
def nested_overloaded_func(a):
|
||||||
|
"""Foo bar documentation."""
|
||||||
|
return str(a)
|
||||||
|
|
||||||
|
|
||||||
|
expect('nested_overloaded_func',
|
||||||
|
"D418: Function/ Method decorated with @overload"
|
||||||
|
" shouldn't contain a docstring")
|
||||||
|
|
||||||
|
|
||||||
|
@overload
|
||||||
|
def overloaded_func(a: int) -> str:
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
|
@overload
|
||||||
|
def overloaded_func(a: str) -> str:
|
||||||
|
"""Foo bar documentation."""
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
|
def overloaded_func(a):
|
||||||
|
"""Foo bar documentation."""
|
||||||
|
return str(a)
|
||||||
|
|
||||||
|
|
||||||
|
expect('overloaded_func',
|
||||||
|
"D418: Function/ Method decorated with @overload"
|
||||||
|
" shouldn't contain a docstring")
|
||||||
|
|
||||||
|
|
||||||
|
@expect('D200: One-line docstring should fit on one line with quotes '
|
||||||
|
'(found 3)')
|
||||||
|
@expect('D212: Multi-line docstring summary should start at the first line')
|
||||||
|
def asdlkfasd():
|
||||||
|
"""
|
||||||
|
Wrong.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
@expect('D201: No blank lines allowed before function docstring (found 1)')
|
||||||
|
def leading_space():
|
||||||
|
|
||||||
|
"""Leading space."""
|
||||||
|
|
||||||
|
|
||||||
|
@expect('D202: No blank lines allowed after function docstring (found 1)')
|
||||||
|
def trailing_space():
|
||||||
|
"""Leading space."""
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@expect('D201: No blank lines allowed before function docstring (found 1)')
|
||||||
|
@expect('D202: No blank lines allowed after function docstring (found 1)')
|
||||||
|
def trailing_and_leading_space():
|
||||||
|
|
||||||
|
"""Trailing and leading space."""
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
expect('LeadingSpaceMissing',
|
||||||
|
'D203: 1 blank line required before class docstring (found 0)')
|
||||||
|
|
||||||
|
|
||||||
|
class LeadingSpaceMissing:
|
||||||
|
"""Leading space missing."""
|
||||||
|
|
||||||
|
|
||||||
|
expect('WithLeadingSpace',
|
||||||
|
'D211: No blank lines allowed before class docstring (found 1)')
|
||||||
|
|
||||||
|
|
||||||
|
class WithLeadingSpace:
|
||||||
|
|
||||||
|
"""With leading space."""
|
||||||
|
|
||||||
|
|
||||||
|
expect('TrailingSpace',
|
||||||
|
'D204: 1 blank line required after class docstring (found 0)')
|
||||||
|
expect('TrailingSpace',
|
||||||
|
'D211: No blank lines allowed before class docstring (found 1)')
|
||||||
|
|
||||||
|
|
||||||
|
class TrailingSpace:
|
||||||
|
|
||||||
|
"""TrailingSpace."""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
expect('LeadingAndTrailingSpaceMissing',
|
||||||
|
'D203: 1 blank line required before class docstring (found 0)')
|
||||||
|
expect('LeadingAndTrailingSpaceMissing',
|
||||||
|
'D204: 1 blank line required after class docstring (found 0)')
|
||||||
|
|
||||||
|
|
||||||
|
class LeadingAndTrailingSpaceMissing:
|
||||||
|
"""Leading and trailing space missing."""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@expect('D205: 1 blank line required between summary line and description '
|
||||||
|
'(found 0)')
|
||||||
|
@expect('D213: Multi-line docstring summary should start at the second line')
|
||||||
|
def multi_line_zero_separating_blanks():
|
||||||
|
"""Summary.
|
||||||
|
Description.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
@expect('D205: 1 blank line required between summary line and description '
|
||||||
|
'(found 2)')
|
||||||
|
@expect('D213: Multi-line docstring summary should start at the second line')
|
||||||
|
def multi_line_two_separating_blanks():
|
||||||
|
"""Summary.
|
||||||
|
|
||||||
|
|
||||||
|
Description.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
@expect('D213: Multi-line docstring summary should start at the second line')
|
||||||
|
def multi_line_one_separating_blanks():
|
||||||
|
"""Summary.
|
||||||
|
|
||||||
|
Description.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
@expect('D207: Docstring is under-indented')
|
||||||
|
@expect('D213: Multi-line docstring summary should start at the second line')
|
||||||
|
def asdfsdf():
|
||||||
|
"""Summary.
|
||||||
|
|
||||||
|
Description.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
@expect('D207: Docstring is under-indented')
|
||||||
|
@expect('D213: Multi-line docstring summary should start at the second line')
|
||||||
|
def asdsdfsdffsdf():
|
||||||
|
"""Summary.
|
||||||
|
|
||||||
|
Description.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
@expect('D208: Docstring is over-indented')
|
||||||
|
@expect('D213: Multi-line docstring summary should start at the second line')
|
||||||
|
def asdfsdsdf24():
|
||||||
|
"""Summary.
|
||||||
|
|
||||||
|
Description.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
@expect('D208: Docstring is over-indented')
|
||||||
|
@expect('D213: Multi-line docstring summary should start at the second line')
|
||||||
|
def asdfsdsdfsdf24():
|
||||||
|
"""Summary.
|
||||||
|
|
||||||
|
Description.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
@expect('D208: Docstring is over-indented')
|
||||||
|
@expect('D213: Multi-line docstring summary should start at the second line')
|
||||||
|
def asdfsdfsdsdsdfsdf24():
|
||||||
|
"""Summary.
|
||||||
|
|
||||||
|
Description.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
@expect('D209: Multi-line docstring closing quotes should be on a separate '
|
||||||
|
'line')
|
||||||
|
@expect('D213: Multi-line docstring summary should start at the second line')
|
||||||
|
def asdfljdf24():
|
||||||
|
"""Summary.
|
||||||
|
|
||||||
|
Description."""
|
||||||
|
|
||||||
|
|
||||||
|
@expect('D210: No whitespaces allowed surrounding docstring text')
|
||||||
|
def endswith():
|
||||||
|
"""Whitespace at the end. """
|
||||||
|
|
||||||
|
|
||||||
|
@expect('D210: No whitespaces allowed surrounding docstring text')
|
||||||
|
def around():
|
||||||
|
""" Whitespace at everywhere. """
|
||||||
|
|
||||||
|
|
||||||
|
@expect('D210: No whitespaces allowed surrounding docstring text')
|
||||||
|
@expect('D213: Multi-line docstring summary should start at the second line')
|
||||||
|
def multiline():
|
||||||
|
""" Whitespace at the beginning.
|
||||||
|
|
||||||
|
This is the end.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
@expect('D300: Use """triple double quotes""" (found \'\'\'-quotes)')
|
||||||
|
def triple_single_quotes_raw():
|
||||||
|
r'''Summary.'''
|
||||||
|
|
||||||
|
|
||||||
|
@expect('D300: Use """triple double quotes""" (found \'\'\'-quotes)')
|
||||||
|
def triple_single_quotes_raw_uppercase():
|
||||||
|
R'''Summary.'''
|
||||||
|
|
||||||
|
|
||||||
|
@expect('D300: Use """triple double quotes""" (found \'-quotes)')
|
||||||
|
def single_quotes_raw():
|
||||||
|
r'Summary.'
|
||||||
|
|
||||||
|
|
||||||
|
@expect('D300: Use """triple double quotes""" (found \'-quotes)')
|
||||||
|
def single_quotes_raw_uppercase():
|
||||||
|
R'Summary.'
|
||||||
|
|
||||||
|
|
||||||
|
@expect('D300: Use """triple double quotes""" (found \'-quotes)')
|
||||||
|
@expect('D301: Use r""" if any backslashes in a docstring')
|
||||||
|
def single_quotes_raw_uppercase_backslash():
|
||||||
|
R'Sum\mary.'
|
||||||
|
|
||||||
|
|
||||||
|
@expect('D301: Use r""" if any backslashes in a docstring')
|
||||||
|
def double_quotes_backslash():
|
||||||
|
"""Sum\\mary."""
|
||||||
|
|
||||||
|
|
||||||
|
@expect('D301: Use r""" if any backslashes in a docstring')
|
||||||
|
def double_quotes_backslash_uppercase():
|
||||||
|
R"""Sum\\mary."""
|
||||||
|
|
||||||
|
|
||||||
|
@expect('D213: Multi-line docstring summary should start at the second line')
|
||||||
|
def exceptions_of_D301():
|
||||||
|
"""Exclude some backslashes from D301.
|
||||||
|
|
||||||
|
In particular, line continuations \
|
||||||
|
and unicode literals \u0394 and \N{GREEK CAPITAL LETTER DELTA}.
|
||||||
|
They are considered to be intentionally unescaped.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
@expect("D400: First line should end with a period (not 'y')")
|
||||||
|
@expect("D415: First line should end with a period, question mark, "
|
||||||
|
"or exclamation point (not 'y')")
|
||||||
|
def lwnlkjl():
|
||||||
|
"""Summary"""
|
||||||
|
|
||||||
|
|
||||||
|
@expect("D401: First line should be in imperative mood "
|
||||||
|
"(perhaps 'Return', not 'Returns')")
|
||||||
|
def liouiwnlkjl():
|
||||||
|
"""Returns foo."""
|
||||||
|
|
||||||
|
|
||||||
|
@expect("D401: First line should be in imperative mood; try rephrasing "
|
||||||
|
"(found 'Constructor')")
|
||||||
|
def sdgfsdg23245():
|
||||||
|
"""Constructor for a foo."""
|
||||||
|
|
||||||
|
|
||||||
|
@expect("D401: First line should be in imperative mood; try rephrasing "
|
||||||
|
"(found 'Constructor')")
|
||||||
|
def sdgfsdg23245777():
|
||||||
|
"""Constructor."""
|
||||||
|
|
||||||
|
|
||||||
|
@expect('D402: First line should not be the function\'s "signature"')
|
||||||
|
def foobar():
|
||||||
|
"""Signature: foobar()."""
|
||||||
|
|
||||||
|
|
||||||
|
@expect('D213: Multi-line docstring summary should start at the second line')
|
||||||
|
def new_209():
|
||||||
|
"""First line.
|
||||||
|
|
||||||
|
More lines.
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@expect('D213: Multi-line docstring summary should start at the second line')
|
||||||
|
def old_209():
|
||||||
|
"""One liner.
|
||||||
|
|
||||||
|
Multi-line comments. OK to have extra blank line
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
@expect("D103: Missing docstring in public function")
|
||||||
|
def oneliner_d102(): return
|
||||||
|
|
||||||
|
|
||||||
|
@expect("D400: First line should end with a period (not 'r')")
|
||||||
|
@expect("D415: First line should end with a period, question mark,"
|
||||||
|
" or exclamation point (not 'r')")
|
||||||
|
def oneliner_withdoc(): """One liner"""
|
||||||
|
|
||||||
|
|
||||||
|
def ignored_decorator(func): # noqa: D400,D401,D415
|
||||||
|
"""Runs something"""
|
||||||
|
func()
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def decorator_for_test(func): # noqa: D400,D401,D415
|
||||||
|
"""Runs something"""
|
||||||
|
func()
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@ignored_decorator
|
||||||
|
def oneliner_ignored_decorator(): """One liner"""
|
||||||
|
|
||||||
|
|
||||||
|
@decorator_for_test
|
||||||
|
@expect("D400: First line should end with a period (not 'r')")
|
||||||
|
@expect("D415: First line should end with a period, question mark,"
|
||||||
|
" or exclamation point (not 'r')")
|
||||||
|
def oneliner_with_decorator_expecting_errors(): """One liner"""
|
||||||
|
|
||||||
|
|
||||||
|
@decorator_for_test
|
||||||
|
def valid_oneliner_with_decorator(): """One liner."""
|
||||||
|
|
||||||
|
|
||||||
|
@expect("D207: Docstring is under-indented")
|
||||||
|
@expect('D213: Multi-line docstring summary should start at the second line')
|
||||||
|
def docstring_start_in_same_line(): """First Line.
|
||||||
|
|
||||||
|
Second Line
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
def function_with_lambda_arg(x=lambda y: y):
|
||||||
|
"""Wrap the given lambda."""
|
||||||
|
|
||||||
|
|
||||||
|
@expect('D213: Multi-line docstring summary should start at the second line')
|
||||||
|
def a_following_valid_function(x=None):
|
||||||
|
"""Check for a bug where the previous function caused an assertion.
|
||||||
|
|
||||||
|
The assertion was caused in the next function, so this one is necessary.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
def outer_function():
|
||||||
|
"""Do something."""
|
||||||
|
def inner_function():
|
||||||
|
"""Do inner something."""
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
@expect("D400: First line should end with a period (not 'g')")
|
||||||
|
@expect("D401: First line should be in imperative mood "
|
||||||
|
"(perhaps 'Run', not 'Runs')")
|
||||||
|
@expect("D415: First line should end with a period, question mark, "
|
||||||
|
"or exclamation point (not 'g')")
|
||||||
|
def docstring_bad():
|
||||||
|
"""Runs something"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def docstring_bad_ignore_all(): # noqa
|
||||||
|
"""Runs something"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def docstring_bad_ignore_one(): # noqa: D400,D401,D415
|
||||||
|
"""Runs something"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@expect("D401: First line should be in imperative mood "
|
||||||
|
"(perhaps 'Run', not 'Runs')")
|
||||||
|
def docstring_ignore_some_violations_but_catch_D401(): # noqa: E501,D400,D415
|
||||||
|
"""Runs something"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@expect(
|
||||||
|
"D401: First line should be in imperative mood "
|
||||||
|
"(perhaps 'Initiate', not 'Initiates')"
|
||||||
|
)
|
||||||
|
def docstring_initiates():
|
||||||
|
"""Initiates the process."""
|
||||||
|
|
||||||
|
|
||||||
|
@expect(
|
||||||
|
"D401: First line should be in imperative mood "
|
||||||
|
"(perhaps 'Initialize', not 'Initializes')"
|
||||||
|
)
|
||||||
|
def docstring_initializes():
|
||||||
|
"""Initializes the process."""
|
||||||
|
|
||||||
|
|
||||||
|
@wraps(docstring_bad_ignore_one)
|
||||||
|
def bad_decorated_function():
|
||||||
|
"""Bad (E501) but decorated"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def valid_google_string(): # noqa: D400
|
||||||
|
"""Test a valid something!"""
|
||||||
|
|
||||||
|
|
||||||
|
@expect("D415: First line should end with a period, question mark, "
|
||||||
|
"or exclamation point (not 'g')")
|
||||||
|
def bad_google_string(): # noqa: D400
|
||||||
|
"""Test a valid something"""
|
||||||
|
|
||||||
|
|
||||||
|
# This is reproducing a bug where AttributeError is raised when parsing class
|
||||||
|
# parameters as functions for Google / Numpy conventions.
|
||||||
|
class Blah: # noqa: D203,D213
|
||||||
|
"""A Blah.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
x : int
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, x):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
expect(os.path.normcase(__file__ if __file__[-1] != 'c' else __file__[:-1]),
|
||||||
|
'D100: Missing docstring in public module')
|
25
resources/test/fixtures/D200.py
vendored
25
resources/test/fixtures/D200.py
vendored
|
@ -1,25 +0,0 @@
|
||||||
def f():
|
|
||||||
"""
|
|
||||||
Fail.
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
def f():
|
|
||||||
"""Fail.
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
def f():
|
|
||||||
"""
|
|
||||||
Fail."""
|
|
||||||
|
|
||||||
|
|
||||||
def f():
|
|
||||||
"""Pass."""
|
|
||||||
|
|
||||||
|
|
||||||
def f():
|
|
||||||
"""Pass.
|
|
||||||
|
|
||||||
More content here.
|
|
||||||
"""
|
|
27
resources/test/fixtures/D400.py
vendored
27
resources/test/fixtures/D400.py
vendored
|
@ -1,27 +0,0 @@
|
||||||
def f1() -> None:
|
|
||||||
"""Hello, world.
|
|
||||||
|
|
||||||
More content here.
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
def f2() -> None:
|
|
||||||
"""Hello, world!
|
|
||||||
|
|
||||||
More content here.
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
def f3() -> None:
|
|
||||||
"""Hello, world
|
|
||||||
|
|
||||||
More content here.
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
def f4() -> None:
|
|
||||||
"""."""
|
|
||||||
|
|
||||||
|
|
||||||
def f5() -> None:
|
|
||||||
""""""
|
|
13
resources/test/fixtures/D419.py
vendored
13
resources/test/fixtures/D419.py
vendored
|
@ -1,13 +0,0 @@
|
||||||
""""""
|
|
||||||
|
|
||||||
|
|
||||||
def f1() -> None:
|
|
||||||
""""""
|
|
||||||
|
|
||||||
|
|
||||||
def f2() -> None:
|
|
||||||
""
|
|
||||||
|
|
||||||
|
|
||||||
def f3() -> None:
|
|
||||||
"""Hello, world!"""
|
|
|
@ -1893,6 +1893,15 @@ impl<'a> Checker<'a> {
|
||||||
if self.settings.enabled.contains(&CheckCode::D200) {
|
if self.settings.enabled.contains(&CheckCode::D200) {
|
||||||
docstrings::one_liner(self, &docstring);
|
docstrings::one_liner(self, &docstring);
|
||||||
}
|
}
|
||||||
|
if self.settings.enabled.contains(&CheckCode::D205) {
|
||||||
|
docstrings::blank_after_summary(self, &docstring);
|
||||||
|
}
|
||||||
|
if self.settings.enabled.contains(&CheckCode::D209) {
|
||||||
|
docstrings::newline_after_last_paragraph(self, &docstring);
|
||||||
|
}
|
||||||
|
if self.settings.enabled.contains(&CheckCode::D210) {
|
||||||
|
docstrings::no_surrounding_whitespace(self, &docstring);
|
||||||
|
}
|
||||||
if self.settings.enabled.contains(&CheckCode::D400) {
|
if self.settings.enabled.contains(&CheckCode::D400) {
|
||||||
docstrings::ends_with_period(self, &docstring);
|
docstrings::ends_with_period(self, &docstring);
|
||||||
}
|
}
|
||||||
|
|
|
@ -152,6 +152,9 @@ pub enum CheckCode {
|
||||||
U008,
|
U008,
|
||||||
// pydocstyle
|
// pydocstyle
|
||||||
D200,
|
D200,
|
||||||
|
D205,
|
||||||
|
D209,
|
||||||
|
D210,
|
||||||
D400,
|
D400,
|
||||||
D419,
|
D419,
|
||||||
// Meta
|
// Meta
|
||||||
|
@ -252,6 +255,9 @@ pub enum CheckKind {
|
||||||
SuperCallWithParameters,
|
SuperCallWithParameters,
|
||||||
// pydocstyle
|
// pydocstyle
|
||||||
OneLinerDocstring,
|
OneLinerDocstring,
|
||||||
|
BlankLineAfterSummary,
|
||||||
|
NewLineAfterLastParagraph,
|
||||||
|
NoSurroundingWhitespace,
|
||||||
EmptyDocstring,
|
EmptyDocstring,
|
||||||
DocstringEndsInNonPeriod,
|
DocstringEndsInNonPeriod,
|
||||||
// Meta
|
// Meta
|
||||||
|
@ -364,6 +370,9 @@ impl CheckCode {
|
||||||
CheckCode::U008 => CheckKind::SuperCallWithParameters,
|
CheckCode::U008 => CheckKind::SuperCallWithParameters,
|
||||||
// pydocstyle
|
// pydocstyle
|
||||||
CheckCode::D200 => CheckKind::OneLinerDocstring,
|
CheckCode::D200 => CheckKind::OneLinerDocstring,
|
||||||
|
CheckCode::D205 => CheckKind::BlankLineAfterSummary,
|
||||||
|
CheckCode::D209 => CheckKind::NewLineAfterLastParagraph,
|
||||||
|
CheckCode::D210 => CheckKind::NoSurroundingWhitespace,
|
||||||
CheckCode::D400 => CheckKind::DocstringEndsInNonPeriod,
|
CheckCode::D400 => CheckKind::DocstringEndsInNonPeriod,
|
||||||
CheckCode::D419 => CheckKind::EmptyDocstring,
|
CheckCode::D419 => CheckKind::EmptyDocstring,
|
||||||
// Meta
|
// Meta
|
||||||
|
@ -455,6 +464,9 @@ impl CheckKind {
|
||||||
CheckKind::SuperCallWithParameters => &CheckCode::U008,
|
CheckKind::SuperCallWithParameters => &CheckCode::U008,
|
||||||
// pydocstyle
|
// pydocstyle
|
||||||
CheckKind::OneLinerDocstring => &CheckCode::D200,
|
CheckKind::OneLinerDocstring => &CheckCode::D200,
|
||||||
|
CheckKind::BlankLineAfterSummary => &CheckCode::D205,
|
||||||
|
CheckKind::NewLineAfterLastParagraph => &CheckCode::D209,
|
||||||
|
CheckKind::NoSurroundingWhitespace => &CheckCode::D210,
|
||||||
CheckKind::DocstringEndsInNonPeriod => &CheckCode::D400,
|
CheckKind::DocstringEndsInNonPeriod => &CheckCode::D400,
|
||||||
CheckKind::EmptyDocstring => &CheckCode::D419,
|
CheckKind::EmptyDocstring => &CheckCode::D419,
|
||||||
// Meta
|
// Meta
|
||||||
|
@ -702,6 +714,15 @@ impl CheckKind {
|
||||||
}
|
}
|
||||||
// pydocstyle
|
// pydocstyle
|
||||||
CheckKind::OneLinerDocstring => "One-line docstring should fit on one line".to_string(),
|
CheckKind::OneLinerDocstring => "One-line docstring should fit on one line".to_string(),
|
||||||
|
CheckKind::BlankLineAfterSummary => {
|
||||||
|
"1 blank line required between summary line and description".to_string()
|
||||||
|
}
|
||||||
|
CheckKind::NewLineAfterLastParagraph => {
|
||||||
|
"Multi-line docstring closing quotes should be on a separate line".to_string()
|
||||||
|
}
|
||||||
|
CheckKind::NoSurroundingWhitespace => {
|
||||||
|
"No whitespaces allowed surrounding docstring text".to_string()
|
||||||
|
}
|
||||||
CheckKind::DocstringEndsInNonPeriod => {
|
CheckKind::DocstringEndsInNonPeriod => {
|
||||||
"First line should end with a period".to_string()
|
"First line should end with a period".to_string()
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,6 +88,83 @@ pub fn one_liner(checker: &mut Checker, docstring: &Docstring) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn blank_after_summary(checker: &mut Checker, docstring: &Docstring) {
|
||||||
|
if let ExprKind::Constant {
|
||||||
|
value: Constant::Str(string),
|
||||||
|
..
|
||||||
|
} = &docstring.expr.node
|
||||||
|
{
|
||||||
|
let mut lines_count = 1;
|
||||||
|
let mut blanks_count = 0;
|
||||||
|
for line in string.trim().lines().skip(1) {
|
||||||
|
lines_count += 1;
|
||||||
|
if line.trim().is_empty() {
|
||||||
|
blanks_count += 1;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if lines_count > 1 && blanks_count != 1 {
|
||||||
|
checker.add_check(Check::new(
|
||||||
|
CheckKind::BlankLineAfterSummary,
|
||||||
|
Range::from_located(docstring.expr),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn newline_after_last_paragraph(checker: &mut Checker, docstring: &Docstring) {
|
||||||
|
if let ExprKind::Constant {
|
||||||
|
value: Constant::Str(string),
|
||||||
|
..
|
||||||
|
} = &docstring.expr.node
|
||||||
|
{
|
||||||
|
let mut line_count = 0;
|
||||||
|
for line in string.lines() {
|
||||||
|
if !line.trim().is_empty() {
|
||||||
|
line_count += 1;
|
||||||
|
}
|
||||||
|
if line_count > 1 {
|
||||||
|
let content = checker
|
||||||
|
.locator
|
||||||
|
.slice_source_code_range(&Range::from_located(docstring.expr));
|
||||||
|
if let Some(line) = content.lines().last() {
|
||||||
|
let line = line.trim();
|
||||||
|
if line != "\"\"\"" && line != "'''" {
|
||||||
|
checker.add_check(Check::new(
|
||||||
|
CheckKind::NewLineAfterLastParagraph,
|
||||||
|
Range::from_located(docstring.expr),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn no_surrounding_whitespace(checker: &mut Checker, docstring: &Docstring) {
|
||||||
|
if let ExprKind::Constant {
|
||||||
|
value: Constant::Str(string),
|
||||||
|
..
|
||||||
|
} = &docstring.expr.node
|
||||||
|
{
|
||||||
|
let mut lines = string.lines();
|
||||||
|
if let Some(line) = lines.next() {
|
||||||
|
if line.trim().is_empty() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if line.starts_with(' ') || (matches!(lines.next(), None) && line.ends_with(' ')) {
|
||||||
|
checker.add_check(Check::new(
|
||||||
|
CheckKind::NoSurroundingWhitespace,
|
||||||
|
Range::from_located(docstring.expr),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn not_empty(checker: &mut Checker, docstring: &Docstring) {
|
pub fn not_empty(checker: &mut Checker, docstring: &Docstring) {
|
||||||
if let ExprKind::Constant {
|
if let ExprKind::Constant {
|
||||||
value: Constant::Str(string),
|
value: Constant::Str(string),
|
||||||
|
|
|
@ -981,7 +981,7 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn d200() -> Result<()> {
|
fn d200() -> Result<()> {
|
||||||
let mut checks = check_path(
|
let mut checks = check_path(
|
||||||
Path::new("./resources/test/fixtures/D200.py"),
|
Path::new("./resources/test/fixtures/D.py"),
|
||||||
&settings::Settings::for_rule(CheckCode::D200),
|
&settings::Settings::for_rule(CheckCode::D200),
|
||||||
&fixer::Mode::Generate,
|
&fixer::Mode::Generate,
|
||||||
)?;
|
)?;
|
||||||
|
@ -990,10 +990,46 @@ mod tests {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn d205() -> Result<()> {
|
||||||
|
let mut checks = check_path(
|
||||||
|
Path::new("./resources/test/fixtures/D.py"),
|
||||||
|
&settings::Settings::for_rule(CheckCode::D205),
|
||||||
|
&fixer::Mode::Generate,
|
||||||
|
)?;
|
||||||
|
checks.sort_by_key(|check| check.location);
|
||||||
|
insta::assert_yaml_snapshot!(checks);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn d209() -> Result<()> {
|
||||||
|
let mut checks = check_path(
|
||||||
|
Path::new("./resources/test/fixtures/D.py"),
|
||||||
|
&settings::Settings::for_rule(CheckCode::D209),
|
||||||
|
&fixer::Mode::Generate,
|
||||||
|
)?;
|
||||||
|
checks.sort_by_key(|check| check.location);
|
||||||
|
insta::assert_yaml_snapshot!(checks);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn d210() -> Result<()> {
|
||||||
|
let mut checks = check_path(
|
||||||
|
Path::new("./resources/test/fixtures/D.py"),
|
||||||
|
&settings::Settings::for_rule(CheckCode::D210),
|
||||||
|
&fixer::Mode::Generate,
|
||||||
|
)?;
|
||||||
|
checks.sort_by_key(|check| check.location);
|
||||||
|
insta::assert_yaml_snapshot!(checks);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn d400() -> Result<()> {
|
fn d400() -> Result<()> {
|
||||||
let mut checks = check_path(
|
let mut checks = check_path(
|
||||||
Path::new("./resources/test/fixtures/D400.py"),
|
Path::new("./resources/test/fixtures/D.py"),
|
||||||
&settings::Settings::for_rule(CheckCode::D400),
|
&settings::Settings::for_rule(CheckCode::D400),
|
||||||
&fixer::Mode::Generate,
|
&fixer::Mode::Generate,
|
||||||
)?;
|
)?;
|
||||||
|
@ -1005,7 +1041,7 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn d419() -> Result<()> {
|
fn d419() -> Result<()> {
|
||||||
let mut checks = check_path(
|
let mut checks = check_path(
|
||||||
Path::new("./resources/test/fixtures/D419.py"),
|
Path::new("./resources/test/fixtures/D.py"),
|
||||||
&settings::Settings::for_rule(CheckCode::D419),
|
&settings::Settings::for_rule(CheckCode::D419),
|
||||||
&fixer::Mode::Generate,
|
&fixer::Mode::Generate,
|
||||||
)?;
|
)?;
|
||||||
|
|
|
@ -4,26 +4,10 @@ expression: checks
|
||||||
---
|
---
|
||||||
- kind: OneLinerDocstring
|
- kind: OneLinerDocstring
|
||||||
location:
|
location:
|
||||||
row: 2
|
row: 124
|
||||||
column: 6
|
column: 6
|
||||||
end_location:
|
end_location:
|
||||||
row: 4
|
row: 126
|
||||||
column: 8
|
column: 8
|
||||||
fix: ~
|
fix: ~
|
||||||
- kind: OneLinerDocstring
|
|
||||||
location:
|
|
||||||
row: 8
|
|
||||||
column: 6
|
|
||||||
end_location:
|
|
||||||
row: 9
|
|
||||||
column: 8
|
|
||||||
fix: ~
|
|
||||||
- kind: OneLinerDocstring
|
|
||||||
location:
|
|
||||||
row: 13
|
|
||||||
column: 6
|
|
||||||
end_location:
|
|
||||||
row: 14
|
|
||||||
column: 13
|
|
||||||
fix: ~
|
|
||||||
|
|
||||||
|
|
21
src/snapshots/ruff__linter__tests__d205.snap
Normal file
21
src/snapshots/ruff__linter__tests__d205.snap
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
---
|
||||||
|
source: src/linter.rs
|
||||||
|
expression: checks
|
||||||
|
---
|
||||||
|
- kind: BlankLineAfterSummary
|
||||||
|
location:
|
||||||
|
row: 195
|
||||||
|
column: 6
|
||||||
|
end_location:
|
||||||
|
row: 198
|
||||||
|
column: 8
|
||||||
|
fix: ~
|
||||||
|
- kind: BlankLineAfterSummary
|
||||||
|
location:
|
||||||
|
row: 205
|
||||||
|
column: 6
|
||||||
|
end_location:
|
||||||
|
row: 210
|
||||||
|
column: 8
|
||||||
|
fix: ~
|
||||||
|
|
13
src/snapshots/ruff__linter__tests__d209.snap
Normal file
13
src/snapshots/ruff__linter__tests__d209.snap
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
---
|
||||||
|
source: src/linter.rs
|
||||||
|
expression: checks
|
||||||
|
---
|
||||||
|
- kind: NewLineAfterLastParagraph
|
||||||
|
location:
|
||||||
|
row: 276
|
||||||
|
column: 6
|
||||||
|
end_location:
|
||||||
|
row: 278
|
||||||
|
column: 20
|
||||||
|
fix: ~
|
||||||
|
|
29
src/snapshots/ruff__linter__tests__d210.snap
Normal file
29
src/snapshots/ruff__linter__tests__d210.snap
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
---
|
||||||
|
source: src/linter.rs
|
||||||
|
expression: checks
|
||||||
|
---
|
||||||
|
- kind: NoSurroundingWhitespace
|
||||||
|
location:
|
||||||
|
row: 283
|
||||||
|
column: 6
|
||||||
|
end_location:
|
||||||
|
row: 283
|
||||||
|
column: 34
|
||||||
|
fix: ~
|
||||||
|
- kind: NoSurroundingWhitespace
|
||||||
|
location:
|
||||||
|
row: 288
|
||||||
|
column: 6
|
||||||
|
end_location:
|
||||||
|
row: 288
|
||||||
|
column: 38
|
||||||
|
fix: ~
|
||||||
|
- kind: NoSurroundingWhitespace
|
||||||
|
location:
|
||||||
|
row: 294
|
||||||
|
column: 6
|
||||||
|
end_location:
|
||||||
|
row: 297
|
||||||
|
column: 8
|
||||||
|
fix: ~
|
||||||
|
|
|
@ -4,18 +4,138 @@ expression: checks
|
||||||
---
|
---
|
||||||
- kind: DocstringEndsInNonPeriod
|
- kind: DocstringEndsInNonPeriod
|
||||||
location:
|
location:
|
||||||
row: 9
|
row: 69
|
||||||
column: 6
|
column: 6
|
||||||
end_location:
|
end_location:
|
||||||
row: 12
|
row: 69
|
||||||
|
column: 12
|
||||||
|
fix: ~
|
||||||
|
- kind: DocstringEndsInNonPeriod
|
||||||
|
location:
|
||||||
|
row: 124
|
||||||
|
column: 6
|
||||||
|
end_location:
|
||||||
|
row: 126
|
||||||
column: 8
|
column: 8
|
||||||
fix: ~
|
fix: ~
|
||||||
- kind: DocstringEndsInNonPeriod
|
- kind: DocstringEndsInNonPeriod
|
||||||
location:
|
location:
|
||||||
row: 16
|
row: 283
|
||||||
column: 6
|
column: 6
|
||||||
end_location:
|
end_location:
|
||||||
row: 19
|
row: 283
|
||||||
column: 8
|
column: 34
|
||||||
|
fix: ~
|
||||||
|
- kind: DocstringEndsInNonPeriod
|
||||||
|
location:
|
||||||
|
row: 288
|
||||||
|
column: 6
|
||||||
|
end_location:
|
||||||
|
row: 288
|
||||||
|
column: 38
|
||||||
|
fix: ~
|
||||||
|
- kind: DocstringEndsInNonPeriod
|
||||||
|
location:
|
||||||
|
row: 350
|
||||||
|
column: 6
|
||||||
|
end_location:
|
||||||
|
row: 350
|
||||||
|
column: 18
|
||||||
|
fix: ~
|
||||||
|
- kind: DocstringEndsInNonPeriod
|
||||||
|
location:
|
||||||
|
row: 401
|
||||||
|
column: 26
|
||||||
|
end_location:
|
||||||
|
row: 401
|
||||||
|
column: 40
|
||||||
|
fix: ~
|
||||||
|
- kind: DocstringEndsInNonPeriod
|
||||||
|
location:
|
||||||
|
row: 405
|
||||||
|
column: 6
|
||||||
|
end_location:
|
||||||
|
row: 405
|
||||||
|
column: 25
|
||||||
|
fix: ~
|
||||||
|
- kind: DocstringEndsInNonPeriod
|
||||||
|
location:
|
||||||
|
row: 411
|
||||||
|
column: 6
|
||||||
|
end_location:
|
||||||
|
row: 411
|
||||||
|
column: 25
|
||||||
|
fix: ~
|
||||||
|
- kind: DocstringEndsInNonPeriod
|
||||||
|
location:
|
||||||
|
row: 417
|
||||||
|
column: 36
|
||||||
|
end_location:
|
||||||
|
row: 417
|
||||||
|
column: 50
|
||||||
|
fix: ~
|
||||||
|
- kind: DocstringEndsInNonPeriod
|
||||||
|
location:
|
||||||
|
row: 424
|
||||||
|
column: 50
|
||||||
|
end_location:
|
||||||
|
row: 424
|
||||||
|
column: 64
|
||||||
|
fix: ~
|
||||||
|
- kind: DocstringEndsInNonPeriod
|
||||||
|
location:
|
||||||
|
row: 465
|
||||||
|
column: 6
|
||||||
|
end_location:
|
||||||
|
row: 465
|
||||||
|
column: 25
|
||||||
|
fix: ~
|
||||||
|
- kind: DocstringEndsInNonPeriod
|
||||||
|
location:
|
||||||
|
row: 470
|
||||||
|
column: 6
|
||||||
|
end_location:
|
||||||
|
row: 470
|
||||||
|
column: 25
|
||||||
|
fix: ~
|
||||||
|
- kind: DocstringEndsInNonPeriod
|
||||||
|
location:
|
||||||
|
row: 475
|
||||||
|
column: 6
|
||||||
|
end_location:
|
||||||
|
row: 475
|
||||||
|
column: 25
|
||||||
|
fix: ~
|
||||||
|
- kind: DocstringEndsInNonPeriod
|
||||||
|
location:
|
||||||
|
row: 482
|
||||||
|
column: 6
|
||||||
|
end_location:
|
||||||
|
row: 482
|
||||||
|
column: 25
|
||||||
|
fix: ~
|
||||||
|
- kind: DocstringEndsInNonPeriod
|
||||||
|
location:
|
||||||
|
row: 504
|
||||||
|
column: 6
|
||||||
|
end_location:
|
||||||
|
row: 504
|
||||||
|
column: 35
|
||||||
|
fix: ~
|
||||||
|
- kind: DocstringEndsInNonPeriod
|
||||||
|
location:
|
||||||
|
row: 509
|
||||||
|
column: 6
|
||||||
|
end_location:
|
||||||
|
row: 509
|
||||||
|
column: 34
|
||||||
|
fix: ~
|
||||||
|
- kind: DocstringEndsInNonPeriod
|
||||||
|
location:
|
||||||
|
row: 515
|
||||||
|
column: 6
|
||||||
|
end_location:
|
||||||
|
row: 515
|
||||||
|
column: 33
|
||||||
fix: ~
|
fix: ~
|
||||||
|
|
||||||
|
|
|
@ -4,26 +4,26 @@ expression: checks
|
||||||
---
|
---
|
||||||
- kind: EmptyDocstring
|
- kind: EmptyDocstring
|
||||||
location:
|
location:
|
||||||
row: 1
|
row: 19
|
||||||
column: 2
|
column: 10
|
||||||
end_location:
|
end_location:
|
||||||
row: 1
|
row: 19
|
||||||
column: 7
|
column: 15
|
||||||
fix: ~
|
fix: ~
|
||||||
- kind: EmptyDocstring
|
- kind: EmptyDocstring
|
||||||
location:
|
location:
|
||||||
row: 5
|
row: 69
|
||||||
column: 6
|
column: 6
|
||||||
end_location:
|
end_location:
|
||||||
row: 5
|
row: 69
|
||||||
|
column: 12
|
||||||
|
fix: ~
|
||||||
|
- kind: EmptyDocstring
|
||||||
|
location:
|
||||||
|
row: 75
|
||||||
|
column: 10
|
||||||
|
end_location:
|
||||||
|
row: 75
|
||||||
column: 11
|
column: 11
|
||||||
fix: ~
|
fix: ~
|
||||||
- kind: EmptyDocstring
|
|
||||||
location:
|
|
||||||
row: 9
|
|
||||||
column: 6
|
|
||||||
end_location:
|
|
||||||
row: 9
|
|
||||||
column: 7
|
|
||||||
fix: ~
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue