Code Journal

Combined Stream

8 thoughts
last posted July 28, 2016, 4:04 p.m.
get stream as: markdown or atom
Sign Up

On the prompting of Jason Myers, I'm going to try my best to keep a journal of little code puzzles and improvements that I make in the course of writing and maintaining open source code in my never ending search for higher quality code.


Recently, I've been doing a lot of work prepping a relaunch of django-stripe-payments, renamed along the way to pinax-stripe.

In this process, I have gone down the rabbit hole of trying all kinds of static analysis things to help inform and drive quality up.


A recent thing that Jason brought to my attention today was bandit. So without delay, I installed and ran it with defaults against pinax-stripe. It reported three issues that previous static analyzers failed to point out:

Run metrics:
    Total lines of code: 2547
    Total lines skipped (#nosec): 0
    Total issues (by severity):
        Undefined: 0.0
        Low: 3.0
        Medium: 0.0
        High: 0.0
    Total issues (by confidence):
        Undefined: 0.0
        Low: 0.0
        Medium: 0.0
        High: 3.0

All three issues were cases of using pass in a try/except block.


The full details of my fixes can be found in this commit.

I'd like to point the fixes individually though as well:

The first example was just a case of reversing the logic so that I only re-raise the exception if it's not the thing we want to ignore. No wizardry there.

The next fix is probably one of my favorite tricks. Often you want to effectively retrieve a single object or return None. It's ok if it doesn't exist and if multiple exist you just need the first one. You can either write a queryset check the count or exists before indexing into it, or wrap a get in a try/except (which is what I originally had in this case), or you can use next and iter do things in a single line and single query. In this example, it was:

customer = next(iter(queryset)), None)

Then you can check if the customer is None and act on it accordingly.

The third fix was simply checking for the existence of the field name in a way that wouldn't raise an exception. In this specific case, I want to add the ability to search by a user's email if the user model in question has an email field like the default django.contrib.auth.User has.

In the fourth and last fix I simply needed to use the .get() method on the response object then I could avoid needing to worry about the KeyError all together.


I'm gonna use this to publish some random things I encounter in my dev work.


Always run git clean -fdx prior to creating a Python release to eliminate possibility of unknown bits getting including in your package.

Discovered a file I had deleted from a previous release laying around in a build/ directory that was getting shipped with subsequent releases somehow, but only in the wheel releases, not the standard sdist.


Setting up my Ubuntu Dev environments

  1. Install Ubuntu (Whatever flavor you like)
  2. sudo apt-get upgrade && sudo apt-get upgrade
  3. Copy over SSH keys
  4. chmod 600 .ssh/*
  5. sudo apt-get install emacs git vim make gnome-tweak-tool curl build-essential libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev wget llvm libncurses5-dev
  6. Run Tweak Tool -> Click Typing -> set Caps Lock key behavior to "Make Caps Lock an additional Ctrl" -> set Alt/Win key behavior to "Alt and Meta are on Alt keys"
  7. Setup Firefox Sync
  8. Copy down dotfiles: git clone
  9. cd dots
  10. ./
  11. rm .emacs.d
  12. Copy down emacs dotfiles: git clone .emacs.d
  13. Setup pyenv: curl -L | bash
  14. Setup pyenv-virtualenvwrapper: git clone ~/.pyenv/plugins/pyenv-virtualenvwrapper
  15. Install Python 2.7.11: pyenv install 2.7.11
  16. Install Python 3.5.1: pyenv install 3.5.1
  17. Install nvm: curl -o- | bash
  18. Download the lastest version of Go from
  19. Install Go: sudo tar -C /usr/local -xzf go1.5.2.linux-amd64.tar.gz
  20. Install Rust: curl -sSf | sh
  21. Download Hack Font:
  22. Install Hack Font: cd ~/Downloads && unzip && mv *.ttf ~/.fonts/ && fc-cache
  23. Setup go-mode: mkdir -p ~/Misc/emacs && cd ~/Misc/emacs && git clone 24 Open emacs, it will compile for a while and end in an error about go auto loads
  24. Run M-x update-file-autoloads, Use "~/Misc/emacs/go-mode.el/go-mode.el" as the first answer, and "~/Misc/emacs/go-mode.el/go-mode-el.load" as the autoloads files
  25. Exit and Save emacs
  26. Install goimports: go get
  27. Install oracle: go get && sudo mv $GOPATH/bin/oracle $GOROOT/bin/
  28. Setup emacs for rust: git clone /tmp/racer && cd /tmp/racer && cargo build --release && mv /tmp/racer/target/release/racer /usr/local/bin && cd ~ && rm -rf /tmp/racer
  29. Download rust source for autocompletion: git clone ~/.rust
  30. Test it with: racer complete std::io::B

In Django forms, you can either use exclude or fields to list a set of fields to exclude or include on the ModelForm.

I prefer to use fields to explicitly include fields on a form because it's easy to add fields to a model without thinking through it's use on a form somewhere in your project. However, if you are adding a field for the purpose of adding it to a form you'll have the form in mind so explicitly adding the field to the fields list will not be forgotten about.