Repository navigation
Handle chararray deprecation - #19267
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.
|
| with warnings.catch_warnings(): | ||
| warnings.filterwarnings("ignore", category=DeprecationWarning) |
There was a problem hiding this comment.
I think this is okay but it does require #19233
There was a problem hiding this comment.
Oh, sorry, I didn't see this before I commented below.
mhvk
left a comment
There was a problem hiding this comment.
I think this works well for 8.0, nice solution for now! Only one suggestion for a simplification.
For 7.2., this cannot work since np.strings is not available for numpy < 2.0, but I think for that we can just filter out the deprecation warning; np.char will surely continue to exist until Fall '26.
| return super().__getattribute__(name) | ||
|
|
||
|
|
||
| def get_chararray(obj, itemsize=None, copy=True, unicode=None, order=None): |
There was a problem hiding this comment.
I'd tend to just import from np.char import array as get_chararray inside a warnings filter above.
There was a problem hiding this comment.
+1
Both approach seem fine to me, but I'd rather we avoid mixing them.
There was a problem hiding this comment.
@mhvk - do you mean to use that for a simplified version in 7.2.x ? (which seems reasonable to me but will be in a follow up PR).
There was a problem hiding this comment.
I realize now that what I wrote was confusing, since of course the numpy version of get_chararray returns the numpy chararray rather than our new one that shows deprecation warnings. In that sense, my comment is moot. But, arguably still a bit cleaner -- since we are deprecating -- might be to use np.char.array and then just view the result as our class. Since I wasn't absolutely sure this would not give warnings, I just tried, and it seemed to work -- I submitted it as a PR to your branch (see saimn#10).
Note that I also went ahead there and moved the deprecated_attributes inside the class; I think that is a bit cleaner (but it is a separate commit, so if you don't like it, just omit it).
|
Probably need a change log under "api", which I don't see yet. For v7.2.x, is max pinning numpy an option? |
It's never ideal, but as far as I can tell it's our only option left |
|
I think your pin of numpy < 2.7 for 7.2 (combined with ignoring the deprecation warnings in tests) is still very liberal, so very unlikely anyone will have a problem other than possibly seeing those numpy deprecation warnings. |
Sorry I'm a bit lost in versions: we are releasing 8.0 this spring so the next major release (9.0) will not be before spring 2027. Since the deprecation is not yet released in Numpy's side, it seems we can wait 9.0 next year to actually remove chararray from astropy, which leaves enough deprecation time ? If this is OK then the deprecation can be added to 8.0, no need to backport to 7.2 ? |
|
Agreed. We dont need to backport this deprecation. |
|
|
||
| if strip_spaces and coltype is np.bytes_: | ||
| arr = arr.rstrip() | ||
| arr = np.strings.rstrip(arr) |
There was a problem hiding this comment.
One additional comment here: if in the future rstrip is applied on the io.fits ndarray column it means that trailing spaces will always be stripped for Table. So strip_spaces will become useless and default behavior will change. But I'm not sure if there a good way to warn people about this upcoming change without adding a noisy and annoying warning...
There was a problem hiding this comment.
what do you mean "noisy" ? Deprecation warnings are still only visible to direct callers and warnings in general only show up once per session by default.
There was a problem hiding this comment.
The warning would need to be emitted by default (since strip_spaces is False by default) and only way to remove it would be to set strip_spaces=True (option that would disappear in the next major version).
There was a problem hiding this comment.
I don't think I understand your initial comment in this thread actually, let's get back to it;
if in the future rstrip is applied on the io.fits ndarray column
why would this happen ? do you expect it to be outside our control ?
There was a problem hiding this comment.
Currently (and on the contrary to io.fits which relies on chararray to do so), Table.read does not strip trailing spaces by default and strip_spaces was added no long ago to offer this option. If in the future rstrip is enforced in io.fits (calling it explicitly instead of relying on chararray) then this would propagate to Table.read and the default behavior would change.
My point above is I don't think there is a good way to warn about this upcoming change. I think it's fine for a major release, but I'm mentioning it because this will likely break some code in the wild (e.g. people using t[t['somecol'] == 'SOMEKEY '] to select some rows).
There was a problem hiding this comment.
I see. If I got this right, there is actually a way to follow a proper deprecation cycle here, and preserve strict backward compatibility for those who want it.
from typing import Literal
UNSET = object()
def foo(*, strip_spaces: bool | Literal[UNSET] = UNSET) -> None:
if strip_spaces is UNSET:
warn(
"default is currently False but will change to True in a future version, "
"pass the argument explicitly to silence this warning.",
AstropyDeprecationWarning,
stacklevel=2,
)
strip_spaces = False
...(note that we could use None as a sentinel value but I don't like it because it behaves too much like False where a bool is expected)
This of course assumes that we could maintain the current default behavior (strip_spaces=False) as an opt-in. Is this possible ?
There was a problem hiding this comment.
The problem is that this is pretty noisy. Though I guess one could at least only warn if the stripping actually has an effect.
There was a problem hiding this comment.
We could use a different default value indeed, this would force people to adapt their code and use strip_spaces=True, but then this option would disappear in the next major release (and probably remain forever in people's code)...
Maintaining the strip_spaces=False option would be difficult since the stripping would be done pretty deep in io.fits. Stripping trailing spaces should be the default and only behavior, it was not done in Table.read for historical reason but at some point this change need to happen and dropping chararray is the good occasion to do it. The question is whether we want to be noisy about it or just make the change at some point with the risk of breaking some code. Anyways people that rely on the old behavior (e.g. t[t['somecol'] == 'SOMEKEY ']) will need to change their code, and there is no way to know who relies on this. We can detect if some spaces are stripped but that does not mean that people's code rely on it.
There was a problem hiding this comment.
ok if we cannot maintain strict backwards compat then I agree my proposal shouldn't be implemented and there is probably no way to warn users ahead of time programmatically. I think the best thing we could do at this time is go with your approach on main and actively seek for feedback in downstream projects (we probably should do the probing ourselves where we already know astropy.io.fits is heavily used).
neutrinoceros
left a comment
There was a problem hiding this comment.
I'm now on board with the current approach. I say let's bite the bullet as soon as possible and see what breaks, since we have no other option.
|
I believe the only thread left hanging is at #19267 (comment) so let me remind @mhvk about it :) |
mhvk
left a comment
There was a problem hiding this comment.
Thanks @neutrinoceros for the ping. I think in principle this is fine as is, but think we can simplify the numpycompat code; see in-line comment.
| return super().__getattribute__(name) | ||
|
|
||
|
|
||
| def get_chararray(obj, itemsize=None, copy=True, unicode=None, order=None): |
There was a problem hiding this comment.
I realize now that what I wrote was confusing, since of course the numpy version of get_chararray returns the numpy chararray rather than our new one that shows deprecation warnings. In that sense, my comment is moot. But, arguably still a bit cleaner -- since we are deprecating -- might be to use np.char.array and then just view the result as our class. Since I wasn't absolutely sure this would not give warnings, I just tried, and it seemed to work -- I submitted it as a PR to your branch (see saimn#10).
Note that I also went ahead there and moved the deprecated_attributes inside the class; I think that is a bit cleaner (but it is a separate commit, so if you don't like it, just omit it).
|
p.s. Arguably, in |
MAINT: avoid copy of function; simple docstrings, cleanup
That was causing a |
72eab86 to
c889574
Compare
mhvk
left a comment
There was a problem hiding this comment.
Oops, sorry for having done incomplete testing, I should have caught that. Anyway, am happy with this now!
|
Yay, green CI! Two small nitpicks; I will let you decide if you want to incorporate the suggestions. Some follow-up questions/comments:
Thanks, all! p.s. Posted an update to https://groups.google.com/g/astropy-dev/c/9u0qVkhAq9Q/m/G8y7_nJVBwAJ |
Co-authored-by: P. L. Lim <[email protected]>
Yes, will do that once the PR is merged.
Yes.
The plan is to remove the compatibility code and use of chararray for v9.0 (don't think we can wait longer since at some point Numpy will remove charray). I already have a branch. |
This comment was marked as resolved.
This comment was marked as resolved.
|
I opened follow-up issue for eventual removal at: I also kicked off a nightly wheel run with this patch: Thanks, all! |
PR: astropy#19267 Issue: astropy#3862 Base commit: e1bf9db Changed lines: 107
Possible fix for #19216
Also fix #3862
np.char.arraysince we no more use it)Description
This pull request is to address ...
Fixes #