72

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.

3
  • assert should really only be used for debugging purpose, any other use is abuse of the assert functionality. All asserts are also removed when running python with the -O option. Commented Apr 17, 2013 at 16:38
  • 21
    @Wessie I don't see how that is relevant. Commented Apr 17, 2013 at 16:40
  • 5
    Besides @Wessie, assert has many uses. It can inform human readers of the code as to features, intentions, limitations, expectations. It has a place in healthy, styled, production code. Commented Jul 24, 2019 at 16:14

5 Answers 5

96

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!')
Sign up to request clarification or add additional context in comments.

6 Comments

+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.
+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. ;-)
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.
This is wrong (the second line of the assert should only be indented 4 spaces), but it demonstrates how to do it, thanks.
The indentation is a matter of taste. See PEP 8 § Indentation: "Continuation lines should align wrapped elements either vertically [...] or using a hanging indent." You're talking about a hanging indent while mgilson is using vertical alignment.
Indentation is NOT a matter of taste. It has syntactic implications. In this particular case - a hanging indent, the syntax is unaffected, however, there's a large community that establishes guidelines as Python Enhancement Proposal (PEP), specifically, PEP8. When I said "wrong" I am implying it doesn't follow community guidelines. When in doubt, use black. Then the debates simply cease.
8
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 ..

5 Comments

When the post is talking about PEP-8 compliance, the CAPS_WITH_UNDERSCORES names are not helping.
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
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.
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.
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)
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.

Comments

4

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!'

Comments

2
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!')

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.