Bad:
assert InitialiseStuff() != False, 'Initialise failed'
If the optimising compiler is set to eliminiate assertions the InitialiseStuff function won't get called! This will (subtly, or not so subtly) break your program!
Bad:
assert InitialiseStuff() != False, 'Initialise failed'
If the optimising compiler is set to eliminiate assertions the InitialiseStuff function won't get called! This will (subtly, or not so subtly) break your program!
I guess there's no reasonable way of changing the language to prevent that from happening, say, only allowing asserts on variables? (I mean obviously because it would break python, but also because it would be an inconsistant implementation.)
Most developers who work with executable compilers tend to know about this sort of thing already; no doubt because for some of them they've done this very thing by accident and gotten burnt by it at some point or another.
For example, say you want to assert that a particular property of your object contains something:
assert obj.whatever != None
Whoops, unless your compiler is sophisticated enough to be able to follow the call chain and ensure that the getter doesn't cause any side effects, this is now no longer allowed. You'd have to use a temporary variable, which is unnatural and prevents the very optimization you're trying to pull off. assert.py:
a = 0
def gadd(b):
global a
a = a + b
return a
assert gadd(1) == 1, 'a != 1'
print a
$python assert.py
1
$python -O assert.py
0assert EnsureUnique( obj )
Which runs through the program's data structures to ensure that nothing else matches a property of obj in some way.
Hacky, slow, but very useful to keep around if you have a constraint like that. But if you run it in release mode with production sized data sets, it'll slow to a crawl if you don't cut out the entire check.
if __debug__:
if not expression: raise AssertionError
My mistake![0]: http://docs.python.org/2/reference/simple_stmts.html#the-ass...