nameparser 1.2.1__tar.gz → 1.3.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. {nameparser-1.2.1/nameparser.egg-info → nameparser-1.3.1}/PKG-INFO +63 -37
  2. {nameparser-1.2.1 → nameparser-1.3.1}/README.rst +62 -36
  3. {nameparser-1.2.1 → nameparser-1.3.1}/nameparser/_version.py +1 -1
  4. nameparser-1.3.1/nameparser/config/__init__.py +861 -0
  5. nameparser-1.3.1/nameparser/config/bound_first_names.py +12 -0
  6. nameparser-1.3.1/nameparser/config/capitalization.py +10 -0
  7. {nameparser-1.2.1 → nameparser-1.3.1}/nameparser/config/conjunctions.py +2 -2
  8. nameparser-1.3.1/nameparser/config/prefixes.py +97 -0
  9. nameparser-1.3.1/nameparser/config/regexes.py +53 -0
  10. {nameparser-1.2.1 → nameparser-1.3.1}/nameparser/config/suffixes.py +48 -9
  11. {nameparser-1.2.1 → nameparser-1.3.1}/nameparser/config/titles.py +55 -4
  12. nameparser-1.3.1/nameparser/parser.py +1595 -0
  13. {nameparser-1.2.1 → nameparser-1.3.1}/nameparser/util.py +1 -2
  14. {nameparser-1.2.1 → nameparser-1.3.1/nameparser.egg-info}/PKG-INFO +63 -37
  15. {nameparser-1.2.1 → nameparser-1.3.1}/nameparser.egg-info/SOURCES.txt +7 -0
  16. {nameparser-1.2.1 → nameparser-1.3.1}/pyproject.toml +7 -5
  17. nameparser-1.3.1/tests/base.py +71 -0
  18. {nameparser-1.2.1 → nameparser-1.3.1}/tests/conftest.py +9 -21
  19. nameparser-1.3.1/tests/test_bound_first_names.py +154 -0
  20. {nameparser-1.2.1 → nameparser-1.3.1}/tests/test_brute_force.py +14 -6
  21. {nameparser-1.2.1 → nameparser-1.3.1}/tests/test_capitalization.py +60 -0
  22. nameparser-1.3.1/tests/test_config_attribute_docstrings.py +79 -0
  23. {nameparser-1.2.1 → nameparser-1.3.1}/tests/test_conjunctions.py +73 -0
  24. nameparser-1.3.1/tests/test_constants.py +971 -0
  25. nameparser-1.3.1/tests/test_east_slavic_patronymic_order.py +194 -0
  26. nameparser-1.3.1/tests/test_initials.py +219 -0
  27. nameparser-1.3.1/tests/test_middle_name_as_last.py +122 -0
  28. nameparser-1.3.1/tests/test_nicknames.py +309 -0
  29. {nameparser-1.2.1 → nameparser-1.3.1}/tests/test_output_format.py +56 -5
  30. nameparser-1.3.1/tests/test_parser_util.py +39 -0
  31. nameparser-1.3.1/tests/test_prefixes.py +395 -0
  32. nameparser-1.3.1/tests/test_python_api.py +647 -0
  33. nameparser-1.3.1/tests/test_suffixes.py +448 -0
  34. {nameparser-1.2.1 → nameparser-1.3.1}/tests/test_titles.py +131 -0
  35. nameparser-1.3.1/tests/test_turkic_patronymic_order.py +302 -0
  36. {nameparser-1.2.1 → nameparser-1.3.1}/tests/test_variations.py +21 -11
  37. nameparser-1.2.1/nameparser/config/__init__.py +0 -288
  38. nameparser-1.2.1/nameparser/config/capitalization.py +0 -10
  39. nameparser-1.2.1/nameparser/config/prefixes.py +0 -47
  40. nameparser-1.2.1/nameparser/config/regexes.py +0 -28
  41. nameparser-1.2.1/nameparser/parser.py +0 -999
  42. nameparser-1.2.1/tests/base.py +0 -40
  43. nameparser-1.2.1/tests/test_constants.py +0 -106
  44. nameparser-1.2.1/tests/test_initials.py +0 -128
  45. nameparser-1.2.1/tests/test_nicknames.py +0 -176
  46. nameparser-1.2.1/tests/test_prefixes.py +0 -118
  47. nameparser-1.2.1/tests/test_python_api.py +0 -226
  48. nameparser-1.2.1/tests/test_suffixes.py +0 -138
  49. {nameparser-1.2.1 → nameparser-1.3.1}/AUTHORS +0 -0
  50. {nameparser-1.2.1 → nameparser-1.3.1}/LICENSE +0 -0
  51. {nameparser-1.2.1 → nameparser-1.3.1}/MANIFEST.in +0 -0
  52. {nameparser-1.2.1 → nameparser-1.3.1}/nameparser/__init__.py +0 -0
  53. {nameparser-1.2.1 → nameparser-1.3.1}/nameparser/__main__.py +0 -0
  54. {nameparser-1.2.1 → nameparser-1.3.1}/nameparser/py.typed +0 -0
  55. {nameparser-1.2.1 → nameparser-1.3.1}/nameparser.egg-info/dependency_links.txt +0 -0
  56. {nameparser-1.2.1 → nameparser-1.3.1}/nameparser.egg-info/requires.txt +0 -0
  57. {nameparser-1.2.1 → nameparser-1.3.1}/nameparser.egg-info/top_level.txt +0 -0
  58. {nameparser-1.2.1 → nameparser-1.3.1}/setup.cfg +0 -0
  59. {nameparser-1.2.1 → nameparser-1.3.1}/tests/__init__.py +0 -0
  60. {nameparser-1.2.1 → nameparser-1.3.1}/tests/test_first_name.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nameparser
