Fuze Test
Fuze Test

Reputation: 31

Writing to a file from python also adds additional characters to the last line

I have a python file named constants.py with the following contents

from pytestLoop.config.testdata_005_connect_for_bank_statements import *

xpath_username="//div[text()='"+uname+"']"
pswd="//div[@id='password']"

# this is the end of the file.

I have another python file called alterConstants.py with the following contents

def changeConstants(fname):
    f = open("pytestLoop/config/constants.py",'r+')
    line = f.read()
    text=(line[line.index('config.') + 7:line.index(' import')])
    linenew = line.replace(text, fname)
    f.seek(0)
    f.write(linenew)
    f.close()

changeConstants("testdata_001")

after i execute the above alterConstants.py file, this is the content of constants.py

from pytestLoop.config.testdata_001 import *

xpath_username="//div[text()='"+uname+"']"
pswd="//div[@id='password']"

# this is the end of the file.his is the end of the file.

my initial goal is to change the line from pytestLoop.config.testdata_005_connect_for_ban_statementsimport * to import whatever filename I pass in the changeConstants function in alterConstants.py which is working fine

but python also writes some additional characters to the last line of the constants.py file

  1. Can someone please explain why does this happen ?
  2. Also please suggest on How to fix this issue.

Thanks in advance.

Upvotes: 0

Views: 555

Answers (2)

ShadowRanger
ShadowRanger

Reputation: 155323

It's not writing extra characters, it's leaving behind the original characters from the older, larger file. You need to truncate the file to the new length to remove the extra content:

def changeConstants(fname):
    with open("pytestLoop/config/constants.py",'r+') as f:
        line = f.read()
        text = line[line.index('config.') + 7:line.index(' import')]
        linenew = line.replace(text, fname)
        f.seek(0)
        f.write(linenew)
        f.truncate()  # Trims file to match the current file offset

If the new file data is larger, the truncate doesn't do anything, but when the data is shorter, it trims the file down to match the file offset produced by writing the new data.

I also changed your code to use with to manage file lifetime (removing the need to explicitly close it, and guaranteeing it gets closed even if an exception occurs during processing).

Upvotes: 4

MisterMiyagi
MisterMiyagi

Reputation: 50076

Instead of seeking back to the start of the file (which leaves the old content intact), open the file again for writing.

def changeConstants(fname):
    with open("pytestLoop/config/constants.py",'r') as f:
        line = f.read()
    text=(line[line.index('config.') + 7:line.index(' import')])
    linenew = line.replace(text, fname)
    with open("pytestLoop/config/constants.py",'w') as f:
        f.write(linenew)

Opening a file in write mode automatically replaces the old content.

Upvotes: 1

Related Questions