Dealing With Pyc Files When Working With Git.
Python developers are familiar with the fact that Python automatically generates a byte code from the
.py file, which is executed by the interpreter. This byte code is stored in a
.pyc file, usually in the same directory of its respective source file. The
.pyc generation can happen either when the main Python script is being executed or when a module is imported for the first time.
As an example, in many Python web frameworks when we create a
views.py, a file containing the logic for our views, we will most probably get a
views.pyc file in the same directory after running an instance of our application.
As developers, we often work with big codebases utilizing Git, and on projects with many developers in teams. This means a bunch of features are being developed at the same time, and thus we have to switch branches frequently to pair with other developers, or to review and test someone’s code. Depending on the differences between two branches, we can end up with
.pyc files from the other branch, which can lead to unexpected behaviors.
Git is a well known source code management tool which cleverly provides hooks, a way to fire custom scripts when certain important actions occur. We can include hooks to the most used actions, like before or after committing, pushing, rebasing, merging, and similar.
One of the available hooks is a “post-checkout” hook, which is fired after we checkout another branch or specific commit. We can include our code to clean the
.pyc files in the “post-checkout” hook. All Git projects have
.git folder in the project’s root and from there we just need to edit (or create new) file
.git/hooks/post-checkout, by adding the following code:
#!/bin/sh find . -type f -name "*.py[co]" -delete find . -type d -name "__pycache__" -delete
This is for Linux and Mac. On Windows, first we need to install Cygwin, so Git can execute the hook scripts as shell. Then we need to change the commands a little bit:
#!/bin/sh find . -type f -name "*.py[co]" | xargs rm find . -type d -name "__pycache__" | xargs rm -rf
When the Python interpreter is invoked with the
-O flag, optimized code is generated and stored in
.pyo files. For that reason, our command checks for
.pyo files and removes them (
*.py[co]). Python 3 stores its compiled bytecode in
__pycache__ directories, so we included a command that will remove them as well.
In the end, after saving our hook file on Linux and Mac, we need to make sure we add execution permissions to it:
$ chmod +x .git/hooks/post-checkout
Freelance Python Developer
Ivan is an engineer with eight years of experience in software and web development. Primarily focused on the web, he has solved code optimization problems arising from growing systems, as well as the migrated production apps and services on-the-fly with zero downtime. While a major part of his experience has been on the back-end, he can also work with the front-end, databases, networking, and infrastructure.Show More