Home > Software design >  Why do some os functions ignore trailing spaces on Windows?
Why do some os functions ignore trailing spaces on Windows?

Time:12-28

I've tried the example program below on both Windows and Linux with Python 3.11.0.

import os

if __name__ == "__main__":
    directory_name = "foo "
    file_name = "bar.txt"
    os.mkdir(directory_name)
    print(os.path.exists(directory_name))
    out_path = os.path.join(directory_name, file_name)
    try:
        with open(out_path, "w") as bar_file:
            pass
        print(f"Successfully opened {repr(out_path)}.")
    except FileNotFoundError:
        print(f"Could not open {repr(out_path)}.")
    print(os.listdir())

The output on Linux is what I expected:

True
Successfully opened 'foo /bar.txt'.
['foo ']

However, on Windows, I get the output below.

True
Could not open 'foo \\bar.txt'.
['foo']

It seems like os.mkdir and os.path.exists are ignoring the trailing space in the directory name, but os.path.join is not.

Why do these methods behave this way on Windows? Is the behavior intentional? Moreover, what is the best way to overcome this discrepancy and get the same behavior on both systems?

CodePudding user response:

On Windows, trailing spaces are generally allowed, but they may be automatically trimmed in some contexts.

The observed behavior is likely due to the underlying implementation of these functions in the operating system. The os.mkdir function and os.path.exists function may be using the Windows API function CreateDirectory, which ignores trailing spaces (see remarks in that hyperlink) in the directory name when creating a new directory. The os.path.join function, on the other hand, may be using string manipulation to concatenate the directory name and file name, which does not automatically trim the trailing space. You may consider browsing os source code to be certain of the later part.

To get consistent behavior on both Windows and Linux, you can trim any trailing spaces from the directory name before using it in these functions. (using rstrip for example):

directory_name = directory_name.rstrip()

  • Related