Python: raise KeyError(key) from None


#!/usr/bin/env python3
import os
testing = os.environ['testing']

will generate:

Traceback (most recent call last):
  File "./", line 3, in <module>
    testing = os.environ['testing']
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/", line 669, in __getitem__
    raise KeyError(key) from None
KeyError: 'testing'

if the environment variable does not exist.


Instead use:

testing = os.environ.get('testing', 'False')

which lets you set a default.


Install multiple versions of Python


Ignore the top link on Google which takes you a process of using pyenv. It’s not until you’ve spent several hours painstakingly following the instructions that you find out it’s for some shell I’ve never used called Fish.

Just do:

  1. brew install python2
  2. brew install python3
  3. then to use Python 2, use python2 and for Python 3, use python3


i.e. DON’T DO:

  1. use pyenv
  2. make sure brew is up to date: brew update && brew upgrade pyenv
  3. pyenv install 3.7.2
  4. pyenv install 2.7.14
  5. Set the global version with pyenv global 3.7.2
  6. Set local versions (e.g. for legacy projects) with pyenv local 2.7.14



  • latest version of Python:
  • Blog post on pyenv:



ERROR: The Python zlib extension was not compiled. Missing the zlib?

brew install readline xz

did not work for me.

This worked though:

CFLAGS="-I$(xcrun --show-sdk-path)/usr/include" pyenv install -v 2.7.14






Python: how to concatenate strings when one is None


Use: print "Some URL: %s" % (some_url)

rather than: print("Some URL " + some_url)



Try to print out a variable that’s actually None rather than a string, e.g. with

print("Some URL " + some_url)

will result in:

Traceback (most recent call last):
File "", line 451, in 
lambda_handler(None, None)
File "", line 442, in lambda_handler
print("Some URL: " + some_url)
TypeError: cannot concatenate 'str' and 'NoneType' objects

Python should not be so dogmatic.

Why Python sucks &#8211; why I hate Python: a Python rant


You can do:

print("Some URL: ")

but that’s dodging the problem. It assumes that you’re aware of the potential bug before you code. Also, you end up with the text on two separate lines.


The solution is to use this syntax:

print "Some URL: %s" % (some_url)






Python: main

Breaking down the Python from

It’s installed with:

pip install awslogs --ignore-installed six


Files are packaged using a file. E.g.


Here’s a sample script (/usr/local/bin/awslogs – source code:


# -*- coding: utf-8 -*-
import re
import sys

from awslogs.bin import main

if __name__ == '__main__':
    sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])



Path to Python. No idea why there’s an @.

Side note: you should use a shebang like:

#!/usr/bin/env python3



# -*- coding: utf-8 -*-

Specifies the encoding.


import re
import sys

Imported as used later on. E.g. sys.argv[0]


from awslogs.bin import main

means: from the package awslogs.bin import the module main.

How does Python find these packages?

They’re in it’s path. E.g.

import sys
print '\n'.join(sys.path)


ls /usr/local/lib/python2.7/site-packages/awslogs*
__init__.pyc   _version.pyc   bin.pyc        core.pyc       exceptions.pyc

DESCRIPTION.rst  METADATA         WHEEL            metadata.json    top_level.txt
INSTALLER        RECORD           entry_points.txt pbr.json

What is this dist-info directory?

It’s created by Wheel – one of Python’s packaging formats. See:


the mainfunction is from awslogs/ here:


More on sys.path:


if __name__ == '__main__':

If run from the command line (e.g. python ) then __name__ will == '__main__'. Otherwise, if it’s been run as a module then __name__ will be the name of the module.


sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])




Python: getting rid of the ‘u’ symbol when outputting text

I find it really annoying that whenever Python prints a string it prints out a u when it’s Unicode.

When you copy and paste that stuff it retains it all. If you’re copying and pasting JSON you’re left with broken JSON. Here’s how to get rid of it:

data = json.dumps(d, ensure_ascii=False).decode('utf8')
print data


Python > Inspect an object


print dir(<my object>)

where <my object> is your object name.


dirreturns the list of names in the current local scope.


vars returns the __dict__attribute for a module, class or instance.


__dict__ is a dictionary or other mapping object used to store an object’s writable attributes.