Skip to content

Commit 6b281b1

Browse files
authored
fix: treat blank boolean strings as false (#2675)
1 parent 41ecd90 commit 6b281b1

3 files changed

Lines changed: 55 additions & 2 deletions

File tree

copier/_tools.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,9 @@ def cast_to_bool(value: Any) -> bool:
129129
return bool(float(value))
130130
# Assume it's a string
131131
with suppress(AttributeError):
132-
lower = value.lower()
132+
lower = value.strip().lower()
133+
if not lower:
134+
return False
133135
if lower in {"y", "yes", "t", "true", "on"}:
134136
return True
135137
elif lower in {"n", "no", "f", "false", "off", "~", "null", "none"}:

tests/test_tasks.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,30 @@ def test_copy_tasks(template_path: str, tmp_path: Path) -> None:
6868
assert not (tmp_path / "false").exists()
6969

7070

71+
def test_task_with_blank_rendered_when_is_skipped(
72+
tmp_path_factory: pytest.TempPathFactory,
73+
) -> None:
74+
src, dst = map(tmp_path_factory.mktemp, ("src", "dst"))
75+
build_file_tree(
76+
{
77+
src / "copier.yml": """\
78+
_tasks:
79+
- command: touch should-not-exist
80+
when: |
81+
{% if false %}
82+
true
83+
{% endif %}
84+
"""
85+
}
86+
)
87+
88+
copier.run_copy(
89+
str(src), dst, quiet=True, defaults=True, overwrite=True, unsafe=True
90+
)
91+
92+
assert not (dst / "should-not-exist").exists()
93+
94+
7195
def test_copy_skip_tasks(template_path: str, tmp_path: Path) -> None:
7296
copier.run_copy(
7397
template_path,

tests/test_tools.py

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import pytest
66
from poethepoet.app import PoeThePoet
77

8-
from copier._tools import normalize_git_path
8+
from copier._tools import cast_to_bool, normalize_git_path
99

1010
from .helpers import git
1111

@@ -16,6 +16,33 @@ def test_types() -> None:
1616
assert result == 0
1717

1818

19+
@pytest.mark.parametrize(
20+
"value",
21+
[
22+
"",
23+
" ",
24+
"\t",
25+
"\n",
26+
" \n\t ",
27+
],
28+
)
29+
def test_cast_to_bool_treats_blank_strings_as_false(value: str) -> None:
30+
assert cast_to_bool(value) is False
31+
32+
33+
@pytest.mark.parametrize(
34+
("value", "expected"),
35+
[
36+
(" true ", True),
37+
("\nfalse\n", False),
38+
],
39+
)
40+
def test_cast_to_bool_ignores_surrounding_whitespace(
41+
value: str, expected: bool
42+
) -> None:
43+
assert cast_to_bool(value) is expected
44+
45+
1946
def test_temporary_directory_with_readonly_files_deletion() -> None:
2047
"""Ensure temporary directories containing read-only files are properly deleted,
2148
whatever the OS.

0 commit comments

Comments
 (0)