Thursday, November 30, 2017

python3 set literals in 3, 2, 1....


>>> {1,2}.add(3)
>>> {1}.add(2)
>>> {}.add(1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'dict' object has no attribute 'add'


why no empty set literal:
https://mail.python.org/pipermail/python-3000/2006-April/001286.html
https://mail.python.org/pipermail/python-3000/2006-May/001666.html

Wednesday, November 29, 2017

a __main__ by any other __name__

$ 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__')






UnicodeDecode SyntaxError

When executing a bytecode for the '+' operation, an invalid byte will raise UnicodeDecodeError.  However, when concatenating adjacent string and unicode constants, it will be a SyntaxError.  (I guess because there is not byte-code executing this is happening at compile time.)

>>> u'a' + '\xff'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xff in position 0: ordinal not in range(128)


>>> u'a' '\xff'
  File "<stdin>", line 1
SyntaxError: (unicode error) 'ascii' codec can't decode byte 0xff in position 0: ordinal not in range(128)