
On Nov 19, 2019, at 09:51, Soni L. fakedme+py@gmail.com wrote:
I still feel like opening the file but delaying the exception would be more beneficial and have better semantics. It allows cd, mv, rm, etc to happen without any surprising semantics, and fits the model you want it to fit.
Well, without any surprising semantics as long as you only care about POSIX or only care about Windows. Writing code that makes sense on both platforms (so rm will either work and leave my file handle open, or raise an exception so I have to remember to delete on close and that may possibly fail; the only thing I know is that it won’t work and make my open fail, although my open might have failed anyway for different reasons…) is pretty hard.
Also, this leads to surprising semantics in other cases:
f1 = open(fn1) f2 = open(fn2, 'w')
Any existing code that does this almost certainly expects that it’s not going to create or truncate a file at fn2 if there’s no file at fn1, but that would no longer be true.
And you’d expect that putting f1 and f2 into a with statement would solve that, but it would actually make things worse: f1.__enter__ raises, so f2.__enter__ never gets called, so fn2 still gets created or truncated, and on top of that we leak a file handle.
The only way to fix this is to move the open itself into a with statement—just like in Python 3.8, so we haven’t gained anything.
Moving the actual open to __enter__, on the other hand, does solve the problem; no matter how you write things, fn2 will never be entered, so no file will be created or truncated and no fd will get leaked.