Python fileinput: Keep file unchanged in case of exception

Question:

I have a program that uses Python 3 fileinput to replace some text within files in-place. Some files causes UnicodeDecodeError as I expect since they are non-readable/binary files, but when the exception occurs these files are completely emptied out from their content.

I can see the file content is moved to a .bak file and the original file is empty but after the exception the .bak file is removed and not written back into the original file.

for subdir, dirs, files in os.walk(currWorkingDir):
    for file in files:
        try:
            for line in fileinput.input(os.path.join(subdir, file), inplace=True, encoding='utf-8'):
                line = line.replace('XXX', 'x')
                print(line, end='')
        except UnicodeDecodeError as e:
            sys.stderr.write('binary file and should not be modified {}.n'.format(
                os.path.join(subdir, file)))
            fileinput.close()

I dont know all file types that would cause UnicodeDecodeError so I cant exclude these files from the loop with an if statement.
Is there a way to "do nothing" if exception occurs and keep the file as is?

Asked By: John Wicked

||

Answers:

Use a context manager for the fileinput. If an exception occurs, rename the backup file to the original filename.

for subdir, dirs, files in os.walk(currWorkingDir):
    for file in files:
        filename = os.path.join(subdir, file)
        try:
            with fileinput.input(filename, inplace=True, encoding='utf-8', backup='.bak') as fi:
                for line in fi:
                    line = line.replace('XXX', 'x')
                    print(line, end='')
        except UnicodeDecodeError as e:
            sys.stderr.write('binary file and should not be modified {}.n'.format(
                os.path.join(subdir, file)))
            # If an error occurs, revert to the backup file
            os.remove(filename)
            os.rename(filename + ".bak", filename)
Answered By: Barmar
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.