Commit 7abb603
Sync fork's maintenance/gramps60 with upstream (2026-05-08) (#13)
* Wrap label vaue to ensure it is a string
The argument `label` to Gtk.Label must be of type string. In recent versions of Python and/or PyGObject, this check has become stricter and as a result is throwing an exception instead of silently converting to a string. So now we explicitly convert to string.
Fixes #14181
* TimelinePedigreeView: fix crash on second right-click in context menu (bug 0012387)
The settings submenu builder appended the same SeparatorMenuItem twice,
which GTK rejected with "Can't set a parent on widget which has a parent".
The corrupt parent linkage caused a segfault when the previous menu was
garbage-collected on the next right-click. Removing the stray duplicate
append fixes all four context-menu paths (background canvas, person,
relation, missing parent) and silences the related GTK_IS_WIDGET
assertion warnings. Also resolves duplicate report 0013463.
* Merge TimelinePedigree PR 819, 823
* DataEntryGramplet: fix crash when adding person with no Family Tree open (bug 0012691)
Clicking Add (or Save after a dirty edit) when no tree was loaded
raised AttributeError: 'DummyDb' object has no attribute 'get_undodb'
from DbTxn. Guard both mutating callbacks on dbstate.is_open() and
surface a clear ErrorDialog instead.
Add unit tests for the closed-db guards, pre-existing input guards,
and .gpr.py registration metadata so future refactors can't silently
break the bug-12691 fix.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* DataEntryGramplet: convert tests to stdlib unittest (bug 0012691)
Gramps' own test suite uses unittest, not pytest, so addon tests that
ship alongside the codebase should follow the same convention to stay
contributable upstream without rewriting.
Replace pytest fixtures, monkeypatch, and module-level test functions
with unittest.TestCase classes and mock.patch.object. Guard the
module-level addon import with a try/except that raises SkipTest so
collection is quiet on environments without the GUI stack, and pin
Gtk to 3.0 before gramps imports to avoid the GTK4 fallback crash on
Gtk.IconSize.MENU.
* DataEntryGramplet: qualify test import to pick up the class not the module
When unittest loads this file as DataEntryGramplet.tests.test_..., the
outer DataEntryGramplet is already a namespace package in sys.modules,
so `from DataEntryGramplet import DataEntryGramplet` binds the submodule
and DataEntryGramplet.NO_REL (class attr) raises AttributeError. Fix by
importing the class via its fully-qualified path.
* Merge DataEntryGramplet: fix crash when adding person with no Family Tree open (bug 0012691) gramps-project#824
* CalculateEstimatedDates: handle ancestry-loop DatabaseError per-person (bug 0007898)
probably_alive_range raises DatabaseError when it detects loops in
ancestor or descendant chains. Previously this propagated out of the
removal, selection, and apply loops and tore down the entire tool,
leaving signals disabled and the progress dialog stuck open.
Wrap each per-person iteration with try/except so a single bad record
is logged and skipped, and add outer try/finally blocks so signals are
re-enabled and the progress dialog is closed even on unexpected
failures. Surface a "Skipped N people due to errors" message to the
user when any rows were skipped.
Add unit tests covering get_modifier branches, calc_estimates happy
path, DatabaseError propagation from calc_estimates, and .gpr.py
registration metadata. The addon module is loaded lazily inside a
fixture so pytest collection succeeds even when the GUI stack cannot
import.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* CalculateEstimatedDates: convert tests to stdlib unittest (bug 0007898)
Gramps' own test suite uses unittest, not pytest, so addon tests that
ship alongside the codebase should follow the same convention to stay
contributable upstream without rewriting.
Replace pytest fixtures, monkeypatch, and pytest.raises with
unittest.TestCase, mock.patch.object, and assertRaisesRegex. Guard the
module-level addon import with a try/except that raises SkipTest so
collection is quiet on environments without the GUI stack, and pin Gtk
to 3.0 before gramps imports to avoid the GTK4 fallback crash on
Gtk.IconSize.MENU.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* Merge CalculateEstimatedDates: handle ancestry-loop DatabaseError (bug 0007898)gramps-project#825
* ImportMerge: fix AttributeError when adding/merging Tag objects
Tag is a table object without a gramps_id field, so the generic
has_<obj_type>_gramps_id / find_next_<obj_type>_gramps_id lookups in
do_commits raised AttributeError when the user selected Add on a Tag
row. Guard both the S_ADD and S_DIFFERS GID-conflict blocks so they
skip Tag.
Adds integration tests covering both branches; verified they fail
without the guard and pass with it.
Fixes bug 0014056
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* ImportMerge: pin Gtk to 3.0 in integration test
On systems with both GTK3 and GTK4 installed, PyGObject defaults to
GTK4, and importing ImportMerge pulls in gramps.gui which crashes on
Gtk.IconSize.MENU (a GTK3-only enum). Mirror the pin that
gramps.grampsapp performs at startup so reviewers can run the test
without environment tweaks.
* ImportMerge: rewrite integration test with unittest framework
AGENTS.md requires the unittest framework for tests. Convert the
pytest-based integration test (fixtures + assert statements) to a
unittest.TestCase with setUp/tearDown and self.assert* calls. GTK
availability is now checked with a module-level try/except raising
unittest.SkipTest, which also makes the separate GTK-pin step
redundant (still applied here before the gramps import).
* ImportMerge: apply Black formatting to integration test
Addresses AGENTS.md rule requiring Black-formatted Python. Collapses
three multi-line function calls that fit on a single line.
* ImportMerge: add type hints and class header to integration test
Addresses AGENTS.md requirements:
- Type hints on all helpers and test methods using Python 3.10+
syntax (``X | None``, ``tuple[X, Y]``).
- Sphinx-style ``:param:`` / ``:returns:`` docstring markers on the
helper functions.
- ``# ------`` class-header divider above the TestCase so it's easy
to locate.
No behavioural change.
* Merge ImportMerge: fix AttributeError when adding/merging Tag objects (bug 0014056) gramps-project#826
* Form: fix crash and surface clear errors for malformed XML (bug 0011707)
A family section whose title lacked the expected 'X/Y' separator caused
a ValueError: not enough values to unpack when the form editor opened,
crashing the Forms gramplet. The underlying issue was that the addon
trusted the XML definitions and had no schema validation or user-facing
error reporting for broken files.
Split the validation out of form.py into a pure-Python form_validator
module (no GTK/Gramps imports) so it can be unit-tested without a GUI.
The Form loader now:
* parses each file defensively (ExpatError -> ErrorDialog),
* runs the validator before loading (invalid files -> ErrorDialog with
the file path, offending form id, and the rule that failed),
* skips any <form> element that fails validation while still loading
sibling well-formed forms from the same file.
split_family_title() in form_validator belt-and-braces the FamilySection
constructor so a missing separator no longer raises, even if validation
is bypassed.
Also adds diagnostic logging:
* INFO log of forms loaded per file,
* DEBUG trace of each file parsed and each form id loaded/skipped,
* DEBUG when EditForm opens (event/citation handles),
* WARNING in FamilySection if its title lacks 'X/Y'.
Tests:
* Form/tests/test_form_validator.py -- 32 pure-Python unit tests,
covers split_family_title, every validation branch, parse_and_validate
file handling, and a sanity check that every shipped form_*.xml passes
validation.
* Form/tests/test_integration_form.py -- unittest integration tests that
patch ErrorDialog to verify the loader surfaces syntax errors, invalid
family titles, missing role, and invalid section types; partially
broken files still load their valid forms; shipped files trigger no
dialogs.
Partially addresses bug 0011010 (request for user error dialog for
unsupported elements) by covering its core ask: clear errors for
invalid section types, missing/empty role, missing/empty type, and XML
syntax errors.
Fixes #11707.
Refs #11010.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* Form: detect empty definition files and warn on column-size mismatches (bug 0011010)
A form definition file whose <forms> root contained no <form> elements
used to load silently — the loader iterated zero <form> children and
returned, leaving the user with no feedback. validate_form_dom now
reports this as an error so the ErrorDialog wiring added for bug 11707
surfaces the problem on load.
get_form_warnings is a new non-fatal check for sections whose <column>
<size> values do not sum to 100. 78 shipped definition files violate
this rule today without breaking rendering (the size field is parsed
but never read by the layout code), so treating it as an error would
flag correctly-working forms. The loader logs the warnings via
LOG.warning instead, making authoring mistakes in user-authored
custom.xml files diagnosable without harassing users of the built-in
forms.
Unit coverage: rejected empty <forms>, forms-root-with-only-comments,
and every branch of the sized-column check (no columns, no sizes,
summing to 100, summing to other totals, partial sizing, independent
of errors, multiple sections). Integration coverage: empty-forms
triggers ErrorDialog; size mismatch is logged but does not block the
form from loading. Tests use stdlib unittest to match Gramps' own
conventions.
* Merge Form: gramps-project#821 and (bug 11010)gramps-project#822
to 6.1 branch
* WebSearch: fix bare imports in test_filetable for dotted-path loading
`WebSearch/tests/test_filetable.py` imports `models`, `constants` and
`db_file_table` without a package prefix. Those resolve only when
`WebSearch/` itself is on sys.path — i.e. when the test is loaded via
`unittest discover` from inside `tests/`. Under the dotted-path form
that addons-source's own ci.yml uses (`python3 -m unittest
WebSearch.tests.test_filetable` from the addons-source root), the
imports look for a top-level `models` module and the test fails to
load:
ImportError: Failed to import test module: test_filetable
ModuleNotFoundError: No module named 'models'
Add the same `sys.path.insert(0, …parent dir…)` prologue that
TMGimporter and Form already use for the same pattern, so the test
loads under either form. No behavioural change beyond the imports.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* Merge WebSearch: fix bare imports in test_filetable for dotted-path loading gramps-project#833
---------
Co-authored-by: Himanshu Gohel <1551217+hgohel@users.noreply.github.com>
Co-authored-by: GaryGriffin <genealogy@garygriffin.net>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>1 parent 146b9c3 commit 7abb603
22 files changed
Lines changed: 2292 additions & 230 deletions
File tree
- CalculateEstimatedDates
- tests
- DataEntryGramplet
- tests
- Form
- po
- tests
- ImportMerge
- tests
- TimelinePedigreeView
- WebSearch
- tests
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
9 | 9 | | |
10 | 10 | | |
11 | 11 | | |
12 | | - | |
| 12 | + | |
13 | 13 | | |
14 | 14 | | |
15 | 15 | | |
| |||
Large diffs are not rendered by default.
Lines changed: 262 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
| 262 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
14 | 14 | | |
15 | 15 | | |
16 | 16 | | |
17 | | - | |
| 17 | + | |
18 | 18 | | |
19 | 19 | | |
20 | 20 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
423 | 423 | | |
424 | 424 | | |
425 | 425 | | |
| 426 | + | |
| 427 | + | |
| 428 | + | |
| 429 | + | |
| 430 | + | |
426 | 431 | | |
427 | 432 | | |
428 | 433 | | |
| |||
498 | 503 | | |
499 | 504 | | |
500 | 505 | | |
| 506 | + | |
| 507 | + | |
| 508 | + | |
| 509 | + | |
501 | 510 | | |
502 | 511 | | |
503 | 512 | | |
| |||
0 commit comments