Sync gramps@maintenance/gramps61 with upstream (2026-06-10)#17
Open
eduralph wants to merge 49 commits into
Open
Sync gramps@maintenance/gramps61 with upstream (2026-06-10)#17eduralph wants to merge 49 commits into
eduralph wants to merge 49 commits into
Conversation
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The original report noted that date columns sort without grouping dates with qualifiers like about, after, before so they appear in an arbitrary order. This happens because get_sort_value() returns only the Julian Day Number with no modifier or quality information. This change adds Date.get_sort_key() which creates a sort key based on the JDN adjusted with scores for modifiers and quality It also updates date sort columns in the list view treemodels (peoplemodel, familymodel, eventmodel, mediamodel, citationbasemodel) to call get_sort_key() instead of get_sort_value(). The key is 'JDN * 12 + modifier_score * 3 + quality_score' Modifier scores: 0 - MOD_BEFORE 1 - MOD_NONE, MOD_FROM, MOD_TO, MOD_SPAN, MOD_RANGE 2 - MOD_ABOUT 3 - MOD_AFTER Quality scores: 0 - QUAL_NONE 1 - QUAL_ESTIMATED 2 - QUAL_CALCULATED For year-only after-dates the position advances to the first JDN of the following year, which is correct for all supported calendars. This ensures 'after 1823' sorts after '1823-12-31'. The max sort key for 31 Dec 9999 is 64481819 (JDN 5373484 * 12) which fits in the format string "%09d" used by treemodels. get_sort_value() is unchanged and continues to be used for date arithmetic, calendar conversion and span calculations throughout the rest of the codebase. Fixes #7761.
Restores support for a user-supplied tile URL in the embedded geography view. The custom URL is entered in Geography preferences using #Z/#X/#Y as coordinate placeholders. Example providers include MapTiler NLS historical Ordnance Survey maps (uk-osgb1888, uk-osgb63k1885, etc.). OsmGpsMap requires a non-null map-source enum value to honour a custom repo_uri; using map_source=0 (NULL) causes it to render gray tiles and ignore the URL entirely. Fix this by passing OPENSTREETMAP_RENDERER, whose built-in URI is NULL (service defunct), so OsmGpsMap keeps the supplied repo_uri and fetches tiles from it. Also fixes the image-format lookup for custom URLs, debounces the url entry field so it only fires on Enter or focus-out rather than on every keystroke, and widens the URL input field to span the full grid width.
8076d69 to
2ac1386
Compare
* Bulk import. * Merge window. * Sign-in from status bar icon. * Enable/disable integration. * Progress fedback. * CSS segregation. * Bug fixes. Co-Authored-By: Doug Blank <doug.blank@gmail.com> Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Currently translated at 96.0% (7260 of 7555 strings) Translation: Gramps/Program Translate-URL: https://hosted.weblate.org/projects/gramps-project/gramps/ru/
Currently translated at 98.6% (7455 of 7555 strings) Translation: Gramps/Program Translate-URL: https://hosted.weblate.org/projects/gramps-project/gramps/it/ Translated using Weblate (Italian) Currently translated at 98.6% (7454 of 7555 strings) Translation: Gramps/Program Translate-URL: https://hosted.weblate.org/projects/gramps-project/gramps/it/ Translated using Weblate (Italian) Currently translated at 98.6% (7454 of 7555 strings) Translation: Gramps/Program Translate-URL: https://hosted.weblate.org/projects/gramps-project/gramps/it/ Translated using Weblate (Italian) Currently translated at 95.0% (7183 of 7555 strings) Translation: Gramps/Program Translate-URL: https://hosted.weblate.org/projects/gramps-project/gramps/it/
Currently translated at 98.2% (7426 of 7555 strings) Translation: Gramps/Program Translate-URL: https://hosted.weblate.org/projects/gramps-project/gramps/ba/
Currently translated at 96.8% (7319 of 7555 strings) Translation: Gramps/Program Translate-URL: https://hosted.weblate.org/projects/gramps-project/gramps/zh_Hans/
Currently translated at 100.0% (7555 of 7555 strings) Translation: Gramps/Program Translate-URL: https://hosted.weblate.org/projects/gramps-project/gramps/da/
Currently translated at 100.0% (7555 of 7555 strings) Translation: Gramps/Program Translate-URL: https://hosted.weblate.org/projects/gramps-project/gramps/he/ Translated using Weblate (Hebrew) Currently translated at 100.0% (7555 of 7555 strings) Translation: Gramps/Program Translate-URL: https://hosted.weblate.org/projects/gramps-project/gramps/he/ Translated using Weblate (Hebrew) Currently translated at 100.0% (7555 of 7555 strings) Translation: Gramps/Program Translate-URL: https://hosted.weblate.org/projects/gramps-project/gramps/he/ Translated using Weblate (Hebrew) Currently translated at 100.0% (7555 of 7555 strings) Translation: Gramps/Program Translate-URL: https://hosted.weblate.org/projects/gramps-project/gramps/he/
Currently translated at 96.0% (7260 of 7555 strings) Translation: Gramps/Program Translate-URL: https://hosted.weblate.org/projects/gramps-project/gramps/ru/
Currently translated at 61.5% (4651 of 7555 strings) Translation: Gramps/Program Translate-URL: https://hosted.weblate.org/projects/gramps-project/gramps/zh_Hant_HK/
Currently translated at 100.0% (7555 of 7555 strings) Translation: Gramps/Program Translate-URL: https://hosted.weblate.org/projects/gramps-project/gramps/sk/ Translated using Weblate (Slovak) Currently translated at 100.0% (7555 of 7555 strings) Translation: Gramps/Program Translate-URL: https://hosted.weblate.org/projects/gramps-project/gramps/sk/
Currently translated at 4.1% (311 of 7555 strings) Translation: Gramps/Program Translate-URL: https://hosted.weblate.org/projects/gramps-project/gramps/ro/
FanChartWidget.set_generations and FanChart2WayWidget.set_generations
initialised self.data[i] with a shared (None,) * 4 tuple per slot,
leaving the userdata element as None. When _fill_data_structures
short-circuited (no rootpersonh on startup, after rename, etc.) the
slots were never replaced, so prepare_background_box's
BACKGROUND_GRAD_AGE and BACKGROUND_GRAD_PERIOD paths called
userdata.append(...) on None and crashed with:
AttributeError: 'NoneType' object has no attribute 'append'
Give each slot its own empty userdata list at init time so the
invariant holds regardless of _fill_data_structures' execution.
Adds a regression test under gramps/gui/widgets/test/ that drives
set_generations via __new__-bypass so it runs headless.
Fixes #13395.
When the database is closed the framework switches the active model
to an empty state by clearing self.tree, so the root entry
self.tree[None] no longer exists. TreeBaseModel.reverse_order
looked it up unconditionally, so the next column-header click in
the People view (or any other list view backed by a TreeBaseModel)
raised:
KeyError: None
at treebasemodel.py:reverse_order, surfacing to the user as an
unhandled exception.
Short-circuit reverse_order when the tree has no root entry: there
is nothing to reverse in a cleared state, and the user's expected
behaviour is "no action because no tree is open". Adds a
regression test under gramps/gui/views/treemodels/test/.
Fixes #13214.
Bug 4658: when the "Limit dates to years only" report option is on, Family Lines Graph rendered "before 1923" as "1923" -- the modifier (before / after / about), quality (estimated / calculated), and the second stop of compound dates (range / span) were all dropped. The sister Relationship Graph plugin shares the same defect via the ported code path that gburto01 flagged in the bug's 2011-02-27 note. Root cause: ``Date(date.get_year())`` invokes the Date constructor's int-source branch, which builds a fresh date with MOD_NONE / QUAL_NONE and a single year, discarding the modifier and any compound second stop. Fix: introduce a private ``_year_only_date`` helper in each plugin that copies the original date (preserving modifier and quality) and truncates month and day to 0, with the second stop of compound dates truncated to year-only on its own. Replace all four ``Date(year)`` call sites (gvfamilylines.py x 3, gvrelgraph.py x 1). The helper is intentionally duplicated rather than placed in a new shared module, to keep the change localised; a ``test_helpers_agree`` test guards against the copies drifting. Regression test added at gramps/plugins/graph/test/year_only_date_test.py covers modifier preservation (BEFORE/AFTER/ABOUT), quality preservation (ESTIMATED/CALCULATED), month/day truncation, compound range/span second-stop preservation, and parity between the two plugin helpers. End-to-end check with the GrampsLocale displayer confirms the reporter's case: before 1923 -> before 1923 (was: 1923) between 1923 and 1925 -> between 1923 and 1925 (was: 1923) estimated about 1923 -> estimated about 1923 (was: 1923) Fixes #4658.
Bug 6556: graphviz-based reports (Family Lines Graph, Relationship
Graph, etc.) failed silently when the chosen output file could not
be written -- typically because another process (a viewer on
Windows) held a lock on it, but also under permission denied / disk
full / missing binary. The user saw no error and no file, and had
no way to learn the report had not been generated. Text and
graphical reports already surfaced this via "Could not create %s"
ReportError; only the graphviz path was silent.
Root cause: graphdoc.py shells out to ``dot`` (and to ``gs`` for the
multi-page PDF path) via ``os.system(...)`` at 11 sites, and
discards the return code. Any failure to write the output is
invisible to the rest of the function.
Fix: route every ``os.system`` invocation through a new
``_check_rc(rc, target)`` helper that raises
``ReportError(_("Could not create %s") % target)`` on a non-zero
return code. The wording matches the message uniformly used by the
other docgen backends (rtfdoc, svgdrawdoc, odfdoc), so downstream
error-handling code paths and the user-visible dialog see the same
text regardless of which output format the user picked.
The 11 call sites span 8 graphdoc classes:
GVPsDoc, GVSvgDoc, GVSvgzDoc, GVPngDoc, GVJpegDoc, GVGifDoc,
GVPdfGvDoc, and GVPdfGsDoc (which has 4 sequential os.system
calls: dot -> tmp ps, then gs in single-page / per-piece /
merge variants).
Each call site keeps its existing cleanup-then-check ordering so
temp files generated before the failure point still get removed
where they were already being removed. The minimum-delta approach
preserves the file's existing cleanup semantics (which were already
inconsistent in the single-page PdfGs path -- that pre-existing
weakness is intentionally out of scope here).
Out of scope: the reporter's additional ask in note ~0038649 for a
pre-flight "try open output for write" check before report
generation begins. That is a feature ask; this commit fixes the
bug-class part of the report (silent failure -> visible error).
Test: new gramps/gen/plug/docgen/test/graphdoc_test.py with two
groups:
- CheckRcTest: four cases asserting the helper is silent on rc=0,
raises ReportError on non-zero, names the target in the
message, and treats *any* non-zero (incl. POSIX-encoded
high-byte exits like 256 and signal-encoded negatives) as
failure.
- GraphdocStaticAssertions: two source-grep guards -- no bare
``os.system(...)`` callsites remain in graphdoc.py, and every
``rc = os.system(...)`` assignment is paired with a
``_check_rc(rc, ...)`` call. This catches a regression that
would silently reopen bug 6556 if a future edit added an
os.system call without the check.
Verified end-to-end:
_check_rc(0, "/tmp/ok.svg") -> silent (success path)
_check_rc(256, "/tmp/locked.svg") -> ReportError: "Could not create /tmp/locked.svg"
Fixes #6556.
Bug 10443: the man page's ENVIRONMENT VARIABLES section listed
LANG only. Users who set LANG=xx_YY.UTF-8 to switch languages and
hit a system where that alone isn't enough -- a common gettext
fallback chain hazard -- had no way to learn from the documentation
that they also needed to set LANGUAGE. The reporter found this
empirically after digging through "gramps -v" output, and asked
that the docs be updated to save other users the same time.
LANGUAGE has been a fully-supported, documented-in-source override
for years (gramps/gen/utils/grampslocale.py:250-256: colon-separated
list of language codes, splits on ":", overrides LANG and
LC_MESSAGES, logs "Overiding locale setting ... with LANGUAGE
setting ..."). The CLI help text in gramps/cli/argparser.py:140
already shows the LANGUAGE=de_DE; LANG=de_DE.UTF-8 idiom in its
report-generation example. Only the man page (and the wiki, which
is outside the source tree) hadn't caught up.
Add a LANGUAGE entry to data/man/en.rst's ENVIRONMENT VARIABLES
section, immediately after LANG, explaining the semantics and the
canonical "set both" idiom the reporter found works:
LANG=ru_RU.UTF-8 LANGUAGE=ru gramps
Backtick style matches the surrounding file (double for variable
names referenced inline, single for value literals).
Out of scope:
* Regenerating data/man/gramps.1.in via sphinx-build. That file
is generated from en.rst and is regenerated in batches by
maintainers (last regen: 8159aca "Generate gramps.1.in
file", Feb 2022; en.rst has seen 4 unpaired commits since).
Following the existing rst-only edit pattern -- maintainer can
re-run sphinx-build -b man at the next batch regeneration.
* Localized man pages under data/man/{cs,fr,nl,pl,pt_BR,sv}/.
Those follow the Weblate translation workflow once en.rst is
updated; translator-side change, not a same-PR concern.
* The wiki pages the reporter and Sam888 actually flagged
(Howto:Change_the_language_of_reports#How_to_install_a_locale
and the two Gramps_5.0_Wiki_Manual_-_Command_Line /
_-_Settings pages). Those are wiki edits outside the source
tree; a separate community task.
Test: this is documentation, no functional code path changes. No
unit test applies. Manual verification: the prose accurately
describes the behavior implemented at grampslocale.py:250-256 (the
authoritative source) and gives the exact form the reporter
empirically found works.
Fixes #10443.
format_long_month_year, format_short_month_year, format_long_month and
format_short_month looked up the inflect key in FORMATS_long_month_year
/ FORMATS_short_month_year with a bare subscript, so an inflection key
absent from those dicts raised KeyError instead of degrading.
display_formatted() builds the inflect key from a translatable string
(e.g. _("", "about-date")), which the surrounding comments ask
translators to leave untranslated or render as the English keyword the
dicts are keyed by ("about"). The Finnish fi.po instead translates
"about-date" to the native word "noin", so an "about <Month> <Year>"
date shown under a long-month format crashed with KeyError: 'noin' --
in the Detailed Ancestral Report, the Relationship View and elsewhere.
Look the key up with dict.get(), falling back to the uninflected ("")
format, so a mistranslated locale degrades to a readable date instead
of aborting.
Fixes #14100.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
`HourGlassReport.traverse_down` linked focal → family → children but
never added the family's *other* parent. `traverse_up` already handles
both — its father-section and mother-section each add the parent node
and an edge to the family. Descending was asymmetric and every
descendant generation's spouse was invisible: e.g. starting from
example.gramps' Lewis Anderson Garner (I00044) with maxdescend=2 the
graph rendered Lewis → F00017 → eight children but never named
Luella Jacques Martel (I00045) nor any of the children's spouses.
In `traverse_down`, after adding the family node and the focal-to-family
edge, derive the other parent's handle (the one that isn't `person`),
add that person to the graph, and link them to the family with the
same arrow style as the focal-to-family edge. Mirrors the per-parent
shape of `traverse_up`, with `__used_people` keeping the spouse from
being re-added if cousin-marriage paths bring them through later.
- `gramps/plugins/graph/gvhourglass.py:163` — `traverse_down` body (now
includes the spouse-add block at lines 178-202)
- `gramps/plugins/graph/gvhourglass.py:193` — `traverse_up` (existing
symmetric pattern this matches)
`gramps/plugins/test/reports_test.py` adds
`test_hourglass_graph_includes_spouse_mantis_9628`. It invokes the
report on data.gramps with center=I0027 (Smith Ingeman), maxdescend=1,
maxascend=0; the expected spouse is Ericsdotter Marta (I0025).
* Pre-fix: fails with `'Ericsdotter' not found in '<DOT>'` — DOT
contains only Ingeman, the family node, and the child Martin.
* Post-fix: `ok` — Marta appears in the DOT as a person node linked
to F0001.
Fixes #9628.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
GEDCOM 5.5.1 requires three-letter month abbreviations
(``7 NOV 1959``), but tools such as ancestry.com export bare numeric
``D/M/YYYY`` dates the spec does not define. ``libgedcom.GedcomDateParser``
hardcodes ``dhformat = "%m/%d/%y"`` (en_US locale, ``libgedcom.py:925``),
so a bare numeric date is unconditionally read MM/DD/YYYY. When the
source actually uses DD/MM/YYYY and the day is ≤ 12 (both readings
syntactically valid), the importer silently swaps day and month and
emits no warning — ``GEDCOM import report: No errors detected``
despite a wrong date being written to the database. Day > 12 already
falls back to text-only storage (visually flagged in the Events view
as bold), so only the day ≤ 12 case is silently dangerous.
This was reported in 2016 and re-confirmed in 2022/2023 across
multiple discourse threads; multiple developers have discussed
narrower-scope fixes (warn-only, source-detect ancestry, switch in
import dialog) but none have shipped. No code-side parse-direction
change is possible without breaking US users who currently rely on
the existing MM/DD/YYYY default for legitimately-shaped numeric input.
The smallest defensible change: emit an advisory warning per
ambiguous bare-numeric date during import, no parse-direction change.
US users see no behaviour change; European users importing
ancestry.com-shaped GEDCOMs get a per-event audit list with both the
original GEDCOM text and the chosen interpretation.
- ``BARE_NUMERIC_DATE`` regex added next to the other module-level
GEDCOM patterns (``libgedcom.py:894``).
- ``GedcomParser.__add_warn`` (new) wraps ``__add_msg`` with the
``number_of_errors -= 1`` pattern already used at the end of
``__finish_import`` for the unknown-references note; the summary
line stays "No errors detected" when the warnings are advisory.
- ``GedcomParser.__warn_if_ambiguous_numeric_date`` (new) is called
from ``__event_date`` after the date object is attached to the
event. Suppresses on ``MOD_TEXTONLY`` (already visually flagged)
and on non-numeric inputs. ``line`` is intentionally not passed
through ``__add_warn`` because ``__add_msg`` truncates the problem
string to 66 columns when a line is supplied, which drops the
actionable half of the message — and the warning text already
contains the original GEDCOM date string verbatim.
Scope is limited to ``__event_date`` (the only date sink the bug
report cites). ``__name_date`` / ``__lds_ord_date`` / ``__addr_date``
/ ``__citation_date`` / ``__media_date`` could call the same helper
in a follow-up if a maintainer asks; left out here to keep the diff
focused on the cited symptom.
- ``gramps/plugins/lib/libgedcom.py:925`` — the hardcoded
``dhformat = "%m/%d/%y"`` that drives the silent swap.
- ``gramps/plugins/lib/libgedcom.py:3797`` — existing precedent for
the ``__add_msg`` then ``number_of_errors -= 1`` pattern used to
attach an advisory note without polluting the error count.
- ``gramps/gen/lib/date.py:590`` — ``Date.MOD_TEXTONLY = 6`` (the
fallback used when the parser can't make sense of the input,
recognised in the helper to suppress the warning).
``gramps/plugins/importer/test/importgedcom_ambiguous_date_test.py``
imports an Ancestry-shaped GEDCOM fixture via ``import_as_dict`` with
a ``CapturingUser`` that intercepts the summary dialog text. Four
assertions:
1. ``7/11/1959`` (day ≤ 12, the silent-swap case) triggers an
"Ambiguous numeric date" warning naming the original text and
the chosen interpretation.
2. ``5 MAR 1899`` (spec-compliant) stays silent.
3. ``25/3/1934`` (day > 12, text-only fallback) stays silent.
4. The summary still reads "GEDCOM import report: No errors detected".
Pre-fix, test 1 fails ("'Ambiguous numeric date' not found in 'GEDCOM
import report: No errors detected'"); the other three pass. Post-fix
all four pass.
Fixes #9298.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Commit 48a6cbf fixed a regression in the RelationshipPathBetween filter rule's init_list method that landed in 1280aa4, where `for person_handle in firstList and secondList` evaluates as `secondList` via Python's short-circuit `and`, causing `firstMap[person_handle]` to raise KeyError on handles reachable from the second root but not the first. The fix shipped without a direct test for the rule (only the RelationshipPathBetweenBookmarks wrapper was tested), so the regression could reappear unnoticed. This test exercises the rule with two example.gramps persons that share no ancestor (I0044, the home person, and I2127, a member of the unrelated Δεληπέτρου family). On the pre-fix code it failed with KeyError at _relationshippathbetween.py:130, matching the line and exception class in Mantis 13830's traceback. With the fix in place it passes, returning the two endpoints unchanged. Issue #13830. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The test_add_persons_one_fetch_raises_other_still_imported test intentionally raises a RuntimeError to simulate a network failure, but did not patch LOG, causing the LOG.warning(..., exc_info=True) call in add_persons to emit a full traceback to stderr on every test run. Patch LOG in that test, matching the pattern already used by the companion test_add_persons_fetch_exception_is_logged_not_raised test. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2ac1386 to
da6a4fb
Compare
GalleryTab.clean_up() did not disconnect the iconlist 'selection-changed' signal handler before super().clean_up() deleted the iconlist attribute via track_ref_for_deletion. A late selection-changed emission - which fires when the parent dialog tears down on Cancel, e.g. when the Forms addon hosts a GalleryTab - then re-entered _selection_changed -> get_selected() -> self.iconlist.get_selected_items() and crashed with AttributeError: 'GalleryTab' object has no attribute 'iconlist'. The original 2012 disconnect (r20849) was removed in 2023 to silence a GTK warning when the iconlist had already been disposed. Restore the disconnect, guarded by GObject.signal_handler_is_connected so it stays silent in the dispose-first case. Fixes #13326.
The disconnect restored for bug 13326 is gated by GObject.signal_handler_is_connected so that the case commit 37395da was working around (iconlist already disposed by GTK before clean_up) stays silent. Add a second test case that destroys the iconlist widget before clean_up and asserts no Python warning of the shape "instance '...' has no handler with id '...'" is recorded. Pre-fix the unguarded disconnect emits exactly that warning; post-fix the test passes. Issue #13326.
gramps-ci.yml runs the unit-test suite without Xvfb and exports GDK_BACKEND=-. Constructing a Gtk.IconView against a NULL screen "succeeds" but segfaults when those orphan widgets are garbage collected at process exit, taking the whole suite down with exit code 139. Detect the no-display case via DISPLAY / GDK_BACKEND / Gtk.init_check at module import and skip the entire TestCase class cleanly. The two regression tests still run under xvfb-run or on a real desktop. Issue #13326.
…llerytab-iconlist-cleanup
The previous contract appended a label whenever an addon dict carried
a "rm" / "rg" / "re" key, regardless of whether the value was a non-
empty list. Present-but-empty keys - e.g. an addon listing with
`"re": []` because its .gpr.py declares `requires_exe=[]` - produced
a labelled section paired with an empty table. Two consequences for
existing consumers:
* gramps core's AddonManager Requirements dialog
(`EnhancedAddonStatus.__on_requires_clicked` in
`gramps/gui/plug/_windows.py`) renders the empty table as a
labelled section with no rows. The PostgreSQL Enhanced listing
surfaces this today: clicking Requires shows an empty
"Executables" section after the real Python-modules section.
* The Plugin Manager Enhanced addon's row-click handler indexes
`req_lst[0]` on the table and crashed with IndexError on the
same shape (Mantis 13979, fixed addon-side in addons-source
PR 916). This change tightens the producer side so any other
future consumer is shielded too.
Build the table first and append the label + table only if the table
has entries. Behaviour for non-empty keys is preserved exactly (same
labels, same table contents, same rm / rg / re order).
Verified on `maintenance/gramps61`:
| input addon dict | before | after |
|-------------------------------------------------|-----------------------------------------------------------------------|------------------------------------|
| `{}` | `[]` | `[]` |
| `{"re": []}` | `["Executables", []]` | `[]` |
| `{"rm": []}` | `["Python modules", []]` | `[]` |
| `{"rg": []}` | `["GObject introspection modules", []]` | `[]` |
| `{"rm": ["psycopg"], "re": []}` | `["Python modules", [["psycopg", "X"]], "Executables", []]` | `["Python modules", [["psycopg", "X"]]]` |
| `{"rm": [], "rg": [], "re": []}` | three empty pairs | `[]` |
Known consumers of `Requirements.info` in gramps core: one call site
in `gramps/gui/plug/_windows.py:349` (the Requirements InfoDialog).
The addons-source Plugin Manager Enhanced addon
(`PluginManager/PluginManager.py`) has the only out-of-tree consumer
in the addons-source repo. Both are improved by the change; the
addon already guards empty tables defensively, so this is belt-and-
suspenders for it.
Ships `gramps/gen/utils/test/requirements_test.py` (8 cases): the
six pre-change shapes (none now emit empty pairs) plus two positive
cases asserting populated-section behaviour is unchanged (label,
table contents, rm/rg/re ordering).
Context for Issue #13979 - that crash is resolved by addons-source
PR 916; this change is the complementary core-side hardening, not a
substitute. No tracker action is taken on 13979 here.
SelectionWidget._button_release_event's "update current selection" else branch (the path that fires when self.current is set and self.grabber == INSIDE) called self.current.set_coords(*self.selection) unconditionally. Under the Mantis 13059 / 12659 reproducer -- resize a box edge, release, then single-click (no drag) inside the same box -- that branch lands with self.selection is None, because the prior resize-release left self.grabber == INSIDE and the no-motion click never rebuilt selection. *None is not iterable, raising TypeError before set_coords is even invoked. Guard both set_coords(*self.selection) call sites in the release handler with "if self.selection is not None:". The safe no-op for a no-motion click is to leave the region's stored coordinates alone -- the user clicked without moving, the region shouldn't move. Conservative guard mirroring the defensive-guard pattern from the 13966 / 13326 teardown-family fixes; no restructuring of the widget. Both call sites guarded for defense in depth: - line 770, grabber-edge branch -- _modify_selection always populates self.selection today, so this is a future-regression guard, not a known bug path. - line 779, INSIDE-click branch -- the actual 13059 path. Regression test ships with the fix at gramps/gui/widgets/test/selectionwidget_test.py (headless unittest, __new__-bypass to avoid needing a live GTK display). Three cases: - test_click_after_resize_with_none_selection_does_not_raise -- the 13059 path (grabber == INSIDE, selection == None). Pre-fix raises TypeError; post-fix does not, and the region's coords are unchanged. - test_grabber_edge_release_with_none_selection_does_not_raise -- same shape on the grabber-edge branch. - test_click_with_valid_selection_still_updates_region -- sanity that a valid selection still updates the region's coords and emits region-modified. This also addresses 12659 (the 2022 "could not reproduce" duplicate of this issue) -- the reproducer on 13059 fires through 12659's path too. Fixes #13059, #12659.
The dialog shown when ``AddonManager.install_addon`` cannot register a plugin said only "The addon will be unavailable in your current configuration" -- it named neither the failing addon nor any of the common causes. The Mantis 13736 reporter and the linked Discourse threads describe the canonical scenario: a 5.x ``gramps.ini`` carried "addons-projects" entries into a 6.x install, those projects index addons-XX.json catalogues whose ``gramps_target_version`` no longer matches, ``valid_plugin_version`` rejects them at registration time, and the user is left with no path from "unavailable" to "fix the project URL". bamaustin's note on 13736 traces the dialog to ``gramps/gui/plug/_windows.py``. Improve the dialog text to: - Name the ``addon_id`` that failed to register, so users with multiple projects know which install attempt produced the error. - Surface the most common cause (target-version mismatch via a stale project URL) and point at the exact GUI path that fixes it (Edit -> Preferences -> Addon Manager -> Projects). - Quote the running Gramps ``major_version`` so users can compare it against the project URL directly without having to open About. Pure message-text change. No behaviour change to plugin registration itself; ``valid_plugin_version`` still does the underlying check. Regression test ``gramps/gui/plug/test/windows_test.py`` (new; headless ``unittest``, ``__new__``-bypass on ``AddonManager``, ``OkDialog`` patched out so the dialog text is captured rather than rendered). Two cases: - ``test_failure_dialog_names_the_addon_and_points_at_projects`` forces ``get_plugin`` to return ``None`` and asserts the dialog's message contains the addon id, the running ``major_version``, and the "Projects" panel pointer. - ``test_failure_dialog_not_shown_on_success`` sanity-checks the happy path: when ``get_plugin`` returns pdata, the dialog is not raised and ``load_plugin`` + the ``plugins-reloaded`` emit fire. Fixes #13736. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The Top Surnames gramplet counted each person under every group name from their primary and alternate names, and stored that person as the representative for each surname. The representative could therefore be a person whose primary surname differed, when they matched only through an alternate name. The Same Surnames quick view re-derives the surname from the representative's primary name, so double-clicking such a surname opened a report for the wrong surname. This most often affected the top surname, which is the most likely to appear as an alternate name on people whose primary surname differs. Prefer a representative whose primary surname matches the group name. The per-person tally is moved to a module-level record_surnames() helper, leaving the gramplet's incremental yielding unchanged, so the selection logic can be tested without GTK or a database. A regression test covers surname counting, representative selection regardless of iteration order, and the fallback for surnames that appear only as alternate names. Fixes #11101.
Add Visual Studio Code's configuration folder to gitignore, allowing developers to have local files which don't get added to commits. For now the entire folder is ignored, but it would make sense to provide a list of recommended extensions, launch configurations, etc. and exclude those files from gitignore.
da6a4fb to
fd07571
Compare
Currently translated at 0.4% (34 of 7555 strings) Translation: Gramps/Program Translate-URL: https://hosted.weblate.org/projects/gramps-project/gramps/lv/
Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Translation: Gramps/Program Translate-URL: https://hosted.weblate.org/projects/gramps-project/gramps/
Currently translated at 100.0% (7644 of 7644 strings) Translation: Gramps/Program Translate-URL: https://hosted.weblate.org/projects/gramps-project/gramps/sk/
Currently translated at 73.9% (5652 of 7644 strings) Translation: Gramps/Program Translate-URL: https://hosted.weblate.org/projects/gramps-project/gramps/ja/
Currently translated at 99.7% (7627 of 7644 strings) Translation: Gramps/Program Translate-URL: https://hosted.weblate.org/projects/gramps-project/gramps/fr/
Currently translated at 100.0% (7644 of 7644 strings) Translation: Gramps/Program Translate-URL: https://hosted.weblate.org/projects/gramps-project/gramps/sv/
Currently translated at 98.6% (7544 of 7644 strings) Translation: Gramps/Program Translate-URL: https://hosted.weblate.org/projects/gramps-project/gramps/he/
The Mac localization helper passed open("/dev/null") as the stderr
argument to subprocess.Popen. Popen's context manager closes only the
pipes it creates itself, not a file object supplied by the caller, so
that handle leaked and raised a ResourceWarning on every unittest run
on macOS. Using subprocess.DEVNULL leaves no Python file object to leak.
Fixes #14243.
The str_incr generator in latexdoc.py produces the column identifiers used for spanning cells in LaTeX tables. Its increment loop iterated the character list's elements instead of its indices, so indexing the list with a string raised TypeError: list indices must be integers or slices, not str. The first value is yielded before the loop runs, so the crash appeared on the second multicolumn id, which a styled note containing subscript and strikeout produces. Iterate the indices instead of the elements, preserving the existing carry behaviour. A headless unit test exercises str_incr. Fixes #13418.
b76aa9a to
9970f9c
Compare
9970f9c to
6578c69
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Automated nightly sync from
gramps-project/gramps@maintenance/gramps61. Generated by .github/workflows/upstream-sync.yml on the testbed.