3
- Version: 1.2.1
3
+ Version: 1.3.1
4
4
  Summary: A simple Python module for parsing human names into their individual components.
5
5
  Author-email: Derek Gulbranson <derek73@gmail.com>
6
6
  License: LGPL
@@ -29,7 +29,7 @@ Dynamic: license-file
29
29
  Name Parser
30
30
  ===========
31
31
 
32
- |Build Status| |PyPI| |PyPI version| |Documentation|
32
+ |Build Status| |PyPI| |PyPI version| |Documentation| |License| |Downloads| |Codecov|
33
33
 
34
34
  A simple Python (3.10+) module for parsing human names into their
35
35
  individual components.
@@ -40,8 +40,12 @@ individual components.
40
40
  * hn.last
41
41
  * hn.suffix
42
42
  * hn.nickname
43
+ * hn.maiden
43
44
  * hn.surnames *(middle + last)*
45
+ * hn.given_names *(first + middle)*
44
46
  * hn.initials *(first initial of each name part)*
47
+ * hn.last_base *(last, minus any prefixes)*
48
+ * hn.last_prefixes *(leading last-name particles, e.g. "van der")*
45
49
 
46
50
  Supported Name Structures
47
51
  ~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -53,19 +57,35 @@ are optional. Comma-separated format like "Last, First" is also supported.
53
57
  2. Lastname [Suffix], Title Firstname (Nickname) Middle Middle[,] Suffix [, Suffix]
54
58
  3. Title Firstname M Lastname [Suffix], Suffix [Suffix] [, Suffix]
55
59
 
56
- Instantiating the `HumanName` class with a string splits on commas and then spaces,
57
- classifying name parts based on placement in the string and matches against known name
58
- pieces like titles and suffixes.
59
-
60
- It correctly handles some common conjunctions and special prefixes to last names
61
- like "del". Titles and conjunctions can be chained together to handle complex
62
- titles like "Asst Secretary of State". It can also try to correct capitalization
63
- of names that are all upper- or lowercase names.
64
-
65
- It attempts the best guess that can be made with a simple, rule-based approach.
66
- Its main use case is English and it is not likely to be useful for languages
67
- that do not conform to the supported name structure. It's not perfect, but it
68
- gets you pretty far.
60
+ How It Works
61
+ ~~~~~~~~~~~~
62
+
63
+ The parser works in two layers.
64
+
65
+ A **vocabulary layer** recognizes name pieces by what they are, using
66
+ configurable sets of known words: titles ("Dr."), suffixes ("III", "PhD"),
67
+ last-name prefixes ("de la"), conjunctions ("y", "&"), and delimited
68
+ nicknames ("Doc"). Titles and conjunctions chain together to handle complex
69
+ titles like "Asst Secretary of State"; prefixes join forward so "de la Vega"
70
+ stays one last name. This layer doesn't care where in the string a word
71
+ appears and it's the layer you customize, by adding or removing entries
72
+ in the sets to fit your dataset.
73
+
74
+ A **positional layer** then assigns everything the vocabulary layer didn't
75
+ claim, based purely on where it sits: the first unclaimed word is the first
76
+ name, the last one is the last name, and anything between them is a middle
77
+ name. There is no semantic understanding — "Dr" is a title when it comes
78
+ before a name and a suffix when it comes after ("pre-nominal" and
79
+ "post-nominal" would probably be better names) — and no attempt to correct
80
+ mistakes in the input.
81
+
82
+ It attempts the best guess that can be made with a simple, deterministic,
83
+ rule-based approach — no statistical models or machine learning; the same
84
+ input always parses the same way. The positional layer assumes Western name
85
+ order (given name first), so the main use case is English and other
86
+ languages that share that structure. It can also try to correct the
87
+ capitalization of names that are all upper- or lowercase. It's not perfect,
88
+ but it gets you pretty far.
69
89
 
