Skip to content

Commit b62e91b

Browse files
authored
Merge pull request #2229 from rawsun007/get-value-boolean-spellings
Read git's yes/no and on/off booleans in get_value
2 parents 41c3954 + 297cd26 commit b62e91b

2 files changed

Lines changed: 42 additions & 12 deletions

File tree

git/config.py

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,36 +10,34 @@
1010
import abc
1111
import configparser as cp
1212
import fnmatch
13-
from functools import wraps
1413
import inspect
15-
from io import BufferedReader, IOBase
1614
import logging
1715
import os
1816
import os.path as osp
1917
import re
2018
import sys
21-
22-
from git.compat import defenc, force_text
23-
from git.util import LockFile
19+
from functools import wraps
20+
from io import BufferedReader, IOBase
2421

2522
# typing-------------------------------------------------------
26-
2723
from typing import (
24+
IO,
25+
TYPE_CHECKING,
2826
Any,
2927
Callable,
28+
Dict,
3029
Generic,
31-
IO,
3230
List,
33-
Dict,
3431
Sequence,
35-
TYPE_CHECKING,
3632
Tuple,
3733
TypeVar,
3834
Union,
3935
cast,
4036
)
4137

42-
from git.types import Lit_config_levels, ConfigLevels_Tup, PathLike, assert_never, _T
38+
from git.compat import defenc, force_text
39+
from git.types import _T, ConfigLevels_Tup, Lit_config_levels, PathLike, assert_never
40+
from git.util import LockFile
4341

4442
if TYPE_CHECKING:
4543
from io import BytesIO
@@ -958,9 +956,9 @@ def _string_to_value(self, valuestr: str) -> Union[int, float, str, bool]:
958956

959957
# Try boolean values as git uses them.
960958
vl = valuestr.lower()
961-
if vl == "false":
959+
if vl in ("false", "no", "off"):
962960
return False
963-
if vl == "true":
961+
if vl in ("true", "yes", "on"):
964962
return True
965963

966964
if not isinstance(valuestr, str):

test/test_config.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,38 @@ def test_backslash_line_continuation(self):
167167
key = "co" if section == "alias" else "k"
168168
self.assertEqual(config.get_value(section, key), expected)
169169

170+
def test_get_value_reads_git_boolean_spellings(self):
171+
# git accepts yes/no and on/off as well as true/false, and getboolean on
172+
# this class already did. get_value returned them as strings, so "no" and
173+
# "off" arrived as non-empty (truthy) values for a caller testing them.
174+
cases = [
175+
(b"true", True),
176+
(b"TRUE", True),
177+
(b"yes", True),
178+
(b"Yes", True),
179+
(b"on", True),
180+
(b"On", True),
181+
(b"false", False),
182+
(b"no", False),
183+
(b"off", False),
184+
(b"Off", False),
185+
]
186+
for raw, expected in cases:
187+
config_file = io.BytesIO(b"[core]\n\tflag = " + raw + b"\n")
188+
config_file.name = "boolean_spellings.config"
189+
config = GitConfigParser(config_file)
190+
config.read()
191+
self.assertIs(config.get_value("core", "flag"), expected, raw.decode())
192+
# The two accessors must not disagree about the same value.
193+
self.assertIs(config.getboolean("core", "flag"), expected, raw.decode())
194+
195+
# A value that is not a boolean at all still comes back untouched.
196+
config_file = io.BytesIO(b"[core]\n\tflag = meld\n")
197+
config_file.name = "boolean_spellings.config"
198+
config = GitConfigParser(config_file)
199+
config.read()
200+
self.assertEqual(config.get_value("core", "flag"), "meld")
201+
170202
@with_rw_directory
171203
def test_comment_backslash_does_not_continue_value(self, rw_dir):
172204
config_path = osp.join(rw_dir, "config")

0 commit comments

Comments
 (0)