Repository navigation
fix: declare the three dependencies the code imports, and drop the async_generator shim - #16
Merged
Merged
Conversation
…ync_generator shim
This package installs and then cannot be imported:
>>> import libcloudspawner.spawner
ModuleNotFoundError: No module named 'async_generator'
and once that is dealt with, again:
ModuleNotFoundError: No module named 'requests'
Comparing every third-party import in the package against pyproject.toml:
imported : jinja2, jupyterhub, libcloud, requests, tornado, traitlets
declared : jinja2, jupyterhub, apache-libcloud
missing : requests, tornado, traitlets
tornado and traitlets happen to be installed today because jupyterhub pulls
them in, so the break only shows for requests -- but the code imports all three
directly, and a transitive that a dependency later drops is a break waiting for
someone else's release. All three are declared now.
async_generator is handled differently, by deletion rather than declaration.
It is a compatibility shim for Python 3.5, and this project requires >=3.7,
where `async def` + `yield` is the language. So:
@async_generator
async def progress(self):
while True:
await yield_(self.nodemanager.spawner_state_event)
becomes a plain async generator with `yield`. Declaring a shim as a dependency
to keep a 2019 workaround alive would have been the wrong repair.
Also adds the first CI lane this repository has ever had. The only workflow
here was python-publish.yml, which releases and does not run on a pull request,
so nothing checked the four dependency pull requests open against this
repository -- and none of them could have caught the missing imports either.
There are no tests in the tree, so the lane does not pretend to run any. It
proves installation, import, packaging, and one behaviour: that
LibcloudSpawner.progress is a real async generator, which is the contract
JupyterHub calls it under. That last one is a behaviour check rather than a
grep because replacing the decorated coroutine with a plain `async def` that
never yields would still import cleanly while silently no longer being a
generator.
Verified in a FRESH virtualenv, outside the source tree: pip install -e .,
import, the async-generator assertion, and python -m build all pass on
Python 3.14. actionlint clean.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This package installs and then cannot be imported.
and once that is dealt with, again:
ModuleNotFoundError: No module named 'requests'.Comparing every third-party import in the package against
pyproject.toml:jinja2,jupyterhub,libcloud,requests,tornado,traitletsjinja2,jupyterhub,apache-libcloudrequests,tornado,traitletstornadoandtraitletshappen to be installed today becausejupyterhubpulls them in, so onlyrequestsbreaks visibly — but the code imports all three directly, and a transitive that a dependency later drops is a break waiting for someone else's release.async_generatoris deleted rather than declared. It is a compatibility shim for Python 3.5; this project requires ≥3.7, whereasync def+yieldis the language:becomes a plain async generator. Declaring a shim as a dependency to keep a 2019 workaround alive would have been the wrong repair.
Also the first CI lane this repository has ever had. The only workflow was
python-publish.yml, which releases and does not run on a pull request — so nothing checked the four dependency pull requests open here, and none of them could have caught the missing imports either.There are no tests in the tree, so the lane does not pretend to run any. It proves install, import, packaging, and one behaviour: that
LibcloudSpawner.progressis a real async generator, the contract JupyterHub calls it under. That is a behaviour check rather than a grep because a plainasync defthat never yields would still import cleanly while silently no longer being a generator.Verified in a fresh virtualenv outside the source tree:
pip install -e ., import, the async-generator assertion andpython -m buildall pass on Python 3.14.actionlintclean.🤖 Generated with Claude Code