I have the following code:
import os
import signal
import time
class mre:
def __init__(self) -> None:
self.fd = None
def write_file(self):
with open("mre.log","w") as f:
self.fd = f
print("writing to file")
while True:
time.sleep(0.1)
f.write("hello")
def signal_handler(self, sig, frame):
#delete the file
try:
#self.fd.close()
os.remove("mre.log")
print("file closed")
except Exception as err:
print("exception raised")
raise err
def main(self):
signal.signal(signal.SIGINT, self.signal_handler)
self.write_file()
if __name__ == "__main__":
temp = mre()
temp.main()
Question 1:
I am unable to understand the program flow. When I run the program (Linux OS) and hit Ctrl+C, signal_handler() is called, and the file is removed, but the program is not terminated until I hit Ctrl+C again.
Here is the output (yt is a virtualenv):
(yt) LAPTOP-28TNND21% echo $0
/usr/bin/zsh
(yt) LAPTOP-28TNND21% python --version
Python 3.8.10
(yt) LAPTOP-28TNND21% python mre.py
writing to file
^Cfile closed
^Cexception raised
Traceback (most recent call last):
File "mre.py", line 34, in <module>
temp.main()
File "mre.py", line 30, in main
self.write_file()
File "mre.py", line 15, in write_file
time.sleep(0.1)
File "mre.py", line 26, in signal_handler
raise err
File "mre.py", line 22, in signal_handler
os.remove("mre.log")
FileNotFoundError: [Errno 2] No such file or directory: 'mre.log'
(yt) LAPTOP-28TNND21%
To understand the problem better, I commented the line os.remove("mre.log") in my code. Now every time I hit Ctrl+C, signal_handler is called, and I don't know what happens to control flow and the situation is an infinite loop that never stops until I kill the process.
Here is the output:
(yt) LAPTOP-28TNND21% echo $0
/usr/bin/zsh
(yt) LAPTOP-28TNND21% python --version
Python 3.8.10
(yt) LAPTOP-28TNND21% python mre.py
writing to file
^Cfile closed
^Cfile closed
^Cfile closed
^Cfile closed
^Cfile closed
^Cfile closed
^Cfile closed
^Cfile closed
^Cfile closed
^Cfile closed
^Cfile closed
I would like to understand the program flow or control flow.
Question 2:
I did run the same program on Windows as well and I get a completely different error. Here is the error (using PowerShell as terminal):
(venv) PS D:\Downloads\testing-main\src> $PSVersionTable.PSVersion
Major Minor Build Revision
----- ----- ----- --------
5 1 22621 436
(venv) PS D:\Downloads\testing-main\src> python --version
Python 3.9.1
(venv) PS D:\Downloads\testing-main\src> python mre.py
writing to file
exception raised
Traceback (most recent call last):
File "D:\Downloads\testing-main\src\mre.py", line 34, in <module>
temp.main()
File "D:\Downloads\testing-main\src\mre.py", line 30, in main
self.write_file()
File "D:\Downloads\testing-main\src\mre.py", line 15, in write_file
time.sleep(0.1)
File "D:\Downloads\testing-main\src\mre.py", line 26, in signal_handler
raise err
File "D:\Downloads\testing-main\src\mre.py", line 22, in signal_handler
os.remove("mre.log")
PermissionError: [WinError 32] The process cannot access the file because it is being used by another process: 'mre.log'
(venv) PS D:\Downloads\testing-main\src>
When the signal_handler is called, the program would have exited the with block, which means that the file should be closed. But based on the error, it is not closed. I would like to know why is the file not closed?
My Assumption:
Since, the file is not closed I assume that with block is not exited meaning that, when the signal_handler is called and finishes execution, the program control returns to with block, which I don't completely understand.