-
Notifications
You must be signed in to change notification settings - Fork 137
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
Fixed ${} references in predicates not being expanded using current()… #536
Conversation
… if the expression contains whitespace before the reference
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I could not break it, though I tried quite hard. :)
pyxform/tests_v1/test_repeat.py
Outdated
| | calculate | pos1 | | position(..) | | ||
| | begin repeat | rep5 | | | | ||
| | calculate | pos5 | | position(..) | | ||
| | calculate | item5 | | join(' ', instance('item')/root/item)[index = ${pos5} and ${pos1} = 1]/label) | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not related to this PR, but just FYI, this test shows how hard it would be (have been) to implement #525. Since join()
expects a node-set attribute but ${pos5} in this case has to be relative nonetheless since it used as a position/index....
Thanks! |
Hi @MartijnR should I make changes or we just wait for @lognaturel to chime in here? Thanks |
@lognaturel - Will you be able to review this in the next couple days? We are working on a release to fix this and other issues and looking to get a tagged version that we can deploy for testing as soon as possible. |
It looks like the failure is caused by pip version 21.1 (used by the build) Based on pypa/pip#9954 , by using pip version 21.1.1 (released on May 1st, a couple of days after the build happened) the warnings will be silenced. Should we try to trigger new build? (I don't know how to do that yet) |
Codecov Report
@@ Coverage Diff @@
## master #536 +/- ##
==========================================
+ Coverage 83.98% 84.00% +0.01%
==========================================
Files 25 25
Lines 3728 3732 +4
Branches 871 872 +1
==========================================
+ Hits 3131 3135 +4
Misses 452 452
Partials 145 145
Continue to review full report at Codecov.
|
As far as I know, only @ukanga has access to the Appveyor account. When I need to re-run, I force push a change to the latest commit message. I did this here and did not change the contents of the commit. What I'm understanding here is that #524 introduced the regular expression @pbowen-oc's example from the issue is particular because it has multiple predicates. I think that's important to introduce some testing around. I would have been tempted to identify the end of an expression we care about by starting with What this PR does is remove any attempt to identify the end of an We don't have to do anything about this now, but I wanted to come back to something from the initial issue that I think we didn't get quite right. At #490 (comment), @MartijnR, you said we should only be using |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Get @MartijnR's evaluation of the extra
current()
prefixes now generated - Add tests for XPath path expressions with multiple predicates
- Add test for other
${}
expressions afterinstance()
that get acurrent()
prefix with an explanation for why that's happening.
Hmm. Now that I think about it with a clear head, wouldn't a regex that captures all strings in between @pbowen-oc @gushil I think this PR certainly makes a valuable improvement. If you can do the two second bullets I mentioned, I could merge and do a release. Then once we get an opportunity to hear from @MartijnR we can evaluate whether the concept I mentioned above might be promising and help capture more useful cases. |
Thanks, @lognaturel. @gushil is working on adding tests for the cases you referenced |
That sounds great. I agree it's better not to create unnecessary
Hmmm, yes, I have a vague recollection that you mentioned this about my misunderstanding of |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, the new tests really help add confidence!
Am I understanding correctly that this new approach keeps the instance()
check and then adds code to only do the current replacement inside a pair of []
after instance()
? So it doesn't address my parallel repeat case (that's ok) but it does avoid putting too many current()
s. If I understood that correctly, I'm comfortable going with this for now.
I can come up with some twisted cases with nested predicate expressions that might break but I don't think these need to be accounted for.
I believe there's now one extra loop that doesn't ever iterate more than once and I've flagged that below.
pyxform/tests_v1/test_repeat.py
Outdated
| | calculate | pos1 | | position(..) | | ||
| | begin repeat | rep5 | | | | ||
| | calculate | pos5 | | position(..) | | ||
| | calculate | item5 | | (instance('item')/root/item)[index = ${pos5} and ${pos1} = 1]/label | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this use of parentheses valid in XPath? Mostly curious about what prompted this test!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, my bad. That comes from previous (non committed locally created) test. Will be fixed in the next commit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I want to test reference path inside a predicate (bracketed) that includes reference in a repeat and reference outside a repeat. Is it acceptable test? Do you have any other test suggestion to achieve that?
Thanks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The rest of the expression looks fine to me, I was just unclear on the significance of the parens! Agreed having a ref in the repeat and one outside is a good idea. 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@lognaturel - I use patterns like this when counting nodes and then iterating over them in a repeating group.
So starting with something like:
count(instance('item')/root/group/item[name = 'test'])
I'd keep the parentheses the same and add an ordinal predicate for my repeating group position counter:
(instance('item')/root/group/item[name = 'test'])[position() = ${pos}]/value
My best recollection is that this was only needed when the data didn't repeat solely at the item
node itself but rather at nodes further up the hierarchy (like group
in this example).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, the parens do make sense in that case. There's no need for them in (instance('item')/root/item)[index = ${pos5} and ${pos1} = 1]/label
but I guess they're ok around any nodeset expression.
pyxform/survey.py
Outdated
@@ -926,11 +928,20 @@ def _in_secondary_instance_predicate(): | |||
# It is possible to have multiple instance in an expression | |||
instance_match_iter = instance_regex.finditer(matchobj.string) | |||
for instance_match in instance_match_iter: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This no longer makes any difference since the first match will greedily capture the whole rest of the string, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are right. Will be fixed in the next commit.
Will aim to release mid-morning tomorrow (Pacific). |
… if the expression contains whitespace before the reference
Closes #531
Why is this the best possible solution? Were any other approaches considered?
Fixing previous working solution.
What are the regression risks?
None.
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:
tests_v1
nosetests
and verified all tests passblack pyxform
to format code