[Python-Dev] the role of assert in the standard library ?

Tarek Ziadé ziade.tarek at gmail.com
Thu Apr 28 09:54:23 CEST 2011


Hello

I removed some assert calls in distutils some time ago because the
package was not behaving correctly when people were using Python with
the --optimize flag. In other words, assert became a full part of the
code logic and removing them via -O was changing the behavior.

In my opinion assert should be avoided completely anywhere else than
in the tests. If this is a wrong statement, please let me know why :)

So, I grepped the stdlib for assert calls, and I have found 177 of
them and many of them are making Python acts differently depending on
the -O flag,

Here's an example on a randomly picked assert in the threading module:

>>>>>>>>>>>>>>>>>>>>>>>>
import threading

class test(threading.Thread):
    def __init__(self):
        self.bla = 1

    def run(self):
        print('running')

t = test()
print(t)
<<<<<<<<<<<<<<<<<<<<<<

The __repr__ method is not behaving the same way depending on the O flag:

$ python3 -O test.py
Traceback (most recent call last):
  File "test.py", line 12, in <module>
    print(t)
  File "/usr/local/lib/python3.2/threading.py", line 652, in __repr__
    if self._started.is_set():
AttributeError: 'test' object has no attribute '_started'

$ python3 test.py
Traceback (most recent call last):
  File "test.py", line 12, in <module>
    print(t)
  File "/usr/local/lib/python3.2/threading.py", line 650, in __repr__
    assert self._initialized, "Thread.__init__() was not called"
AttributeError: 'test' object has no attribute '_initialized'

$ python test.py
Traceback (most recent call last):
  File "test.py", line 12, in <module>
    print(t)
  File "/usr/lib/python2.6/threading.py", line 451, in __repr__
    assert self.__initialized, "Thread.__init__() was not called"
AssertionError: Thread.__init__() was not called
             <--- oops different error

$ python -O test.py
Traceback (most recent call last):
  File "test.py", line 12, in <module>
    print(t)
  File "/usr/lib/python2.6/threading.py", line 453, in __repr__
    if self.__started.is_set():
AttributeError: 'test' object has no attribute '_Thread__started'


I have seen some other places where thing would simply break with -O.

Am I right thinking we should do a pass on those and remove them or
turn them into exception that are triggered with -O as well ?

This flag is meant to "optimize generated bytecode slightly", but I am
not sure this involves also slightly changing the way the code behaves

Cheers
Tarek
-- 
Tarek Ziadé | http://ziade.org


More information about the Python-Dev mailing list