Assertions
Steve D'Aprano
steve+python at pearwood.info
Thu Sep 21 13:23:27 EDT 2017
On Fri, 22 Sep 2017 02:59 am, Ned Batchelder wrote:
> On 9/21/17 12:29 PM, Tobiah wrote:
>> Are these completely equivalent?
[... assert, versus test and raise AssertionError ...]
> Let's see:
[...]
> Yes, they are completely equivalent, compiling to precisely the same
> bytecode.
That is definitely version-dependent, because I've just tried it and got
different byte-code in Python 2.7.
py> import dis
py> def test1():
... assert foo, "bar baz"
...
py> def test2():
... if not foo: raise AssertionError("bar baz")
...
py>
py> dis.dis(test1)
2 0 LOAD_GLOBAL 0 (foo)
3 POP_JUMP_IF_TRUE 15
6 LOAD_GLOBAL 1 (AssertionError)
9 LOAD_CONST 1 ('bar baz')
12 RAISE_VARARGS 2
>> 15 LOAD_CONST 0 (None)
18 RETURN_VALUE
py> dis.dis(test2)
2 0 LOAD_GLOBAL 0 (foo)
3 POP_JUMP_IF_TRUE 21
6 LOAD_GLOBAL 1 (AssertionError)
9 LOAD_CONST 1 ('bar baz')
12 CALL_FUNCTION 1
15 RAISE_VARARGS 1
18 JUMP_FORWARD 0 (to 21)
>> 21 LOAD_CONST 0 (None)
24 RETURN_VALUE
So I do not believe that we can say that they will always compile to the same
byte-code. There were differences in past versions, there could be differences
again in the future.
I was going to be cheeky and run the same test with -0, giving:
py> dis.dis(test1)
2 0 LOAD_CONST 0 (None)
3 RETURN_VALUE
which of course is a big difference between the two, but it turned out that
there can be other byte-code differences.
So no, I don't believe we can say they are *completely* equivalent, since they
could compile to slightly different byte-code with slightly-different
performance characteristics. But I think we can say that *semantically* the two
ought to be the same.
--
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.
More information about the Python-list
mailing list