Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

${} references in predicates should be expanded using current() #524

Merged
merged 5 commits into from
Apr 13, 2021
Merged

${} references in predicates should be expanded using current() #524

merged 5 commits into from
Apr 13, 2021

Conversation

gushil
Copy link
Contributor

@gushil gushil commented Mar 3, 2021

Closes #490

Why is this the best possible solution? Were any other approaches considered?

I use simple predicate testing by checking whether current context start with instance(. I'm thinking about using external library for xpath checking, but thought that would be too overkill for this case.

What are the regression risks?

None, but probably still need some more tests. Open to more tests suggestion!

Does this change require updates to documentation? If so, please file an issue here and include the link below.

No.

Before submitting this PR, please make sure you have:

  • included test cases for core behavior and edge cases in tests_v1
  • run nosetests and verified all tests pass
  • run black pyxform to format code
  • verified that any code or assets from external sources are properly credited in comments

Copy link
Contributor

@MartijnR MartijnR left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've not been able to break this 3-line solution 😄

I added some tests to the issue, that may be helpful if this code ever gets refactored.

pyxform/survey.py Outdated Show resolved Hide resolved
@gushil
Copy link
Contributor Author

gushil commented Mar 5, 2021

I added some tests to the issue, that may be helpful if this code ever gets refactored.

Thanks. I will add those tests.

@codecov-io
Copy link

codecov-io commented Mar 5, 2021

Codecov Report

Merging #524 (f176380) into master (bee9654) will increase coverage by 0.01%.
The diff coverage is 100.00%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #524      +/-   ##
==========================================
+ Coverage   83.92%   83.93%   +0.01%     
==========================================
  Files          25       25              
  Lines        3713     3716       +3     
  Branches      865      866       +1     
==========================================
+ Hits         3116     3119       +3     
  Misses        452      452              
  Partials      145      145              
Impacted Files Coverage Δ
pyxform/survey.py 92.56% <100.00%> (+0.04%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update bee9654...f176380. Read the comment docs.

@gushil
Copy link
Contributor Author

gushil commented Mar 5, 2021

@MartijnR

Addressed your feedbacks in recently pushed commits.

Thanks.

# (starts with 'instance(' and have square bracket in it)
is_secondary_instance = (
matchobj.string.startswith("instance(")
and re.search(r"\[(.+)\]", matchobj.string) is not None
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for my confusing comment. I think the square bracket (i.e. predicate) check may not be necessary (like you had initiallly), since the use of ${node} syntax implies this. But would be good to hear what @lognaturel thinks.

@MartijnR MartijnR requested a review from lognaturel March 5, 2021 17:27
Copy link
Contributor

@lognaturel lognaturel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apologies for the delay on this!

I agree with @MartijnR that looking ONLY for instance( as you had before is a clever way to identify expressions that will need current. As far as I can tell, the only place there could be a ${} reference in such an expression is in a predicate.

The issue with this is that it will only work if a complete expression starts with instance(. Consider for example changing test_repeat_using_select_with_reference_path_in_predicate_uses_current to have ${item-counter} + instance('item')/root/item[itemindex=${item-counter}]/label (it's nonsense but illustrates the point). Now current() isn't used anywhere.

@gushil
Copy link
Contributor Author

gushil commented Mar 29, 2021

Apologies for the delay on this!

I agree with @MartijnR that looking ONLY for instance( as you had before is a clever way to identify expressions that will need current. As far as I can tell, the only place there could be a ${} reference in such an expression is in a predicate.

The issue with this is that it will only work if a complete expression starts with instance(. Consider for example changing test_repeat_using_select_with_reference_path_in_predicate_uses_current to have ${item-counter} + instance('item')/root/item[itemindex=${item-counter}]/label (it's nonsense but illustrates the point). Now current() isn't used anywhere.

Thanks for the review @lognaturel

Commit ae2125e includes fixes for this.

@gushil gushil requested a review from lognaturel March 29, 2021 07:32
@pbowen-oc
Copy link

@lognaturel - Is there anything @gushil or I can do to help with this issue?

@lognaturel
Copy link
Contributor

Is there anything @gushil or I can do to help with this issue?

@pbowen-oc Y'all have cycles for some of my other work? ;) Taking a look...

Copy link
Contributor

@lognaturel lognaturel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you, this approach makes sense to me semantically -- check to see if a ${} expression is in a predicate for a path expression that starts with instance(. This will slow form conversion down since every single ${} expression will go through an extra check but I can't think of a great alternative.

I can't think of additional test cases. I would like the naming in the code changes to be a little more precise.

instance_regex = re.compile(r"instance\([^)]+\S+")

def _is_secondary_instance():
"""check if current matchobj is a predicate and part of primary instance"""
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we're really going to tie ourselves up in knots if this code needs to be revisited so making sure the naming is precise is important.

Name: _in_secondary_instance_predicate
Comment: check if ${} expression represented by matchobj is in a predicate for a path expression for a secondary instance

@MartijnR any other ideas for tightening the wording?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the suggestion @lognaturel
Fixed in the next commit.

Copy link
Contributor

@lognaturel lognaturel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, @gushil!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

${} references in predicates not used as choice filters should be expanded using current()
5 participants