Skip to content

TST: fine tune per-index cooldown periods - #19886

Merged
neutrinoceros merged 2 commits into
astropy:mainfrom
neutrinoceros:mnt/per-index-cooldowns
Sep 16, 2026
Merged

neutrinoceros merged 2 commits into
astropy:mainfrom
neutrinoceros:mnt/per-index-cooldowns

Conversation

@neutrinoceros

@neutrinoceros neutrinoceros commented Jun 9, 2026 •

Copy link
Copy Markdown
Contributor

Description

Follow up to #19527
Instead of whitelisting certain packages as I initially imagined, move the trust to the sp-python nightlies channel itself.

  • 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.

@neutrinoceros neutrinoceros added this to the v8.1.0 milestone Jun 9, 2026
@github-actions

github-actions Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

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.

@neutrinoceros

Copy link
Copy Markdown
Contributor Author

Ah, this doesn't quite work as I thought. Configuring an index implies it's always included in resolution, which isn't what we want.

@neutrinoceros

Copy link
Copy Markdown
Contributor Author

This is now working as intended, with an extremely minor defect: it h5py's nightlies are currently preferred to stable releases. And that's just because it doesn't use dev version numbers (yet). All other nightly packages behave as you'd expect, so even with indexes permanently configured, we only get nightlies when preleases are enabled.

@neutrinoceros
neutrinoceros force-pushed the mnt/per-index-cooldowns branch from 4dce841 to b67d9f9 Compare June 10, 2026 06:33
@neutrinoceros
neutrinoceros marked this pull request as ready for review June 10, 2026 06:33
@neutrinoceros
neutrinoceros force-pushed the mnt/per-index-cooldowns branch 2 times, most recently from 25e2f6c to 0e0a0a2 Compare June 10, 2026 09:08
@neutrinoceros

Copy link
Copy Markdown
Contributor Author

h5py is now in line with other nightly-publishers, so there really nothing blocking this anymore !

@neutrinoceros
neutrinoceros force-pushed the mnt/per-index-cooldowns branch from 0e0a0a2 to 9226dea Compare July 22, 2026 07:51
@neutrinoceros
neutrinoceros requested a review from pllim July 22, 2026 07:53
Comment thread pyproject.toml
# It is called "unsafe" because it allows dependency confusion-based attacks
# but we trust anaconda.org's nightly channels because they only serve a
# very limited set of packages that can't easily be expanded.
index-strategy = "unsafe-best-match"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I don't understand the full implication of moving this here rather than only for specific tox flags in tox.ini

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The implication is that uv will always match pip's resolution strategy and effectively merge all configured indexes in resolution, regardless if it's used through tox or not, and regardless of the tox environment considered. In practice this only makes a difference where pre-releases are allowed, because no index other than PyPI contains anything else than pre-releases.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Does this answer your questions ?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Mainly I want to know what kind of commands would now trigger this behavior because it is not longer jailed within devdeps directive in tox.ini . I don't use uv. Maybe someone more familiar with this toolset should review and approve. @astrofrog ?

@neutrinoceros neutrinoceros Jul 25, 2026 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Any (non locked) uv based installation would use this, but it won't change anything without pre-releases allowed: this setting only matters when multiple indexes are used in resolution, and we're effectively enabling a single one (PyPI.org) when pre-releases are excluded (default).

@neutrinoceros

Copy link
Copy Markdown
Contributor Author

beyond the cleanup aspect, it would useful for me (and other uv users) to get this in. It makes installing devdeps much easier from calling uv directly (--pre is then sufficient to tap into nightly builds, which is generally what I want)

@neutrinoceros

neutrinoceros commented Aug 3, 2026 •

Copy link
Copy Markdown
Contributor Author

With the release of uv 0.12.0 this also simplifies testing CPython pre-prereleases, because e.g. numpy nightlies will be auto selected when no other binary is available.

@neutrinoceros

Copy link
Copy Markdown
Contributor Author

@astrofrog could we get this in soon ?

@neutrinoceros

Copy link
Copy Markdown
Contributor Author

@Andrej730, as a uv user, can I ask you for a review ?

@Andrej730

Copy link
Copy Markdown
Contributor

No idea how much any of the below is practically possible to be harmful, just tried to think through the edge cases of such change.

Having --pre being useful directly at uv seems convenient indeed, but unfortunately there's no way in uv to cleanly configure it to use some indexes only on --pre. Ideally, uv needs some kind of flag in tool.uv.index to mark index to be considered only during --pre. But in its absence, all indexes will be used always and there are some drawbacks.

