# Bug 0014146: Display Name Editor does not allow to enter keyword "Notpatronymic" into Format string, replaces it with "NotPatronymic"

**URL:** <https://gramps.discourse.group/t/bug-0014146-display-name-editor-does-not-allow-to-enter-keyword-notpatronymic-into-format-string-replaces-it-with-notpatronymic/9231>\
**Category:** Bug triage\
**Tags:** name-display\
**Created:** [March 19, 2026, 3:14pm UTC](https://gramps.discourse.group/t/bug-0014146-display-name-editor-does-not-allow-to-enter-keyword-notpatronymic-into-format-string-replaces-it-with-notpatronymic/9231 "2026-03-19T15:14:52Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![petr\_fedorov](https://yyz2.discourse-cdn.com/free1/user_avatar/gramps.discourse.group/petr_fedorov/32/9556_2.png) [@petr\_fedorov](https://gramps.discourse.group/u/petr_fedorov)\
**Post date:** [March 19, 2026, 3:14pm UTC](https://gramps.discourse.group/t/bug-0014146-display-name-editor-does-not-allow-to-enter-keyword-notpatronymic-into-format-string-replaces-it-with-notpatronymic/9231/1 "2026-03-19T15:14:52Z")

</div>

This is how the bug comes out:

 ![NotPatronymic_entered](https://global.discourse-cdn.com/free1/uploads/gramps/original/2X/a/ae18b71cd2ec3024674c01d12950be15d5ed3dcc.jpeg)  
 ![NotPatronymic_modified](https://global.discourse-cdn.com/free1/uploads/gramps/original/2X/8/84946ef405f215ddce5558dfaab1fabe346ba9ea.jpeg)

It happens because _internal_ keyword **patronymic** is a part of another, longer, _external_ (i.e. visible to a user) keyword ‘Not **patronymic** ’ and vice versa. The same bug exists for Raw **surname** s for the same reason: **surname** is an internal keyword too.

The bug appears to be fixed by mangling internal keywords **patronymic** , **notpatronymic** , **surname** and **rawsurnames** so they are not parts of each other anymore.

Keywords are duplicated (twice!) in [gramps/gen/display/name.py](https://github.com/gramps-project/gramps/blob/ffcaf4b1b3099e7f384118007479eb57a7fff21f/gramps/gen/display/name.py) , so they need to be changed there too.

[Pull request](https://github.com/gramps-project/gramps/pull/2191) has been submitted to the current maintenance branch. Detailed description of the bug and its solution follows.

Below is the fragment of the code processing string entered by the user into Format field, copied from [gramps/gui/configure.py](https://github.com/gramps-project/gramps/blob/ffcaf4b1b3099e7f384118007479eb57a7fff21f/gramps/gui/configure.py#L1190):

> **Fragment A**
>
> ```python
> # build a pattern from translated pattern:
> pattern = new_text
> if len(new_text) > 2 and new_text[0] == '"' and new_text[-1] == '"':
> passtag
> else:
> for key in get_translations():
> if key in pattern:
> pattern = pattern.replace(
> key, get_keyword_from_translation(key)
> )
> # now build up a proper translation:
> translation = pattern
> if len(new_text) > 2 and new_text[0] == '"' and new_text[-1] == '"':
> pass
> else:
> for key in get_keywords():
> if key in translation:
> translation = translation.replace(
> key, get_translation_from_keyword(key)
> )
> 
> ```

Above code uses 4 functions from [gramps/gen/utils/keyword.py](https://github.com/gramps-project/gramps/blob/ffcaf4b1b3099e7f384118007479eb57a7fff21f/gramps/gen/utils/keyword.py#L54), namely `get_translations()`, ` get_keyword_from_translation(key) `, `get_keywords()` and `get_translation_from_keyword(key)`

> **Fragment B**
>
> ```python
> KEYWORDS = [
> ("title", "t", _("Title", "Person"), _("TITLE", "Person")),
> ("given", "f", _("Given"), _("GIVEN")),
> ("surn2me", "l", _("Surname"), _("SURNAME")),
> ("call", "c", _("Call", "Name"), _("CALL", "Name")),
> ("common", "x", _("Common", "Name"), _("COMMON", "Name")),
> ("initials", "i", _("Initials"), _("INITIALS")),
> ("suffix", "s", _("Suffix"), _("SUFFIX")),
> ("primary", "m", _("Primary", "Name"), _("PRIMARY")),
> ("primary[pre]", "0m", _("Primary[pre]"), _("PRIMARY[PRE]")),
> ("primary[sur]", "1m", _("Primary[sur]"), _("PRIMARY[SUR]")),
> ("primary[con]", "2m", _("Primary[con]"), _("PRIMARY[CON]")),
> ("patr2nymic", "y", _("Patronymic"), _("PATRONYMIC")),
> ("patronymic[pre]", "0y", _("Patronymic[pre]"), _("PATRONYMIC[PRE]")),
> ("patronymic[sur]", "1y", _("Patronymic[sur]"), _("PATRONYMIC[SUR]")),
> ("patronymic[con]", "2y", _("Patronymic[con]"), _("PATRONYMIC[CON]")),
> ("rawsurn0mes", "q", _("Rawsurnames"), _("RAWSURNAMES")),
> ("notpatr0nymic", "o", _("Notpatronymic"), _("NOTPATRONYMIC")),
> ("prefix", "p", _("Prefix"), _("PREFIX")),
> ("nickname", "n", _("Nickname"), _("NICKNAME")),
> ("familynick", "g", _("Familynick"), _("FAMILYNICK")),
> ]
> KEY_TO_TRANS = {}
> TRANS_TO_KEY = {}
> for key, code, standard, upper in KEYWORDS:
> KEY_TO_TRANS[key] = standard
> KEY_TO_TRANS[key.upper()] = upper
> KEY_TO_TRANS["%" + ("%s" % code)] = standard
> KEY_TO_TRANS["%" + ("%s" % code.upper())] = upper
> TRANS_TO_KEY[standard.lower()] = key
> TRANS_TO_KEY[standard] = key
> TRANS_TO_KEY[upper] = key.upper()
> 
> def get_translation_from_keyword(keyword):
> """Return the translation of keyword"""
> return KEY_TO_TRANS.get(keyword, keyword)
> 
> def get_keyword_from_translation(word):
> """Return the keyword of translation"""
> return TRANS_TO_KEY.get(word, word)
> 
> def get_keywords():
> """Get all keywords, longest to shortest"""
> keys = list(KEY_TO_TRANS.keys())
> keys.sort(key=lambda a: len(a), reverse=True)
> return keys
> 
> def get_translations():
> """Get all translations, longest to shortest"""
> trans = list(TRANS_TO_KEY.keys())
> trans.sort(key=lambda a: len(a), reverse=True)
> return trans
> 
> ```

The first loop in Fragment A uses `get_translation()` to replace all _external_ keywords entered by a user with their _internal_ equivalents.

The second loop in Fragment A uses `get_keywords()` to replace all _internal_ keywords by their _external_ equivalents.

As it can be seen from Fragment B, both `get_translations()` and `get_keywords()` starts from longer keywords and proceed towards shorter ones.

Suppose that a user entered “Notpatronymic” into `new_text` variable. Then first loop transform it first into “notpatronymic” internal keyword (as soon as it recognizes “Notpatronymic”) and then it will see _external_ keyword “patronymic” and will replace it with \*internal" keyword for _external_ “patronymic”. (Currently they are the same, but if internal keyword for “patronymic” were “pAtRoNyMiC”, the stringu would transform into the wrong string “notpAtRoNyMiC”).

In a similar fashion, the second loop first translates “notpatronymic” into “Notpatronymic” (since Notpatronymic is longer than Patronymic) and then into the wrong “NotPatronymic”.

Mangling of internal keywords **patronymic** , **notpatronymic** , **surname** and **rawsurnames** into **patr2nymic** , **notpatr0nymic** , **surn2me** , **rawsurn0mes** respectively solves the issue.

Please let me know if you see any issues with the proposed solution.

---

<div class="post-metadata">

**Author:** ![dsblank](https://yyz2.discourse-cdn.com/free1/user_avatar/gramps.discourse.group/dsblank/32/3649_2.png) [@dsblank](https://gramps.discourse.group/u/dsblank)\
**Post date:** [March 20, 2026, 1:38pm UTC](https://gramps.discourse.group/t/bug-0014146-display-name-editor-does-not-allow-to-enter-keyword-notpatronymic-into-format-string-replaces-it-with-notpatronymic/9231/2 "2026-03-20T13:38:04Z")

</div>

After some good discussion on the Pull Request, I think you have a great solution. Thanks for working on that!

I think next time, you can skip this post in discourse. If you want to have this level of conversation, @Nick-Hall has suggested we could use github’s discussions. But that isn’t turned on yet. Or just create the PR as you did. Developers will see your contribution and review.

Thanks again!

---

<div class="post-metadata">

**Author:** ![StoltHD](https://avatars.discourse-cdn.com/v4/letter/s/db5fbb/32.png) [@StoltHD](https://gramps.discourse.group/u/StoltHD)\
**Post date:** [March 21, 2026, 10:55am UTC](https://gramps.discourse.group/t/bug-0014146-display-name-editor-does-not-allow-to-enter-keyword-notpatronymic-into-format-string-replaces-it-with-notpatronymic/9231/3 "2026-03-21T10:55:36Z")

</div>

I think these types of discussions are highly valuable here, even though I am not a developer myself.

Why shouldn’t a non-developer be able to read or join a technical issue discussion? This is essential for learning purposes, but also because users often have a crucial perspective on how these features actually work in practice.

Furthermore, users should be able to participate and report issues to a greater extent **WITHOUT** being forced to use GitHub. Requiring a separate developer-oriented account just to contribute feedback creates an unnecessary barrier. Technical logic—like why a specific keyword is being replaced in the name editor—affects every user, and we should be able to discuss and influence these fixes right here in the forum.

---

<div class="post-metadata">

**Author:** ![dsblank](https://yyz2.discourse-cdn.com/free1/user_avatar/gramps.discourse.group/dsblank/32/3649_2.png) [@dsblank](https://gramps.discourse.group/u/dsblank)\
**Post date:** [March 21, 2026, 11:21am UTC](https://gramps.discourse.group/t/bug-0014146-display-name-editor-does-not-allow-to-enter-keyword-notpatronymic-into-format-string-replaces-it-with-notpatronymic/9231/4 "2026-03-21T11:21:14Z")

</div>

@StoltHD I think you misinterpreted the intention of my comment. I only mentioned that @petr_fedorov need not post here too. Why not? Because no developer saw it. I think it is asking too much for developers to duplicate their work in two places.

In any event, the above description of a fix was incorrect, and there was a discussion on the issue, a related bug report, and the analysis that lead to the real solution. What was the final outcome? If you actually want to know any of that then you’ll want to read it here:

> <https://github.com/gramps-project/gramps/pull/2191>
>
> Fixes \[#14146\](https://gramps-project.org/bugs/view.php?id=14146)

---

<div class="post-metadata">

**Author:** ![StoltHD](https://avatars.discourse-cdn.com/v4/letter/s/db5fbb/32.png) [@StoltHD](https://gramps.discourse.group/u/StoltHD)\
**Post date:** [March 21, 2026, 11:50am UTC](https://gramps.discourse.group/t/bug-0014146-display-name-editor-does-not-allow-to-enter-keyword-notpatronymic-into-format-string-replaces-it-with-notpatronymic/9231/5 "2026-03-21T11:50:04Z")

</div>

Well, that is exactly my point. If the discussion only exists on GitHub, people like me—but who may not have a GitHub account—will never be able to learn the technical aspects of an issue. This, in turn, makes them less efficient at providing adequate information or helping out where we can.

Personally, I have no problem going to GitHub or **Mantis** to contribute if I _know_ an issue actually exists. However, I refuse to spend my time chasing discussions across the numerous platforms Gramps now uses—be it mailing lists, GitHub, **the Mantis bug tracker** , Discourse, or social media like Reddit and Facebook.

I stopped following the different Facebook groups for Gramps, Reddit, and all the mailing lists years ago. To be effective, we need a centralized place where users and developers can actually meet without these unnecessary barriers.

I can take one very important example, and that is the time/period handling in Gedcom/Gramps and other genealogy systems, which is historically wrong and will end up falsifying historical timespans/periods. It feels like the developers used a template from **MS Project** or **Artemis** instead of historical logic.

Treating an ‘After December’ as a **‘Start No Earlier Than’** constraint is a catastrophic logical error. In project management, this constraint exists for **resource planning** —if a resource becomes available early, the task might start sooner. But history is not a project plan; it is fixed. ‘After December’ means January or later. By using project management logic, you are allowing a ‘float’ where events leak into a month the source has already defined as passed. This is project management, not genealogy.  
I have added this to discussed here:

> [@Misleading date range labels? (Before, After, Between)](https://gramps.discourse.group/t/misleading-date-range-labels-before-after-between/7250/18):
>
> This shows how historically incorrect data propagates when blindly following theological formats presented as technical standards like GEDCOM. GEDCOM – created by LDS Church for temple ordinance work – treats years as task scheduling (‘no earlier than’) rather than complete historical periods. ‘After 1941’ should mean post-Dec 31st 1941. GEDCOM’s ‘post-Jan 1st 1941’ creates events matching both ‘1941’ AND ‘After 1941’ = chronological absurdity. LDS temple logic ≠ historical chronology.\*\* Gram…

and here:

> [@Alternative place name](https://gramps.discourse.group/t/alternative-place-name/9215/13):
>
> This must be a bug. “After 1941” should mean after 1941‑12‑31 23:59:59 (or 00:00 on the next day), including all days after that point. From 1941 should mean from 1941‑01‑01, including that day. After 1941 should mean from 1942‑01‑01, including 1942‑01‑01. After 1941‑January should mean from 1942‑02‑01 and later. In other words: “From ” must include the written day. “After ” must exclude the written day. “From ” must include the entire month. “After ” must include ever…

If I had been aware of these issues at the moment they were raised, I would have been screaming my throat out not to follow this historically incorrect way of interpreting time periods! For me, this has actually become a reason to reconsider the use of Gramps and other genealogy software altogether.

* * *

**I didn’t misinterpret your comment; I am challenging the very logic that developers ‘don’t need’ to look where the users actually are and involve users and especially power users of a system.**

* * *

_ **Author’s Note:** This text was originally written in Norwegian and later translated and edited for clarity with the assistance of Google AI. Some structural adjustments were made during the process to improve coherence, but all analytical content and conclusions remain my own._

* * *

Edit: I added some more info in a section of my writing.\>

---

<div class="post-metadata">

**Author:** ![dsblank](https://yyz2.discourse-cdn.com/free1/user_avatar/gramps.discourse.group/dsblank/32/3649_2.png) [@dsblank](https://gramps.discourse.group/u/dsblank)\
**Post date:** [March 21, 2026, 12:42pm UTC](https://gramps.discourse.group/t/bug-0014146-display-name-editor-does-not-allow-to-enter-keyword-notpatronymic-into-format-string-replaces-it-with-notpatronymic/9231/6 "2026-03-21T12:42:09Z")

</div>

What is your proposal?

Here is an idea: what if every time a Pull Request was created on github, it posted a message in the Developer topic here in discourse? It is _possible_, but I worry that it would put more burden on the contributors to follow two conversations.

---

<div class="post-metadata">

**Author:** ![StoltHD](https://avatars.discourse-cdn.com/v4/letter/s/db5fbb/32.png) [@StoltHD](https://gramps.discourse.group/u/StoltHD)\
**Post date:** [March 21, 2026, 1:17pm UTC](https://gramps.discourse.group/t/bug-0014146-display-name-editor-does-not-allow-to-enter-keyword-notpatronymic-into-format-string-replaces-it-with-notpatronymic/9231/7 "2026-03-21T13:17:46Z")

</div>

The issue isn’t about setting up automatic notifications or ‘more posts’ for developers to follow. It’s about **where the actual discussion and decision-making happen.**

Technical programming discussions—like whether to use ‘if’ or ‘or’ in the code, or whether a function adheres to the Gramps standard—can certainly stay on GitHub or in a mailing list if some prefer.  
However, if a technical choice (like the date logic) affects the historical integrity of the data, that discussion belongs here on Discourse where power users and historians can contribute—not hidden away in a GitHub Pull Request that 99% of users never see.

Relatively small bugfixes do not need a discussion here, but technical issues that can affect data and data integrity should. This is because there may be researchers, historians, or seasoned genealogists in this forum who **do not frequent GitHub, Mantis, or the mailing lists.**

My proposal is simple:  
**Before** a technical path is locked in via a PR on GitHub, the core logic should be presented and discussed here on Discourse.  
**Ideally, these posts should use some form of ‘Attention’ tag, making it easier for users who are only visiting briefly to notice that a new, serious topic is being discussed.**

This isn’t a ‘burden’; it’s quality insurance.  
Involving users, and especially power users, at an early stage **might prevent** the corruption of historical data and other issues that a user or power user of the system will spot long before they even arise in the code—issues that at a later stage **might become a real problem** regarding data integrity or functionality.

A simple link from GitHub to a Discourse thread is a small task that could have prevented the catastrophic historical errors I mentioned earlier.

**And just to be clear, I am not talking about someone wanting to add a new view that doesn’t alter the data or similar features; it is specifically when changes can or might have a direct impact on the data itself or core usage itself.**

* * *

_ **Author’s Note:** This text was originally written in Norwegian and later translated and edited for clarity with the assistance of Google AI. Some structural adjustments were made during the process to improve coherence, but all analytical content and conclusions remain my own._

---

<div class="post-metadata">

**Author:** ![petr\_fedorov](https://yyz2.discourse-cdn.com/free1/user_avatar/gramps.discourse.group/petr_fedorov/32/9556_2.png) [@petr\_fedorov](https://gramps.discourse.group/u/petr_fedorov)\
**Post date:** [March 21, 2026, 1:36pm UTC](https://gramps.discourse.group/t/bug-0014146-display-name-editor-does-not-allow-to-enter-keyword-notpatronymic-into-format-string-replaces-it-with-notpatronymic/9231/8 "2026-03-21T13:36:12Z")

</div>

It seems that the first half of the discussion about some new bug should be here, in discourse, and the second (final) in Github. Those non-technical users who wants to follow the second part may join GitHub for this purpose. The migration to Github will happen as soon as PR is created there. Reference to the PR may be provided in discourse. Usually it will take some time between the first part of the discussion and creation of PR.

---

<div class="post-metadata">

**Author:** ![StoltHD](https://avatars.discourse-cdn.com/v4/letter/s/db5fbb/32.png) [@StoltHD](https://gramps.discourse.group/u/StoltHD)\
**Post date:** [March 21, 2026, 1:47pm UTC](https://gramps.discourse.group/t/bug-0014146-display-name-editor-does-not-allow-to-enter-keyword-notpatronymic-into-format-string-replaces-it-with-notpatronymic/9231/9 "2026-03-21T13:47:26Z")

</div>

What I write is not a critique of you or what you have done in this specific case; it is about the **general workflow**.

While providing a reference to a PR is a step in the right direction, the problem is that ‘migrating’ to GitHub often means the functional logic is already being locked in. As I mentioned with the **Project Management vs. Historical logic** for dates, these are fundamental principles that need to be fully vetted here on Discourse _before_ they are moved to a technical implementation on GitHub.

**And in the specific case of dates and periods, those should never have been adopted from GEDCOM in the first place.** By adopting a flawed standard without a deep functional discussion with power users and historians, we end up with the data integrity issues we see today.

If the functional discussion stops here the moment a PR is created, we risk losing the insight from those who can spot these issues long before they become hard-coded reality. We need to ensure that the **logic** remains a conversation here, while the **code** happens there."

* * *

_ **Author’s Note:** This text was originally written in Norwegian and later translated and edited for clarity with the assistance of Google AI. Some structural adjustments were made during the process to improve coherence, but all analytical content and conclusions remain my own._

* * *

**At this moment I will stop, because I feel I start hijacking your post… sorry.**"

---

<div class="post-metadata">

**Author:** ![emyoulation](https://yyz2.discourse-cdn.com/free1/user_avatar/gramps.discourse.group/emyoulation/32/67_2.png) [@emyoulation](https://gramps.discourse.group/u/emyoulation)\
**Post date:** [March 21, 2026, 3:18pm UTC](https://gramps.discourse.group/t/bug-0014146-display-name-editor-does-not-allow-to-enter-keyword-notpatronymic-into-format-string-replaces-it-with-notpatronymic/9231/10 "2026-03-21T15:18:28Z")

</div>

> [@dsblank](#):
>
> What is your proposal?

There is a fallow RSS “[Headline News](https://gramps-project.org/wiki/index.php/Addon:HeadlineNewsGramplet)” addon Gramplet in Gramps that might serve the purpose with some modification.  
It is so seldomly updated that no one seems to use it. I tried launching it and it was stuck on “Loading Gramps Headline News…”. So the feed might be dead?

 ![image](https://global.discourse-cdn.com/free1/uploads/gramps/original/2X/0/0ddf82634ac865507dd8a501fb41076054792479.png)

Say that RSS feeds were added from Discourse, GitHub issues, possibly the Gramps-Devel maillist. Perhaps the gramplet could be adapted to as a QuickView that runs in the Gramps minor alert window or launches an undocked Headline News gramplet from the Dashboard?

Add a different emoji (📣) than the Lightbulb [💡 Warning](https://gramps-project.org/wiki/index.php/Gramps_6.0_Wiki_Manual_-_Error_and_Warning_Reference#Warnings) to the status bar to indicate there is news? And have checkboxes for the each heading that less users persistently choose which Feeds they follow?

 ![image](https://global.discourse-cdn.com/free1/uploads/gramps/original/2X/f/f1c2710a03dfd89236f49b9a8587b218673d51f9.png)
