@@ -389,6 +389,32 @@ class Constants:
389389
390390 """
391391
392+ middle_name_as_last = False
393+ """
394+ If set, folds middle names into the last name: ``middle_list`` is prepended
395+ to ``last_list`` and ``middle_list`` is cleared, so ``.last`` becomes what
396+ ``.surnames`` already was and ``.middle`` becomes empty. Useful for naming
397+ systems with no middle-name concept, where everything after the given name
398+ is lineage/family (e.g. Arabic patronymic chaining: given + father +
399+ grandfather + family).
400+
401+ The fold is uniform across both no-comma and comma ("Last, First Middle")
402+ input, so the two written forms of a name converge on the same result.
403+
404+ For per-instance control without a shared ``Constants``, pass a dedicated
405+ instance: ``HumanName("...", constants=Constants(middle_name_as_last=True))``.
406+
407+ .. doctest::
408+
409+ >>> from nameparser import HumanName
410+ >>> from nameparser.config import Constants
411+ >>> C = Constants(middle_name_as_last=True)
412+ >>> hn = HumanName("Mohamad Ahmad Ali Hassan", constants=C)
413+ >>> hn.first, hn.middle, hn.last
414+ ('Mohamad', '', 'Ahmad Ali Hassan')
415+
416+ """
417+
392418 def __init__ (self ,
393419 prefixes : Iterable [str ] = PREFIXES ,
394420 suffix_acronyms : Iterable [str ] = SUFFIX_ACRONYMS ,
@@ -401,6 +427,7 @@ def __init__(self,
401427 capitalization_exceptions : TupleManager [str ] | Iterable [tuple [str , str ]] = CAPITALIZATION_EXCEPTIONS ,
402428 regexes : RegexTupleManager | TupleManager [re .Pattern [str ]] | Iterable [tuple [str , re .Pattern [str ]]] = REGEXES ,
403429 patronymic_name_order : bool = False ,
430+ middle_name_as_last : bool = False ,
404431 ) -> None :
405432 # These four descriptor assignments call _CachedUnionMember.__set__, which
406433 # calls _invalidate_pst() and establishes self._pst. They must come before
@@ -423,6 +450,7 @@ def __init__(self,
423450 # needing to override parse_nicknames() itself. See issue #112.
424451 self .extra_nickname_delimiters = TupleManager ()
425452 self .patronymic_name_order = patronymic_name_order
453+ self .middle_name_as_last = middle_name_as_last
426454
427455 def _invalidate_pst (self ) -> None :
428456 self ._pst = None
0 commit comments