ENH: ensure that dir(astropy) lists subpackages#17598
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.
|
|
|
||
| __dir_inc__ = [ | ||
| "__version__", | ||
| "__githash__", |
There was a problem hiding this comment.
I had to remove this one since it is not actually defined and ipython seems to use __all__ when doing tab completion.
EDIT: indeed, this means that once you tab-complete, all subpackages are loaded. I think that's OK, since that's just interactive usage anyway.
There was a problem hiding this comment.
this means that once you tab-complete, all subpackages are loaded.
I think that's how the IPython REPL implements autocompletes for import statements, but I'd like to try it with Python 3.13's new REPL too.
There was a problem hiding this comment.
Python 3.13's REPL (aka PyREPL) doesn't seem to even try autocompletion in this area, so no change there.
I agree that it's fine that IPython users will now implicitly load everything if they use , that is part of the IPython deal anyway.
There was a problem hiding this comment.
I just check and I do get python 3.13.1 to auto-complete astropy.<TAB> - and it also autoloads them to show what is available. Indeed, it does just the logical thing: if I do astropy.sta<TAB> then it finds stats but astropy.time is not loaded.
There was a problem hiding this comment.
Ah, indeed, confirmed that that does not work on python 3.13 (but does on ipython); I've noticed before that __getattr__/__dir__ don't quite work as nicely with from ... import ... - must involve a slightly different path or so.
There was a problem hiding this comment.
There was a problem hiding this comment.
python/cpython#129329 was just merged though I have no idea what Python versions it will land on. Anything we need to follow-up on still?
There was a problem hiding this comment.
It'll be in 3.14. We can test this further then, but I don't anticipate any follow up to be needed.
There was a problem hiding this comment.
Thanks for the info! I opened #18055 as reminder, just in case.
|
@celik-muhammed are you satisfied with this proposed solution? |
|
Hmm seems to break RTD somehow. |
|
pyinstaller is not happy, hmm, why? |
|
Maybe this needs patching too? astropy/astropy/utils/introspection.py Line 341 in 80aa67d |
a9ea40f to
cf23549
Compare
|
Nice catch on |
neutrinoceros
left a comment
There was a problem hiding this comment.
looks great. Just a couple minor suggestions from me !
| module_dirs = { | ||
| f.name | ||
| for f in Path(astropy.__file__).parent.glob("[a-z]*") | ||
| if f.is_dir() and f.name != "extern" |
There was a problem hiding this comment.
| if f.is_dir() and f.name != "extern" | |
| if f.is_dir() and f.name != "extern" and f.joinpath("__init__.py").is_file() |
There was a problem hiding this comment.
I'd hope we won't add non-python module directories - if we ever do, then maybe that's the right time to add the extra clause... (similarly, in principle one can have modules defined in *.py files, which I also ignore; this just tests the existing scheme).
There was a problem hiding this comment.
The reason I'm worried about this isn't that non-python module dirs are added to vcs, but that it might be done on a development copy and change this test's status possibly in a non-obvious way. I think it's worth spending a minute emaking the test narrow and correct now to save what would likely be a longer time spent on confused debugging for this hypothetical future contributor.
There was a problem hiding this comment.
This isn't a blocking request though; if I haven't convinced you yet, then we're probably wasting more time discussing it that it'll ever save.
There was a problem hiding this comment.
I see your point now, though perhaps not quite enough to run all CI again... Let's just get it in!
Seems to be because of a bad changelog entry, from #17503. Not sure why that didn't get caught in testing before, though... |
1d52ffc to
b9dbbd7
Compare
|
I added two commits that should fix the RTD problems. Since these are not directly related to this PR (though somehow it exposes the problems!?), probably best not to squash-merge this PR. |
|
p.s. Because this fixes a previous changelog entry, the bot fails - so I put |
|
Hmm |
b9dbbd7 to
8fd65e0
Compare
|
Thanks! With that silly too-quick-to-adapt change fixed, tests seem to pass, including for readthedocs and pyinstaller (other OSes still running). |
pllim
left a comment
There was a problem hiding this comment.
LGTM now! Unless @neutrinoceros has further comments, I think this is good to merge. I really like the idea of lazy import. Thanks!
|
sounds good, we keep lazy loading strategy then when we call dir(obj) it would loaded/listed submodules by getattr. It was a useful development. |
| def test_toplevel_lazy_imports(): | ||
| # Check that subpackages are loaded on demand. | ||
| cmd = dedent(""" | ||
| import astropy, sys | ||
| assert 'astropy.units' not in sys.modules | ||
| astropy.units | ||
| assert 'astropy.units' in sys.modules | ||
| """) | ||
| cp = subprocess.check_call([sys.executable, "-c", cmd]) | ||
| assert cp == 0 |
There was a problem hiding this comment.
@mhvk @pllim looking for other sources of test pollution locally, I hit (I assume by chance) a failure mode for this test. It is extremely puzzling to me that this test might fail in a subprocess, let alone have anything to do with pollution, but unfortunately it is also very hard to debug; I don't even have a good traceback to work with. All I have is
subprocess.CalledProcessError: Command '['/Users/clm/dev/astropy-project/coordinated/astropy/.venv/bin/python3', '-c', "\nimport astropy, sys\nassert 'astropy.units' not in sys.modules\nastropy.units\nassert 'astropy.units' in sys.modules\n"]' returned non-zero exit status 1.
So, I'm pinging you guys in the hope that we can figure out a different test for this feature, but I for one don't have a clear idea how. I tried using monkeypatch.delitem(sys.modules, "astropy.units", raising=False), but it doesn't suffice to simulate "astropy.units has not been imported yet" and the second assert statement fails.
There was a problem hiding this comment.
Actually, this should have its own issue. I'll open one now.
After
import astropy,dir(astropy)will now list all subpackages, including those that have not yet been loaded explicitly. This also means tab completion will work as expected (e.g.,from astropy.coo<TAB>will expand tofrom astropy.coordinates).Fixes #17589