summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Stapleton Cordasco <graffatcolmingov@gmail.com>2020-11-19 14:06:38 -0600
committerGitHub <noreply@github.com>2020-11-19 14:06:38 -0600
commit9dd78b97dea0e943300c92c853d6869e7fe41299 (patch)
treec5eda48ab614b299e79eaffb9eca07c00cb40087
parent07b113bdb43524181ec828a3b9da009a388c2161 (diff)
parentc060b1c1f46b126a5f0c429701f30f2e7e800815 (diff)
downloadpep8-9dd78b97dea0e943300c92c853d6869e7fe41299.tar.gz
Merge pull request #970 from bukzor/multi-indent
Support for space indents with size other than 4
-rw-r--r--docs/intro.rst1
-rwxr-xr-xpycodestyle.py40
-rw-r--r--testsuite/test_api.py49
3 files changed, 78 insertions, 12 deletions
diff --git a/docs/intro.rst b/docs/intro.rst
index 991db47..7945053 100644
--- a/docs/intro.rst
+++ b/docs/intro.rst
@@ -159,6 +159,7 @@ Quick help is available on the command line::
--max-line-length=n set maximum allowed line length (default: 79)
--max-doc-length=n set maximum allowed doc line length and perform these
checks (unchecked if not set)
+ --indent-size=n set how many spaces make up an indent (default: 4)
--hang-closing hang closing bracket instead of matching indentation of
opening bracket's line
--format=format set the error format [default|pylint|<custom>]
diff --git a/pycodestyle.py b/pycodestyle.py
index 88eb4d7..17fac7a 100755
--- a/pycodestyle.py
+++ b/pycodestyle.py
@@ -104,6 +104,7 @@ BLANK_LINES_CONFIG = {
'method': 1,
}
MAX_DOC_LENGTH = 72
+INDENT_SIZE = 4
REPORT_FORMAT = {
'default': '%(path)s:%(row)d:%(col)d: %(code)s %(text)s',
'pylint': '%(path)s:%(row)d: [%(code)s] %(text)s',
@@ -543,8 +544,9 @@ def missing_whitespace(logical_line):
@register_check
def indentation(logical_line, previous_logical, indent_char,
- indent_level, previous_indent_level):
- r"""Use 4 spaces per indentation level.
+ indent_level, previous_indent_level,
+ indent_size, indent_size_str):
+ r"""Use indent_size (PEP8 says 4) spaces per indentation level.
For really old code that you don't want to mess up, you can continue
to use 8-space tabs.
@@ -564,8 +566,11 @@ def indentation(logical_line, previous_logical, indent_char,
"""
c = 0 if logical_line else 3
tmpl = "E11%d %s" if logical_line else "E11%d %s (comment)"
- if indent_level % 4:
- yield 0, tmpl % (1 + c, "indentation is not a multiple of four")
+ if indent_level % indent_size:
+ yield 0, tmpl % (
+ 1 + c,
+ "indentation is not a multiple of " + indent_size_str,
+ )
indent_expect = previous_logical.endswith(':')
if indent_expect and indent_level <= previous_indent_level:
yield 0, tmpl % (2 + c, "expected an indented block")
@@ -581,7 +586,8 @@ def indentation(logical_line, previous_logical, indent_char,
@register_check
def continued_indentation(logical_line, tokens, indent_level, hang_closing,
- indent_char, noqa, verbose):
+ indent_char, indent_size, indent_size_str, noqa,
+ verbose):
r"""Continuation lines indentation.
Continuation lines should align wrapped elements either vertically
@@ -620,7 +626,8 @@ def continued_indentation(logical_line, tokens, indent_level, hang_closing,
indent_next = logical_line.endswith(':')
row = depth = 0
- valid_hangs = (4,) if indent_char != '\t' else (4, 8)
+ valid_hangs = (indent_size,) if indent_char != '\t' \
+ else (indent_size, indent_size * 2)
# remember how many brackets were opened on each line
parens = [0] * nrows
# relative indents of physical lines
@@ -685,7 +692,8 @@ def continued_indentation(logical_line, tokens, indent_level, hang_closing,
# visual indent is broken
yield (start, "E128 continuation line "
"under-indented for visual indent")
- elif hanging_indent or (indent_next and rel_indent[row] == 8):
+ elif hanging_indent or (indent_next and
+ rel_indent[row] == 2 * indent_size):
# hanging indent is verified
if close_bracket and not hang_closing:
yield (start, "E123 closing bracket does not match "
@@ -708,7 +716,7 @@ def continued_indentation(logical_line, tokens, indent_level, hang_closing,
error = "E131", "unaligned for hanging indent"
else:
hangs[depth] = hang
- if hang > 4:
+ if hang > indent_size:
error = "E126", "over-indented for hanging indent"
else:
error = "E121", "under-indented for hanging indent"
@@ -775,8 +783,8 @@ def continued_indentation(logical_line, tokens, indent_level, hang_closing,
if last_token_multiline:
rel_indent[end[0] - first_row] = rel_indent[row]
- if indent_next and expand_indent(line) == indent_level + 4:
- pos = (start[0], indent[0] + 4)
+ if indent_next and expand_indent(line) == indent_level + indent_size:
+ pos = (start[0], indent[0] + indent_size)
if visual_indent:
code = "E129 visually indented line"
else:
@@ -1960,8 +1968,12 @@ class Checker(object):
self._ast_checks = options.ast_checks
self.max_line_length = options.max_line_length
self.max_doc_length = options.max_doc_length
+ self.indent_size = options.indent_size
self.multiline = False # in a multiline string?
self.hang_closing = options.hang_closing
+ self.indent_size = options.indent_size
+ self.indent_size_str = ({2: 'two', 4: 'four', 8: 'eight'}
+ .get(self.indent_size, str(self.indent_size)))
self.verbose = options.verbose
self.filename = filename
# Dictionary where a checker can store its custom state.
@@ -2528,8 +2540,8 @@ def get_parser(prog='pycodestyle', version=__version__):
usage="%prog [options] input ...")
parser.config_options = [
'exclude', 'filename', 'select', 'ignore', 'max-line-length',
- 'max-doc-length', 'hang-closing', 'count', 'format', 'quiet',
- 'show-pep8', 'show-source', 'statistics', 'verbose']
+ 'max-doc-length', 'indent-size', 'hang-closing', 'count', 'format',
+ 'quiet', 'show-pep8', 'show-source', 'statistics', 'verbose']
parser.add_option('-v', '--verbose', default=0, action='count',
help="print status messages, or debug with -vv")
parser.add_option('-q', '--quiet', default=0, action='count',
@@ -2569,6 +2581,10 @@ def get_parser(prog='pycodestyle', version=__version__):
default=None,
help="set maximum allowed doc line length and perform "
"these checks (unchecked if not set)")
+ parser.add_option('--indent-size', type='int', metavar='n',
+ default=INDENT_SIZE,
+ help="set how many spaces make up an indent "
+ "(default: %default)")
parser.add_option('--hang-closing', action='store_true',
help="hang closing bracket instead of matching "
"indentation of opening bracket's line")
diff --git a/testsuite/test_api.py b/testsuite/test_api.py
index ad96074..ce2d33a 100644
--- a/testsuite/test_api.py
+++ b/testsuite/test_api.py
@@ -391,3 +391,52 @@ class APITestCase(unittest.TestCase):
# TODO: runner
# TODO: input_file
+
+ def test_styleguides_other_indent_size(self):
+ pycodestyle.register_check(DummyChecker, ['Z701'])
+ lines = [
+ 'def foo():\n',
+ ' pass\n',
+ '\n',
+ '\n',
+ 'def foo_correct():\n',
+ ' pass\n',
+ '\n',
+ '\n',
+ 'def bar():\n',
+ ' [1, 2, 3,\n',
+ ' 4, 5, 6,\n',
+ ' ]\n',
+ '\n',
+ '\n',
+ 'if (1 in [1, 2, 3]\n',
+ ' and bool(0) is False\n',
+ ' and bool(1) is True):\n',
+ ' pass\n'
+ ]
+
+ pep8style = pycodestyle.StyleGuide()
+ pep8style.options.indent_size = 3
+ count_errors = pep8style.input_file('stdin', lines=lines)
+ stdout = sys.stdout.getvalue()
+ self.assertEqual(count_errors, 4)
+ expected = (
+ 'stdin:2:5: '
+ 'E111 indentation is not a multiple of 3'
+ )
+ self.assertTrue(expected in stdout)
+ expected = (
+ 'stdin:11:6: '
+ 'E127 continuation line over-indented for visual indent'
+ )
+ self.assertTrue(expected in stdout)
+ expected = (
+ 'stdin:12:6: '
+ 'E124 closing bracket does not match visual indentation'
+ )
+ self.assertTrue(expected in stdout)
+ expected = (
+ 'stdin:17:6: '
+ 'E127 continuation line over-indented for visual indent'
+ )
+ self.assertTrue(expected in stdout)