70
90
  Installation
71
91
  ------------
@@ -93,17 +113,18 @@ Quick Start Example
93
113
  >>> name = HumanName("Dr. Juan Q. Xavier de la Vega III (Doc Vega)")
94
114
  >>> name
95
115
  <HumanName : [
96
- title: 'Dr.'
97
- first: 'Juan'
98
- middle: 'Q. Xavier'
99
- last: 'de la Vega'
100
- suffix: 'III'
101
- nickname: 'Doc Vega'
116
+ title: 'Dr.'
117
+ first: 'Juan'
118
+ middle: 'Q. Xavier'
119
+ last: 'de la Vega'
120
+ suffix: 'III'
121
+ nickname: 'Doc Vega'
122
+ maiden: ''
102
123
  ]>
103
124
  >>> name.last
104
125
  'de la Vega'
105
126
  >>> name.as_dict()
106
- {'last': 'de la Vega', 'suffix': 'III', 'title': 'Dr.', 'middle': 'Q. Xavier', 'nickname': 'Doc Vega', 'first': 'Juan'}
127
+ {'title': 'Dr.', 'first': 'Juan', 'middle': 'Q. Xavier', 'last': 'de la Vega', 'suffix': 'III', 'nickname': 'Doc Vega', 'maiden': ''}
107
128
  >>> str(name)
108
129
  'Dr. Juan Q. Xavier de la Vega III (Doc Vega)'
109
130
  >>> name.string_format = "{first} {last}"
@@ -111,32 +132,31 @@ Quick Start Example
111
132
  'Juan de la Vega'
112
133
 
113
134
 
114
- The parser does not attempt to correct mistakes in the input. It mostly just splits on white
115
- space and puts things in buckets based on their position in the string. This also means
116
- the difference between 'title' and 'suffix' is positional, not semantic. "Dr" is a title
117
- when it comes before the name and a suffix when it comes after. ("Pre-nominal"
118
- and "post-nominal" would probably be better names.)
135
+ Because the positional layer has no semantic understanding, position is
136
+ everything:
119
137
 
120
138
  ::
121
139
 
122
140
  >>> name = HumanName("1 & 2, 3 4 5, Mr.")
123
141
  >>> name
124
142
  <HumanName : [
125
- title: ''
126
- first: '3'
127
- middle: '4 5'
128
- last: '1 & 2'
129
- suffix: 'Mr.'
130
- nickname: ''
143
+ title: ''
144
+ first: '3'
145
+ middle: '4 5'
146
+ last: '1 & 2'
147
+ suffix: 'Mr.'
148
+ nickname: ''
149
+ maiden: ''
131
150
  ]>
132
151
 
133
152
  Customization
134
153
  -------------
135
154
 
136
- Your project may need some adjustment for your dataset. You can
137
- do this in your own pre- or post-processing, by `customizing the configured pre-defined
138
- sets`_ of titles, prefixes, etc., or by subclassing the `HumanName` class. See the
139
- `full documentation`_ for more information.
155
+ Your project may need some adjustment for your dataset. Most customization
156
+ is vocabulary `customizing the configured pre-defined sets`_ of titles,
157
+ prefixes, etc. that the vocabulary layer matches against. You can also do
158
+ your own pre- or post-processing, or subclass the `HumanName` class for
159
+ deeper changes. See the `full documentation`_ for more information.
140
160
 
141
161
 
142
162
  `Full documentation`_
@@ -172,3 +192,9 @@ https://github.com/derek73/python-nameparser
172
192
  :target: http://nameparser.readthedocs.io/en/latest/?badge=latest
