352

Just opened a file with Sublime Text (with Sublime Linter) and noticed a PEP8 formatting error that I'd never seen before. Here's the text:

urlpatterns = patterns('',
    url(r'^$', listing, name='investment-listing'),
)

It's flagging the second argument, the line that starts url(...)

I was about to disable this check in ST2 but I'd like to know what I'm doing wrong before I ignore it. You never know, if it seems important I might even change my ways :)

Oli
  • 235,628
  • 64
  • 220
  • 299

2 Answers2

553

PEP-8 recommends you indent lines to the opening parentheses if you put anything on the first line, so it should either be indenting to the opening bracket:

urlpatterns = patterns('',
                       url(r'^$', listing, name='investment-listing'))

or not putting any arguments on the starting line, then indenting to a uniform level:

urlpatterns = patterns(
    '',
    url(r'^$', listing, name='investment-listing'),
)

urlpatterns = patterns(
    '', url(r'^$', listing, name='investment-listing'))

I suggest taking a read through PEP-8 - you can skim through a lot of it, and it's pretty easy to understand, unlike some of the more technical PEPs.

Gareth Latty
  • 86,389
  • 17
  • 178
  • 183
  • I see! Yeah that makes sense. I've adopted this code from the "standard" Django way of doing things. I guess if I were writing something like this I would have put the first argument on its own line. – Oli Mar 15 '13 at 15:15
  • @Oli Yeah. I can understand the instinct to put the `''` on the first line, but it also makes it very easy to miss that it's there. The two styles in PEP-8 make it harder to skim past an argument when reading. – Gareth Latty Mar 15 '13 at 15:16
  • 5
    Anybody know why Django does this; is there a good reason? It seems that it would be just as easy to follow PeP-8. – theherk Mar 22 '14 at 01:35
  • @TheHerk I agree, and, as I mentioned in the comment above, I'd argue that doing it 'the django way' makes it easier to miss arguments. I imagine it's just a case of a style that someone picked and others followed. – Gareth Latty Mar 25 '14 at 17:05
  • 7
    This is so ubiquitous in Django code I've seen (plus it's all over their docs) that it arguably supersedes PEP-8, after all it says "*Many projects have their own coding style guidelines. In the event of any conflicts, such project-specific guides take precedence for that project.*" – Nick T May 13 '14 at 22:04
  • 6
    @TheHerk the rationale is probably that the first argument to [`patterns()`](https://docs.djangoproject.com/en/dev/ref/urls/#patterns) is unique (a prefix for everything else specified), and all the other arguments are url patterns which are basically the same. – Nick T May 13 '14 at 22:06
  • @NickT I'd argue that if I didn't see that, and it took over a year for someone to comment on this saying that might be the reason, it's not a particularly clear way of showing that, if that's the intention. In general, I still think that it being easier to miss is reason enough to warrant the syntax PEP-8 recommends. Obviously if you were contributing to Django, follow their styles, for your own codebases, I'd avoid it if you can. – Gareth Latty May 14 '14 at 22:01
  • 3
    @Lattyware if you look at the Django docs, that is *exclusively* the formatting they use. If you are using `patterns()` in your own projects, **PEP-8 recommends their formatting** because it is the *de facto* standard/convention for Django. – Nick T May 15 '14 at 01:03
  • 6
    @NickT You are mis-reading PEP-8 - PEP-8 recommends following the existing convention where a given project uses it - but in this case the code is not going into Django, it's going into your project using Django - there is no need to follow their convention. The aim of that rule is to keep consistency inside code-bases. – Gareth Latty May 17 '14 at 14:34
  • 26
    Note that PEP8 also states that you should ignore PEP8 where it makes sense to do so, and I would argue that in this case in makes sense. Feel free to disagree for your own projects. In any case this will soon be a moot point as using `patterns()` will be deprecated in Django 1.8: https://docs.djangoproject.com/en/dev/releases/1.8/#django-conf-urls-patterns – Tom Carrick Jul 29 '14 at 10:16
  • There is another case where it makes sense to ignore this rule. The indentation of `self` and `cls` in methods and `@classmethods` can be done similar way to reflect how many parameters will be passed into the function in case of a multi-line function declaration. – Caveman Feb 09 '20 at 16:02
  • good tip to read through PEP-8. It's clear and well-written. But it _is_ a long document: roughly 30 pages if printed... – Kai Carver Apr 22 '20 at 14:59
  • 1
    @KaiCarver True, I'll change my wording a little: it doesn't take too long to go through because you can skim a lot of it (there are a lot of examples and stuff). – Gareth Latty Apr 23 '20 at 22:44
23

This goes also for statements like this (auto-formatted by PyCharm):

    return combine_sample_generators(sample_generators['train']), \
           combine_sample_generators(sample_generators['dev']), \
           combine_sample_generators(sample_generators['test'])

Which will give the same style-warning. In order to get rid of it I had to rewrite it to:

    return \
        combine_sample_generators(sample_generators['train']), \
        combine_sample_generators(sample_generators['dev']), \
        combine_sample_generators(sample_generators['test'])
Stefan Falk
  • 23,898
  • 50
  • 191
  • 378
  • 6
    I highly prefer parenthesis over backslash here, first line being `return (`, then each returnable item on its own line, indented, and finally the closing bracket on a separate line, at the same indentation level as the `return`. **Edit:** Like this https://pastebin.com/fAe7558X – Markus Meskanen May 27 '19 at 06:27
  • 2
    @MarkusMeskanen Yes, me too. I just wanted to point out that not even the auto-format complies fully with this specification. – Stefan Falk May 27 '19 at 08:57