Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions copier/_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,14 +127,20 @@ def cast_to_bool(value: Any) -> bool:
# Assume it's a number
with suppress(TypeError, ValueError):
return bool(float(value))

# Handle whitespace-only strings first
if isinstance(value, str) and not value.strip():
return False

Comment on lines +130 to +134
Copy link
Copy Markdown
Member

@sisp sisp Apr 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See #2462 (comment):

Suggested change
# Handle whitespace-only strings first
if isinstance(value, str) and not value.strip():
return False

# Assume it's a string
with suppress(AttributeError):
lower = value.lower()
lower = value.lower().strip()
if lower in {"y", "yes", "t", "true", "on"}:
return True
elif lower in {"n", "no", "f", "false", "off", "~", "null", "none"}:
return False
# Assume nothing

# Fallback
return bool(value)


Expand Down
20 changes: 19 additions & 1 deletion tests/test_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import pytest
from poethepoet.app import PoeThePoet

from copier._tools import normalize_git_path
from copier._tools import cast_to_bool, normalize_git_path

from .helpers import git

Expand Down Expand Up @@ -52,3 +52,21 @@ def test_temporary_directory_with_git_repo_deletion() -> None:
)
def test_normalizing_git_paths(path: str, normalized: str) -> None:
assert normalize_git_path(path) == normalized

def test_cast_to_bool_whitespace_only_strings_are_false() -> None:
"""Test that whitespace-only strings are False and valid keywords with surrounding whitespace still work."""
# Whitespace-only strings should be False
assert cast_to_bool("") is False
assert cast_to_bool(" ") is False
assert cast_to_bool("\n") is False
assert cast_to_bool(" \n\t") is False

# Whitespace around valid keywords should still work
assert cast_to_bool(" yes ") is True
assert cast_to_bool(" YES ") is True
assert cast_to_bool(" no ") is False
assert cast_to_bool(" NO ") is False
assert cast_to_bool(" true ") is True
assert cast_to_bool(" false ") is False