Home > Software engineering >  os.rename does not raise FileExistsError when file exists
os.rename does not raise FileExistsError when file exists

Time:03-20

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))

CodePudding user response:

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))

CodePudding user response:

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.

  • Related