Releases: derek73/python-nameparser
Release list
v1.4.0
- Add
Constants.copy(), a detached deep copy that preserves the source instance's current customizations (unlikeConstants(), which always starts from library defaults) -- useful asCONSTANTS.copy()for a private snapshot of the shared config (#260) - Deprecate passing
constants=NonetoHumanName(or assigninghn.C = None): it silently builds a freshConstants(), discarding any customizations the caller may have expected to carry over from the sharedCONSTANTS. EmitsDeprecationWarning; will raiseTypeErrorin 2.0. Useconstants=Constants()for fresh library defaults orconstants=CONSTANTS.copy()for a private snapshot instead (closes #260) - Deprecate assigning
Constants.empty_attribute_defaultfor removal in 2.0 (#255): onceNonesupport goes, the only legal value left is the default'', so a dial with one position isn't configuration. EmitsDeprecationWarning; reading the attribute is unaffected - Deprecate unknown-key attribute access on
TupleManager/RegexTupleManager(CONSTANTS.regexes.typo,CONSTANTS.capitalization_exceptions.typo, etc.) for removal in 2.0 (#256): a misspelled or omitted key currently degrades silently (None/EMPTY_REGEX) with no traceback pointing at the typo. EmitsDeprecationWarningnaming the miss and the known keys; will raiseAttributeErrorin 2.0..get()remains available for intentional soft access - Deprecate
HumanNameslice access (name[1:-3]) and item assignment (name['first'] = value) for removal in 2.0 (#258): field access by position has no real use case, and item assignment duplicates plain attribute assignment. Both emitDeprecationWarning; string-key access (name['first']) is unaffected - Deprecate
SetManager.add_with_encoding()itself for removal in 2.0 (#245), regardless of argument type: useadd()instead (decoding bytes first). Previously only thebytespath warned; thestrpath was silent even though the whole method goes away - Deprecate loading a legacy-format
Constantspickle (written by nameparser <= 1.2.x, before the 1.3.0 pickle fix) for removal in 2.0 (#279):__setstate__'s migration shim currently skips the stale computed-property key silently. EmitsDeprecationWarningonce per call telling users to re-pickle; will raiseValueErrorin 2.0 - Fix the
"Lastname, Firstname"comma format not being recognized when the input uses the Arabic comma،(U+060C, the standard comma in Arabic/Persian/Urdu text) or the fullwidth CJK comma,(U+FF0C) instead of the ASCII comma: both variants now also split the format and no longer leak into the parsed output (closes #265)
Full changelog: https://github.com/derek73/python-nameparser/blob/master/docs/release_log.rst
v1.3.1
Patch release with two output-corruption bug fixes. No API changes. Full details in the release log.
Bug fixes
- Invisible Unicode bidirectional control characters are now stripped during preprocessing (#266, thanks @apoorva-01) — LRM/RLM/ALM, the embedding/override marks, and the isolates U+2066–U+2069 previously survived parsing and stuck to
first/last/etc., so a copy-pasted right-to-left name silently failed equality and dedup. Disable viaCONSTANTS.regexes.bidi = False. str()no longer corrupts name text containing the substring"None"whenempty_attribute_defaultisNone(#254) — e.g."Nonez Smith"rendered as"z Smith". Empty attributes are now substituted as''before the format string is applied, instead of scrubbing the interpolated"None"from the output afterward. Present since 2016; the default''configuration was never affected.
v1.3.0
This release works through essentially the entire backlog of open issues — nearly every bug and feature request in the tracker, including several dating back to 2014. Alongside the fixes, it adds long-requested functionality: maiden name support, surname-prefix splitting, patronymic name ordering, and a set of new customization hooks on Constants.
The release was developed with Claude Code, and every fix and feature ships with regression tests. The complete list of changes is below.
This release is the bridge release ahead of 2.0: every planned 2.0 removal now has its replacement shipped and emits a DeprecationWarning naming it, so code can migrate while both APIs work. Full details in the release log.
Deprecations (removal in 2.0)
==andhash()onHumanName(#223) — the design's three promises (case-insensitive equality, equality with plain strings, hashability) are mutually inconsistent, equality depends onstring_format, andmaidenis invisible to it. Replacements, new in this release:matches()for semantic comparison (name.matches("Smith, John")andname.matches("John Smith")both match) andcomparison_key()for sets, dicts, dedup, and sorting.bytesinput (#245) — decode first, e.g.value.decode('utf-8'); theencodingkwarg is deprecated with it.SetManager.__call__(#243) — iterate the manager or copy withset(manager).SetManager.remove()of a missing member (#243) — will raiseKeyErrorin 2.0 likeset.remove; newdiscard()is the intentional ignore-missing spelling.
Breaking changes
HumanNameis no longer its own iterator;iter(name)returns a fresh independent iterator (fixes state corruption frombreak/nested loops/len()mid-loop) (#225)- Vestigial
unparsableattribute removed (unreachable since 2013; uselen(name) == 0);__ne__removed (derived from__eq__) REGEXESandCAPITALIZATION_EXCEPTIONSare now dicts — iterate with.items()(#227, #233)- Internal
__process_initial__renamed_process_initial(dunder names are reserved)
Behavior changes affecting parse output (default-on)
- Bound Arabic given-name prefixes (
abdul,abu, …) join forward into the first name (#150); disable viaCONSTANTS.bound_first_names.clear() - A leading unknown multi-letter period-abbreviation (
"Major.") parses as a title (#109) - Parsing no longer mutates the shared
CONSTANTSit reads — parse results no longer depend on what was parsed earlier in the process, and parsing is thread-safe against config writes
New
maidenfield withmaiden_delimitersrouting (#22);given_names(#157);last_base/last_prefixesfor surname particles (#130, #132)patronymic_name_orderfor Russian and Turkic formal-order names (#85, #185);middle_name_as_last(#133);non_first_name_prefixes(#121); expanded international titles and prefixes (#18, #101, #187)initials_separator(#171),suffix_delimiter(#156),nickname_delimiters(#110, #112),suffix_acronyms_ambiguous(#111)
Hardening & fixes
- Config boundaries now fail loud instead of silently corrupting: bare strings no longer shred into characters (#238), assignment paths validate (#239, #241),
TupleManagerrejects malformed input (#242), membership checks normalize like every other operation (#244),Constantssubclasses are respected (#226) - Customized
Constantssurvivepickle/deepcopy(#167, #168, #169); many parsing fixes — suffix boundaries with prefixed last names (#100), repeated prefix chains (#208), degenerate comma input, roman-numeral and suffix recognition in comma formats (#136, #144), and more
v1.2.1
What's Changed
- 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_default - Add
python -m nameparser "Name String"command-line helper that prints a parsed name - Reorganize the test suite from a single
tests.pyinto atests/pytest package
Full Changelog: v1.2.0...v1.2.1
v1.2.0
What's changed
- 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.py - Remove dead Python 2 compatibility shims (
ENCODINGconstant,next()aliases) - Modernize CI: uv-based workflow, trusted publishing to PyPI, Dependabot