Repository navigation
Try to improve version checks in VOTable - #18366
Conversation
|
Thank you for your contribution to Astropy! 🌌 This checklist is meant to remind the package maintainers who will review this pull request of some common things to look for.
|
8dafbcd to
236f9ff
Compare
| parameter unchanged. | ||
| """ | ||
| if config is None: | ||
| if hasattr(votable, "_get_version_checks"): |
There was a problem hiding this comment.
Now that I've made it so that VOTableFile always has the version checks set for it, it's probably better to make this line instead be:
| if hasattr(votable, "_get_version_checks"): | |
| if hasattr(votable, "config"): |
and then copy the entire config over.
There was a problem hiding this comment.
That's a good point. I don't have a strong preference, though limiting the scope to the version configs makes it a little more explicit why this is being done and is closest to what was being done before with Field. Copying the whole config could bring in config items from the votable, which is probably not harmful and might even be good in most cases, but it does go beyond what is explicitly needed for this fix.
It's messy that version concerns aren't better encapsulated (away from configs). Without bigger refactoring, it will be hard to make configs really safe during programmatic construction of a votable, i.e., that they meet all the same implicit assumptions as when they are created during parsing. The API allows passing anything in for config in each element constructor.
There was a problem hiding this comment.
Ok. I'll leave it with the explicit _get_version_checks call, although I will add "version" field into the dict so that all the version information is present.
|
It occurred to me that it would be much easier if
Since then when constructing a VOTable programmatically (and not from parsing an XML file) you can reliably pass in |
6c54d56 to
bec861c
Compare
| if element is before: | ||
| if getattr(element, attr, None) == ref: | ||
| vo_raise( | ||
| KeyError, |
There was a problem hiding this comment.
How did this ordering error not trigger in CI for the past 14 years? 😱
There was a problem hiding this comment.
My working theory is that the code has always raised (since the code assumes an exception class but falls over when it's given a string) but nothing in CI was in fact checking the actual exception class.
|
Need change log. Thanks! |
|
Will add a changelog once I get some feedback that I'm on the right track. |
tomdonaldson
left a comment
There was a problem hiding this comment.
Thanks for tackling this @timj. I think this is a very reasonable approach to addressing the missing config values. I appreciate the nice new test and the code cleanup changes you made along the way.
It looks like there are a couple minor CI items (a ruff complaint and needing a changelog over in docs/changes/io.votable). I'll be happy to approve when that's in place. Let us know if we can help with those items.
| parameter unchanged. | ||
| """ | ||
| if config is None: | ||
| if hasattr(votable, "_get_version_checks"): |
There was a problem hiding this comment.
That's a good point. I don't have a strong preference, though limiting the scope to the version configs makes it a little more explicit why this is being done and is closest to what was being done before with Field. Copying the whole config could bring in config items from the votable, which is probably not harmful and might even be good in most cases, but it does go beyond what is explicitly needed for this fix.
It's messy that version concerns aren't better encapsulated (away from configs). Without bigger refactoring, it will be hard to make configs really safe during programmatic construction of a votable, i.e., that they meet all the same implicit assumptions as when they are created during parsing. The API allows passing anything in for config in each element constructor.
This lets the version checks succeed.
It needs an exception class.
Cannot use the version setter because we allow v1.0 files to be read from XML even though we don't allow someone to create one with the APIs directly.
d7de74c to
f7bf1ed
Compare
This ensures that error messages can report the actual version without having to work it out from the or_later values.
|
@tomdonaldson looks like all checks pass now. |
|
@tomdonaldson whilst I was testing my upstream code, I noticed that Astropy VOTable output fails validation, at least for v1.5. Because the element_sets = [
self.coordinate_systems,
self.time_systems,
self.params,
self.infos,
self.links,
]but the schema requires that INFO comes before COOSYS. This causes Trivial fix if you want me to add it on this ticket. |
|
Looking at the history I think Astropy VOTables with COOSYS and INFO in the RESOURCE block have been failing validation since the beginning of time (I tracked the problem back to at least 2011). |
|
Since it was a one line fix I fixed it here. |
|
Clearly some tests hardwire the wrong order... [fixed] |
Without this change the COOSYS was coming before INFO and this
was failing linting because the schema requires INFO to come
first.
ERROR (l.8, c.59): cvc-complex-type.2.4.a: Invalid content was found starting with element '{"http://www.ivoa.net/xml/VOTable/v1.3":INFO}'.
One of '{"http://www.ivoa.net/xml/VOTable/v1.3":COOSYS,
"http://www.ivoa.net/xml/VOTable/v1.3":TIMESYS,
"http://www.ivoa.net/xml/VOTable/v1.3":GROUP,
"http://www.ivoa.net/xml/VOTable/v1.3":PARAM,
"http://www.ivoa.net/xml/VOTable/v1.3":LINK,
"http://www.ivoa.net/xml/VOTable/v1.3":TABLE,
"http://www.ivoa.net/xml/VOTable/v1.3":RESOURCE,
WC[##other:"http://www.ivoa.net/xml/VOTable/v1.3"]}' is expected.
ca8ae4d to
ede16c4
Compare
tomdonaldson
left a comment
There was a problem hiding this comment.
@timj Nice catch and thanks for the fix. I'm glad you've been pushing on the votable creation and writing aspects of this module, and that (at least so far) the issues have been manageable. Clearly those use cases could use a lot more test coverage.
The INFO elements have been a subject of some confusion for a while. It's always been weird that they have been allowed both at the beginning and end of VOTABLE and RESOURCE, but that in VOTABLE the order of the first one didn't matter. Another area of confusion was that up through v1.3, the usually helpful figures summarizing the elements got the ordering requirement wrong in RESOURCE (subsequently fixed in v1.4).
This all looks good now.
Description
This pull request is to address some issues I encountered creating a VOTable programmatically.
It doesn't solve all the problems in that I'm still not clear how I'm supposed to instantiate a
TimeSysobject since it's not clear how I am supposed to be able to get the version compatibility config from a VOTableFile, but it does at least solve part of the problem by allowing TableElement to know its own version from the associated VOTableFile.Fixes #18356