View README.md

When are Python circular imports fatal?

In your Python package, you have:

  • an __init__.py that designates this as a Python package
  • a module_a.py, containing a function action_a() that references an attribute (like a function or variable) in module_b.py, and
  • a module_b.py, containing a function action_b() that references an attribute (like a function or variable) in module_a.py.

This situation can introduce a circular import error: module_a attempts to import module_b, but can't, because module_b needs to import module_a, which is in the process of being interpreted.

But, sometimes Python is magic, and code that looks like it should cause this circular import error works just fine!

View git-branch-simplify.md

Ideas for improvements to git log --graph

I will maybe someday get around to dusting off my C and making these changes myself unless someone else does it first.

Make the graph for --topo-order less wiggly

Imagine a long-running development branch periodically merges from master. The git log --graph --all --topo-order is not as simple as it could be, as of git version 1.7.10.4.

It doesn't seem like a big deal in this example, but when you're trying to follow the history trails in ASCII and you've got several different branches displayed at once, it gets difficult quickly.

View ergodox.md

My ErgoDox Keyboard

I spent a lot of money ($236) on a computer keyboard. A computer keyboard that you can only buy a couple times per year, that you can't purchase in any store, which took three months to arrive after I placed the order, that I had to painstakingly solder together myself.

The design is called the [ErgoDox][]. [Massdrop.com][] has periodic group-buying events where they solicit buyers for all the parts, as a cost savings measure. If you were to order in small quantities through electrionics retailers like digikey.com or mouser.com to build for yourself a single keyboard, the cost could be above $500.

I had been noodling around for a while on my own design for "the perfect keyboard" with very slow success, as I have very little experience with electronics. But, thanks to the recent "maker" movement the field of printed circuit board manufacturing is becoming more accessible to hobbyists, so I was giving it a go. Despite not getting very far into a design, I still managed to take down lots

View gist:2199506

Virtualenv's bin/activate is Doing It Wrong

I'm a Python programmer and frequently work with the excellent [virtualenv][] tool by Ian Bicking.

Virtualenv is a great tool on the whole but there is one glaring problem: the activate script that virtualenv provides as a convenience to enable its functionality requires you to source it with your shell to invoke it. The activate script sets some environment variables in your current environment and defines for you a deactivate shell function which will (attempt to) help you to undo those changes later.

This pattern is abhorrently wrong and un-unix-y. activate should instead do what ssh-agent does, and launch a sub-shell or sub-command with a modified environment.

Problems

View README.md

I agree with Guido, in that I think

[ x * 2 for x in some_list if x < 12 ]

is much easier to read than the equivalent

map(lambda x:x * 2, filter(lambda x:x<12, some_list))
View git-serve.md

Launch a one-off git server from any local repository.

I [tweeted this already][1] but I thought it could use some expansion:

Enable decentralized git workflow: git config alias.serve "daemon --verbose --export-all --base-path=.git --reuseaddr --strict-paths .git/"

Say you use a git workflow that involves working with a core "official" repository that you pull and push your changes from and into. I'm sure many companies do this, as do many users of git hosting services like Github.

Say that server, or Github, goes down for a bit.

View vendoring.md

"Vendoring" is a vile anti-pattern

What is "vendoring"?

From a comment on StackOverflow:

Vendoring is the moving of all 3rd party items such as plugins, gems and even rails into the /vendor directory. This is one method for ensuring that all files are deployed to the production server the same as the dev environment.

The activity described above, on its own, is fine. It merely describes the deployment location for various resources in an application.

View README.md

When you cancel a Jenkins job

Unfinished draft; do not use until this notice is removed.

We were seeing some unexpected behavior in the processes that Jenkins launches when the Jenkins user clicks "cancel" on their job. Unexpected behaviors like:

  • apparently stale lockfiles and pidfiles
  • overlapping processes
  • jobs apparently ending without performing cleanup tasks
  • jobs continuing to run after being reported "aborted"
View object_comprehensions.md

Object comprehensions in CoffeeScript

This is a literate CoffeeScript file: save it, rename it with a .litcoffee extension, and you can execute it with coffee.

Motivation

Python 2.7 has nice dictionary comprehensions:

# result = {n: n**2 for n in range(5)}
View mutt-ldap.py
#!/usr/bin/python
'''This is a python port of http://www.bsdconsulting.no/tools/mutt-ldap.pl
'''
import ldap
# To do:
# - encode search string as UTF-8