As you mentioned, h5py is posting their release wheels to the nightly too (e.g. h5py-3.16.0-cp311-cp311-win_arm64.whl currently available at https://pypi.anaconda.org/scientific-python-nightly-wheels/simple/h5py/ and https://pypi.org/project/h5py/#files), so when I do uv sync currently it picks up https://pypi.org/simple and after this PR it will pick up anaconda.

(you mentioned it as fixed, but apparently it's either regressed and starting posting non-dev builds again or I misunderstood your message)

So there's a bit of risk involved because non-pre users start to depend on how well nightlies are maintained.
It brings us to 2 possible problems:

  • current releases on nightlies shadowing pypi releases - as it is with h5py. In most cases it's probably not a problem - it's likely that releases on nightlies are exact releases from pypi, but there's strictly speaking there's no guarantee. They also can possible sneak into lock files, if they will be ever adapted.

Had an idea that it can be worked around just by adding pypi index to the toml explicitly, that will make it first choice instead of being a default index (which in uv means a fallback) and will guard from duplicated releases from nightlies.

[[tool.uv.index]]
name = "PyPI"
url = "https://pypi.org/simple"
  • second case is if nightly all of a sudden will have h5py-3.17.0 release while it's still not present on the PyPI. Having exclude-newer = "P7D" guarding against the most severe cases when something truly breaking sneaks in, but it may be unexpected in some cases.

One more thing to note that currently it will be checking all packages from nightly indexes. Unsure if some unexpected package might show up, but maybe its worth using explicit = true for those indexes - at least to document what packages are expected to get nightlies if --pre is used.

@neutrinoceros

Copy link
Copy Markdown
Contributor Author

Thanks a bunch !

(you mentioned it as fixed, but apparently it's either regressed and starting posting non-dev builds again or I misunderstood your message)

Thanks for pointing it out. I was assuming the old wheels would be gone by now but they're not. Fortunately I have the key to this index and should be able to delete them manually :)

They also can possibly sneak into lock files

uv.lock is invalidated if one changes the prerelease setting, so I don't think that's correct

Had an idea that it can be worked around just by adding pypi index to the toml explicitly, that will make it first choice instead of being a default index (which in uv means a fallback) and will guard from duplicated releases from nightlies.

Interesting ! is that still true with index-strategy="unsafe-best-match" ?

One more thing to note that currently it will be checking all packages from nightly indexes. Unsure if some unexpected package might show up, but maybe its worth using explicit = true for those indexes - at least to document what packages are expected to get nightlies if --pre is used.

I'll need to look into it !

@neutrinoceros

Copy link
Copy Markdown
Contributor Author

Fortunately I have the key to this index and should be able to delete them manually :)

update: I just did

@neutrinoceros

Copy link
Copy Markdown
Contributor Author

One more thing to note that currently it will be checking all packages from nightly indexes. Unsure if some unexpected package might show up, but maybe its worth using explicit = true for those indexes - at least to document what packages are expected to get nightlies if --pre is used.

If I'm understanding the docs correctly, this would actually completely disable nightly indexes until uv add is used to set [tool.uv.sources], which seems like a step back in terms of practicality: it won't compose nicely with tox or direct uv users. Am I missing something ?

ref: https://docs.astral.sh/uv/concepts/indexes/#pinning-a-package-to-an-index

@Andrej730

Copy link
Copy Markdown
Contributor

They also can possibly sneak into lock files

uv.lock is invalidated if one changes the prerelease setting, so I don't think that's correct

To clarify - I meant e.g. if h5py 3.16 release is present on both PyPI and nightly, then it might get locked using nightly url and then nightly url might become dead and there will be an error during resync.

Had an idea that it can be worked around just by adding pypi index to the toml explicitly,

Interesting ! is that still true with index-strategy="unsafe-best-match" ?

Yeah, can confirm it, I was testing with this PR + explicit PyPI index and it was preferring h5py from PyPI. I believe if the best matching version is present on the multiple indexes, it just picks the first one from the list.

If I'm understanding the docs correctly, this would actually completely disable nightly indexes until uv add is used to set [tool.uv.sources], which seems like a step back in terms of practicality: it won't compose nicely with tox or direct uv users. Am I missing something ?

Ahh, you're right, I thought it's possible to do h5py = { index = ["sp-nightlies", "PyPI" } in tool.uv.sources and then sp-nightlies would only be considered for h5py. But uv only allows h5py = { index = "sp-nightlies" }, locking everyone to nightlies, so explicit = true is not an option.

Fortunately I have the key to this index and should be able to delete them manually :)

update: I just did

A bit harder to reproduce nightly index sneaking in now, haha.

@neutrinoceros

Copy link
Copy Markdown
Contributor Author

To clarify - I meant e.g. if h5py 3.16 release is present on both PyPI and nightly, then it might get locked using nightly url and then nightly url might become dead and there will be an error during resync.

Oh, that's right. Fortunately h5py was the only rogue package in the entire index and the easiest one to fix for me, but I am explicitly assuming that this won't happen again, and if it does... well, lock files are human-readable and I hope we'll be collectively disciplined enough to leverage this feature and not commit such a change.

@neutrinoceros
neutrinoceros force-pushed the mnt/per-index-cooldowns branch from 9226dea to bf53ca0 Compare August 6, 2026 05:42
@pllim

pllim commented Sep 8, 2026

Copy link
Copy Markdown
Member

Since @jdavies-st just stared into this UV rabbit hole elsewhere, I would appreciate extra pair of eyes if he has the time. Thanks, all!

@astrofrog astrofrog left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

A few comments - I can review again shortly once you've had a chance to take a look!

Comment thread pyproject.toml
# exclude packages published less than a week ago (ISO 8601)
exclude-newer = "P7D"
# always allow arbitrarily new versions of astropy-iers-data
exclude-newer-package = { "astropy-iers-data" = false }

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Is exclude-newer-package supported in [[tool.uv.index]]? If not, it should be kept at top/global level?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

technically it's in preview right now. Configuring it is enough to enable the feature, you just get a warning on every install for the time being. I do not anticipate any breaking change when it's stabilized, though for completeness it does mean participating to testing an 'unstable' feature.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I'm now explicitly opting into this preview feature in tool.uv

Comment thread pyproject.toml
name = "pypi"
url = "https://pypi.org/simple"
# exclude packages published less than a week ago (ISO 8601)
exclude-newer = "P7D"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

So to be clear, if there is a package released only say 2 days ago on PyPI, does it get excluded in favor of older packages on the nightly channels?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Also is this going to cause issues for packages which have short RC periods like e.g. sphinx? (as in we might miss an RC phase altogether?)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

So to be clear, if there is a package released only say 2 days ago on PyPI, does it get excluded in favor of older packages on the nightly channels?

if pre-releases are enabled, yes.

Also is this going to cause issues for packages which have short RC periods like e.g. sphinx?

only for packages that have short rcs and nightlies, which as far as I know is an empty set. Even then, we'd get the nightly wheel instead of the rc, which should mean testing closer to the dev branch rather than further away from it

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

But what about packages that don't have any nightlies? Would we ignore any release from the last 7 days?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Ah, for these, yeah, but that's already what happens on main

Comment thread tox.ini

commands =
# docdeps-predeps: Override sphinx max pin in sphinx-design
docdeps-predeps: uv pip install sphinx -U --pre --no-deps

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

So does every -predeps factor now pick up dev wheels too? Is there a difference between -predeps and -devdeps anymore?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

predeps is still special in how it compounds with docdeps, though the remaining difference should tend towards 0 eventually.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Is that desirable though? Predeps allow us to test RCs without necessarily testing more unstable dev versions? (As in it is normal for a dev test to fail sometimes whereas predeps failing indicates a real issue we have to act on)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

IMHO the difference isn't worth it, but we could in principle disable all indexes other than PyPI for predeps

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I personally think that would be preferable otherwise we might as well drop the name predeps?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

dropping predeps is on my radar for a follow up PR, so that's the trajectory I'm setting course for. I think it's fine either way but if we configure it further now then dropping it becomes unachievable so we might as well take a decision now.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Whoa whoa... hold your horses. Dropping predeps was never discussed and I would have never agreed to it. There is a difference between testing combo of RCs and combo of nightly wheels. We didn't do it for fun; it is necessary.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I just pushed an additional commit to resolve this, as well as #19886 (comment)

Comment thread tox.ini

setenv =
predeps: UV_INDEX_STRATEGY = unsafe-best-match # match pip's behavior

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

So does this pick up the setenv from the base job, or no setenv?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

it takes it from the base job

@neutrinoceros

Copy link
Copy Markdown
Contributor Author

rebased, now explicitly opting in the index-exclude-newer preview feature, disabling the warning that normally comes along with it.

@neutrinoceros

Copy link
Copy Markdown
Contributor Author

@astrofrog I think all your requests were addressed. Let me know if there's anything else !

@neutrinoceros
neutrinoceros marked this pull request as draft September 16, 2026 11:44
@neutrinoceros
neutrinoceros marked this pull request as ready for review September 16, 2026 11:48
@neutrinoceros
neutrinoceros force-pushed the mnt/per-index-cooldowns branch from 2a8d83b to 7935c2e Compare September 16, 2026 11:48
@neutrinoceros
neutrinoceros force-pushed the mnt/per-index-cooldowns branch from 7935c2e to 131bc0b Compare September 16, 2026 11:49
# requires-python = ">=3.11"
# dependencies = [
# "uv==0.11.19",
# "uv==0.12.11",

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

forced pushed to include this upgrade, because uv 0.11 didn't support the preview-feature setting at all

@neutrinoceros
neutrinoceros merged commit e588eab into astropy:main Sep 16, 2026
36 of 38 checks passed
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.

TST: UV_INDEX_STRATEGY is set twice for predeps

4 participants