'os.rename does not raise FileExistsError when file exists

I have a file_rename mechanism which I want to improve with a simple try/except block that will check if the renamed file does already exists in the directory.

I prepared in my directory 2 files: data.txt and old_data.txt. Function should throw an exception, as old_data.txt already exists, which implies that data was processed in the past.

However, the below code is not working, as it is still renaming the data.txt file. I'd appreciate any assistance and guidance on this.

@staticmethod
def file_rename(file, dir):
    source_file_new_name = "old_" + file
    try:
        os.path.isfile(dir + source_file_new_name)
        os.rename(os.path.join(dir, file), os.path.join(dir, source_file_new_name))
    except FileExistsError:
        raise FileExistsError("this file was already processed")

With Rafał's and BrokenBenchmark hint I came up with below version but not sure if its enough pythonic ;)

class FileExistsError(Exception):
    pass

@staticmethod
def file_rename(file, dir):
    source_file_new_name = "old_" + file

    if os.path.isfile(dir + source_file_new_name):
        raise FileExistsError("this file was already processed!")
    else:
        os.rename(os.path.join(dir, file), os.path.join(dir, source_file_new_name))


Solution 1:[1]

os.path.isfile method just returns True (if a file exists) or False (if it doesn't). Use an if statement to check its result before calling os.rename.

Solution 2:[2]

Your code assumes that os.rename will raise a FileExistsError. That assumption can only be made if the code is being run on Windows. The Python docs for os.rename() state:

os.rename(src, dst, *, src_dir_fd=None, dst_dir_fd=None)

Rename the file or directory src to dst. If dst exists, the operation will fail with an OSError subclass in a number of cases:

On Windows, if dst exists a FileExistsError is always raised.

On Unix, ... [i]f both [src and dst] are files, dst it [sic] will be replaced silently if the user has permission.

To resolve this issue, use an if statement with .isfile() instead, rather than relying on a try/except that hinges on behavior that isn't portable in order to work:

def file_rename(file, dir):
    source_file_new_name = "old_" + file
    if os.path.isfile(os.path.isfile(dir + source_file_new_name)):
        os.rename(os.path.join(dir, file), os.path.join(dir, source_file_new_name))

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2