Skip to content
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

Make several argument defaults immutable (and annotate them) #17496

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

eerovaher
Copy link
Member

Description

The first commit adds annotations to a few functions in units, all of which have a parameter with the type Collection[UnitBase]1. In several functions with such a parameter its default value is an empty set or an empty list, both of which are mutable. In Python it is possible to permanently modify mutable function parameter defaults, which can cause bugs (see also Ruff rule B006 (mutable-argument-default)). It is better to use an immutable default such as an empty tuple because then it is obvious just from reading the function signature that calling the function does not modify the default argument.

Usually I prefer to avoid changing code in type annotation pull requests, but in this case the annotations make it obvious that the sets and lists can be replaced with tuples without changing code behavior, so adding the annotations and changing the code are conceptually related.

  • By checking this box, the PR author has requested that maintainers do NOT use the "Squash and Merge" button. Maintainers should respect this when possible; however, the final decision is at the discretion of the maintainer that merges the PR.

Footnotes

  1. I find it somewhat difficult to understand why the type is Collection[UnitBase] instead of Collection[NamedUnit], but there is a test that asserts that NamedUnit is too restrictive: https://github.com/astropy/astropy/blob/24d3dd96015839ecf87899b02d403a9002bd3ef6/astropy/units/tests/test_units.py#L749-L755

Mutable function argument defaults can be modified persistently (see
Ruff rule B006). In several functions mutable default empty sets or
lists can easily be replaced with immutable empty tuples, which makes it
obvious that these defaults are not modified.
@eerovaher eerovaher added this to the v7.1.0 milestone Dec 3, 2024
Copy link
Contributor

github-actions bot commented Dec 3, 2024

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.

  • Do the proposed changes actually accomplish desired goals?
  • Do the proposed changes follow the Astropy coding guidelines?
  • Are tests added/updated as required? If so, do they follow the Astropy testing guidelines?
  • Are docs added/updated as required? If so, do they follow the Astropy documentation guidelines?
  • Is rebase and/or squash necessary? If so, please provide the author with appropriate instructions. Also see instructions for rebase and squash.
  • Did the CI pass? If no, are the failures related? If you need to run daily and weekly cron jobs as part of the PR, please apply the "Extra CI" label. Codestyle issues can be fixed by the bot.
  • Is a change log needed? If yes, did the change log check pass? If no, add the "no-changelog-entry-needed" label. If this is a manual backport, use the "skip-changelog-checks" label unless special changelog handling is necessary.
  • Is this a big PR that makes a "What's new?" entry worthwhile and if so, is (1) a "what's new" entry included in this PR and (2) the "whatsnew-needed" label applied?
  • At the time of adding the milestone, if the milestone set requires a backport to release branch(es), apply the appropriate "backport-X.Y.x" label(s) before merge.

Copy link
Contributor

@mhvk mhvk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good to me, with one request for adding a comment (for non-typing gurus like me), and a suggestion for a tightening.

Probably best for @nstarman to have the final say.

@@ -2262,13 +2262,34 @@ class CompositeUnit(UnitBase):

_decomposed_cache: CompositeUnit | None = None

@overload
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe add a comment along the lines of

# The typing overloads here refect that with `_error_check=False`,
# we can count on the scale and power being sanitized already.

astropy/units/core.py Show resolved Hide resolved
@mhvk
Copy link
Contributor

mhvk commented Dec 3, 2024

p.s. Just to be clear, I'm fine with the change to empty tuples; it works fine here.

Copy link
Member

@nstarman nstarman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree about adding the comment. Otherwise LGTM! Nice to get rid of some mutable defaults.
I remember looking at the full set of B006 violations in astropy — it's VERY large.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants