fix: normalized gender comparisons and defaulted to genderless rather than male in salutation and pronoun methods#958
Conversation
… than male in salutation and pronoun methods
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Updates gender handling in pronoun and salutation helpers by normalizing gender comparisons and introducing gender-neutral defaults.
Changes:
- Normalize gender checks via
casefold()across pronoun helpers. - Change fallback pronoun behavior to default to gender-neutral forms instead of defaulting to male.
- Add “Mx.” as the default salutation for non-
male/femalegenders.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 7 comments.
| File | Description |
|---|---|
| docassemble_base/docassemble/base/util.py | Normalizes gender comparisons and adjusts fallback pronoun selection. |
| docassemble_base/docassemble/base/functions.py | Normalizes gender comparisons and adds “Mx.” for non-binary/other genders in salutations. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
There are some judgment calls to be made here about how exactly to handle this. At the very least it would be nice if the gender comparisons were improved (I used casefold, but lower would probably be just fine, too). For the specific project that caused me to dig into this, we're using helper functions instead because we also need some language handling. These aren't perfect, but should work for what we need for now without requiring the upstream changes. _SALUTATION_LOOKUP = {
"en": {
"male": "Mr.",
"female": "Ms.",
"nonbinary": "Mx.",
},
"es": {
"male": "Sr.",
"female": "Sra.",
"nonbinary": "Mx.",
},
}
def greet(person: Individual) -> str:
preferred = person.attr("preferred_greeting")
if preferred:
greeting = preferred
elif getattr(person, "language", "") == "es":
greeting = (
"Estimada"
if getattr(person, "gender", "").casefold() == "female"
else "Estimado"
)
else:
greeting = "Dear"
return f"""{greeting} {salute(person)}"""
def salute(person: Individual) -> str:
greeting = str(person.name)
salutation = person.attr("preferred_salutation") or _SALUTATION_LOOKUP.get(
getattr(person, "language", "en"), {}
).get(getattr(person, "gender", "").casefold(), None)
if salutation:
greeting = f"""{salutation} {person.name.last}"""
return greeting |
This PR normalizes gender comparisons, particularly so that capitalized genders are still handled correctly. If the
genderattribute is actually an object with a__str__()method, then this will actually cause that to work as well by casting the attribute to a string first.It also changes salutation and the pronoun methods to all default/fall-through to genderless options rather than male options as they were before. I don't actually care that much about this part, I really only want the casefold/lower on the gender attribute comparison, but it seemed weird that if you called
.salutation()on anIndividualthat had a specificgender == 'other'that it would still returnMr., and I did look it up, "Mx." is the genderless salutation.