I disagree, because side effects in an assert would always be a code smell, but placing slow code in there is useful behavior. The line could have easily been:
assert 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.
When it optimizes out a statement that the spec explicitly says can be optimized out? A correct compiler is one that conforms to spec. You using a statement for something outside of its intended purpose makes the compiler incorrect?
Sorry, I'm not deeply familiar with the Python spec. Outside of C or a lisp I would expect assert to behave more like a function which discards its arguments when disabled and less like a macro which stops evaluating its arguments when disabled. This expectation would obviously be incorrect in the case of Python, which is fairly explicit as to the meaning of assert[0]:
if __debug__:
if not expression: raise AssertionError
This sounds nice in theory. In practice, the compiler cannot eliminate any log statements (writing to a log file is a side effect). Thus, the decision to not execute "FOO" as for example Java does when asserts are disabled, is the correct one.