173
193
  .. |PyPI version| image:: https://img.shields.io/pypi/pyversions/nameparser.svg
174
194
  :target: https://pypi.org/project/nameparser/
195
+ .. |License| image:: https://img.shields.io/pypi/l/nameparser.svg
196
+ :target: https://pypi.org/project/nameparser/
197
+ .. |Downloads| image:: https://static.pepy.tech/badge/nameparser
198
+ :target: https://pepy.tech/project/nameparser
199
+ .. |Codecov| image:: https://codecov.io/gh/derek73/python-nameparser/branch/master/graph/badge.svg
200
+ :target: https://codecov.io/gh/derek73/python-nameparser
@@ -1,7 +1,7 @@
1
1
  Name Parser
2
2
  ===========
3
3
 
4
- |Build Status| |PyPI| |PyPI version| |Documentation|
4
+ |Build Status| |PyPI| |PyPI version| |Documentation| |License| |Downloads| |Codecov|
5
5
 
6
6
  A simple Python (3.10+) module for parsing human names into their
7
7
  individual components.
@@ -12,8 +12,12 @@ individual components.
12
12
  * hn.last
13
13
  * hn.suffix
14
14
  * hn.nickname
15
+ * hn.maiden
15
16
  * hn.surnames *(middle + last)*
17
+ * hn.given_names *(first + middle)*
16
18
  * hn.initials *(first initial of each name part)*
19
+ * hn.last_base *(last, minus any prefixes)*
20
+ * hn.last_prefixes *(leading last-name particles, e.g. "van der")*
17
21
 
18
22
  Supported Name Structures
19
23
  ~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -25,19 +29,35 @@ are optional. Comma-separated format like "Last, First" is also supported.
25
29
  2. Lastname [Suffix], Title Firstname (Nickname) Middle Middle[,] Suffix [, Suffix]
26
30
  3. Title Firstname M Lastname [Suffix], Suffix [Suffix] [, Suffix]
27
31
 
28
- Instantiating the `HumanName` class with a string splits on commas and then spaces,
29
- classifying name parts based on placement in the string and matches against known name
30
- pieces like titles and suffixes.
31
-
32
- It correctly handles some common conjunctions and special prefixes to last names
33
- like "del". Titles and conjunctions can be chained together to handle complex
34
- titles like "Asst Secretary of State". It can also try to correct capitalization
35
- of names that are all upper- or lowercase names.
36
-
37
- It attempts the best guess that can be made with a simple, rule-based approach.
38
- Its main use case is English and it is not likely to be useful for languages
39
- that do not conform to the supported name structure. It's not perfect, but it
40
- gets you pretty far.
32
+ How It Works
33
+ ~~~~~~~~~~~~
34
+
35
+ The parser works in two layers.
36
+
37
+ A **vocabulary layer** recognizes name pieces by what they are, using
38
+ configurable sets of known words: titles ("Dr."), suffixes ("III", "PhD"),
39
+ last-name prefixes ("de la"), conjunctions ("y", "&"), and delimited
40
+ nicknames ("Doc"). Titles and conjunctions chain together to handle complex
41
+ titles like "Asst Secretary of State"; prefixes join forward so "de la Vega"
42
+ stays one last name. This layer doesn't care where in the string a word
43
+ appears and it's the layer you customize, by adding or removing entries
44
+ in the sets to fit your dataset.
45
+
46
+ A **positional layer** then assigns everything the vocabulary layer didn't
47
+ claim, based purely on where it sits: the first unclaimed word is the first
48
+ name, the last one is the last name, and anything between them is a middle
49
+ name. There is no semantic understanding — "Dr" is a title when it comes
50
+ before a name and a suffix when it comes after ("pre-nominal" and
51
+ "post-nominal" would probably be better names) — and no attempt to correct
52
+ mistakes in the input.
53
+
54
+ It attempts the best guess that can be made with a simple, deterministic,
55
+ rule-based approach — no statistical models or machine learning; the same
56
+ input always parses the same way. The positional layer assumes Western name
57
+ order (given name first), so the main use case is English and other
58
+ languages that share that structure. It can also try to correct the
59
+ capitalization of names that are all upper- or lowercase. It's not perfect,
60
+ but it gets you pretty far.
41
61
 
42
62
  Installation
43
63
  ------------
