Package: ifileoperation
IFileOperation- a simple wrapper to use Windows shell file operations.This is a very small wrapper around IFileOperation to expose methods to perform file opereration (
move, copy, rename, delete) on files using Windows shell operations.  This means these
operations can be undone, files can be recycled, and you can allow users to handle name conflicts:
just like when you do any of these through Windows Explorer.At the moment this is a very young and so only exposes the file operations:MoveCopyRenameDeleteMore features may be added in the future, feel free to open a feature request for something
specific.Installation:pip install ifileoperationAt the moment the library is tested to run on Python 3.11, but other version might work ifpywin32andcomtypesare available.UsageAll of the functionality is accessed via theFileOperatorclass.  This is a scheduling context
manager. If you're familiar with IFileOperation, you'll know that you queue a bunch of operations
you wish to be performed, then order them to be executed all at once:fromPathlibimportPathfromifileoperationimportFileOperator,FileOperationFlagsif__name__=='__main__':# Configure for recycling, showing a prompt if the file(s) can't be recyled# and must be deleted instead.recycle_flags=(# ALLOW_UNDO: for versions < Win8, ADDUNDORECORD is preferred for Win8+FileOperationFlags.ALLOW_UNDO|FileOperationFlags.ADDUNDORECORD|# RECYCLEONDELETE: Perform deletes as recyclesFileOperationFlags.RECYCLEONDELETE|# WANTNUKEWARNING: If a file is too big to be recyled, show a warning that#  it will be deleted insteadFileOperationFlags.WANTNUKEWARNING|)# Don't show any confirmation dialogs (except for WANTNUKEWARNING), or a UAC# prompt if elevation is required (default behavior)ui_flags=(# NO_CONFIMATION: Don't show confirmation dialogs (ie, treat all dialogs# as if 'Yes to All' was selected)FileOperationFlags.NO_CONFIRMATION|)config=recycle_flags|ui_flagswithFileOperator(flags=config,commit_on_exit=True)asop:op.delete_file('Q:/foo.txt')op.delete_file(Path.cwd().join('bar.txt'))FileOperatorA thin wrapper around IFileOperation, exposing the move, copy, rename, and
delete operations.  All paths can be specified as anything implementing theos.PathLike[str]interface: strings,Pathobjects, or your own customPathLikeclass.  TheFileOperatorinstance is a context manager: you queue
operations in thewithblock, and thencommitthem or have them committed
automatically.NOTE:FileOperatoris not reentrant.  Once you've entered thewithblock and
exited, you should create a new instance to perform more operations.Configuring:Configuration is done via the constructor:__init__(self,parent=None,flags=FileOperator.DEFAULT_FLAGS,commit_on_exit=False):parent: A optionalHANDLEto the parent that should own any dialog boxes
shown. You may also pass awx.Windowobject, andFileOperatorwill extract
the handle for you.flags: AFileOperationFlagsinstance indicating the options you want when
performing the operations.  See the Microsoft documentation onthese flagsfor more details on what each means.  These are also in the docstrings forFileOperationFlags, so you can read there them as well.  Some common defaults are
provided as well:FileOperator.DEFAULT_FLAGS: This causes behavior as if the user had initiated the
file operations from within Windows Exlorer with no modifier keys pressed (Shift,
Ctrl, etc).FileOperator.UNDO_FLAGS: This sets the flags needed to allow your operation to be
undone withCtrl+Z.FileOperator.SEMI_SILENT_FLAGS: This hides the progress dialog, and only shows
dialogs if user intervention is required. For example, if a name collision occurs, or
when attempting to move a file that cannot be (temporarily) due to being open in
another program, or if a file must be deleted instead of recycled.FileOperator.FULL_SILENT_FLAGS: This performs the operations fully silently, responding
to any prompts as if "Yes to All" or "Continue" was selected.  Note this doesnotresolve other errors, and will fail if any error occurs.  The only prompt that may be shown
is a UAC prompt if elevation is required.  You can further suppress the UAC prompt withFileOperationFlags.REQUIREELEVATION.commit_on_exit: If set toTrue, all the queued operations will be
automatically commited as long as no exceptions occurred withing thewithblock before exiting.  Exceptionsmightstill occur during the committing
itself though!Operations supported:The basic file operations can be scheduled.  In these method signatures,StrPathis defined asstr | os.PathLike[str].move_file(source: StrPath, destination: StrPath, new_name: str | None = None):
Moves the file atsourceto the destination directorydestination.  Ifnew_nameis supplied, the file will also be renamed to the new name.move_files(sources: Iterable[StrPath], destination: StrPath, new_name: str | None = None):
Moves the specified filessourcesto the destination directorydestination.  Ifnew_nameis supplied, the files will all be renamed to the new name. In this case,
you probably also want to supplyFileOperationFlags.RENAMEONCOLLISION.copy_file(source: StrPath, destination: StrPath, new_name: str | None = None):
Like move, but performs a copy instead.copy_files(sources: Iterable[StrPath], destination: StrPath):
Like move (without the rename), but performs a copy instead.rename_file(source: StrPath, new_name: str, allow_move: bool = True):
Renames a file to a new name.  Normally,new_nameshould just be the name of
the new file, without its directory.  However, if you're used to other file
APIs that let you "rename" a file into a different directory,rename_filesupports this as well.  Whenallow_moveisTrue, if it is detected thatnew_nameis actually a path resolving to a different directory, this will
automatically be transformed into amove_fileoperation instead.rename_files(sources: Iterable[StrPath], new_name: str):  Renames the given
files to have the new name.  Unlikerename_file, you cannot rename files
into files in different directories. If multiple source files are in the same
directory, you probably want to includeFileOperationFlags.RENAMEONCOLLISIONto
prevent errors while renaming.delete_file(source: StrPath): Deletes the target file.delete_files(sources: Iterable[StrPath]): Deletes the target files.commit(): Cause all the queue operations to be performed.Post-commit attributesAfter acommit, additional attributes are available on theFileOperatorinstance:return_code: TheHRESULTreturn code from the overall operation. This is usually
not required to be inspected.aborted:Trueif any of the operations were aborted / skipped.results: A mapping of source filenames to destination filenames for successful
operations.  In the special case of deleted files, the destination will be'RECYCLED'or'DELETED'respectively.ExceptionsThis library may raise any of the following exceptions:NotADirectoryError: This can happen when trying to rename a folder if a file
already exists with the same name, or attempting to move/copy to a directory
that doesn't exist.IsADirectoryError: This can happen when trying to rename a file if a folder
already exists with the same name.PermissionError: Can occur for various reasons, common examples are UAC
elevation being required, or modifying a read-only file.FileExistsError: Can occur when attempting to create a new file, when one
of the same name already exists.FileNotFoundError: Happens if the source file for an operation cannot be
found.ifileoperation.IFileOperationError: For all other errors that occur. These
are a simple wrapper aroundpythoncom.com_error, and expose an.hresultattribute with theHRESULTthat triggered the error.
In the future, moreHRESULTs may be converted into standard libraryOSErrors.ContributingPull requests are welcome!  We use branch protection with some (minimal) tests
at the moment: just formatting really. To install the dependencies needed for
development, use:pip install -r requirements-dev.txtAnd before committing make sure to check against the tests and formatters:pytest: No tests at the momentblack ifileoperation: Code formattingisort ifileoperation: Code formattingflake8 ifileoperation: LintingIFileOperation usessemantic versioning, but if you're
unsure if your changes need a version bump feel free to note that in your pull
request and you'll get feedback!If you're not into coding, you can open aBug Report or Feature Requestand I'll look into it.Known Issues:Incompatible with WINE: see:https://github.com/lojack5/IFileOperation/issues/9