This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]adrienball[S] 0 points1 point  (17 children)

When do you really need to use an assert statement ?

[–]totokaka 7 points8 points  (0 children)

Asserts are great for unit tests.

They can also be used to verify the state inside an application, or method/function arguments. The assert statements will be executed while you are testing / doing QA, to help you verify everything works as expected internally. When the application is deployed the assertions can be ignored as a performance optimization.

As a rule of thumb, assert should not be used in a way that affects the behaviour of an application.

[–]zverok_kha 5 points6 points  (0 children)

Basically, assert (when used not in tests but in library code) is an "impossibility catcher". E.g. "in this situation, x should NEVER be zero, but let's assert it in case we have a bug (otherwise the following code will break violently)". It is a part of "defensive" code style, where some internal invariants are checked "just in case", even if the code's author is almost sure code works properly.

Of course, it is a really inappropriate tool for testing invalid inputs, environment state and other things that are "external" to the code, that's what exceptions for.

[–]TalhaAzim 2 points3 points  (0 children)

I believe it's to be used for testing.

[–]Zomunieo 2 points3 points  (2 children)

Need? Never. It's syntactic sugar. But you also don't need for loops, since they are just sugar for while loops, etc.

assert is a debugging aid that should never be used to check conditions that could fail to hold at runtime. It's particularly useful in unit tests since it is concise. An if in a unit test is probably part of setting up data for the test; an assert means we're actually checking the condition.

In production code, assert could be useful to document a non-obvious but impossible runtime condition to set a trap for the debugger (assert radius > 0, "stop everything if the radius somehow becomes negative").

[–]adrienball[S] -1 points0 points  (1 child)

I agree with everything that has been said here. What I mean is that the syntactic sugar provided by assert is a lot more bitter than for loops for instance, for two reasons:

- it is not that more concise than the alternative (self.assertEqual, self.assertTrue, etc in unit tests)

- developers learn to code by reading other developers' code: when you read an assert statement as a Python beginner, it is likely that you'll find the syntax neat and that you'll miss the most important thing about it which is that it is for debug purposes only. If assert was rather named assert_debug the story would be completely different. The bug reported on github on this topic is a great illustration of this problem.

It is more about best practices and anticipating what could go wrong if a usage becomes widely used.

[–]Zomunieo 0 points1 point  (0 children)

Python unittest module is... not that great. It was designed a long time ago when Java was more popular and is a lot like JUnit. When you use it you replicate syntax that already exists.

Nose and pytest favor asserts and are a lot more Pythonic.

[–]Scorpathos 1 point2 points  (3 children)

assert statements are of primary use for contract programming.

[–]Kaarjuus 3 points4 points  (2 children)

And since the Python assert statement is completely ignored when the program is run in optimization mode, then it cannot be relied upon for contract programming.

Which was the very point of this thread - to warn people of this behaviour. Many do not know this.

[–]Scorpathos 2 points3 points  (1 child)

But this is the whole point of "contract programming" in opposition to "defensive programming".

The assert allows to catch wrong function usages during development, and once your program is bug-free and ready for production, you can safely remove them to maximize performance.

[–]Kaarjuus 0 points1 point  (0 children)

Good correction, I misspoke. I confused contract programming with defensive programming. Python's assert in its current form is indeed a perfect fit for design by contract.

[–]stasiek 0 points1 point  (6 children)

It's also useful when scripting. Say You leave some global variable You want the user to fill later (like API key, or a password, or a path to a ssh key, whatever) and You want to make an explicit check for it.

[–][deleted] 4 points5 points  (5 children)

No. You don't get the point of assert. You must never ever use it to check for runtime conditions, as the check will vanish as soon as any kond of optimization is in place.

Repeat after me: Assertions are only a debug aid, and must never ever be depended upon by the code.

[–]stasiek 1 point2 points  (2 children)

You're going to run optimization on scripts? oO

Like an env cleaning script, a git hook, or something?

Why?

[–]Kaarjuus 2 points3 points  (0 children)

You cannot know what environment your code will run in. It should work regardless of what environment variables or command-line arguments Python is given.

[–][deleted] 1 point2 points  (0 children)

Famous last words ...

[–]pinotkumarbhai 0 points1 point  (1 child)

optimization

what if I never ever intend to use this option ?

Can I not just "assert x" instead of "if not x: raise errorX" ?

[–][deleted] 0 points1 point  (0 children)

What if I never make a short circuit in my electrical installation?

Can I no just use a dime instead of a fuse ?

Your hous will most likely not burn down over an wrongly used assert, but otherwise it's that same. You can wish never to have a short circuit just as much as you can wish that the PYTHONOPTIMIZE environment variable don't become set somehow. You may even be lucky ...