-
-
Notifications
You must be signed in to change notification settings - Fork 30.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Warn when files are not explicitly closed #54302
Comments
This patch outputs a warning on file deallocation when it hasn't been explicitly closed by the programmer. Printing the warning by default is probably not desirable, but using the patch for "-X" options in bpo-10089 would allow to switch on when necessary. |
By the way, python-dev discussion was here: The rough consensus seems to be that there should be a command-line option to enable it, but to enable it by default with pydebug. |
If the warnings are emitted as usual with the warnings module, you can use -W to control this. -X isn't necessary. |
Right. Perhaps we can add a new warning category (e.g. ResourceWarning), or simply reuse RuntimeWarning. |
+1 for RuntimeError. |
RuntimeWarning you mean? I don't think anyone is suggesting making it an error. |
2010/10/13 Alex <report@bugs.python.org>:
Indeed. |
There is a slight issue with warnings, and that's the filtering by module/location. Since these warnings will occur in destructors, they can appear at any point without being related to the code being executed. The "default" filtering method (print the first occurrence of matching warnings for each location where the warning is issued) then is not appropriate; therefore I suggest a separate warning category (ResourceWarning?) for which people can enable different rules. |
Does this work also for sockets? |
Not with the current implementation. I guess this could be added, but then I would have to make the warning method ("_dealloc_warn") public on IO classes. |
Here is an updated patch using warnings (RuntimeWarning for now) and also warning about unclosed sockets. |
Here is a patch adding ResourceWarning, adding new tests, and fixing failures in existing tests. |
I committed the test fixes to py3k, so here is an updated patch. |
Please add a similar warning in PC/_subprocess.c::sp_handle_dealloc() This ad-hoc fix would suppress the warning: |
Do you want to provide a patch? |
After thinking about what warning to go with, I take back my python-dev suggestion of ResourceWarning and switch to DebugWarning. It is in fact harder to add in DebugWarning as a superclass to ResourceWarning than the other way around, especially once people start doing custom filters and decide that DebugWarning should not be filtered as a whole but ResourceWarning should (or some such crazy thing). |
So what is your advice now? |
On Fri, Oct 22, 2010 at 12:49, Antoine Pitrou <report@bugs.python.org> wrote:
That's true. And the warning hierarchy is rather shallow anyway. I'm |
I wonder why you think a warning is needed if files aren't closed explicitly. The fact that they get closed on garbage collection is one of the nice features of Python and has made programming easy for years. Explicitly having to close files may have some benefits w/r to resource management, but in most cases is not needed. I disagree that we should discourage not explicitly closing files. After all, this is Python, not C. |
But this is meant to be an optional warning; users will never see it. Me as a developer, I would like to know when I leave a file open as that is a waste of resources, plus with no guarantee of everything being flushed to disk. Besides, the context manager for files makes the chance of leaving a file open a much more blaring mistake. |
I would need opinions on one more thing. The current patch warns when a socket has not been explicitly closed. But it does so even when the socket isn't bound at all. e.g.: $ ./python -c "import socket; socket.socket()"
-c:1: ResourceWarning: unclosed <socket.socket object, fd=3, family=2, type=1, proto=0> Perhaps we should be more discriminate and only warn when either bind(), listen() or connect() had been called previously? What do you think? |
If a new, unbound socket uses some form of OS resource, then a warning is needed. Is their an equivalent limitation like there is with file descriptors as to how many an OS can possibly have open at once? |
A socket *is* a file descriptor (under Unix), so, yes, there is a limit. |
That's what I thought. So if socket.socket() alone is enough to consume an fd then there should be a warning. |
Brett Cannon wrote:
That's what I'm referring to: most Python applications are That's a perfectly fine way of writing Python applications,
See above: context aren't required for working with files. And again: The same applies for sockets. Think of the simple idiom: data = open(filename).read() This would always create a warning under the proposal. Same for: for line in open(filename):
print line Also note that files and sockets can be kept as references in data If you want to monitor resource usage in your application it |
Some people would disagree, especially Windows users who cannot timely
Again: it is an *optional* warning. It is *disabled* by default, except
It is *definitely* a mistake if the socket has been bound to a local
We have had many Windows buildbot failures because of such coding style.
Agreed it would be useful as well, but please tell that to operating |
Here is an updated patch (also fixes a small refleak). |
I've committed the patch in r85920; let's watch the buildbots. Also, you'll see many warnings in the test suite if compiled --with-pydebug. |
Antoine Pitrou wrote:
There is no difference here: Whether you write an application with automatic closing of The only difference is with Python implementations that don't
Yes, I know. I still find the warning rather useless, since it
I don't follow you. Where's the difference between writing: s.close()
or
s = None for an open socket s ?
Again: where's the difference between writing: data = open(filename).read()
and
f = open(filename)
data = f.read()
f.close() ? If the above coding style causes problems, the reasons must be The for-loop file iterator support was explicitly added to make for line in open(filename):
print line possible.
At least for Linux, that's not hard and I doubt it is for other OSes. 4 On other Unixes, you can simply use fcntl() to scan all possible FDs On Windows you can use one of these functions for the same effect: |
No, because objects can be kept alive through tracebacks (or reference
The difference is when s is still referenced elsewhere.
So what?
Until you post some code I won't understand what you are talking about. |
Antoine Pitrou wrote:
If you get a traceback, the explicitly file.close() won't help
Sure, but that's not the point. It is not a mistake to write If the application keeps references to the objects in other
The warning will trigger without any reason.
RoundUp's email interface ate the code. I'll post it again via the |
Reposted via the web interface:
At least for Linux, that's not hard and I doubt it is for other OSes. >>> import os
>>> nfds = len(os.listdir('/proc/%i/fd' % os.getpid()))
>>> print nfds
4 On other Unixes, you can simply use fcntl() to scan all possible FDs On Windows you can use one of these functions for the same effect: |
Well, by now you should have understood the reason, so I conclude that This is my last answer to you on this topic. Goodbye. |
Antoine Pitrou wrote:
Ignoring your insults, I think the problem is that you fail to see Warnings in Python are meant to tell programmers that something Note that you've just added warning filters to the test suite A truely useful ResourceWarning would trigger if resources gets |
The buildbots showed no major issue, so this issue is now resolved. The warnings expose a lot of issues in the stdlib that deserve addressing, though ;) |
2010/10/29 Marc-Andre Lemburg <report@bugs.python.org>:
>
> Marc-Andre Lemburg <mal@egenix.com> added the comment:
>
> Antoine Pitrou wrote:
>>
>> Antoine Pitrou <pitrou@free.fr> added the comment:
>>
>>> The warning will trigger without any reason.
>>
>> Well, by now you should have understood the reason, so I conclude that
>> you are either 1) deaf 2) stupid 3) deliberately obnoxious.
>>
>> This is my last answer to you on this topic. Goodbye.
>
> Ignoring your insults, I think the problem is that you fail to see
> point or address it:
>
> Warnings in Python are meant to tell programmers that something
> should be fixed. The warnings in the examples I gave do not point
> to cases that need to be fixed, in fact, they are very common
> idioms used in Python books, examples and tutorials. They're not particularly good idioms then. Leaving files open |
MAL wrote:
> Antoine wrote:
>> MAL wrote:
>>> I don't follow you. Where's the difference between writing:
>>>
>>> s.close()
>>> or
>>> s = None
>>>
>>> for an open socket s ?
>>
>> The difference is when s is still referenced elsewhere.
>> Also, the intent of the former is clear while the latter is deliberately
>> obscure (while not saving any significant amount of typing).
>
>Sure, but that's not the point. It is not a mistake to write
>such code and neither is this obscure, otherwise we'd also
>require explicit garbage collection for other parts of Python. Yes it is a mistake: In an earlier message MAL wrote:
This by definition makes it non-equivalent and a bad *Python* idiom, |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: