Search code examples
pythonpython-3.xoperating-systemfilepath

Making username-independent os.rename


I was making a module for my friend, which knows of basically nothing on the coding side of things, so I had a setup.py which will put things from the download folder to the folders the projects need to be in. However, my friend does not know their computer username, so I used os.getlogin(), but when I try to put the variable I assigned the value to into the file paths, it gives multiple errors.

Here is my current code:

import os

user = os.getlogin()

os.rename(r"C:\Users\"" + user + "\FILEPATH\FILEPATH\FILENAME", r"C:\Users\"" +
         user +"\FILEPATH\FILEPATH\FILENAME")

Solution

  • In your code r"C:\Users\"" is problematic.

    >>> path_prefix
    'C:\\Users\\"'
    

    From the documentation:

    Even in a raw literal, quotes can be escaped with a backslash, but the backslash remains in the result; for example, r"\"" is a valid string literal consisting of two characters: a backslash and a double quote; r"\" is not a valid string literal (even a raw string cannot end in an odd number of backslashes). Specifically, a raw literal cannot end in a single backslash (since the backslash would escape the following quote character). Note also that a single backslash followed by a newline is interpreted as those two characters as part of the literal, not as a line continuation.

    You can combine f-strings with raw strings in order to avoid the issue you're encountering:

    import os
    
    user = os.getlogin()
    
    os.rename(
        fr"C:\Users\{user}\old\path",
        fr"C:\Users\{user}\new\path",
    )
    

    You could also use os.path.expanduser to get the user's home directory:

    import os
    
    home = os.path.expanduser("~")
    
    os.rename(
        fr"{home}\old\path",
        fr"{home}\new\path",
    )
    

    Having said that, using os.path.join appears to be a more appropriate way to join paths while avoiding concatenation with the + operator and dealing with raw strings and/or backslashes:

    import os
    
    home = os.path.expanduser("~")
    
    os.rename(
        os.path.join(home, "old", "path"),
        os.path.join(home, "new", "path"),
    )