2

I learned today that in python on windows, doing os.chdir('f:\\') is very different than doing os.chdir('f:'). The command with the trailing backslash actually changes the current directory. Without the backslash, the command is like typing f: in the command prompt, and changes the current directory to the last current directory on the f drive.

Here's an example:

import time
import os
if __name__ == '__main__':
    os.chdir('f:\\directory')
    print 'cwd is {}'.format(os.getcwd())
    os.chdir('d:\\directory')
    print 'cwd is {}'.format(os.getcwd())
    os.chdir('f:')
    print 'cwd is {}'.format(os.getcwd())
    os.chdir('f:\\')
    print 'cwd is {}'.format(os.getcwd())

prints

cwd is f:\directory
cwd is d:\directory
cwd is f:\directory
cwd is f:\

I can understand why this difference is useful, but couldn't find anything documenting this behavior. I'd gotten used to leaving trailing slashes off my directories as I usually use here strings...

Is this behavior documented anywhere? Can I rely on it not changing?

aggieNick02
  • 2,106
  • 1
  • 19
  • 29
  • 3
    This isn't a Python feature, it's a Windows feature. On Windows, each drive has its own working directory, so `F:` means the current working directory of the F drive, while `F:\\` means the root directory of the F drive. – abarnert Jul 19 '18 at 23:08
  • 1
    Also, it's not specific to `chdir`. If you `open('F:spam.txt')`, you get `spam.txt` on F's current working directory, but `open('F:\\spam.txt')` you get `spam.txt` on F's root directory. – abarnert Jul 19 '18 at 23:10
  • That is a Windows feature. And Python's documentation is meant to be cross-platform, so most details about the operating systems that it may run on are not discussed. – Rory Daulton Jul 19 '18 at 23:14
  • @abarnert: those 2 comments make a fine answer – especially the first one. (Apart from the "Can I rely on it not changing", I mean who can tell what Microsoft will break in their newly announced 'improved' console.) – Jongware Jul 19 '18 at 23:15

2 Answers2

6

This isn't a Python feature, it's a general Windows feature.

On Windows, every drive keeps track of its own current working directory. So really, "the current working directory" is the current working directory of the current drive.

  • chdir('F:') changes the drive to F, but doesn't change F's working directory, so you end up changing to the current directory of the F drive.

  • chdir('F:\\') changes the drive to F, and changes F's working directory to its root, so you end up changing to the root directory of the F drive.

It's also not specific to chdir. Any function that deals with pathnames, even open, will act this way.

*open('F:spam.txt') opens the file spam.txt in the F drive's current working directory (even if your current drive is, say, C). (This is consistent with the way DOS-style tools work.)

*open('F:\\spam.txt') opens the file spam.txt in the F drive's root directory.


Some cross-platform tools try to instead pretend the drives are top-level mount points, so cd F: is like cd /f/, and does go to the root of F. This has the advantage of making native Windows and Cygwin builds of your program work very similarly, but the disadvantage of making your program not work like traditional DOS-style programs. In general, more tools do things the way Python does—it gives you more flexibility, and is usually less confusing.


As you added in a comment:

Apart from the "Can I rely on it not changing", I mean who can tell what Microsoft will break in their newly announced 'improved' console.

Well, this behavior goes back to… I think PC-DOS 2.0, or whenever they first added directories. And if they ever were going to improve this, they'd presumably do it by getting rid of the drive-and-path for something either more flexible, or more POSIX-like. (Although UNC paths and \\.\… "raw" paths are already arguably both more flexible and more POSIX-like, and they didn't get rid of the drive-and-dir system when they added those in NT…)

abarnert
  • 313,628
  • 35
  • 508
  • 596
  • The cd f: comment is spot on. It did not occur to me to try, in a command prompt, cd f: to see that it does not change the cwd. I'm glad that os.chdir behaves differently than cd in the case that the argument is not for the current drive, because that would be incredibly frustrating... – aggieNick02 Jul 19 '18 at 23:33
4

The documentation mentions this behavior for another function in the same module. Its probably safe to assume that they will be handled the same way:

Note that since there is a current directory for each drive, os.path.join("c:", "foo") represents a path relative to the current directory on drive C: (c:foo), not c:\foo.

https://docs.python.org/3/library/os.path.html

However, the comment by abarnert is correct. The behavior is caused by how Windows interprets paths.

Anonymous
  • 10,924
  • 6
  • 31
  • 56