-
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
fix: ensure choices/option parent is set correctly #750
Conversation
ff902d8
to
d433a7b
Compare
Thanks! Can you please check the import order for the linter? |
Sorry but I'm strongly against this change. Many performance and correctness issues have been due to dict-like behaviour in pyxform and this change propagates that assumption, making it more difficult to transition to classes. Unnecessarily performing copies or deepcopies of dicts, either actual dicts (e.g. the Anyway, navigating SurveyElements via parent/child for questions and choices will not be compatible usage soon. I identified this parent reference issue a few weeks ago and it is addressed in #746 (mainly commit 6927767) by using an Itemset class and changing the SurveyElement structures to remove the parent-child relationship for Questions and Choices. In other words, a choice list doesn't really "belong" to a Question in any sense that is meaningful to generating the XForm: a choice belongs to an Itemset and an Itemset belongs to Survey; and one or more Questions can reference each Itemset. In the context of the generated XForm, this corresponds to the change from choices being copied into the question and always being in the External code that wants to use these pyxform internals should reference the choices on the |
@lindsay-stevens Can we then remove the parent reference that currently exists with choices? The reference exists, hence the assumption that it is broken, but if the expected behaviour is that it should not be aware of the parent, then we should make it so. |
d433a7b
to
6c4970b
Compare
@lindsay-stevens Are we not meant to use the I use them so I do not have to reread the XLSForm file, specifically when making minor server-side modifications to the survey, such as setting a version. |
I have opened #751 for this. It makes sense but it's not a simple refactor, and should come after #746 is merged.
No immediate plans to remove, but these serialisation functions seem to be only used in tests, the |
@lindsay-stevens, how do you access the (rectangular) XLSForm formats? Assuming you have an Excel file representing the XLSForm, you plan not to reread it once you process it but would want to persist a representation of it and make some modifications. I mainly use pyxform as a library, and such representation is quite helpful to the functionality we have built using this library. Losing such changes will result in a need for a tremendous rewrite of an 11-year-old codebase. |
By rectangular XLSForm formats I'm referring to XLSX, XLS, CSV, and MD. Is this input data not retained by your app? Why cannot the modifications be done in-memory on the I don't know about your use case but I hope you can appreciate that it will be nearly impossible to non-disruptively maintain pyxform against unknown requirements placed on its internal data structures and behaviour. I think the solution will involve discussion about what exactly your app is doing, what it's needs and assumptions are, and how that might fit into an explicitly supported use case for pyxform. In the meantime |
The output of Similar changes might be done when changing or adding an public key to make the survey use encryption. |
My apologies, I took a quick look at this and didn't think through the implications and the broader work in progress! As far as I can tell, there was never an effort to document or clarify what should be intended as a stable interface to pyxform beyond the XML output for clients. As @lindsay-stevens describes, that has lead to different systems making different assumptions around what should be considered public vs private. As we work to improve performance and make some aspects of the system easier to evolve, we're bound to break some integrators, and we're trying to signal that with major release bumps and discussion in PRs as they come in. Please join those conversations! @ukanga did you close this because you've found a satisfactory solution for now? Given that you are updating specific, well-known fields, maybe you don't need pyxform to make those changes? Or maybe a public interface specifically to make those changes could be provided? I'm not seeing the connection between choices and the needs you've mentioned, though! |
@lognaturel I found a different way to handle it, I think. I am still identifying and fixing tests on onadata to accommodate the changes introduced with release https://github.com/XLSForm/pyxform/releases/tag/v3.0.0. This has been manageable and was almost done. However, with the proposed changes on #746, I don't think we can use pyxform as a library the way we have been using it. I hope there is a way to persist the new structure other than the XML and the source XLSForm file since reprocessing those is overkill for our use case. For now, I will pin us to https://github.com/XLSForm/pyxform/releases/tag/v3.0.0 + 6524d17 which is not as chaotic for us for the time being. We will wait and see what Do consider the intermediate structure pyxform has as a useful part of the library, not just the final XForm XML. |
Thanks, that's great to hear! Do keep us posted on any other issues you may run into.
Should some of those tests be in pyxform instead? A big challenge we have in trying to improve
That sounds great. @lindsay-stevens are syncing up shortly and will discuss how to help accommodate your usage. Do you actually use OMK still? My understanding was that the app had been long deprecated and that |
It's okay to remove OMK. I am not aware of any current usage. However, we do have plenty of data collected with OSM. None of it is active anymore, but I may need to check. There are no reservations about removing the functionality; the use case evolved, and the |
Closes #749
Why is this the best possible solution? Were any other approaches considered?
Restores the previous behaviour where traversing choices always point to the parent they are assigned to.
The deep copy is at the last possible place when the choices are assigned to a question before the parent is set.
What are the regression risks?
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
python -m unittest
and verified all tests passruff format pyxform tests
andruff check pyxform tests
to lint code