[openstack-dev] battling stale .pyc files

Mike Bayer mbayer at redhat.com
Fri Sep 12 15:18:09 UTC 2014


I’ve just found https://bugs.launchpad.net/nova/+bug/1368661, "Unit tests sometimes fail because of stale pyc files”.

The issue as stated in the report refers to the phenomenon of .pyc files that remain inappropriately, when switching branches or deleting files.

Specifically, the kind of scenario that in my experience causes this looks like this.  One version of the code has a setup like this:

   mylibrary/mypackage/somemodule/__init__.py

Then, a different version we switch to changes it to this:

   mylibrary/mypackage/somemodule.py

But somemodule/__init__.pyc will still be sitting around, and then things break - the Python interpreter skips the module (or perhaps the other way around. I just ran a test by hand and it seems like packages trump modules in Python 2.7).

This is an issue for sure, however the fix that is proposed I find alarming, which is to use the PYTHONDONTWRITEBYTECODE=1 flag written directly into the tox.ini file to disable *all* .pyc file writing, for all environments unconditionally, both human and automated.

I think that approach is a mistake.  .pyc files have a definite effect on the behavior of the interpreter.   They can, for example, be the factor that causes a dictionary to order its elements in one way versus another;  I’ve had many relying-on-dictionary-ordering issues (which make no mistake, are bugs) smoked out by the fact that a .pyc file would reveal the issue.    .pyc files also naturally have a profound effect on performance.   I’d hate for the Openstack community to just forget that .pyc files ever existed, our tox.ini’s safely protecting us from them, and then we start seeing profiling results getting published that forgot to run the Python interpreter in it’s normal state of operation.  If we put this flag into every tox.ini, it means the totality of openstack testing will not only run more slowly, it also means our code will never be run within the Python runtime environment that will actually be used when code is shipped.   The Python interpreter is incredibly stable and predictable and a small change like this is hardly something that we’d usually notice…until something worth noticing actually goes wrong, and automated testing is where that should be found, not after shipment.

The issue of the occasional unmatched .pyc file whose name happens to still be imported by the application is not that frequent, and can be solved by just making sure unmatched .pyc files are deleted ahead of time.    I’d favor a utility such as in oslo.utils which performs this simple step of finding all unmatched .pyc files and deleting (taking care to be aware of __pycache__ / pep3147), and can be invoked from tox.ini as a startup command.

But guess what - suppose you totally disagree and you really want to not have any .pyc files in your dev environment.   Simple!  Put PYTHONDONTWRITEBYTECODE=1 into *your* environment - it doesn’t need to be in tox.ini, just stick it in your .profile.   Let’s put it up on the wikis, let’s put it into the dev guides, let’s go nuts.   Banish .pyc files from your machine all you like.   But let’s *not* do this on our automated test environments, and not force it to happen in *my* environment. 

I also want to note that the issue of stale .pyc files should only apply to within the library subject to testing as it lives in its source directory.  This has nothing to do with the packages that are installed under .tox as those are full packages, unless there’s some use case I’m not aware of (possible), we don’t checkout code into .tox nor do we manipulate files there as a matter of course.

Just my 2.5c on this issue as to the approach I think is best.   Leave the Python interpreter’s behavior as much as “normal” as possible in our default test environment.


More information about the OpenStack-dev mailing list