@@ -65,17 +85,18 @@ Quick Start Example
65
85
  >>> name = HumanName("Dr. Juan Q. Xavier de la Vega III (Doc Vega)")
66
86
  >>> name
67
87
  <HumanName : [
68
- title: 'Dr.'
69
- first: 'Juan'
70
- middle: 'Q. Xavier'
71
- last: 'de la Vega'
72
- suffix: 'III'
73
- nickname: 'Doc Vega'
88
+ title: 'Dr.'
89
+ first: 'Juan'
90
+ middle: 'Q. Xavier'
91
+ last: 'de la Vega'
92
+ suffix: 'III'
93
+ nickname: 'Doc Vega'
94
+ maiden: ''
74
95
  ]>
75
96
  >>> name.last
76
97
  'de la Vega'
77
98
  >>> name.as_dict()
78
- {'last': 'de la Vega', 'suffix': 'III', 'title': 'Dr.', 'middle': 'Q. Xavier', 'nickname': 'Doc Vega', 'first': 'Juan'}
99
+ {'title': 'Dr.', 'first': 'Juan', 'middle': 'Q. Xavier', 'last': 'de la Vega', 'suffix': 'III', 'nickname': 'Doc Vega', 'maiden': ''}
79
100
  >>> str(name)
80
101
  'Dr. Juan Q. Xavier de la Vega III (Doc Vega)'
81
102
  >>> name.string_format = "{first} {last}"
@@ -83,32 +104,31 @@ Quick Start Example
83
104
  'Juan de la Vega'
84
105
 
85
106
 
86
- The parser does not attempt to correct mistakes in the input. It mostly just splits on white
87
- space and puts things in buckets based on their position in the string. This also means
88
- the difference between 'title' and 'suffix' is positional, not semantic. "Dr" is a title
89
- when it comes before the name and a suffix when it comes after. ("Pre-nominal"
90
- and "post-nominal" would probably be better names.)
107
+ Because the positional layer has no semantic understanding, position is
108
+ everything:
91
109
 
92
110
  ::
93
111
 
94
112
  >>> name = HumanName("1 & 2, 3 4 5, Mr.")
95
113
  >>> name
96
114
  <HumanName : [
97
- title: ''
98
- first: '3'
99
- middle: '4 5'
100
- last: '1 & 2'
101
- suffix: 'Mr.'
102
- nickname: ''
115
+ title: ''
116
+ first: '3'
117
+ middle: '4 5'
118
+ last: '1 & 2'
119
+ suffix: 'Mr.'
120
+ nickname: ''
121
+ maiden: ''
103
122
  ]>
104
123
 
105
124
  Customization
106
125
  -------------
107
126
 
108
- Your project may need some adjustment for your dataset. You can
109
- do this in your own pre- or post-processing, by `customizing the configured pre-defined
110
- sets`_ of titles, prefixes, etc., or by subclassing the `HumanName` class. See the
111
- `full documentation`_ for more information.
127
+ Your project may need some adjustment for your dataset. Most customization
128
+ is vocabulary `customizing the configured pre-defined sets`_ of titles,
129
+ prefixes, etc. that the vocabulary layer matches against. You can also do
130
+ your own pre- or post-processing, or subclass the `HumanName` class for
131
+ deeper changes. See the `full documentation`_ for more information.
112
132
 
113
133
 
114
134
  `Full documentation`_
@@ -144,3 +164,9 @@ https://github.com/derek73/python-nameparser
144
164
  :target: http://nameparser.readthedocs.io/en/latest/?badge=latest
145
165
  .. |PyPI version| image:: https://img.shields.io/pypi/pyversions/nameparser.svg
146
166
  :target: https://pypi.org/project/nameparser/
167
+ .. |License| image:: https://img.shields.io/pypi/l/nameparser.svg
168
+ :target: https://pypi.org/project/nameparser/
169
+ .. |Downloads| image:: https://static.pepy.tech/badge/nameparser
170
+ :target: https://pepy.tech/project/nameparser
171
+ .. |Codecov| image:: https://codecov.io/gh/derek73/python-nameparser/branch/master/graph/badge.svg
172
+ :target: https://codecov.io/gh/derek73/python-nameparser
@@ -1,2 +1,2 @@
1
- VERSION = (1, 2, 1)
1
+ VERSION = (1, 3, 1)
2
2
  __version__ = '.'.join(map(str, VERSION))