XLSForm / pyxform

A Python package to create XForms for ODK Collect.
BSD 2-Clause "Simplified" License
77 stars 134 forks source link

dynamic default expression causes KeyError #507

Closed MartijnR closed 3 years ago

MartijnR commented 3 years ago

Software and hardware versions

pyxform v1.3.3

Problem description

Follow form produces an unhelpful error.

type name label calculation default
calculate r     random() + 0.5
calculate one     if(${r} < 1,'A','B')
Screen Shot 2020-12-28 at 3 05 33 PM

The full error is:

Traceback (most recent call last):
  File "/Users/martijnvanderijdt/.virtualenvs/local_pyxform/bin/xls2xform", line 11, in <module>
    load_entry_point('pyxform', 'console_scripts', 'xls2xform')()
  File "/Users/martijnvanderijdt/Code/pyxform/pyxform/xls2xform.py", line 177, in main_cli
    enketo=args.enketo_validate,
  File "/Users/martijnvanderijdt/Code/pyxform/pyxform/xls2xform.py", line 49, in xls2xform_convert
    enketo=enketo,
  File "/Users/martijnvanderijdt/Code/pyxform/pyxform/survey.py", line 1055, in print_xform_to_file
    raise error
  File "/Users/martijnvanderijdt/Code/pyxform/pyxform/survey.py", line 1051, in print_xform_to_file
    file_obj.write(self._to_ugly_xml())
  File "/Users/martijnvanderijdt/Code/pyxform/pyxform/survey.py", line 838, in _to_ugly_xml
    return '<?xml version="1.0"?>' + self.xml().toxml()
  File "/Users/martijnvanderijdt/Code/pyxform/pyxform/survey.py", line 243, in xml
    node("h:head", node("h:title", self.title), self.xml_model()),
  File "/Users/martijnvanderijdt/Code/pyxform/pyxform/survey.py", line 546, in xml_model
    model_children += self.xml_bindings()
  File "/Users/martijnvanderijdt/Code/pyxform/pyxform/survey_element.py", line 479, in xml_bindings
    dynamic_default = e.get_setvalue_node_for_dynamic_default()
  File "/Users/martijnvanderijdt/Code/pyxform/pyxform/survey_element.py", line 369, in get_setvalue_node_for_dynamic_default
    default_with_xpath_paths = self.get_root().insert_xpaths(self.default, self)
  File "/Users/martijnvanderijdt/Code/pyxform/pyxform/survey.py", line 996, in insert_xpaths
    return re.sub(BRACKETED_TAG_REGEX, _var_repl_function, unicode(text))
  File "/Users/martijnvanderijdt/.virtualenvs/local_pyxform/lib/python3.7/re.py", line 192, in sub
    return _compile(pattern, flags).sub(repl, string, count)
  File "/Users/martijnvanderijdt/Code/pyxform/pyxform/survey.py", line 993, in _var_repl_function
    matchobj, context, use_current, reference_parent
  File "/Users/martijnvanderijdt/Code/pyxform/pyxform/survey.py", line 976, in _var_repl_function
    if _is_return_relative_path():
  File "/Users/martijnvanderijdt/Code/pyxform/pyxform/survey.py", line 960, in _is_return_relative_path
    and "indexed-repeat" in context["bind"]["calculate"]
KeyError: 'calculate'

Steps to reproduce the problem

transform above form, also available here

Expected behavior

For this expression to be accepted without an error.

Other information

I have thoughts about considering type=calculate to be an alias to type=text (and type=hidden) (which doesn't have this problem). https://github.com/XLSForm/pyxform/issues/508

lognaturel commented 3 years ago

As we reviewed #499, we discovered that there were some bad branches introduced into the code for handling indexed-repeat. I think that PR might fix this. Could you please add a test, @gushil?

gushil commented 3 years ago

@lognaturel

Test added and passed in #499