1

In Question 2918898, users discussed how to avoid caching because modules were changing, and solutions focused on reloading. My question is somewhat different; I want to avoid caching in the first place.

My application runs on Un*x and lives in /usr/local. It imports a module with some shared code used by this application and another. It's normally run as an ordinary user, and Python doesn't cache the module in that case, because it doesn't have write permission for that system directory. All good so far.

However, I sometimes need to run the application as superuser, and then it does have write permission and it does cache it, leaving unsightly footprints in a system directory. Do not want.

So ... any way to tell CPython 3.2 (or later, I'm willing to upgrade) not to cache the module? Or some other way to solve the problem? Changing the directory permissions doesn't work; root can still write, root is all-powerful.

I looked through PEP 3147 but didn't see a way to prevent caching.

I don't recall any way to import code other than import. I suppose I could read a simple text file and exec it, but that seems inelegant and bug-prone.

The run-as-root is accomplished by calling the program with sudo in a shell script, and I can have the shell script delete the cache after the run, but I'm hoping for something more elegant that doesn't change the directory's last-modified timestamp.


Implemented solution, based on Wander Nauta's answer:

Since I run the executable as a plain filename, not as python executablename, I went with the environment variable. First, the sudoers file needs to be changed to allow setting environment variables:

tom     ALL=(ALL) SETENV: NOPASSWD: /usr/local/bkup/bin/mkbkup

Then, the invocation needs to include the variable:

/usr/bin/sudo PYTHONDONTWRITEBYTECODE=true /usr/local/bkup/bin/mkbkup "$@"
Community
  • 1
  • 1
Tom Zych
  • 13,329
  • 9
  • 36
  • 53
  • Possible duplicate of [How to avoid .pyc files?](https://stackoverflow.com/questions/154443/how-to-avoid-pyc-files) – Tom Zych Aug 08 '19 at 13:47

1 Answers1

3

You can start python with the -B command-line flag to prevent it from writing cached bytecode.

$ ls
bar.py  foo.py
$ cat foo.py 
import bar
$ python -B foo.py; ls
bar.py  foo.py
$ python foo.py; ls
bar.py  foo.py  __pycache__

Setting the PYTHONDONTWRITEBYTECODE environment variable to a non-empty string or the sys.dont_write_bytecode to True will have the same effect.

Of course, I'd say that the benefits in this case (faster loading times for your app, for free) vastly outweigh the perceived unsightliness you were talking about - but if you really want to disable caching, here's how.

Source: man python

Wander Nauta
  • 18,832
  • 1
  • 45
  • 62
  • 1
    Ah, I wish you'd posted the `sys.dont_write_bytecode` a little earlier. Would have spared me struggling with how to make `sudo` accept an environment variable. It works now. Will post details of what I did in the question for future reference. Thanks! – Tom Zych Sep 03 '15 at 11:19