[Python-ideas] Adding `pathlib.Path` method that would send file to recycle bin

Andrew Barnert abarnert at yahoo.com
Tue Dec 30 00:46:28 CET 2014

On Dec 29, 2014, at 22:15, random832 at fastmail.us wrote:

> On Mon, Dec 29, 2014, at 13:58, Andrew Barnert wrote:
>> And I don't know what the right thing to do on OS X would be for a file
>> on a different filesystem than the user's home that doesn't have its own
>> .Trash or is mounted read-only or no-trash.
> If it's mounted read-only, you have a bigger problem.

Well, yes, but the point is that Finder gives you a special message for this rather than trying to move it and giving you a permissions error. 

And more importantly, if it's mounted no-trash or doesn't have a trash can, you don't have a bigger problem, but you still have this problem, so this problem needs to be solved.

> Another possible issue could be: bad permission on trash directory, bad
> permission or nonexistent parent directory that trash directory must be
> created in (home or .Trashes). These are also all issues that must be
> faced for XDG.

I believe all of those issues could just raise the normal exception, because Finder treats them as normal errors--that is, rather than giving you the special "can't trash; delete?" message, it tries, fails, asks you to authenticate as an administrator, and tries again.

> XDG has a database of original location and deleted date for files in
> the trash - does OSX? (according to the tool I found, it does, at least
> for original location, but only works if you use Finder to trash the
> files)

That's a whole other issue. I believe that if you use the higher-level APIs instead of POSIX functions they take care of the desktop database and alias/bookmark info and all that stuff. If not... It may happen automatically (at least if you're on an HFS+ drive) but it may not.

>> Finder gives you a popup in
>> each of those cases asking if you want to delete it immediately because
>> it can't be trashed. And similarly for Linux, but the details are
>> different (especially since you might not even have a home trash).
> Another option would be to just script Finder with osascript. The tool
> http://hasseg.org/trash/ has objc code to "directly" script Finder
> without actually going through osascript.

If you want to script Finder, the easy way to do it (well, as easy as it gets without Appscript) is ScriptingBridge and/or the lower-level Cocoa AppleScript APIs (via PyObjC, but none of that is going to go into the stdlib, which means shutil needs to be written partly in ObjC), but that will raise the minimum OS X version, because 10.6 didn't have NSAppleScript and friends yet. (And the Carbon AEM calls are deprecated, of course.) This could also make it more difficult for Python apps to be sandboxed and AppStore'd.

But the biggest problem is that you're asking Finder to do it. If you don't have permission to trash a file, instead if getting an error, you'll get an auth dialog from Finder. If you trash a bunch of files you'll get a progress bar in Finder (and your script will get a timeout from the synchronous AppleEvent and not know if the trashing succeeded). Worse, if you don't have a Finder to talk to (because you're running in an ssh shell, or in a LaunchDaemon or a detached script, or because you're using a third-party Finder replacement like PathFinder) you won't be able to trash anything.

There are plenty of applications that's reasonable for, but I don't think it's reasonable stdlib behavior.

> When it does not use Finder,
> it uses FSMoveObjectToTrashSync, which seems to be depreciated.

Yeah, that's Carbon; you're supposed to use the Cocoa/CF APIs instead. NSWorkspace had one method that's guaranteed to do exactly the same thing as trashing in Finder--which it does by asking Finder--and a more general "perform operations on files" method that can be used for trashing without the Finder, but there's no way to control whether it's synchronous or asynchronous, and requires a runloop in case it's async.

Anyway, I don't think these details change the point: There is no low-level function to be added to os. There may be a high-level function to be added to shutil, but it's not trivial.

More information about the Python-ideas mailing list