33

I am trying to properly indent following piece of code:

RULES_LIST = [
    ('Name1', 1, 'Long string upto 40 chars'),
    ('Name2', 2, 'Long string upto 40 chars'),
    ('Name3', 3, 'Long string upto 40 chars'),
    ('Name4', 4, 'Long string upto 40 chars'),
    ('Name5', 5, 'Long string upto 40 chars'),
    ('Name6', 6, 'Long string upto 40 chars'),
    ('Name7', 7, 'Long string upto 40 chars'),
    ('Name8', 8, 'Long string upto 40 chars')
]

Pylint complains Wrong hanging indentation. for above code, and PEP8 complains E121: under-indented for hanging indent.

A possible fix for pylint is changing it to:

RULES_LIST = [\
    ('Name1', 1, 'Long string upto 40 chars'),
     ...
    ('Name8', 8, 'Long string upto 40 chars')]

but PEP8 complains E121 and E502

PEP8: 1.5.7 (default configuration)
Pylint: 1.3.0 (default configuration)
Python: 2.7.5 (Running on OSX 10.9.3)

The list can grow longer. Can someone please suggest a proper indentation for this?

Jatin Kumar
  • 2,635
  • 9
  • 36
  • 46
  • 2
    I just ran pylint (default config) and flake8 on your first example and neither had any problem. Are you using a custom pylint config? It also looks right, except for no hanging comma. – Jason S Aug 14 '14 at 08:51
  • @JasonS: Its showing errors for me. I have updated question with configuration and version number of PEP8, Pylint and Python. – Jatin Kumar Aug 14 '14 at 09:05
  • I can only reproduce this if I replace my 4 spaces at the beginning of each line by a tab (of length 4 spaces). With spaces it runs fine. If you're using tabs, you may want to replace those by 4 spaces (or configure your text editor to do so for Python files). Then again, pep8 actually tells me there are tabs (as well as giving E121, with a different message). –  Aug 14 '14 at 09:41
  • I've simply disabled this message in Pylint. ”Fixing” the source makes it either less robust (inserting '\' and make sure there's never any whitespace after that) or less readable by choosing an indentation which doesn't represent the structure of the data anymore. – BlackJack Aug 18 '14 at 13:44
  • notice that pylint shows you the places considered as correct (the '^' on the line below your source code snippet). – sthenault Aug 25 '14 at 07:16
  • pylint 1.4.4 doesn't complain in default config. – jcomeau_ictx Dec 08 '15 at 19:42

4 Answers4

16

If you want to continue using tabs, you can change the following settings in the .pylintrc file:

indent-string='\t'
indent-after-paren=1

If you only change the first one, pylint will expect four tabs to be used for indentation.

James Brierley
  • 4,630
  • 1
  • 20
  • 39
12

You're using tabs instead of four spaces.

Those three possibilities are correct from pylint point of view, as long as you use four spaces instead of tabs, the first one is the one black would use:

RULES_LIST = [
    ('Name1', 1, 'Long string upto 40 chars'),
    ('Name2', 2, 'Long string upto 40 chars'),
    ('Name3', 3, 'Long string upto 40 chars'),
    ('Name4', 4, 'Long string upto 40 chars'),
    ('Name5', 5, 'Long string upto 40 chars'),
    ('Name6', 6, 'Long string upto 40 chars'),
    ('Name7', 7, 'Long string upto 40 chars'),
    ('Name8', 8, 'Long string upto 40 chars'),
]

RULES_LIST = [('Name1', 1, 'Long string upto 40 chars'),
              ('Name2', 2, 'Long string upto 40 chars'),
              ('Name3', 3, 'Long string upto 40 chars'),
              ('Name4', 4, 'Long string upto 40 chars'),
              ('Name5', 5, 'Long string upto 40 chars'),
              ('Name6', 6, 'Long string upto 40 chars'),
              ('Name7', 7, 'Long string upto 40 chars'),
              ('Name8', 8, 'Long string upto 40 chars')]

