Rename
Renames a file or folder to a specified new name while keeping it in the same directory.
Rename
Processing
Renames a file or folder to a specified new name while keeping it in the same directory. Handles conflicts based on the chosen conflict mode (skip, overwrite, or auto-number).
Inputs
- current_path
- The path to the file or folder to be renamed.
- new name
- The new name for the file or folder. For files, this excludes the extension, which is preserved from the original file.
Inputs Types
Input | Types |
---|---|
current_path |
Str , Path |
new name |
Str |
You can check the list of supported types here: Available Type Hints.
Outputs
- status
- A boolean indicating whether the rename operation was successful.
- final path
- The resulting path of the file or folder after renaming.
Outputs Types
Output | Types |
---|---|
status |
Bool |
final path |
Str |
You can check the list of supported types here: Available Type Hints.
Options
The Rename brick contains some changeable options:
- Manage Conflict By
- Specifies how to handle naming conflicts. Options are "skip" (do not rename if target exists), "auto-number" (append a number to the name), or "overwrite" (replace the existing file or folder).
- Verbose
- Enables detailed logging of the rename operation when set to True.
import logging
from coded_flows.types import Str, Tuple, Union, Bool, Path
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
def rename(
current_path: Union[Str, Path], new_name: Str, options=None
) -> Tuple[Bool, Str]:
brick_display_name = "Rename"
options = options or {}
verbose = options.get("verbose", True)
conflict_mode = options.get("conflict_mode", "skip")
final_path = str(current_path)
status = False
try:
current_path_obj = Path(current_path)
if verbose:
logger.info(f"[{brick_display_name}] Starting rename operation")
logger.info(f"[{brick_display_name}] Current path: {current_path_obj}")
logger.info(f"[{brick_display_name}] New name: {new_name}")
logger.info(f"[{brick_display_name}] Conflict mode: {conflict_mode}")
if not current_path_obj.exists():
verbose and logger.error(
f"[{brick_display_name}] Source path does not exist: '{current_path_obj}'."
)
raise ValueError(f"Source path does not exist: {current_path_obj}")
invalid_chars = '<>:"/\\|?*'
if any((char in new_name for char in invalid_chars)):
verbose and logger.error(
f"[{brick_display_name}] Invalid characters in new name: '{new_name}'."
)
raise ValueError(f"Invalid characters in new name: '{new_name}'")
if not new_name.strip():
verbose and logger.error(f"[{brick_display_name}] New name cannot be empty")
raise ValueError("New name cannot be empty")
parent_dir = current_path_obj.parent
if current_path_obj.is_file():
original_extension = current_path_obj.suffix
if "." in new_name:
new_name_without_ext = new_name.rsplit(".", 1)[0]
else:
new_name_without_ext = new_name
final_new_name = new_name_without_ext + original_extension
else:
final_new_name = new_name
new_path = parent_dir / final_new_name
verbose and logger.info(f"[{brick_display_name}] Target path: {new_path}")
if new_path.exists() and new_path != current_path_obj:
verbose and logger.info(
f"[{brick_display_name}] Target path already exists"
)
if conflict_mode == "skip":
verbose and logger.info(
f"[{brick_display_name}] Skipping rename due to existing target"
)
elif conflict_mode == "overwrite":
verbose and logger.info(
f"[{brick_display_name}] Removing existing target for overwrite"
)
try:
if new_path.is_dir():
import shutil
shutil.rmtree(new_path)
else:
new_path.unlink()
status = True
except Exception as e:
verbose and logger.error(
f"[{brick_display_name}] Failed to remove existing target."
)
raise Exception(f"Failed to remove existing target: {e}")
elif conflict_mode == "auto-number":
verbose and logger.info(
f"[{brick_display_name}] Finding available name with auto-numbering."
)
if current_path_obj.is_file():
name_part = new_name_without_ext
ext_part = original_extension
elif "." in final_new_name:
(name_part, ext_part) = final_new_name.rsplit(".", 1)
ext_part = "." + ext_part
else:
name_part = final_new_name
ext_part = ""
counter = 1
while new_path.exists():
numbered_name = f"{name_part}_{counter}{ext_part}"
new_path = parent_dir / numbered_name
counter += 1
if counter > 9999:
if verbose:
logger.error(
f"[{brick_display_name}] Too many numbered variations exist!"
)
raise Exception("Too many numbered variations exist!")
verbose and logger.info(
f"[{brick_display_name}] Using auto-numbered name: {new_path.name}."
)
status = True
if new_path == current_path_obj:
verbose and logger.info(
f"[{brick_display_name}] Source and target are the same, no operation needed."
)
final_path = str(new_path)
status = True
verbose and logger.info(f"[{brick_display_name}] Performing rename operation.")
current_path_obj.rename(new_path)
final_path = str(new_path)
if verbose:
logger.info(
f"[{brick_display_name}] Rename operation completed successfully"
)
logger.info(f"[{brick_display_name}] Final path: '{final_path}'.")
except Exception as e:
verbose and logger.error(f"[{brick_display_name}] Unexpected error!")
raise
return (status, final_path)
Brick Info
version
v0.1.4
python
3.10,
3.11,
3.12,
3.13
requirements
-
-