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.
|
Factor the message building of the ``@deprecated`` decorator into a public ``deprecation_msg`` function, so that the identical message can be produced without the decorator, e.g. ``warnings.deprecated(deprecation_msg(...))``. A custom ``message`` is now validated. An unsupported format specifier previously failed with a bare ``KeyError`` from ``str.format``, and an ``alternative`` that the message never interpolates was silently dropped; both now raise a ``ValueError`` naming the supported specifiers. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: nstarman <nstarman@users.noreply.github.com>
…ated`` Factor the docstring handling out of ``@deprecated`` into a public ``deprecate_doc`` decorator, which takes the deprecation message from the object's ``__deprecated__`` attribute. It can therefore document objects deprecated by ``warnings.deprecated``, which sets that attribute but leaves the docstring alone. ``warnings.deprecated`` is typed as taking a ``LiteralString``, so overload ``deprecation_msg`` to return one when every argument is a literal, while the runtime ``str`` that ``@deprecated`` itself passes still gives a ``str``. Also annotate the return type of ``deprecated`` itself. It was ``Callable``, which erased the signature of whatever it decorated; it now returns ``Callable[[T], T]``, or the deprecated function for the call that passes one as ``message``. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
``warnings.deprecated`` is only available from Python 3.13 onwards, so ``typing_extensions`` is needed to provide it on 3.12. It is also a build requirement because ``setup.py`` imports ``astropy.units`` in the isolated build environment to generate the unit type stubs, the same reason ``pyerfa`` is listed there. Key ``min_versions`` in the docs configuration by canonical name, so the lookup does not depend on whether the requirement is recorded with a hyphen or an underscore. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: nstarman <nstarman@users.noreply.github.com>
Move every ``@deprecated`` use in ``astropy.cosmology`` onto ``warnings.deprecated`` (PEP 702), combining ``deprecation_msg`` for the message and ``deprecate_doc`` for the ``.. deprecated::`` directive. Type checkers report uses of an object deprecated this way, which astropy's own decorator cannot express. The messages and warning categories are unchanged: each site passes the ``obj_type`` that the decorator used to infer, and the category it used to issue. In ``representation/base.py`` the ``classmethod`` had to become the outer decorator, since the standard library decorator rejects a classmethod object. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: nstarman <nstarman@users.noreply.github.com>
5ee28a1 to
f660e04
Compare
deprecated
deprecateddeprecated
|
| message="Use ``angular_diameter_distance(z1, z2)`` instead.", | ||
| obj_type="function", | ||
| ), | ||
| category=AstropyDeprecationWarning, |
There was a problem hiding this comment.
As an API change I'm happy to drop this argument. I don't think any users are filtering for only Astropy deprecations.
There was a problem hiding this comment.
hard to tell. In any case this should be done piecemeal, so this part would go to another PR
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
| for line in metadata.requires("astropy"): | ||
| req = Requirement(line.split(";")[0]) | ||
| min_versions[req.name.lower()] = str(req.specifier) | ||
| min_versions[canonicalize_name(req.name)] = str(req.specifier) |
There was a problem hiding this comment.
typing extensions was complaining.
There was a problem hiding this comment.
You mean a type checker ?
There was a problem hiding this comment.
Sorry. I meant it was complaining about typing_extensions.
There was a problem hiding this comment.
I don't think this is a one-to-one replacement. https://packaging.pypa.io/en/stable/utils.html#packaging.utils.canonicalize_name does more than just lowercase.
There was a problem hiding this comment.
is it typing-extensions or typing_extensions, only the canonicalized may know.
There was a problem hiding this comment.
This discussion triggered my motivation to learn more about packaging APIs, here's the result: #20414
There was a problem hiding this comment.
Great. We can wait on that PR to merge before rebasing and simplifying this one.
| specifier, or passing ``alternative`` without referencing ``{alternative}`` in | ||
| the message (which silently dropped it), raises a ``ValueError``. | ||
|
|
||
| Added ``astropy.utils.decorators.deprecate_doc``, a decorator that prepends a |
There was a problem hiding this comment.
This one is confusing. Is it useful beyond internal usage during transitional period? Should this be private?
There was a problem hiding this comment.
agreed. Any new API needed for this PR should be private. We can always consider promoting them later if anyone downstream actually needs them.
There was a problem hiding this comment.
Sure. But private in which way: not listed in "all" or underscore-prefixed?
There was a problem hiding this comment.
We don't often import underscore-prefixed functions across modules.
There was a problem hiding this comment.
But private in which way
That is for your APE to figure out. 😅 As far as I am concern, private in a way we can use internally and then remove without deprecation. 😸
There was a problem hiding this comment.
Lol. The problem is my APE did figure it out. Folks just didn't like the implied consequences. There is no good way for me to write this as reasonable private functions at this moment. Underscore-prefixes aren't imported across modules in Astropy and just removing it from __all__ will not dissuade people from using it on discovery, leading to deprecations-before-removal.
I'm fine doing either way since both are broken.
(I challenge anyone to find unclear public vs private API in https://github.com/GalacticDynamics/unxt or https://github.com/GalacticDynamics/coordinax/)
IMO since I think this will probably end up being public, making it look-public-but-it's-actually-not-in-__all__ is probably the better choice.
|
At a glance, the diff isn't too shocking. I can do a more careful review once current concerns are addressed and CI is green. Thanks! |
Trying an alternative starting point to #15307
Things I found:
deprecation_msgneeds the function name, which is a little inconvenient.astropy.utils.deprecateddoes docstring manipulation, so I needed to add another decorator that handles that.astropy.utils.deprecated:(AI Disclosure
Claude Code to help with the refactors, and then to clean up my 20+ commit history into something reasonable.
And to write the docstrings / changelog.
Merge method