$ cat <<EOF > what_is_happening.py
if __name__ == "__main__":
import what_is_happening
else:
print("what is happening?")
EOF
$ python what_is_happening.py
what is happening?
Ambiguous entrypoints can create a maze of state in your program. In case the above example doesn't seem so bad, lets make it worse.
$ cat <<EOF > innocent_bystander.py
import what_is_happening
def func(): raise what_is_happening.TrustFall('catch me!')
EOF
$ cat <<EOF > what_is_happening.py
import innocent_bystander
class TrustFall(Exception): pass
if __name__ == "__main__":
try:
innocent_bystander.func()
except TrustFall:
print("gotcha!")
except Exception as e:
print('oops, butterfingers!')
print('{} is not {}.... what have I done?'.format(
type(e), TrustFall))
EOF
$ python what_is_happening.py
oops, butterfingers!
<class 'what_is_happening.TrustFall'> is not <class '__main__.TrustFall'>.... what have I done?
What happened? This is executing the main module twice, a special case of double import.
One solution is to put import guards in all entrypoint scripts:
if __name__ != "__main__":
raise ImportError('double import of __main__')
No comments:
Post a Comment