On Mon, May 18, 2020 at 11:25:39AM +0200, Alex Hall wrote:

>  I understand this, but I still don't understand in what situation people
> use assertions 'correctly'. 

https://import-that.dreamwidth.org/676.html


> To me an assert implies:
> 
> 1. If the condition is false: that's bad, and the code shouldn't keep
> running.
>
> 2. I'm not 100% sure the condition is always true (a bug in my code is
> always a possiblity) and I need code to check for me.
 
They apply to many other conditional checks apart from assertions.

The question should be, what distinguishes an *assertion* from other 
conditional checks followed by raise? Both trigger on errors; the 
difference is in the semantics: assert is intended for use 
during development.

If we are confident that there are no bugs (at least not in the areas 
checked by assertions), then the assertions are safe to disable in 
production.

If we're not confident, then we're running a system which is not ready 
for production, and we should be honest about that at least to 
ourselves even if we don't exactly advertise that fact :-)

And if removing the asserts could *cause* bugs, rather than reveal 
their existence, then they certainly shouldn't be asserts.


> In that case I want the check there even more in production than in
> development. It never makes sense to me for such checks to be turned off.

That opinion pretty much goes against the standard practice in every 
language that I know of that has assertions. "Assertions that you cannot 
turn off" are just regular error checking. The ability to disable 
assertions is a feature, not a bug, and is the primary feature that 
distinguishes asserts from `if... raise`.

    ---------------------------  ---------------------------------
    assert                       if...raise
    ---------------------------  ---------------------------------
    raises if not condition      raises if condition
    can be disabled              cannot be disabled
    limited to AssertionError    no limit to the exception type
    ---------------------------  ---------------------------------

If you expect the assertions to fail in production, why not fix the 
error conditions that could lead them to fail?

Probably no other language makes assertions a bigger part of the 
language than Eiffel. They have, by my count, at least five kinds of 
assertions:

* preconditions
* postconditions
* loop invariants
* class invariants
* checks

and they are so fundamental to Eiffel's programming model that they are 
part of the syntactic structure of classes and methods. But even 
Eiffel designed assertions to be disabled:

"During development and testing, assertion monitoring should be turned 
on at the highest possible level. [...] When releasing the final version 
of a system, it is usually appropriate to turn off assertion monitoring, 
or bring it down to the `require` level. The exact policy depends on the 
circumstances; it is a trade off between efficiency considerations, the 
potential cost of mistakes, and how much the developers and quality 
assurance team trust the product."

https://www.eiffel.org/doc/eiffel/ET-_Design_by_Contract_%28tm%29%2C_Assertions_and_Exceptions

Compared to Eiffel's fine-grained assertion system, Python's is pretty 
coarse, we don't have multiple levels of assertion testing, just All On 
and All Off. But the principle still applies. Assertions are intended to 
be capable of being disabled.


> I understand the reason to turn them off is performance, but this always
> seems like a minor optimisation.

Certainly in Python the optimizations tend to be small, but not always 
insignificant. And even small things can add up to make a significant 
difference.


> I don't want code to be significantly
> slower without -O.

So you want it to be equally slow with -O? *wink*

The aim isn't to intentionally slow down the unoptimised code, but to 
speed up the optimized code by trading off some "just in case" tests 
which should never fail for additional speed. It is the person running 
the code, not the developer, who decides whether to make that tradeoff 
or not.

(Unless the developer and the user are the same person, in which 
case why do you care? Just don't run your code with -O. If you are your 
application's sole user, then do whatever you like, it's okay.)

If you know a test should never fail, then it is safe to turn it off. If 
it's not safe to turn it off, then it's not an assertion.

(Safety, of course, is not an absolute. If it were absolute, we wouldn't 
bother running the assertions at all, ever, since we would know that 
they absolutely will never fail.)

> For me it makes development and testing slow and painful,

Sorry, are you saying that assertions make development and testing slow 
and painful? If that's not what you mean, I don't know what this means.

In pre-production and debugging, you run your code without -O. If the 
application is slow and painful, you have to solve that regardless of 
assert. When you are satisfied that the application is ready for 
production, you hand it over to your users who may or may not run it 
with -O, that's not your decision to make.


> for users it pushes them to use a global switch to solve a local
> problem at the cost of safety.

If that is true, that's a sign you are misusing assertions.

If the end user sees an AssertionError failure, that is 
indistinguishable from a bug in the code that causes it to crash. If 
your asserts trigger in production, that's not "safety", that's a bug.


> Really slow correctness checking is
> generally reserved for continuous integration tests. I've never wanted to
> put something significantly slow in an assert 

*shrug*

The cost of lots of cheap tests can still add up. If you haven't 
compared the speed of your application with and without -O then you 
don't know what the total cost of those assertions are.

You might be surprised, or you might be disappointed about how little 
benefit you get. It's hard to say.


-- 
Steven
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/TAKROQPGK7DRE6FZL3F3ASOWTJRZXVIZ/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to