RULES_LIST = [
    ('Name1', 1, 'Long string upto 40 chars'),
    ('Name2', 2, 'Long string upto 40 chars'),
    ('Name3', 3, 'Long string upto 40 chars'),
    ('Name4', 4, 'Long string upto 40 chars'),
    ('Name5', 5, 'Long string upto 40 chars'),
    ('Name6', 6, 'Long string upto 40 chars'),
    ('Name7', 7, 'Long string upto 40 chars'),
    ('Name8', 8, 'Long string upto 40 chars')]

Note that, in the first one, there's a trailing coma, this is intended as it reduces differences when you add a line:

Adding a 9th line without trailing coma:

     ("Name7", 7, "Long string upto 40 chars"),
-    ("Name8", 8, "Long string upto 40 chars")
+    ("Name8", 8, "Long string upto 40 chars"),
+    ("Name9", 9, "Long string upto 40 chars")
 ]

Adding a 9th line with trailing coma:

     ("Name8", 8, "Long string upto 40 chars"),
+    ("Name9", 9, "Long string upto 40 chars"),
 ]
Julien Palard
  • 8,736
  • 2
  • 37
  • 44
0

I didn't want to bother messing with a config file, so I found the easiest solution was to simply convert the tabs into spaces before checking:

expand --tabs=4 $filename | pylint --from-stdin stdin

Note: This requires pylint 2.4 to work. Make sure you double check the version, because when I wrapped the above line into a custom pylint checker script it decided to use a different version of pylint mysteriously installed elsewhere on the system, instead of the one the terminal gave me.

Here's a heavily abbreviated version of the mylint script that you can edit as you see fit:

set -e
pylint="/usr/bin/pylint"

#Warnings that I don't care about:
disabler(){
echo no-else-return             #No else after return
echo pointless-string-statement
echo no-self-use                #Class method without a self. in it.
echo useless-else-on-loop       #For else loop where the else isn't needed
echo too-many-locals            #More than 15 local vars
echo cell-var-from-loop         #https://stackoverflow.com/questions/25314547/cell-var-from-loop-warning-from-pylint
echo no-else-continue           #No else after contiune statement
echo no-else-break              #No else after break statement
echo C0114,C0116                #Docstring nonsense

echo W0614,W0401                #Wildcard imports are fixed by star_namer.py
}

expand --tabs=4 $1 | $pylint --from-stdin stdin --max-line-length=120 --variable-rgx="[a-z0-9_]{1,30}$" --disable=`disabler | tr '\n' ','` --docstring-min-length=5 --min-public-methods=1  | sed G | less

It's nice to be able to comment, uncomment the warnings easily and leave a little note so I don't forget what they do.

SurpriseDog
  • 462
  • 8
  • 18
-3

It was expecting maybe like this

RULES_LIST = [
    ('Name1', 1, 'Long string upto 40 chars'),
    ('Name2', 2, 'Long string upto 40 chars'),
    ('Name3', 3, 'Long string upto 40 chars'),
    ('Name4', 4, 'Long string upto 40 chars'),
    ('Name5', 5, 'Long string upto 40 chars'),
    ('Name6', 6, 'Long string upto 40 chars'),
    ('Name7', 7, 'Long string upto 40 chars'),
    ('Name8', 8, 'Long string upto 40 chars')
    ]

the closing square bracket.

idwaker
  • 406
  • 3
  • 10
  • Did you try running this? It doesn't work :/ Its like you do anything without using '\', unless you indent all lines (but first) beyond the opening square braces, it won't work!! – Jatin Kumar Aug 14 '14 at 14:54
  • 1
    I think that this should work according to pep8 `The closing brace/bracket/parenthesis on multiline constructs may either line up under the first non-whitespace character of the last line of list`; however flake8 / pylint will still complain. – FZeiser Aug 18 '21 at 08:43