68

How does one format a long assert statement that complies with PEP8? Please ignore the contrived nature of my example.

def afunc(some_param_name):
    assert isinstance(some_param_name, SomeClassName), 'some_param_name must be an instance of SomeClassName, silly goose!'

One cannot wrap it in parenthesis, because that changes the behavior of the assert statement since it is a keyword, not a builtin function.

stantonk
  • 1,922
  • 1
  • 18
  • 24
  • `assert` should really only be used for **debugging** purpose, any other use is abuse of the `assert` functionality. All `assert`s are also removed when running python with the `-O` option. – Wessie Apr 17 '13 at 16:38
  • 19
    @Wessie I don't see how that is relevant. – Gareth Latty Apr 17 '13 at 16:40
  • 4
    Besides @Wessie, [assert has many uses](https://stackoverflow.com/a/18980471/673991). It can inform human readers of the code as to features, intentions, limitations, expectations. It has a place in healthy, styled, production code. – Bob Stein Jul 24 '19 at 16:14

5 Answers5

94

It's important to remember that PEP8 is only a guideline and even states that there are times when the rules should be broken.

But most importantly: know when to be inconsistent -- sometimes the style guide just doesn't apply.

With that in mind, I would probably write this with old style line continuation:

def afunc(some_param_name):
    assert isinstance(some_param_name, SomeClassName), \ 
           'some_param_name must be an instance of SomeClassName, silly goose!'

If that doesn't sit well with you (or your linter), you can always do:

def afunc(some_param_name):
    assert isinstance(some_param_name, SomeClassName), ( 
           'some_param_name must be an instance of SomeClassName, silly goose!')

or even:

def afunc(some_param_name):
    assert isinstance(some_param_name, SomeClassName), ( 
           'some_param_name must be an instance of SomeClassName, '
           'silly goose!')
mgilson
  • 300,191
  • 65
  • 633
  • 696
  • 1
    +1. I would argue this is the more readable solution here. Bracket continuations are *preferred* over backslash line continuations, but that's a general statement, and individual cases vary. – Gareth Latty Apr 17 '13 at 16:42
  • +1 for "rules should be broken". I tend to use the old style line continuation, if only because it's the solution which requires the fewest keystrokes to write. That's also one of the reasons I prefer Python to PHP: `def` is shorter than `function`. There are, of course, far more compelling reasons than that. ;-) – Aya Apr 17 '13 at 17:29
  • Awesome, thanks. Totally agree on PEP8 being a guideline. We use flake8 (which combines pyflakes and pep8.py), and I figured that there was *something* that would satisfy the spirit of PEP8 as well as the linters. – stantonk Apr 17 '13 at 21:04
  • This is wrong (the second line of the assert should only be indented 4 spaces), but it demonstrates how to do it, thanks. – Wyrmwood Nov 20 '20 at 21:07
7
ERR_MESSAGE_01 = '''
Some really long error message
'''

assert condition(a,b), ERR_MESSAGE_01

Is how I do it ...and I think that complies fine ..

Joran Beasley
  • 110,522
  • 12
  • 160
  • 179
  • 7
    When the post is talking about PEP-8 compliance, the `CAPS_WITH_UNDERSCORES` names are not helping. – Gareth Latty Apr 17 '13 at 16:39
  • yeah fair point ... carryover from c #defines and constants. dubious... but im sticking to it . besides i am thinking of it as a module level constant which pep8 tells us to name as such – Joran Beasley Apr 17 '13 at 16:42
  • 6
    Constants: Constants are usually defined on a module level and written in all capital letters with underscores separating words. Examples include MAX_OVERFLOW and TOTAL. – Joran Beasley Apr 17 '13 at 16:44
  • Yes, except in this case, extracting the error message to a module level constant would be awkward (meaning the user would have to jump around to see the value), and `CONDITION()` is a function, not a constant. – Gareth Latty Apr 17 '13 at 16:45
  • not really I usually create an errors.py module that contains all my error messages as (well named)constants ... obviously not naming them ERR_1 ... also I fixed the function name and the local a,b variable names as you are 100% correct on that front :) (this also lends itself well to localization) – Joran Beasley Apr 17 '13 at 16:48
5

It's worth noting that it is possible to wrap with parenthesis, just not in the way you are thinking.

assert isinstance(some_param_name, 
                  SomeClassName), ('some_param_name must be an instance of '
                                   'SomeClassName, silly goose!')

I wouldn't argue it's particularly readable, however. In some cases, it might be the right option.

Gareth Latty
  • 86,389
  • 17
  • 178
  • 183
3

This is described in pep8 in the end of the Maximum Line Length section.

Backslashes may still be appropriate at times. For example, [...] Another such case is with assert statements.

So the pep8 recommendation is to do as mgilsons first example, e.g.:

def afunc(some_param_name):
    assert isinstance(some_param_name, SomeClassName), \ 
           'some_param_name must be an instance of SomeClassName, silly goose!'
Olsgaard
  • 1,006
  • 9
  • 19
1
def afunc(some_param_name):
    assert (isinstance(some_param_name, SomeClassName)
            ), 'some_param_name must be an instance of SomeClassName, silly goose!'

This gives you the implied line continuation from parentheses that is recommended by PEP 8 without breaking the assert behavior.

Alternatively:

def afunc(some_param_name):
    assert isinstance(some_param_name, SomeClassName), (
           'some_param_name must be an instance of SomeClassName, silly goose!')
Andrew Clark
  • 202,379
  • 35
  • 273
  • 306