Skip to content
Merged
Show file tree
Hide file tree
Changes from 38 commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
417810d
chg: more consistent survey_element subclass inits, add type to repr
lindsay-stevens Feb 11, 2026
ef0fd5a
chg: loosen dict requirement for builder.py to Mapping
lindsay-stevens Feb 11, 2026
19e5ea3
chg: initial implementation of entities spec 2025.1.0 (v2)
lindsay-stevens Feb 11, 2026
2348363
fix: emit repeat setvalue if entity target has a repeat ancestor
lindsay-stevens Feb 12, 2026
813ed13
fix: save_to validation raising wrong error message
lindsay-stevens Feb 16, 2026
0dd6578
add: detailed xpath assertions for entities create repeat test cases
lindsay-stevens Feb 17, 2026
ab8c080
add: new entities test module with test plans and poc test cases
lindsay-stevens Feb 20, 2026
2a0672d
dev: delete test covered by new test_entities module
lindsay-stevens Feb 20, 2026
b8ee322
dev: delete test covered by new test_entities module
lindsay-stevens Feb 20, 2026
d604c58
dev: delete test covered by new test_entities module
lindsay-stevens Feb 20, 2026
305247b
dev: delete test covered by new test_entities module
lindsay-stevens Feb 20, 2026
cf5b22b
dev: delete test covered by new test_entities module
lindsay-stevens Feb 20, 2026
efc0ee6
dev: delete test covered by new test_entities module
lindsay-stevens Feb 20, 2026
bd500d1
dev: delete test covered by new test_entities module
lindsay-stevens Feb 20, 2026
f231f54
dev: delete test covered by new test_entities module
lindsay-stevens Feb 20, 2026
da3eb47
fix: docstring typo in validate_question_group_repeat_name
lindsay-stevens Feb 20, 2026
3e073fc
add: container saveto + duplicate entity checks, move save_to name tests
lindsay-stevens Feb 20, 2026
b65baf3
add: validation for a missing entity declaration
lindsay-stevens Feb 23, 2026
49bd637
chg: update message and tests for missing entity create label error
lindsay-stevens Feb 23, 2026
12c5339
dev: tidy up markdown table formatting / alignment
lindsay-stevens Feb 23, 2026
990bd4d
chg: update message and tests for missing entity upsert update_if error
lindsay-stevens Feb 23, 2026
13b7d41
chg: update missing entity update/upsert entity_id error
lindsay-stevens Feb 23, 2026
12b5fab
add: validation for missing entity save_to prefix with multiple entities
lindsay-stevens Feb 23, 2026
4722df0
chg: delete EV013 since it's covered by EV008 unresolved save_to prefix
lindsay-stevens Feb 23, 2026
ca25142
add: tests and clearer error for unsolvable meta/entity topology check
lindsay-stevens Feb 24, 2026
a4eee45
add: tests and clearer error for save_to scope breach check
lindsay-stevens Feb 24, 2026
c271d67
add: tests and clearer error for reference scope conflict check
lindsay-stevens Feb 24, 2026
eb139e5
add: duplicate save_to delimiter check
lindsay-stevens Feb 24, 2026
ed66206
add: test for entity name column alias
lindsay-stevens Feb 24, 2026
0f15f13
chg: consolidate existing tests for create mode into test_entities.py
lindsay-stevens Feb 24, 2026
fc69624
add: type for entity container allocation request data
lindsay-stevens Feb 25, 2026
fb6d332
fix: save_to must be in nearest container not nearest scope boundary
lindsay-stevens Feb 25, 2026
17efd06
fix: entity for save_to can be higher but only if no other entities
lindsay-stevens Feb 26, 2026
fe43ba9
dev: refactor entities_parsing for clarity / efficiency
lindsay-stevens Feb 26, 2026
1eb3a2d
fix: duplicate setvalue with entity_id, add more implicit mode coverage
lindsay-stevens Feb 27, 2026
047327f
dev: resolve some todo items in entities_parsing.py
lindsay-stevens Feb 27, 2026
dda77cc
dev: resolve todo item in entities_parsing.py
lindsay-stevens Feb 27, 2026
6b525bb
dev: resolve todo item in entities_parsing.py
lindsay-stevens Feb 27, 2026
4d4db08
dev: fix tests failing on odk_validate xpath check for instance ref
lindsay-stevens Mar 2, 2026
465e1dc
add: tests for savetos within same boundary but different containers
lindsay-stevens Mar 2, 2026
25efe67
add: allocate unreferenced entities to /survey, tie break on row_number
lindsay-stevens Mar 2, 2026
6eb21a2
dev: fix ci fail due to different attributes being checked by validate
lindsay-stevens Mar 2, 2026
86ec42f
add: test cases for save_to scenarios
lindsay-stevens Mar 3, 2026
83c341e
add: check for missing dataset name, fix errors on row_number > 2
lindsay-stevens Mar 3, 2026
85eee0b
chg: move variable parsing to get_entity_declaration
lindsay-stevens Mar 3, 2026
1342843
fix: add instance to save_to with update mode tests
lindsay-stevens Mar 3, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pyxform/aliases.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@
"requiredmsg": ("bind", "jr:requiredMsg"),
"required_message": ("bind", "jr:requiredMsg"),
"body": "control",
constants.ENTITIES_SAVETO: ("bind", "entities:saveto"),
constants.ENTITIES_SAVETO: ("bind", constants.ENTITIES_SAVETO_NS),
}

