This is Episode 4 of The Vibe Coder’s Guide to the Machine: computer science for a new generation.
Deleting a file removes its name, and a download that already has the file open can still finish reading it. A thing and its name end separately, and so do most things a running program makes: each is ended by a particular owner, on a particular event. That makes the useful question not whether something has stopped but who ends each thing, and by what event. In a folder you can check the answer by listing it. The harder cases have nothing to list: objects in memory that outlive the variable naming them, database connections that a pool keeps after a request lets go, and a platform that runs your code without ever showing you the process. The question stays the same in each; only the place to look for the answer changes.
Deleting a name inside your own code
The same split between a name and its thing exists inside a running program, and there it decides when a resource is released.
Code often wraps a resource in an object: a database client, a file, a connection to some service. The object is a value in the process’s memory, and the variable that refers to it is a name. Removing the variable does not necessarily remove the object, because other references may still lead to it. Python’s runtime can reclaim an object’s memory once nothing can reach it any more, through a part called the garbage collector. Some objects carry a finalizer, a piece of cleanup registered to run when the object is collected; in the documentation’s words, it is “called when obj is garbage collected.” So there are two ways for the resource inside such an object to be released: your code closes it explicitly, or the object is collected and its finalizer closes it then.
I wrote a small object that opens a file, holds the descriptor and registers a finalizer to close it. Then I made two of them. The first I closed explicitly. The second I simply deleted, with del, which removes the variable, the name. To make the moment hold still long enough to look at, I gave the object a reference to itself, so that deleting the name would not free it at once, and switched off automatic collection, so the collector would not run until the script asked. The deleted object would sit unreachable but uncollected. Then I triggered a collection by hand. Each line of the output answers the same question: is the file closed?



