Best way to avoid stale *.pyc files?

Another solution would be imp.reload(). I think in 2.7 you can do the following (will check later)

>>> import sys
>>> reload(sys)
  <module 'sys' (built-in)>
>>>

The disadvantage of this method is that versions of your *.pyc files would still be on the repository and updated every time there is a commit. However it would safeguard you from stale versions of *.pyc.

Another solution would be to make git ignore *.pyc files as well as delete them. Another solution would be to ignore the pycache directory. From the book by Mark Lutz:

In 3.2 and later, Python instead saves its .pyc byte code files in a subdirectory named pycache located in the directory where your source files reside, and in files whose names identify the Python version that created them (e.g., script.cpython-33.pyc). The new pycache subdirectory helps to avoid clutter, and the new naming convention for byte code files prevents different Python versions installed on the same computer from overwriting each other’s saved byte code.


There is a useful environment variable for that: PYTHONDONTWRITEBYTECODE

export PYTHONDONTWRITEBYTECODE=true

Similar to khampson, git and mercurial (and likely others) allow client side hooks. You can sprinkle around scripts that do

find -iname "*.pyc" -exec rm -f {} \; 

on linux at least. Search "git hooks" and "mercurial hooks" for more details.


I would recommend a combined approach.

First, add *.pyc to your .gitignore file, which should help to avoid issues when switching branches (at least for cases where the cause is that a .pyc file somehow got committed). I generally always add both *.pyc and *.log to my .gitignore so as not to potentially commit any of those files accidentally, and so they don't clutter my git status output.

Second, create a wrapper shell script which first removes all .pyc files (recursively if your source directory structure calls for it) and then invokes your actual script. That should ensure any resulting .pyc files are newly created using the current source.

i.e. something like (without the & if you want the script to wait):

#!/bin.sh
rm -f *.pyc
./foo.py &