Compare commits

...

3 Commits

Author SHA1 Message Date
Andrew Senetar d249f0106b
Fix #59, initialize and uninitialize COM for threading 2021-08-07 22:16:33 -05:00
Andrew Senetar 94e1ec007a
Add ability to handle pathlib paths
- Handle pathlib paths across all implementations, plat_other already did
- Move preprocessing code to common location
2021-08-07 21:48:10 -05:00
Andrew Senetar 84c220cbd9
Change extra requires to filter on platform
Also created one extra `nativeLib` to replace the orignal two.  Will remove
the others after a couple releases.
2021-08-07 21:04:40 -05:00
9 changed files with 47 additions and 14 deletions

View File

@ -22,10 +22,14 @@ issues and fixes would be most appreciated.
Installation Installation
------------ ------------
You can download it with pip:: You can download it with pip:
python -m pip install -U send2trash python -m pip install -U send2trash
To install with pywin32 or pyobjc required specify the extra `nativeLib`:
python -m pip install -U send2trash[nativeLib]
or you can download the source from http://github.com/arsenetar/send2trash and install it with:: or you can download the source from http://github.com/arsenetar/send2trash and install it with::
>>> python setup.py install >>> python setup.py install

View File

@ -6,11 +6,11 @@
from gi.repository import GObject, Gio from gi.repository import GObject, Gio
from .exceptions import TrashPermissionError from .exceptions import TrashPermissionError
from .util import preprocess_paths
def send2trash(paths): def send2trash(paths):
if not isinstance(paths, list): paths = preprocess_paths(paths)
paths = [paths]
for path in paths: for path in paths:
try: try:
f = Gio.File.new_for_path(path) f = Gio.File.new_for_path(path)

View File