entities_header = {constants.LIST_NAME_U: "dataset"}
Expand Down
11 changes: 6 additions & 5 deletions pyxform/builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import os
from collections import defaultdict
from collections.abc import Mapping
from typing import Any

from pyxform import constants as const
Expand Down Expand Up @@ -65,7 +66,7 @@ def set_sections(self, sections):
the name of the section and the value is a dict that can be
used to create a whole survey.
"""
if not isinstance(sections, dict):
if not isinstance(sections, Mapping):
raise PyXFormError("""Invalid value for `sections`.""")
self._sections = sections

Expand All @@ -79,7 +80,7 @@ def create_survey_element_from_dict(

:param d: data to use for constructing SurveyElements.
"""
if "add_none_option" in d:
if d.get("add_none_option", None) is not None:
self._add_none_option = d["add_none_option"]

if d[const.TYPE] in SECTION_CLASSES:
Expand Down Expand Up @@ -266,7 +267,7 @@ def _name_and_label_substitutions(question_template, column_headers):
# if the label in column_headers has multiple languages setup a
# dictionary by language to do substitutions.
info_by_lang = None
if isinstance(column_headers[const.LABEL], dict):
if isinstance(column_headers[const.LABEL], Mapping):
info_by_lang = {
lang: {
const.NAME: column_headers[const.NAME],
Expand All @@ -279,10 +280,10 @@ def _name_and_label_substitutions(question_template, column_headers):
for key in result:
if isinstance(result[key], str):
result[key] %= column_headers
elif isinstance(result[key], dict):
elif isinstance(result[key], Mapping):
result[key] = result[key].copy()
for key2 in result[key]:
if info_by_lang and isinstance(column_headers[const.LABEL], dict):
if info_by_lang and isinstance(column_headers[const.LABEL], Mapping):
result[key][key2] %= info_by_lang.get(key2, column_headers)
else:
result[key][key2] %= column_headers
Expand Down
1 change: 1 addition & 0 deletions pyxform/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
TITLE = "title"
NAME = "name"
ENTITIES_SAVETO = "save_to"
ENTITIES_SAVETO_NS = "entities:saveto"
ID_STRING = "id_string"
SMS_KEYWORD = "sms_keyword"
SMS_FIELD = "sms_field"
Expand Down
Loading
Loading