4 ms·
Working to Make Python Lazy
- dataflow 13d ago> This pattern, for example, can’t be lazy: try: import numpy; except ModuleNotFoundError: ... Wait, that seems bad. These kinds of modules (especially numba) are often exactly the ones that you want to delay importing. Why not provide a way to check the existence at import time? How are you supposed to handle nonexistence in that case?
- zbentley 13d ago...crash? Seriously: crash if your dependencies aren't available. There are better ways to do optional dependencies. ImportError ain't it.
- dataflow 13d agoWhat is the right way to handle an optional dependency?
- rtpg 13d agoI think this import flow tends to be the canonical one. I might recommend doing something like importing from something like `numpy.version` (or some other "random" very small utils package) so that the work done on file load is still fairly small.
- dataflow 13d agoIt's not clear such a thing even exists in general though. It's certainly not guaranteed by packages. What would that be for numba?
- rtpg 12d agoYep it's not clear, and a bit of a case-by-case thing. Fortunately most codebases only need to do this in a handful of spots so you can really "just" look at a package and find a file that probably is safe. For example, numba._version only imports standard library stuff so is probably good enough here[0] It would be nice to have general querying capabilities here, of course. I just think that in practice there's at least a halfway-decent workaround in almost any real situation [0] https://github.com/numba/numba/blob/main/numba/_version.py https://github.com/numba/numba/blob/main/numba/_version.py
- zbentley 13d agoCommon? Yes. Canonical/ideal? No. Optional dependency specifiers in your package metadata is a much better way to go. You can use those even if you don't publish your package as an artifact; `pip install -e .[optional-thing]` should work, or can be made to, easily.
- rtpg 12d agoThat's only part of the puzzle. Your program needs to branch on whether the dependency is installed or not! "Oh you don't have optional dependency? Then do X" needs to happen at runtime right?
- zbentley 9d agoI explained further here: https://news.ycombinator.com/item?id=49604462 https://news.ycombinator.com/item?id=49604462 In my preference order: an explicit CLI option/envvar which requires the optional dep, a flag file on the filesystem, or an ImportError attempt if you absolutely must. Use a stub/trampoline file in the conditionals so that static analyzers and laziness analysis on that file itself still work.
- zbentley 13d agohttps://packaging.python.org/en/latest/guides/writing-pyproject-toml/#dependencies-optional-dependencies https://packaging.python.org/en/latest/guides/writing-pyproj...
- dataflow 13d agoI don't understand, sorry. How does declaring an optional dependency in a toml file solve the problem of accessing the symbol in your code? Also, you need something that works for simple one-file scripts, not just a whole package or project.
- zbentley 9d agoDeclare the optional dependency and then import it unconditionally if the optional is installed. You can conditionally import a file you control based on asking whether an optional specifier was installed, either by probing the filesystem, a CLI argument, an environment variable, or whatever folks come up with for https://github.com/pypa/packaging-problems/issues/215 https://github.com/pypa/packaging-problems/issues/215. The "if: ... import" laziness-defeating clause only applies to your stub module, and the imports in that module are unconditional and thus will work with analyzers/laziness/etc. If you need something for one-off scripts, use https://docs.astral.sh/uv/guides/scripts/ https://docs.astral.sh/uv/guides/scripts/.
- js2 13d ago> The error here will move to the first usage of something from numpy. There is a semi-lazy alternative: import importlib.util if importlib.util.find_spec("numpy") is None: ... # whatever you wanted to do if numpy is missing lazy import numpy
- mhashemi 13d agoI've got my reservations about lazy imports, but scipy in particular is such a memory hog, I've increasingly been vendoring smaller utilities out of it. Good lazy imports would be a big help.
- wodenokoto 13d agodoesn't `from scipy import ...` help with memory?
- stevesimmons 13d ago[dead]
- yuriks 13d agoThis feature seems really valuable for commandline tools! However this paragraph gave me pause: > Currently, disabling lazy imports disabled the syntax keyword, which means that you can’t use it for circular imports, type checking, etc. Imo this is a good thing, laziness shouldn't be semantically important. The ability to force disable laziness while maintaining semantics is important for linting and testing, and more often than not, circular imports are a sign of bad code structure.
- nxtfari 13d agoGood feature but god I hate there’s a whole new keyword for a minor modification on an existing concept. Very unnecessary.
- jwilk 13d agoIt's a soft keyword: https://docs.python.org/3.15/reference/lexical_analysis.html#soft-keywords https://docs.python.org/3.15/reference/lexical_analysis.html... > As soft keywords, their use in the grammar is possible while still preserving compatibility with existing code that uses these names as identifier names.
- throwaway81523 13d agoThis seems like an ugly hack. We really need a way to snapshot a python program after its imports have been loaded, similar to temacs/emacs that's been around for decades, or a similar thing that exists in gforth. Emacs's old unexec scheme became unmaintainable but maybe there are still good alternate ways to do it.
- disdegeneration 13d agoIs there a language with a hybrid laziness approach? similar to "do work only if needed" but if you have ressources, do work most likely to be needed, like lazy anticipating?
- 4563lk 13d agoOr just use C++. The Python ecosystem is just bloat, blogs and tools.