A few years ago I wrote a Django app for a client. One part of the app called os.getcwd()
, and another part (that I thought of as completely separate) used a temporary directory to build PDFs.
Occasionally the call to os.getcwd()
would raise an error. I was confused. How can there be no current directory? It took me a while to figure it out, but in hindsight it’s kind of obvious (as these things often are).
My PDF-building code created a temporary directory, set that directory to be the current working directory, and then removed the directory once the PDF was built. After that, there was no current working directory. It’s easy to demonstrate —
$ python3 Python 3.4.3 (v3.4.3:9b73f1c3e601, Feb 23 2015, 02:52:03) [GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> import os >>> import tempfile >>> temp_dir = tempfile.TemporaryDirectory() >>> os.chdir(temp_dir.name) >>> os.getcwd() '/private/var/folders/9f/4zptd_j10dx343w0r7tvkm0r0000gn/T/tmpfcwpe1xs' >>> temp_dir.cleanup() >>> os.getcwd() Traceback (most recent call last): File "", line 1, in FileNotFoundError: [Errno 2] No such file or directory >>>
I have a feeling I’m not the only developer who was foolish enough to assume that os.getcwd()
would never fail. At least now I know better, and you do too!
Funny you should post this today. I just pushed https://github.com/moreati/cloudabi-ports/blob/python/packages/python/patch-no-getcwd to disable os.getcwd() on CloudABI, a platform which has no concept of a working directory or even an absolute path 🙂
That’s one of the nice parts about working with a stripped-down environment like the one in CloudABI — fewer places to hide surprises.
I tried it in Python 3.5.1, and I can’t clean the temp folder anymore, while I am into it.
I an receiving an exception of ‘Permission Error’..
So maybe it’s was fixed in the past.
And maybe from now the os.getcwd() function will always work with no failure.
Hi bityon,
That’s interesting. On my Mac, Python 3.5.1 behaves the same way as 3.4.3 in this regard. Did you run your test on Windows, perhaps?
It could be differences in filesystem semantics. Linux is quite happy to rmdir() a directory while someone’s cd’d into it, Windows considers it an error (someone has the directory open). It probably stems from Unix vs. VMS file semantics (you used to be able to seriously corrupt a filesystem in VMS by using SET FILE to create multiple directory entries for the same file and then not being careful about exactly how you deleted them, because directory entries were NOT just references to an inode).
The problem isn’t that there’s no current directory. It’s that the current directory doesn’t have a path. It has been unlinked (deleted), so the inode exists, but isn’t linked into the filesystem.
In C, you get an ENOENT result. http://manpages.debian.org/cgi-bin/man.cgi?query=getcwd&apropos=0&sektion=0&manpath=Debian+8+jessie&format=html&locale=en
Thanks, Stefano, for the precise description of what’s actually going on. It makes sense now that you say it, but I would not have arrived at on my own.