Repository navigation
VO table no longer access char field as bytes - #9505
Conversation
| def _binparse_var(self, read): | ||
| length = self._parse_length(read) | ||
| return read(length), False | ||
| return read(length).decode('ascii'), False |
There was a problem hiding this comment.
Note: This no longer choose between 'ascii' and 'utf-8' based on 'verify' setting. This one is stricter, but I suspect it wouldn't be hard to add it back in, though the VO table standard did say char is ASCII. 🤷♀
There was a problem hiding this comment.
With the updated commit, I changed this behavior to allow non-ASCII characters for FIELDs with datatype="char" in TABLEDATA serializations, but with a new warning message. Whether all ASCII or not, values for those FIELDs are stored in the astropy Table as strings.
There was a problem hiding this comment.
It seems to me that @pllim's comment is still valid; but I'm not familiar with this code so maybe I'm misreading it. As in, putting utf-8 text in a char field and setting 'verify' to 'ignore' seems to raise an exception, but I've not actually tried this. I'm in favor of allowing utf-8, even if it is not in the official standard.
Edit to clarify: I meant trying to read non-utf-8 char fields, not writing them.
There was a problem hiding this comment.
Hi @hugobuddel . Thanks for the taking a look at this.
The context here a is a little misleading. You are correct that in the _binparse_var() method shown above, non-ASCII characters will cause an exception. This occurs for the BINARY and BINARY2 serializations when any of the byte values are outside the range 0-127. I think that behavior is probably OK since values outside that range may just as likely represent corrupt binary data as opposed to deliberate characters in the extended ASCII range (128-255), but I could go either way. I should (and will) at least add a test case to demonstrate that as the expected behavior.
My comment above though was referring to the parse() method that is just above _binparse_var(). parse() handles the TABLEDATA serialization (in which non-ASCII unicode might most easily sneak in). In that case a try clause catches the decode exception and calls vo_warn() with a new warning message. vo_warn() looks at the verify value to decide whether to show the message.
There was a problem hiding this comment.
Thanks for the clarification @tomdonaldson . Adding tests would indeed help, because that's where I looked to see whether my interpretation of the code was correct, but it is clear now.
I'm personally not using the BINARY/BINARY2 serializations (only FITS or TABLEDATA), so I'll let others decide. (At least, I'm not writing them; no idea whether I read them from other sources.)
ea80ae9 to
1023d73
Compare
|
This PR has been updated to ensure that it handles both fixed-length and variable length strings. The upshot is that for That behavior was already the case for For
For
For all serializations, the astropy Table column |
|
Without having looked at the patch as such – someone will have to poke me again for that –, I heartily support the intent of the PR. VOTable char[] most definitely is supposed to be an ASCII string (as opposed to unsignedByte), and so it shouldn't have been turned into bytes in the first place. I kind-of also support interpreting content as utf-8; I've spoken for this ages ago (http://mail.ivoa.net/pipermail/apps/2014-October/001010.html is a thread from 2014), and if astropy establishes a quasi-standard here, that may actually push this along. It should be made clear somewhere that it's possible that behaviour with non-ASCII in char is actually undefined by the IVOA. Of course, this will break some code that did something with strings from VOTable. But bytes coming out of VOTable are so painful that to me that seems worth it. Hence: informally, +1. |
pllim
left a comment
There was a problem hiding this comment.
At this point, the changes are beyond my field of expertise, so I heavily rely on @tomdonaldson and those whose work rely on VOTable. Nonetheless, I left some general comments. Thank you very much for taking this over, Tom D!
| dtypes = [ | ||
| (('string test', 'string_test'), '|O8'), | ||
| (('fixed string test', 'string_test_2'), '|S10'), | ||
| (('fixed string test', 'string_test_2'), '<U10'), |
There was a problem hiding this comment.
Is this type change in the expected results still abide by the VOTable standards? (Asking as a person unfamiliar with those standards. 😬 )
|
Reading the ascii datatype as unicode char is fine, as long there is a warning emitted. This is necessary for writing a service compliance checker with astropy/pyvo (This idea came up somewhere). I'm missing a |
a3dec06 to
3c0e83f
Compare
|
@tomdonaldson , do you think this is ready for another round of review, or are you still waiting to add more code or hear back from VO stakeholders? |
9c83886 to
b2ce7ef
Compare
@funbaker Thanks for noticing that! I've added code to the Char converter that warns if the value contains non-ASCII characters, and added corresponding test cases. Perhaps that check can be a little cleaner with isascii() once we require Python 3.7+. @pllim With this last commit, this is ready for another round of review. Perhaps @funbaker and/or @hugobuddel could also have another look? It would be great to get this in for the upcoming 4.0.1 release. To summarize, I believe we've changed the behavior to parse all |
Note to self: Open a follow-up issue for this after this PR is merged. |
pllim
left a comment
There was a problem hiding this comment.
Just some minor comments. Thank you, all!
p.s. I am still technically the owner of this PR so I cannot approve this. But that also means you can, @tomdonaldson ! 😉
Co-Authored-By: P. L. Lim <[email protected]>
Co-Authored-By: P. L. Lim <[email protected]>
Co-Authored-By: P. L. Lim <[email protected]>
Co-Authored-By: P. L. Lim <[email protected]>
tomdonaldson
left a comment
There was a problem hiding this comment.
After a couple iterations of review on the intent and logic, and detailed code reviews by the maintainers, I think this is ready to be merged. Thanks to all contributors on this!
|
Now I gotta clean up |
VO table no longer access char field as bytes
|
@bsipocz and @tomdonaldson , as discussed on Slack, since this change is causing some downstream breakage (e.g., |
Description
This pull request is to address the issue of VO table parsing
charfield as bytes unnecessarily.This does change a subtle behavior, so it should only go into a major release. I suspect it would affect packages downstream, e.g.,
astroquery.vo_conesearchor whoever is parsing VO table usingTable.read()and then decoding bytes to UTF-8 themselves.So, the gist is that VO table parser was relying on bytes vs str to differentiate between
charandunicodeCharfields. A quick glance at VO table standards did not seem to indicate that this is a rule from the standards. Since I can't ask Mike D anymore, I am wildly guessing that the behavior was something that was just convenient to do at the time in Python 2 but turned into a nuisance in Python 3.Note to reviewers: Those who are familiar with the VO standards and use VO table a lot should really look at this carefully and think about the implications of merging this.
TODO:
Fixes #8716
Supersedes #8745