Release Log¶
1.3.0 - July 5, 2026
Breaking Changes & Deprecations
Deprecate
HumanName.__eq__and__hash__for removal in 2.0 (#223): the current design’s three promises — case-insensitive equality, equality with plain strings, and hashability — are mutually inconsistent (equal objects can hash differently), equality depends onstring_format, andmaidenis invisible to it. Both now emitDeprecationWarningnaming the replacement; behavior is otherwise unchanged until 2.0 (closes #224)Deprecate
bytesinput for removal in 2.0 (#245): passingbytestoHumanName/full_nameor toSetManager.add()/add_with_encoding()now emitsDeprecationWarning— decode first, e.g.value.decode('utf-8'). Theencodingconstructor argument is deprecated with itDeprecate
SetManager.__call__for removal in 2.0 (#243): calling a manager returns the raw underlying set, so mutating the result bypasses normalization and cache invalidation; iterate the manager or copy withset(manager)insteadAdd
SetManager.discard(), and deprecateremove()of a missing member (#243): it currently does nothing but will raiseKeyErrorin 2.0, matchingset.remove; usediscard()for intentional ignore-missing removal. Removing present members is unchanged and does not warnFix
HumanNameacting as its own iterator with a stored cursor: breaking out of a loop, iterating in nested loops, or callinglen(name)mid-loop corrupted subsequent iteration;iter(name)now returns a fresh independent iterator each time.next(name)on the instance itself (undocumented) now raisesTypeError— callnext(iter(name))instead (closes #225)Remove the vestigial
unparsableattribute: the guard that was meant to set it has been unreachable since 2013 (v0.2.9), so it has reportedFalsefor every parsed name for over a decade; checklen(name) == 0to detect an empty parseRemove
__ne__; Python 3 derives!=from__eq__automaticallyChange internal initials helper
__process_initial__to_process_initial: double-underscore-both-sides names are reserved for Python special methods; subclasses overriding the old name must rename their overrideChange
REGEXESfrom asetof(name, pattern)tuples to adict, so a duplicate name is a visible overwrite in the source instead of a nondeterministic winner at import time; code iteratingREGEXESdirectly now gets keys instead of pairs — use.items()(#227)Change
CAPITALIZATION_EXCEPTIONSfrom a tuple of(key, value)tuples to adict; code iterating it directly now gets keys instead of pairs — use.items()(#233)
Behavior Changes (affect existing parse output)
Add
bound_first_namesset toConstants; bound Arabic given-name prefixes (abdul,abu, etc.) now join forward to form a single first name (e.g."abdul salam ahmed salem"→first="abdul salam",middle="ahmed",last="salem"). Disable viaCONSTANTS.bound_first_names.clear(). Default-on: changes parsing output for names with these prefixes. (#150)Treat an unrecognized, multi-letter token ending in a period in the leading title run (before the first name is set), e.g.
"Major.", as atitleinstead of afirstname; internal-period abbreviations ("E.T.") and single-letter initials ("J.") are unaffected. Default-on: changes parsing of names with a leading unknown period-abbreviation (closes #109)Fix parsing writing back into the
Constantsit reads (usually the shared module-levelCONSTANTS): 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 permanentlyadd()-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 threadsFix
__hash__to lowercase the name like__eq__does, so equalHumanNameinstances hash equal and behave correctly in sets and dicts
New comparison methods
Add
matches()andcomparison_key()for explicit name comparison:matches()compares parsed components case-insensitively (parsingstrarguments first, soname.matches("Smith, John")andname.matches("John Smith")both match) andcomparison_key()returns a hashable tuple of the seven components for dedup, dict keys, and sorting (#224)
New name fields
Add a first-class
maidenfield andmaiden_delimiterstoConstants, so a delimiter (e.g. parenthesis) can be routed tomaideninstead ofnicknamefor alternate/maiden surnames, e.g."Baker (Johnson), Jenny"(closes #22)Add
given_names(andgiven_names_list) attribute as aggregate of first and middle names, mirroringsurnames(closes #157)Add
last_base,last_prefixes(and_listvariants) for splitting last-name prefix particles (tussenvoegsels) from the core surname (#130, #132)
New customization options
Add
initials_separatortoConstantsandHumanNameto control spacing between consecutive initials within a name group (#171)Add
suffix_delimitertoConstantsandHumanNamefor parsing suffixes separated by arbitrary delimiters, e.g."RN - CRNA"(#156)Add
nickname_delimiterstoConstantsfor registering additional nickname-delimiter regex patterns at runtime, without subclassing (closes #110, #112)Add
suffix_acronyms_ambiguoustoConstantsfor acronym suffixes that also read as given-name nicknames (e.g."JD","Ed"), used when disambiguating parenthesized/quoted content (#111)
International name support
Add
patronymic_name_orderflag toConstantsandHumanNamefor opt-in detection and reordering of Russian formal-order names (Surname GivenName Patronymic) (#85)Add Turkic (Azerbaijani/Central-Asian) patronymic detection to
patronymic_name_order, rotating the reversed 4-token formal shape (Surname GivenName PatronymicRoot Marker, e.g.oglu/qizi) into Western order (#185)Add
middle_name_as_lastflag toConstantsandHumanNamefor opt-in folding of middle names into the last name, for naming systems with no middle-name concept (e.g. Arabic patronymic chaining) (#133)Add
non_first_name_prefixestoConstants: a leading particle that is never a first name (e.g."de Mesnil","dos Santos") now parses as a surname with an empty first name, instead of treating the particle as the first name (closes #121)Add international honorifics to
TITLES(#187)Add German/Austrian nobility and ecclesiastical titles to
TITLES(closes #101)Add German/Dutch last-name prefixes and title/degree suffixes; fix
join_on_conjunctions()to register multi-word prefix chains (e.g."von und zu") as prefixes, mirroring existing title handling (closes #18)
Parsing fixes
Fix suffix boundary lookup for prefixed last names with a title before and after (e.g.
"dr Vincent van Gogh dr"producing a corrupted middle name) (closes #100)Fix a repeated prefix word in a prefix chain (e.g.
"Juan de la de la Vega") silently dropping the earlier occurrence injoin_on_conjunctions(): value-basedpieces.index(prefix)lookups re-found the wrong occurrence once the list had already been mutated by prior joins; prefix positions are now tracked positionally instead of re-derived by value (closes #208)Fix a trailing suffix being silently dropped after an empty comma segment, e.g.
"Doe, John,, Jr."losing the"Jr."Fix degenerate comma input (a bare
","or an empty comma segment, e.g."Doe,, Jr.","John Doe, Jr.,,") leaving an empty-string member infirst_list,last_list, orsuffix_list; whitespace-only tokens assigned via the setters are dropped the same wayFix suffix-shaped parenthesized/quoted content (e.g.
"(Ret)","(MBA)") being misclassified as a nickname instead of a suffix (closes #111)Fix single-character symbol conjunctions (e.g.
"&","/") being ignored in short names (#173)Fix recognition of single-letter roman numeral suffixes (e.g.
"I","V") in suffix-comma format (closes #136)Fix recognition of trailing
suffix_not_acronyms(e.g."Jr.") in lastname-comma format (closes #144)Fix missing comma between
'msc'and'mscmsm'insuffix_acronyms, which silently concatenated them into a bogus'mscmscmsm'entry (#111)Fix
'apn aprn'split into separatesuffix_acronymsentries so each is recognized independently (closes #155)
Formatting and output fixes
Fix
IndexErrorininitials()/initials_list()when a*_listattribute was assigned directly with an element containing unnormalized whitespace (e.g.name.middle_list = ['Q R']), bypassing the parser’s whitespace normalization (closes #232)Fix
initials()emitting a stray empty initial (e.g."J. . V.") – or raisingTypeErrorwhenempty_attribute_defaultisNone– for name parts with no initialable words, e.g. a prefix-only middle name like"de la"Fix capitalization of suffix acronyms written with dots, e.g.
"M.D."(closes #141)Fix extra whitespace before punctuation in
str()output when astring_formatfield is empty (closes #139)Fix spurious leading space in surnames and empty token in suffix list after
capitalize()with an empty middle or suffix (#164)
API correctness and cleanup
Fix the five non-cached-union
SetManager-backedConstantsattributes (first_name_titles,conjunctions,bound_first_names,non_first_name_prefixes,suffix_acronyms_ambiguous) accepting non-SetManagerassignment silently (e.g.constants.conjunctions = 'and'), degrading membership checks into substring tests with no error; assignment now raisesTypeErrorlike the four cached-union attributes already did (closes #241)Fix
HumanName.Caccepting an invalidconstantsvalue on post-construction assignment (e.g.hn.C = 'garbage'), bypassing the constructor’s validation and failing later with an unrelatedAttributeError;Cis now a property that validates on assignment too (closes #239)Fix
TupleManager(andRegexTupleManager) accepting a bare string/bytes argument (raising a crypticdict-internalsValueError) or an iterable of 2-character strings (silently shredding each into a key/value pair, e.g.Constants(capitalization_exceptions=['ii'])becoming{'i': 'i'}); both now raiseTypeErrorwith a clear message (closes #242)Fix
SetManager.__contains__being the one operation that didn’t normalize (lowercase, strip leading/trailing periods) its operand, so e.g.'Dr.' in constants.titlescould returnFalseeven though the title was correctly configured; membership checks now normalize likeadd()/remove()/the constructor/the set operators (closes #244)Fix a bare string passed to a set-backed
Constantsargument (e.g.Constants(titles='dr')), toSetManager, or as aSetManagerset-operator operand (e.g.constants.titles |= 'esq') being silently split into single characters, replacing or polluting the set and producing wrong parses with no error; it now raisesTypeErrorwith the suggested fix — wrap strings in a list, decodebytesfirst (closes #238)Fix
SetManagerset operators and the constructor skipping the lowercase/strip-edge-periods normalization thatadd()applies:constants.titles |= ['Esq.']kept a raw'Esq.'the parser’s lookups could never match,titles & ['Dr.']missed'dr', andConstants(titles=[...])stored raw elements that silently never matched; elements and operands are now normalized everywhere, and non-strelements (bytes,None, numbers) raiseTypeErrorinstead of crashing cryptically or being coercedFix the
constantsconstructor argument silently discardingConstantssubclass instances: the exact-type check replaced them with fresh defaults, throwing away the caller’s configuration. Subclass instances are now used as given; anything that is neitherNonenor aConstantsinstance now raisesTypeErrorinstead of being silently swapped for defaults (closes #226)Fix
Constantscustomizations, singleton identity, andTupleManagersubclass being lost acrosspickle/deepcopyround-trips (#167, #168, #169)Fix
is_rootname()returning stale results afteradd()/remove()ontitles,prefixes,suffix_acronyms, orsuffix_not_acronyms(#166)Fix the library logger calling
setLevel(logging.ERROR)on import, which silently discarded log records regardless of an application’s own logging configuration; the logger now leaves its level atNOTSETand lets the application control verbosity (closes #228)Minor internal cleanups: drop a dead length check in the initials helper, simplify double-wrapped
len(list(...))calls, and other small parser tidy-ups with no behavior change (closes #229)Change
Constants.__repr__to report collection sizes and non-default scalar config, replacing the uninformative<Constants() instance>(#221)
- 1.2.1 - June 19, 2026
Fix
initials()interpolating the literalNonefor empty name parts whenempty_attribute_default = None(e.g."J. None D."); empty parts now render as an empty string and a fully-empty result returnsempty_attribute_defaultAdd
python -m nameparser "Name String"command-line helper that prints a parsed nameReorganize the test suite from a single
tests.pyinto atests/pytest package
- 1.2.0 - June 11, 2026
Drop Python 2 and Python < 3.10 support; Python 3.10–3.14 now required
Add type hints and type declarations (PEP 561
py.typedmarker)Migrate build tooling to
pyproject.toml, dropsetup.pyRemove dead Python 2 compatibility shims (
ENCODINGconstant,next()aliases)Modernize CI: uv-based workflow, trusted publishing to PyPI, Dependabot
- 1.1.3 - September 20, 2023
Fix case when we have two same prefixes in the name ()#147)
- 1.1.2 - November 13, 2022
Add support for attributes in constructor (#140)
Make HumanName instances hashable (#138)
Update repr for names with single quotes (#137)
- 1.1.1 - January 28, 2022
Fix bug in is_suffix handling of lists (#129)
- 1.1.0 - January 3, 2022
Add initials support (#128)
Add more titles and prefixes (#120, #127, #128, #119)
- 1.0.6 - February 8, 2020
Fix Python 3.8 syntax error (#104)
- 1.0.5 - Dec 12, 2019
Fix suffix parsing bug in comma parts (#98)
Fix deprecation warning on Python 3.7 (#94)
Improved capitalization support of mixed case names (#90)
Remove “elder” from titles (#96)
Add post-nominal list from Wikipedia to suffixes (#93)
- 1.0.4 - June 26, 2019
Better nickname handling of multiple single quotes (#86)
full_name attribute now returns formatted string output instead of original string (#87)
- 1.0.3 - April 18, 2019
fix sys.stdin usage when stdin doesn’t exist (#82)
support for escaping log entry arguments (#84)
- 1.0.2 - Oct 26, 2018
Fix handling of only nickname and last name (#78)
- 1.0.1 - August 30, 2018
Fix overzealous regex for “Ph. D.” (#43)
Add surnames attribute as aggregate of middle and last names
- 1.0.0 - August 30, 2018
Fix support for nicknames in single quotes (#74)
Change prefix handling to support prefixes on first names (#60)
Fix prefix capitalization when not part of lastname (#70)
Handle erroneous space in “Ph. D.” (#43)
- 0.5.8 - August 19, 2018
Add “Junior” to suffixes (#76)
Add “dra” and “srta” to titles (#77)
- 0.5.7 - June 16, 2018
Fix doc link (#73)
Fix handling of “do” and “dos” Portuguese prefixes (#71, #72)
- 0.5.6 - January 15, 2018
Fix python version check (#64)
- 0.5.5 - January 10, 2018
Support J.D. as suffix and Wm. as title
- 0.5.4 - December 10, 2017
Add Dr to suffixes (#62)
Add the full set of Italian derivatives from “di” (#59)
Add parameter to specify the encoding of strings added to constants, use ‘UTF-8’ as fallback (#67)
Fix handling of names composed entirely of conjunctions (#66)
- 0.5.3 - June 27, 2017
Remove emojis from initial string by default with option to include emojis (#58)
- 0.5.2 - March 19, 2017
Added names scrapped from VIAF data, thanks daryanypl (#57)
- 0.5.1 - August 12, 2016
Fix error for names that end with conjunction (#54)
- 0.5.0 - August 4, 2016
Refactor join_on_conjunctions(), fix #53
- 0.4.1 - July 25, 2016
Remove “bishop” from titles because it also could be a first name
Fix handling of lastname prefixes with periods, e.g. “Jane St. John” (#50)
- 0.4.0 - June 2, 2016
Remove “CONSTANTS.suffixes”, replaced by “suffix_acronyms” and “suffix_not_acronyms” (#49)
Add “du” to prefixes
Add “sheikh” variations to titles
Add parameter to force capitalization of mixed case strings
- 0.3.16 - March 24, 2016
Clarify LGPL licence version (#47)
Skip pickle tests if pickle not installed (#48)
- 0.3.15 - March 21, 2016
Fix string format when empty_attribute_default = None (#45)
Include tests in release source tarball (#46)
- 0.3.14 - March 18, 2016
Add CONSTANTS.empty_attribute_default to customize value returned for empty attributes (#44)
- 0.3.13 - March 14, 2016
Improve string format handling (#41)
- 0.3.12 - March 13, 2016
Fix first name clash with suffixes (#42)
Fix encoding of constants added via the python shell
Add “MSC” to suffixes, fix #41
- 0.3.11 - October 17, 2015
Fix bug capitalization exceptions (#39)
- 0.3.10 - September 19, 2015
Fix encoding of byte strings on python 2.x (#37)
- 0.3.9 - September 5, 2015
Separate suffixes that are acronyms to handle periods differently, fixes #29, #21
Don’t find titles after first name is filled, fixes (#27)
Add “chair” titles (#37)
- 0.3.8 - September 2, 2015
Use regex to check for roman numerals at end of name (#36)
Add DVM to suffixes
- 0.3.7 - August 30, 2015
Speed improvement, 3x faster
Make HumanName instances pickleable
- 0.3.6 - August 6, 2015
Fix strings that start with conjunctions (#20)
handle assigning lists of names to a name attribute
support dictionary-like assignment of name attributes
- 0.3.5 - August 4, 2015
Fix handling of string encoding in python 2.x (#34)
Add support for dictionary key access, e.g. name[‘first’]
add ‘santa’ to prefixes, add ‘cpa’, ‘csm’, ‘phr’, ‘pmp’ to suffixes (#35)
Fix prefixes before multi-part last names (#23)
Fix capitalization bug (#30)
- 0.3.4 - March 1, 2015
Fix #24, handle first name also a prefix
Fix #26, last name comma format when lastname is also a title
- 0.3.3 - Aug 4, 2014
Allow suffixes to be chained (#8)
Handle trailing suffix in last name comma format (#3). Removes support for titles with periods but no spaces in them, e.g. “Lt.Gen.”. (#21)
- 0.3.2 - July 16, 2014
Retain original string in “original” attribute.
Collapse white space when using custom string format.
Fix #19, single comma name format may have trailing suffix
- 0.3.1 - July 5, 2014
Fix Pypi package, include new config module.
- 0.3.0 - July 4, 2014
Refactor configuration to simplify modifications to constants (backwards incompatible)
use unicode_literals to simplify Python 2 & 3 support.
Generate documentation using sphinx and host on readthedocs.
- 0.2.10 - May 6, 2014
If name is only a title and one part, assume it’s a last name instead of a first name, with exceptions for some titles like ‘Sir’. (#7).
Add some judicial and other common titles. (#9)
- 0.2.9 - Apr 1, 2014
Add a new nickname attribute containing anything in parenthesis or double quotes (Issue 33).
- 0.2.8 - Oct 25, 2013
Add support for Python 3.3+. Thanks to @corbinbs.
- 0.2.7 - Feb 13, 2013
Fix bug with multiple conjunctions in title
add legal and crown titles
- 0.2.6 - Feb 12, 2013
Fix python 2.6 import error on logging.NullHandler
- 0.2.5 - Feb 11, 2013
Set logging handler to NullHandler
Remove ‘ben’ from PREFIXES because it’s more common as a name than a prefix.
Deprecate BlankHumanNameError. Do not raise exceptions if full_name is empty string.
- 0.2.4 - Feb 10, 2013
Adjust logging, don’t set basicConfig. Fix Issue 10 and Issue 26.
Fix handling of single lower case initials that are also conjunctions, e.g. “john e smith”. Re Issue 11.
Fix handling of initials with no space separation, e.g. “E.T. Jones”. Fix #11.
Do not remove period from first name, when present.
Remove ‘e’ from PREFIXES because it is handled as a conjunction.
Python 2.7+ required to run the tests. Mark known failures.
tests/test.py can now take an optional name argument that will return repr() for that name.
0.2.3 - Fix overzealous “Mac” regex
0.2.2 - Fix parsing error
- 0.2.0
Significant refactor of parsing logic. Handle conjunctions and prefixes before parsing into attribute buckets.
Support attribute overriding by assignment.
Support multiple titles.
Lowercase titles constants to fix bug with comparison.
Move documentation to README.rst, add release log.
0.1.4 - Use set() in constants for improved speed. setuptools compatibility - sketerpot
0.1.3 - Add capitalization feature - twotwo
0.1.2 - Add slice support