Skip to content

Commit 5377392

Browse files
derek73fdesoyeclaude
committed
feat: add given_names attribute aggregating first and middle names (closes #157)
Adds given_names (and given_names_list), the first name followed by all middle names, mirroring the existing surnames attribute (middle + last). Reimplemented fresh on current master from the approach in #157, which was based on a pre-refactor codebase and had drifted. Co-Authored-By: fdesoye <fdesoye@users.noreply.github.com> Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 8cb62a9 commit 5377392

4 files changed

Lines changed: 26 additions & 0 deletions

File tree

docs/release_log.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ Release Log
77
to 1.2.1 first (which includes a one-version compatibility shim), load and
88
re-pickle under 1.2.1, then upgrade to 1.3.0.
99

10+
- Add ``given_names`` (and ``given_names_list``) attribute as aggregate of first and middle names, mirroring ``surnames`` (closes #157)
1011
- Add ``suffix_delimiter`` to ``Constants`` and ``HumanName`` for parsing suffixes separated by arbitrary delimiters, e.g. ``"RN - CRNA"`` (#156)
1112
- Add ``initials_separator`` to ``Constants`` and ``HumanName`` to control spacing between consecutive initials within a name group (#171)
1213
- Fix ``Constants`` customizations, singleton identity, and ``TupleManager`` subclass being lost across ``pickle``/``deepcopy`` round-trips (#167, #168, #169)

docs/usage.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ Requires Python 3.10+.
2525
'III'
2626
>>> name.surnames
2727
'Q. Xavier de la Vega'
28+
>>> name.given_names
29+
'Juan Q. Xavier'
2830
>>> name.full_name = "Juan Q. Xavier Velasquez y Garcia, Jr."
2931
>>> name
3032
<HumanName : [

nameparser/parser.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ class HumanName:
4444
* :py:attr:`suffix`
4545
* :py:attr:`nickname`
4646
* :py:attr:`surnames`
47+
* :py:attr:`given_names`
4748
4849
:param str full_name: The name string to be parsed.
4950
:param constants constants:
@@ -415,6 +416,20 @@ def surnames(self) -> str:
415416
"""
416417
return " ".join(self.surnames_list) or self.C.empty_attribute_default
417418

419+
@property
420+
def given_names_list(self) -> list[str]:
421+
"""
422+
List of first name followed by middle names.
423+
"""
424+
return self.first_list + self.middle_list
425+
426+
@property
427+
def given_names(self) -> str:
428+
"""
429+
A string of the first name followed by all middle names.
430+
"""
431+
return " ".join(self.given_names_list) or self.C.empty_attribute_default
432+
418433
# setter methods
419434

420435
def _set_list(self, attr: str, value: str | list[str] | None) -> None:

tests/test_python_api.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,14 @@ def test_surnames_attribute(self) -> None:
263263
hn = HumanName("John Edgar Casey Williams III")
264264
self.m(hn.surnames, "Edgar Casey Williams", hn)
265265

266+
def test_given_names_list_attribute(self) -> None:
267+
hn = HumanName("John Edgar Casey Williams III")
268+
self.m(hn.given_names_list, ["John", "Edgar", "Casey"], hn)
269+
270+
def test_given_names_attribute(self) -> None:
271+
hn = HumanName("John Edgar Casey Williams III")
272+
self.m(hn.given_names, "John Edgar Casey", hn)
273+
266274
def test_is_prefix_with_list(self) -> None:
267275
hn = HumanName()
268276
items = ['firstname', 'lastname', 'del']

0 commit comments

Comments
 (0)