Skip to content

Commit 8f570ce

Browse files
authored
Merge pull request #283 from derek73/docs/262-constants-contract-reframe
Reframe shared CONSTANTS as an application-startup contract
2 parents 18c9b6a + 381ca36 commit 8f570ce

2 files changed

Lines changed: 33 additions & 18 deletions

File tree

docs/customize.rst

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,15 @@
11
Customizing the Parser with Your Own Configuration
22
==================================================
33

4+
:py:class:`~nameparser.config.Constants` is for application-level
5+
configuration, set once at startup: the shared module-level ``CONSTANTS``
6+
instance is the only channel that reaches parses happening in code you don't
7+
own -- helpers, pipelines, a third-party library using nameparser internally
8+
-- the same role ``logging`` and ``locale`` play elsewhere. For anything
9+
scoped to one dataset, one library, or one test, pass your own ``Constants``
10+
instance instead -- see the three explicit forms under "Module-level Shared
11+
Configuration Instance" below.
12+
413
Recognition of titles, prefixes, suffixes and conjunctions is handled by
514
matching the lower case characters of a name piece with pre-defined sets
615
of strings located in :py:mod:`nameparser.config`. You can adjust
@@ -428,13 +437,14 @@ making them lower case and removing periods.
428437
Module-level Shared Configuration Instance
429438
------------------------------------------
430439

431-
When you modify the configuration, by default this will modify the behavior all
432-
HumanName instances. This could be a handy way to set it up for your entire
433-
project, but it could also lead to some unexpected behavior because changing
434-
the config on one instance could modify the behavior of another instance.
435-
Parsing itself never modifies the configuration — only your own ``add`` and
436-
``remove`` calls do — so the shared instance is safe to read concurrently,
437-
e.g. parsing names on multiple threads.
440+
As established above, ``CONSTANTS`` is shared by every ``HumanName`` created
441+
without its own config -- that's what makes it the right place for
442+
application-level setup, and also the source of the one gotcha it carries:
443+
changing the config on one instance changes the behavior of every other
444+
instance that shares it, which can be surprising if you only meant to
445+
configure the one you're holding. Parsing itself never modifies the
446+
configuration — only your own ``add`` and ``remove`` calls do — so the shared
447+
instance is safe to read concurrently, e.g. parsing names on multiple threads.
438448

439449
.. doctest:: module config
440450
:options: +ELLIPSIS, +NORMALIZE_WHITESPACE

nameparser/config/__init__.py

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,24 @@
11
"""
22
The :py:mod:`nameparser.config` module manages the configuration of the
3-
nameparser.
3+
nameparser.
44
5-
A module-level instance of :py:class:`~nameparser.config.Constants` is created
6-
and used by default for all HumanName instances. You can adjust the entire module's
7-
configuration by importing this instance and changing it.
5+
:py:class:`~nameparser.config.Constants` is for application-level
6+
configuration, set once at startup. ``CONSTANTS``, the module-level instance
7+
used by every ``HumanName`` created without its own config, is the only
8+
channel that reaches parses happening in code you don't own (helpers,
9+
pipelines, a third-party library using nameparser internally) -- the same
10+
role ``logging`` and ``locale`` play elsewhere. Import it and change it
11+
directly:
812
913
::
1014
1115
>>> from nameparser.config import CONSTANTS
1216
>>> CONSTANTS.titles.remove('hon').add('chemistry','dean') # doctest: +SKIP
1317
14-
You can also adjust the configuration of individual instances by passing
15-
your own :py:class:`Constants` instance as the second argument upon
16-
instantiation -- ``Constants()`` for fresh library defaults, or
17-
``CONSTANTS.copy()`` for a private snapshot of the current module config.
18+
For anything scoped -- one dataset, one library, one test -- pass your own
19+
:py:class:`Constants` instance as the second argument upon instantiation
20+
instead: ``Constants()`` for fresh library defaults, or ``CONSTANTS.copy()``
21+
for a private snapshot of the current module config.
1822
1923
::
2024
@@ -24,9 +28,10 @@
2428
>>> hn.C.titles.add('dean') # doctest: +SKIP
2529
>>> hn.parse_full_name() # need to run this again after config changes
2630
27-
**Potential Gotcha**: If you do not pass your own :py:class:`Constants`
28-
instance as the second argument, ``hn.C`` will be a reference to the module
29-
config, possibly yielding unexpected results. See `Customizing the Parser
31+
Mixing the two up is where the surprises come from, not the API itself: if
32+
you do not pass your own :py:class:`Constants` instance as the second
33+
argument, ``hn.C`` will be a reference to the module config, and a change
34+
there reaches every other instance sharing it. See `Customizing the Parser
3035
<customize.html>`_.
3136
3237
.. deprecated:: 1.4.0

0 commit comments

Comments
 (0)