Skip to content

Commit ed604d3

Browse files
derek73claude
andcommitted
fix: honor initials_separator kwarg in __process_initial__; fix string_format='' in __str__
- `__process_initial__` was reading `self.C.initials_separator` (Constants) instead of `self.initials_separator` (per-instance), so the constructor kwarg was silently ignored for multi-word name parts - `__str__` used `if self.string_format:` (truthiness) so `string_format=""` fell through to the default format despite the assignment fix in the PR - Add regression tests for both kwarg paths through the affected code - Fix `test_initials_separator_multiword_name_part` to set instance attr instead of Constants attr, so it tests the now-correct code path - Correct `Constants.initials_separator` docstring example (requires initials_format="{first}{middle}{last}" to produce "J.A.D.") - Clarify usage.rst: initials_separator only removes intra-group spaces; inter-group spacing is still governed by initials_format Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 67d8e5b commit ed604d3

4 files changed

Lines changed: 21 additions & 6 deletions

File tree

docs/usage.rst

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -206,12 +206,13 @@ Furthermore, the delimiter for the string output can be set through:
206206

207207
The separator between consecutive initials *within* a name group (e.g. two middle
208208
names) is controlled by :py:attr:`~nameparser.config.Constants.initials_separator`,
209-
which defaults to ``" "``. Setting it to ``""`` removes that space.
209+
which defaults to ``" "``. Setting it to ``""`` removes that space within a group;
210+
spacing *between* groups is still governed by ``initials_format``.
210211

211212
``initials_delimiter``, ``initials_separator``, and ``initials_format`` work together:
212213

213214
- ``initials_delimiter`` — appended *after* each individual initial (default ``"."``)
214-
- ``initials_separator`` — placed *between* consecutive initials in the same group (default ``" "``)
215+
- ``initials_separator`` — placed *after* the delimiter between consecutive initials in the same group (default ``" "``), so with ``delimiter="."`` and ``separator=" "`` you get ``A. K.``
215216
- ``initials_format`` — controls how the first, middle, and last groups are arranged
216217

217218
For example, to produce compact period-separated initials with no spaces:

nameparser/config/__init__.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,9 @@ class Constants:
223223
224224
With defaults ``initials_delimiter="."`` and ``initials_separator=" "``,
225225
``initials()`` produces ``"J. A. D."``. Setting ``initials_separator=""``
226-
with ``initials_delimiter="."`` produces ``"J.A.D."``.
226+
with ``initials_delimiter="."`` and ``initials_format="{first}{middle}{last}"``
227+
produces ``"J.A.D."``. With the default ``initials_format``, group-level
228+
spacing from the template is still applied.
227229
"""
228230

229231
empty_attribute_default = ''

nameparser/parser.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ def __next__(self) -> str:
179179
return getattr(self, self._members[c]) or next(self)
180180

181181
def __str__(self) -> str:
182-
if self.string_format:
182+
if self.string_format is not None:
183183
# string_format = "{title} {first} {middle} {last} {suffix} ({nickname})"
184184
_s = self.string_format.format(**self.as_dict())
185185
# remove trailing punctuation from missing nicknames
@@ -243,7 +243,7 @@ def __process_initial__(self, name_part: str, firstname: bool = False) -> str:
243243
if not (self.is_prefix(part) or self.is_conjunction(part)) or firstname:
244244
initials.append(part[0])
245245
if len(initials) > 0:
246-
return self.C.initials_separator.join(initials)
246+
return self.initials_separator.join(initials)
247247
else:
248248
return self.C.empty_attribute_default
249249

tests/test_initials.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,11 +155,23 @@ def test_constructor_multiple(self) -> None:
155155
self.m(hn.last, "lastname", hn)
156156
self.m(hn.title, "mytitle", hn)
157157

158+
def test_initials_separator_kwarg_multiword_part(self) -> None:
159+
# Regression: initials_separator kwarg must flow into __process_initial__
160+
# for multi-word name parts, not just into the initials() join calls.
161+
hn = HumanName("", initials_separator="")
162+
result = hn.__process_initial__("Van Berg", firstname=True)
163+
self.assertEqual(result, "VB")
164+
165+
def test_string_format_empty_string_kwarg(self) -> None:
166+
# Regression: string_format='' was silently ignored due to `or` defaulting
167+
hn = HumanName("John Doe", string_format="")
168+
self.assertEqual(str(hn), "")
169+
158170
def test_initials_separator_multiword_name_part(self) -> None:
159171
# __process_initial__ splits on spaces internally for multi-word tokens;
160172
# initials_separator must flow through there too.
161173
hn = HumanName("", constants=None)
162-
hn.C.initials_separator = ""
174+
hn.initials_separator = ""
163175
# Directly exercise __process_initial__ with a two-word part
164176
result = hn.__process_initial__("Van Berg", firstname=True)
165177
self.assertEqual(result, "VB")

0 commit comments

Comments
 (0)