In the general case, this is hard because you can easily disallow a lot of useful cases that don't cause problems.
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.