Skip to content

Commit d7ad5b6

Browse files
authored
Merge pull request #236 from derek73/fix/issue-232-initials-indexerror
Fix IndexError in initials for unnormalized *_list elements
2 parents 7b4c5fe + c72953c commit d7ad5b6

3 files changed

Lines changed: 14 additions & 1 deletion

File tree

docs/release_log.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
Release Log
22
===========
33
* 1.3.0 - Unreleased
4+
- Fix ``IndexError`` in ``initials()``/``initials_list()`` when a ``*_list`` attribute was assigned directly with an element containing unnormalized whitespace (e.g. ``name.middle_list = ['Q R']``), bypassing the parser's whitespace normalization (closes #232)
45
- Fix ``HumanName`` acting as its own iterator with a stored cursor: breaking out of a loop, iterating in nested loops, or calling ``len(name)`` mid-loop corrupted subsequent iteration; ``iter(name)`` now returns a fresh independent iterator each time. ``next(name)`` on the instance itself (undocumented) now raises ``TypeError`` — call ``next(iter(name))`` instead (closes #225)
56
- Fix parsing writing back into the ``Constants`` it reads (usually the shared module-level ``CONSTANTS``): pieces derived while parsing a name — period-joined titles/suffixes like ``"Lt.Gov."`` and conjunction-joined pieces like ``"Mr. and Mrs."`` or ``"von und zu"`` — are now tracked per parse instead of being permanently ``add()``-ed to the config, so parse results no longer depend on which names were parsed earlier in the process and parsing no longer mutates shared state across threads
67
- Remove the vestigial ``unparsable`` attribute: the guard that was meant to set it has been unreachable since 2013 (v0.2.9), so it has reported ``False`` for every parsed name for over a decade; check ``len(name) == 0`` to detect an empty parse

nameparser/parser.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,10 @@ def _process_initial(self, name_part: str, firstname: bool = False) -> str:
250250
Name parts may include prefixes or conjunctions. This function filters these from the name unless it is
251251
a first name, since first names cannot be conjunctions or prefixes.
252252
"""
253-
parts = name_part.split(" ")
253+
# split() rather than split(" "): *_list attributes assigned directly
254+
# bypass parse_pieces whitespace normalization, and split(" ") yields
255+
# empty strings for repeated spaces (#232)
256+
parts = name_part.split()
254257
initials = []
255258
for part in parts:
256259
if not (self.is_prefix(part) or self.is_conjunction(part)) or firstname:

tests/test_initials.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,15 @@ def test_str_default_behavior_unchanged(self) -> None:
134134
hn = HumanName("John Doe")
135135
self.assertEqual(str(hn), "John Doe")
136136

137+
def test_initials_with_doubled_space_in_list_element(self) -> None:
138+
# direct *_list assignment bypasses parse_pieces whitespace
139+
# normalization, so initials must tolerate unnormalized elements
140+
# instead of raising IndexError (#232)
141+
hn = HumanName(first="John")
142+
hn.middle_list = ["Q R"]
143+
self.assertEqual(hn.initials_list(), ["J", "Q R"])
144+
self.assertEqual(hn.initials(), "J. Q R.")
145+
137146
def test_constructor_first(self) -> None:
138147
hn = HumanName(first="TheName")
139148
self.m(hn.first, "TheName", hn)

0 commit comments

Comments
 (0)