cardinal_pythonlib.fileops¶
Original code copyright (C) 2009-2022 Rudolf Cardinal (rudolf@pobox.com).
This file is part of cardinal_pythonlib.
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
File operations.
-
class
cardinal_pythonlib.fileops.
FileWatcher
(filenames: List[str])[source]¶ Watch several files for changes.
Initialize with a list of filenames to watch.
-
cardinal_pythonlib.fileops.
chmod_r
(root: str, permission: int) → None[source]¶ Recursive
chmod
.Parameters: - root – directory to walk down
- permission – e.g.
e.g. stat.S_IWUSR
-
cardinal_pythonlib.fileops.
chown_r
(path: str, user: str, group: str) → None[source]¶ Performs a recursive
chown
.Parameters: - path – path to walk down
- user – user name or ID
- group – group name or ID
-
cardinal_pythonlib.fileops.
concatenate
(src: List[str], dest: str, filesep: str = '\n')[source]¶ Concatenate multiple text files into one.
-
cardinal_pythonlib.fileops.
copy_tree_contents
(srcdir: str, destdir: str, destroy: bool = False) → None[source]¶ Recursive copy. Unlike
copy_tree_root()
,copy_tree_contents()
works as follows. With the file structure:/source/thing/a.txt /source/thing/b.txt /source/thing/somedir/c.txt
the command
copy_tree_contents("/source/thing", "/dest")
ends up creating:
/dest/a.txt /dest/b.txt /dest/somedir/c.txt
-
cardinal_pythonlib.fileops.
copy_tree_root
(src_dir: str, dest_parent: str) → None[source]¶ Copies a directory
src_dir
into the directorydest_parent
. That is, with a file structure like:/source/thing/a.txt /source/thing/b.txt /source/thing/somedir/c.txt
the command
copy_tree_root("/source/thing", "/dest")
ends up creating
/dest/thing/a.txt /dest/thing/b.txt /dest/thing/somedir/c.txt
-
cardinal_pythonlib.fileops.
copyglob
(src: str, dest: str, allow_nothing: bool = False, allow_nonfiles: bool = False) → None[source]¶ Copies files whose filenames match the glob src” into the directory “dest”. Raises an error if no files are copied, unless allow_nothing is True.
Parameters: - src – source glob (e.g.
/somewhere/*.txt
) - dest – destination directory
- allow_nothing – don’t raise an exception if no files are found
- allow_nonfiles – copy things that are not files too (as judged by
os.path.isfile()
).
Raises: ValueError
– if no files are found andallow_nothing
is not set- src – source glob (e.g.
-
cardinal_pythonlib.fileops.
delete_files_within_dir
(directory: str, filenames: List[str]) → None[source]¶ Delete files within
directory
whose filename exactly matches one offilenames
.
-
cardinal_pythonlib.fileops.
exists_locked
(filepath: str) → Tuple[bool, bool][source]¶ Checks if a file is locked by opening it in append mode. (If no exception is thrown in that situation, then the file is not locked.)
Parameters: filepath – file to check Returns: (exists, locked)
Return type: tuple See https://www.calazan.com/how-to-check-if-a-file-is-locked-in-python/.
-
cardinal_pythonlib.fileops.
find
(pattern: str, path: str) → List[str][source]¶ Finds files in
path
whose filenames matchpattern
(viafnmatch.fnmatch()
).
-
cardinal_pythonlib.fileops.
find_first
(pattern: str, path: str) → str[source]¶ Finds first file in
path
whose filename matchespattern
(viafnmatch.fnmatch()
), or raisesIndexError
.
-
cardinal_pythonlib.fileops.
gen_filenames
(starting_filenames: List[str], recursive: bool) → Generator[str, None, None][source]¶ From a starting list of files and/or directories, generates filenames of all files in the list, and (if
recursive
is set) all files within directories in the list.Parameters: - starting_filenames – files and/or directories
- recursive – walk down any directories in the starting list, recursively?
Yields: each filename
-
cardinal_pythonlib.fileops.
get_directory_contents_size
(directory: str = '.') → int[source]¶ Returns the total size of all files within a directory.
See https://stackoverflow.com/questions/1392413/calculating-a-directorys-size-using-python.
Parameters: directory – directory to check Returns: size in bytes Return type: int
-
cardinal_pythonlib.fileops.
mkdir_p
(path: str) → None[source]¶ Makes a directory, and any intermediate (parent) directories if required.
This is the UNIX
mkdir -p DIRECTORY
command; of course, we useos.makedirs()
instead, for portability.
-
cardinal_pythonlib.fileops.
moveglob
(src: str, dest: str, allow_nothing: bool = False, allow_nonfiles: bool = False) → None[source]¶ As for
copyglob()
, but moves instead.
-
cardinal_pythonlib.fileops.
preserve_cwd
(func: Callable) → Callable[source]¶ Decorator to preserve the current working directory in calls to the decorated function.
Example:
@preserve_cwd def myfunc(): os.chdir("/faraway") os.chdir("/home") myfunc() assert os.getcwd() == "/home"
-
cardinal_pythonlib.fileops.
purge
(path: str, pattern: str) → None[source]¶ Deletes all files in
path
matchingpattern
(viafnmatch.fnmatch()
).
-
cardinal_pythonlib.fileops.
pushd
(directory: str) → None[source]¶ Context manager: changes directory and preserves the original on exit.
Example:
with pushd(new_directory): # do things
-
cardinal_pythonlib.fileops.
relative_filename_within_dir
(filename: str, directory: str) → str[source]¶ Starting with a (typically absolute)
filename
, returns the part of the filename that is relative to the directorydirectory
. If the file is not within the directory, returns an empty string.
-
cardinal_pythonlib.fileops.
require_executable
(executable: str) → None[source]¶ If
executable
is not found byshutil.which()
, raiseFileNotFoundError
.
-
cardinal_pythonlib.fileops.
rmglob
(pattern: str) → None[source]¶ Deletes all files whose filename matches the glob
pattern
(viaglob.glob()
).
-
cardinal_pythonlib.fileops.
shutil_rmtree_onerror
(func: Callable[[str], None], path: str, exc_info: Tuple[Optional[Any], Optional[BaseException], Optional[traceback]]) → None[source]¶ Error handler for
shutil.rmtree
.If the error is due to an access error (read only file) it attempts to add write permission and then retries.
If the error is for another reason it re-raises the error.
Usage:
shutil.rmtree(path, onerror=shutil_rmtree_onerror)
See https://stackoverflow.com/questions/2656322/shutil-rmtree-fails-on-windows-with-access-is-denied
-
cardinal_pythonlib.fileops.
which_and_require
(executable: str, fullpath: bool = False) → str[source]¶ Ensures that
executable
is on the path, and returns it (or its full path viashutil.which()
).
-
cardinal_pythonlib.fileops.
which_with_envpath
(executable: str, env: Dict[str, str]) → str[source]¶ Performs a
shutil.which()
command using the PATH from the specified environment.Reason: when you use
run([executable, ...], env)
and thereforesubprocess.run([executable, ...], env=env)
, the PATH that’s searched forexecutable
is the parent’s, not the new child’s – so you have to find the executable manually.Parameters: - executable – executable to find
- env – environment to fetch the PATH variable from