2

is it bad practice to use asserts within methods?

e.g.

def add(x, y):
    assert isinstance(x, int) and isinstance(y, int)
    return x + y

Any ideas?

skaffman
  • 398,947
  • 96
  • 818
  • 769
RadiantHex
  • 24,907
  • 47
  • 148
  • 244

4 Answers4

6

Not at all.

In your sample, provided you have documented that add expects integers, asserting this constraint at the beginning of the method is actually great practice.

Just imagine the other choices you have and how bad they are:

  • don't verify your arguments. This means, the method will fail later with a strange backtrace that will presumably confuse the caller and force him to have a look at the implementation of add to get a hint what's going on.
  • be nice and try to convert the input to int - very bad idea, users will keep wondering why add(2.4,3.1) keeps returning 5.
Alexander Gessler
  • 45,603
  • 7
  • 82
  • 122
  • 1
    In a case like this, wouldn't you prefer to raise an exception instead? I prefer to use asserts only when debugging code. – Chinmay Kanchi Apr 22 '11 at 12:46
  • it surely depends on the occasion (especially in dynamically-typed languages), but exceptions are for runtime errors while assertions are used to catch programming errors. If the docs for `add` clearly state that it only accepts 'int', then it is the responsibility of the caller to keep to this constraint and any contract violation is a programming error. – Alexander Gessler Apr 22 '11 at 12:49
  • (Besides, `assert` in Python raises `AssertionError` - so it is actually syntatic sugar to raise an exception). – Alexander Gessler Apr 22 '11 at 12:51
  • 1
    Yes, it raises an `AssertError`. IMHO, in this case, I'd simply raise `TypeError` instead. – Chinmay Kanchi Apr 22 '11 at 12:59
  • 3
    But semantically, an assertion means "this cannot possibly be false". Invalid arguments are very possible and should raise an appropriate error (e.g. `TypeError`) that indicates "some data is wrong" instead of "this code is broken" - also, I consider `except AssertionError` (outside of tests perhaps) rather smelly for that very reason. –  Apr 22 '11 at 13:00
  • It cannot possible be false if you assume that the caller never violates the method's contract. I would agree that `TypeError` perhaps has a stronger semantic meaning in the given sample, but the question is about raising assertions within methods in general. And that's fine. – Alexander Gessler Apr 22 '11 at 13:02
  • Yes, assertions in methods are perfectly fine - why not? But since the sole example is about assertions for argument validation, the appropriateness of assertions for should get special mention imho. And your answer ignored the third alternative Chinmay and I defend, raising an approriate exception "manually". –  Apr 22 '11 at 13:12
  • +1 Except for "a strange backtrace that will presumably confuse the caller and force him to have a look at the implementation of add to get a hint what's going on." That's all false. It's quite obvious when wrong type data has been provided. – S.Lott Apr 22 '11 at 15:38
2

It's ok because you may run your application with -O command line option and no code would be generated for your assert statement see here

Update:

But also you should handle all errors anyway. Otherwise after stripping assertions unhandled exceptions may occur. (as McConnell recomended. See his citations here)

Community
  • 1
  • 1
Andrey Sboev
  • 7,454
  • 1
  • 20
  • 37
  • Why is that an argument in favor of asserts? –  Apr 22 '11 at 12:49
  • I mean asserting is good practice, so the question is whether there are drawbacks in case of python scripts. The bad thing would be assertion exceptions appearing when your script is running on "release" mode. However, python allows you to avoid this. – Andrey Sboev Apr 22 '11 at 12:55
  • But code such as OP's uses asserts for argument validation - it may carry on with wrong/bogus values and crash later on if asserts are skipped. –  Apr 22 '11 at 12:57
  • I agree with McConnell in Thomas Owens's answer here: http://stackoverflow.com/questions/17732/when-should-assertions-stay-in-production-code/17834#17834 – Andrey Sboev Apr 22 '11 at 13:02
  • Then add that to the answer. It's important. Without the "handle the error anyway" part, stripping the assertions leads to incorrect code. –  Apr 22 '11 at 13:07
0

It's not but if your code contains more assert statements than your actual code then I would be angry.

0

Instead of using assertions and raising Assertion exception...better perform proper checks using instance() and raise a proper TypeError.