@ -10,6 +10,7 @@ from ctypes import cdll, byref, Structure, c_char, c_char_p
from ctypes.util import find_library from ctypes.util import find_library
from .compat import binary_type from .compat import binary_type
from .util import preprocess_paths
Foundation = cdll.LoadLibrary(find_library("Foundation")) Foundation = cdll.LoadLibrary(find_library("Foundation"))
CoreServices = cdll.LoadLibrary(find_library("CoreServices")) CoreServices = cdll.LoadLibrary(find_library("CoreServices"))
@ -40,8 +41,7 @@ def check_op_result(op_result):
def send2trash(paths): def send2trash(paths):
if not isinstance(paths, list): paths = preprocess_paths(paths)
paths = [paths]
paths = [ paths = [
path.encode("utf-8") if not isinstance(path, binary_type) else path path.encode("utf-8") if not isinstance(path, binary_type) else path
for path in paths for path in paths

View File

@ -6,6 +6,7 @@
from Foundation import NSFileManager, NSURL from Foundation import NSFileManager, NSURL
from .compat import text_type from .compat import text_type
from .util import preprocess_paths
def check_op_result(op_result): def check_op_result(op_result):
@ -16,8 +17,7 @@ def check_op_result(op_result):
def send2trash(paths): def send2trash(paths):
if not isinstance(paths, list): paths = preprocess_paths(paths)
paths = [paths]
paths = [ paths = [
path.decode("utf-8") if not isinstance(path, text_type) else path path.decode("utf-8") if not isinstance(path, text_type) else path
for path in paths for path in paths

View File

@ -30,6 +30,7 @@ except ImportError:
from urllib import quote from urllib import quote
from .compat import text_type, environb from .compat import text_type, environb
from .util import preprocess_paths
from .exceptions import TrashPermissionError from .exceptions import TrashPermissionError
try: try:
@ -172,8 +173,7 @@ def get_dev(path):
def send2trash(paths): def send2trash(paths):
if not isinstance(paths, list): paths = preprocess_paths(paths)
paths = [paths]
for path in paths: for path in paths:
if isinstance(path, text_type): if isinstance(path, text_type):
path_b = fsencode(path) path_b = fsencode(path)

View File

@ -7,6 +7,8 @@
from __future__ import unicode_literals from __future__ import unicode_literals
import os.path as op import os.path as op
from .compat import text_type from .compat import text_type
from .util import preprocess_paths
from ctypes import ( from ctypes import (
windll, windll,
Structure, Structure,
@ -101,8 +103,7 @@ def get_short_path_name(long_name):
def send2trash(paths): def send2trash(paths):
if not isinstance(paths, list): paths = preprocess_paths(paths)
paths = [paths]
# convert data type # convert data type
paths = [ paths = [
text_type(path, "mbcs") if not isinstance(path, text_type) else path text_type(path, "mbcs") if not isinstance(path, text_type) else path

View File

@ -7,6 +7,7 @@
from __future__ import unicode_literals from __future__ import unicode_literals
import os.path as op import os.path as op
from .compat import text_type from .compat import text_type
from .util import preprocess_paths
from platform import version from platform import version
import pythoncom import pythoncom
import pywintypes import pywintypes
@ -15,8 +16,7 @@ from .IFileOperationProgressSink import CreateSink
def send2trash(paths): def send2trash(paths):
if not isinstance(paths, list): paths = preprocess_paths(paths)
paths = [paths]
# convert data type # convert data type
paths = [ paths = [
text_type(path, "mbcs") if not isinstance(path, text_type) else path text_type(path, "mbcs") if not isinstance(path, text_type) else path
@ -26,6 +26,8 @@ def send2trash(paths):
paths = [op.abspath(path) if not op.isabs(path) else path for path in paths] paths = [op.abspath(path) if not op.isabs(path) else path for path in paths]
# remove the leading \\?\ if present # remove the leading \\?\ if present
paths = [path[4:] if path.startswith("\\\\?\\") else path for path in paths] paths = [path[4:] if path.startswith("\\\\?\\") else path for path in paths]
# Need to initialize the com before using
pythoncom.CoInitialize()
# create instance of file operation object # create instance of file operation object
fileop = pythoncom.CoCreateInstance( fileop = pythoncom.CoCreateInstance(
shell.CLSID_FileOperation, None, pythoncom.CLSCTX_ALL, shell.IID_IFileOperation, shell.CLSID_FileOperation, None, pythoncom.CLSCTX_ALL, shell.IID_IFileOperation,
@ -65,3 +67,6 @@ def send2trash(paths):
# convert to standard OS error, allows other code to get a # convert to standard OS error, allows other code to get a
# normal errno # normal errno
raise OSError(None, error.strerror, path, error.hresult) raise OSError(None, error.strerror, path, error.hresult)
finally:
# Need to make sure we call this once fore every init
pythoncom.CoUninitialize()

16
send2trash/util.py Normal file
View File

@ -0,0 +1,16 @@
# encoding: utf-8
# Copyright 2017 Virgil Dupras
# This software is licensed under the "BSD" License as described in the "LICENSE" file,
# which should be included with this package. The terms are also available at
# http://www.hardcoded.net/licenses/bsd_license
def preprocess_paths(paths):
if not isinstance(paths, list):
paths = [paths]
# Convert items such as pathlib paths to strings
paths = [
path.__fspath__() if hasattr(path, "__fspath__") else path for path in paths
]
return paths

View File

@ -35,7 +35,14 @@ setup(
description="Send file to trash natively under Mac OS X, Windows and Linux.", description="Send file to trash natively under Mac OS X, Windows and Linux.",
long_description=LONG_DESCRIPTION, long_description=LONG_DESCRIPTION,
classifiers=CLASSIFIERS, classifiers=CLASSIFIERS,
extras_require={"win32": ["pywin32"], "objc": ["pyobjc-framework-Cocoa"]}, extras_require={
"win32": ['pywin32; sys_platform == "win32"'],
"objc": ['pyobjc-framework-Cocoa; sys_platform == "darwin"'],
"nativeLib": [
'pywin32; sys_platform == "win32"',
'pyobjc-framework-Cocoa; sys_platform == "darwin"',
],
},
project_urls={"Bug Reports": "https://github.com/arsenetar/send2trash/issues"}, project_urls={"Bug Reports": "https://github.com/arsenetar/send2trash/issues"},
entry_points={"console_scripts": ["send2trash=send2trash.__main__:main"]}, entry_points={"console_scripts": ["send2trash=send2trash.__main__:main"]},
) )