#venvstacks
1 messages · Page 1 of 1 (latest)
For anyone that immediately wonders "But what about the dynamic linking problem?", I'm aware, and I'm pretty sure I have a viable solution: https://github.com/lmstudio-ai/venvstacks/issues/38
Even if that proposed solution ends up not working out, though, there are ways of working around the limitation.
Different perpective on the launch (my personal one rather than the company one): https://www.curiousefficiency.org/posts/2024/11/the-origin-of-venvstacks/
If anyone is experimenting with this, it's worth being aware of the (undocumented) constraint that postinstall scripts in 0.1.x. have to be executed using the underlying base runtime, or they won't work properly: https://github.com/lmstudio-ai/venvstacks/issues/66
Rather than documenting that, I'm instead working on eliminating the restriction.
The fix for that has been merged to main, but I'll only publish 0.2.0 after I've finished the automatic layer versioning feature that picked up that those test cases were broken.
0.2.0 has been published: https://venvstacks.lmstudio.ai/changelog/#changelog-0-2-0
venvstacks Changelog - venvstacks Documentation
This fixes the post-install script fragility problem mentioned above, as well as enabling automatic layer versioning based on lockfile changes.
The big docs addition is the section on the specification and metadata file formats: https://venvstacks.lmstudio.ai/file-formats/
venvstacks Specification and Metadata File Formats - venvstacks Documentation
Just a question - if I wanted to use venvstacks in my own application, with the current functionality, I'd have to write my own venvstacks.toml manually?
Kind of, in that there's no venvstacks init command to generate a skeleton. However, grabbing a copy of https://github.com/lmstudio-ai/venvstacks/blob/main/tests/minimal_project/venvstacks.toml or https://github.com/lmstudio-ai/venvstacks/blob/main/tests/sample_project/venvstacks.toml and editing it to suit the specific use case is a better workaround than starting with a blank file.
And just to be sure, something like cli.py in the sample_project is the main python logic I intending to get running, right?
or the x_imports are just applications too?
OH I see, the difference is between the deps, got it!
Yeah, there are two things that can differ between the application layers:
- which dependencies to install
- the launch module code
In the sample project, both of those things are different (since it's aiming to be a decent exercise of the full end-to-end capability)
Actually running the launch modules is with the deployed env's Python -m switch, but the docs for locating that in a platform independent way aren't really there yet.
Bare w/ me because I am pretty new to build systems revolving python in general - let's say if I have my application published with venvstacks and I get the .tar.gz files. How would I run the python code, for example, my golang code?
- Unpack all 3 layers in the same location on the target system (so the directories end up next to each other). For each one, run the post-installation script after unpacking.
- Once everything is unpacked, run the application layer's launch module using the
-mswitch for the Python executable in that environment.
I shall try this and get back to you!
The docs for doing that mostly don't exist, but https://venvstacks.lmstudio.ai/file-formats/#deployed-layer-configuration has the info on the fields in share/venv/metadata/venvstacks_layer.json that say where to find everything.
venvstacks Specification and Metadata File Formats - venvstacks Documentation
The longer version of the required steps:
- Read the layer config from
{env_path}share/venv/metadata/venvstacks_layer.json - Resolve
base_pythonfrom the layer config relative to the environment folder - Use that resolved path to run
{base_python_path} {env_path}/postinstall.py - Read
launch_modulefrom the layer config - Resolve
pythonfrom the layer config relative to the environment folder - Use that resolved path to run
{python_path} -m {launch_module}(potentially with CLI arguments, depending on the use case)
The rest of the fields in the layer config are for the post-installation script to worry about - the embedding application won't need to care.
would my launch module be present in site_packages?
Yeah, they get copied there by the layer build process.
So naming conflicts with dependencies are something to watch out for.
And I only need to run the launch_module for the application layer?
That's right. The build process will complain if you try to define them for other layers.
Pretty sure I did something wrong, I am going to retry this
I turned my notes from ^^^ into a docs issue: https://github.com/lmstudio-ai/venvstacks/issues/99
Currently the only docs on actually deploying and using the built environments are the list of layer config fields in https://venvstacks.lmstudio.ai/file-formats/#deployed-layer-configuration Summa...
Let me list down the steps I did
- Extract these 3 files
- Go in each folder starting from cpython and run
./bin/python -m postinstall - Run the launch module in the
app-scipyfolder by going inside the lib folder and running../../../bin/python -m scipy_import
I am trying to do it in my terminal manually
(i'd assumed the /bin/python have symlinks so they all end up using the same binary)
Gives me no module name 'scipy'
You shouldn't need to change directory. Something more like (adjust exact layer versions as needed):
$ cpython-3.11/bin/python cpython-3.11/postinstall.py
$ cpython-3.11/bin/python framework-scipy@1/postinstall.py
$ cpython-3.11/bin/python app-scipy@1/postinstall.py
$ app-scipy@1/bin/python -m scipy_import
Using the layered envs before they're configured properly mostly works on non-Windows systems (as you say, they're just symlinks), but the above avoids making that assumption.
One potential trap is that the unpack needs to not include the tarball's own name - the relative paths between environments won't work if that extra layer is present (I doubt that is the case for you though, since the postinstall executions would fail for that scenario).
A useful diagnostic is to run app-scipy@1/bin/python -m site to get the layer Python to dump where it is looking for files.
Same thing ~
Curious, my dir has app-scipy@2, does that have significance?
Yes, that's the "adjust exact layer versions as needed" part. Those layers have autonumbering turned on, so they may come out different based on whether someone has just grabbed the venvstacks.toml file from the test suite, or has grabbed the full requirements folder as well (the environment locks used for the layer autonumbering are stored alongside the locked dependency files)
App layers have an additional quirk, which is that they're not taking the launch module version into account (that's the subject of https://github.com/lmstudio-ai/venvstacks/issues/89 )
Hey, I'm excited to see someone outside LMStudio actively trying it out 🙂
I just rebuilt everything with the @1 instead of @2 and I think that solved the problem?
We published it because we thought other people would find it useful, but there's nothing like actually getting real feedback to validate that 🙂
haha i actually interned at LMStudio this summer and join the team next year - but surprisingly venvstacks would solve a problem for my own side project hence i was curious to try it out
If you still have the original tarballs, I'd be interested in their venvstacks_layer.json files.
In particular, if the app layer config file was referencing the wrong version of the framework layer, that could explain what you were seeing.
Oh yes! That is exactly the issue (this is the older .json)
"base_python": "../cpython-3.11/bin/python",
"dynlib_dirs": [],
"py_version": "3.11.10",
"pylib_dirs": [
"../framework-scipy@1/lib/python3.11/site-packages",
"../cpython-3.11/lib/python3.11/site-packages"
],
"python": "bin/python",
"site_dir": "lib/python3.11/site-packages"
}
any reason why this happened? or was it something i did which broke it?
Certainly the easiest way to get into that situation is to update the framework layer without rebuilding the application layer. The fact you lose transparent framework layer updates is the biggest downside of turning on the layer versioning (and is the main reason the layer versioning is opt-in rather than opt-out)
It's not impossible for there to be bugs around relocking-and-rebuilding in the same step, though - the test suite necessarily separates the failing test run that updates the locked requirements from the subsequent successful test run using those updated expectations.
Got it!
Hmm, Neil might have a stronger argument than I thought he did for ditching the implicit lock support.
(when we added the separate lock and publish subcommands, he wondered if we should keep the "all-in-one" aspects of the build subcommand)
We will need to consider that further if anyone else starts running into similar "framework was built as version X, but built app layer still declared a dependency on version X-1" problems.
I still have no idea how I ended up with the 2nd layer version - I had just used the commands from the homepage of the documentation. Trying to rerun them again in different combinations still hasn't reproduced another layer version for me, which is very interesting (or lock version I think after reading the github issue)
If you got a double version bump when starting from a bare venvstacks.toml file (with no parallel requirements folder) that would definitely be interesting, since that scenario isn't covered in the test suite (the full sample project test is always running against the previously checked in version, and the minimal project doesn't have layer versioning enabled).
... that's a pretty good argument to add layer versioning to the minimal project tests.
Ah I see. Tomorrow I'll try to build a stack from scratch for my app, let's see how'd that go
venvstacks 0.2.1 has been published with a Typer compatibility fix that @misty fiber picked up: https://github.com/lmstudio-ai/venvstacks/issues/96#issuecomment-2519491396
Finally getting my own venvstack for my application
simple question - why do we need to redefine the requirements in the application layer if we are already giving it the framework?
name = "sklearn-import"
launch_module = "launch_modules/sklearn_import.py"
frameworks = ["sklearn"]
requirements = [
"scikit-learn",
]
platforms = ["linux_x86_64"]
Good news - it worked super super seemlessly
The requirements redefinition is because an app may only depend on a subset of what the framework layer provides. Having it default to depending on the same things the framework depends on would be a reasonable bit of syntactic sugar, though.
I'm currently pondering this design problem for venvstacks: https://github.com/lmstudio-ai/venvstacks/issues/2
The current "constraints" locking model works by locking from the bottom up (runtimes, then frameworks, then applications), and using the lower layer requirements.txt files as constraints when locking the upper layers. This can lead to locking failures in upper layers if they impose an upper bound that the lower layers aren't otherwise aware of. The upper bounds (once known) can be added to the lower layer definitions, but then there is no straightforward way to determine if they're still needed (other than removing them and seeing if the stack still locks).
It shouldn't be that hard to build a "comprehensive" locking mode atop uv's workspace mechanism that bundles a runtime layer and all the framework and application layers that depend on it into a single mutually compatible lock file that all the layers then use as their constraints file. The downside of comprehensive locking is that it loses the ability to incrementally relock parts of the dependency tree without risking inconsistencies.
The question is then whether it would be feasible to make a hybrid mode that used the differences between the locked versions for those two approaches to determine a set of "inferred upper bounds" for the runtime and framework layers, which would then allow incremental relocking the same way the currently locking model does, without having to manually infer the transitive upper bounds.
0.3.0 has been published: https://venvstacks.lmstudio.ai/changelog/#changelog-0-3-0
Notable additions:
win_arm64andlinux_aarch64added to the permitted target platforms- New
--reset-lock "*"option when locking layers that allows the previous lock information to be discarded before locking (resetting any previously pinned version info)
venvstacks Changelog - venvstacks Documentation
With inspiration from @inner rover , the local wheel test case in https://github.com/lmstudio-ai/venvstacks/pull/122 is now looking promising (it uses stable ABI wheels built on the Python version running the test suite to populate a pair of virtual environment stacks that specifically run on Python 3.11).
(adding this test case is a preparatory step towards making the "split layers" case work on platforms other than Windows)
Hmm, I'm annoyingly getting a "failed to find ninja" error in the Windows builds, while the dynamic-library builds don't seem to be hitting a problem with that.
Only difference I've found is venvstacks using the windows-2019 runner image, while dynamic-library uses windows-2022. While neither of those have ninja (although that's coming soon), they do have different versions of vcpkg, which may impact meson's behaviour.
Switching to windows-2022 didn't help, but switching to windows-2019 picked up the new image version with ninja included, so the wheels are at least building now.
ninja, Windows, GitHub Actions
Success! Local wheel test has been merged to main, which means next week I can get started on removing the Windows qualifier from the split framework layer test case 🙂
Ugh, something somewhere is being clever, and it is making writing this test case difficult:
/tmp/tmpbqiwe6lm/_export🦎/framework-only-consumer/lib/python3.11/site-packages/dynlib_consumer.abi3.so
linux-vdso.so.1 (0x00007ffcbf1ee000)
libcheckdynlib.so => /tmp/tmp5_0p7lwp/build_venv/lib/python3.12/site-packages/dynlib_publisher/libcheckdynlib.so (0x00007f2220141000)
I don't know how the dynamic linker is finding the built-in-a-subprocess shared library inside the build venv, but it is.
I guess I don't really need to figure it out - I can just destroy the build venv after the wheels are built, so the built dynlib simply isn't there anymore (there's a separate folder that stores the locally built wheels for the test case)
Hah, and in complaining about it, I realised this is happening because the consumer lib has an absolute RPATH in it instead of a relative one. So once I delete the build venv copy, even the version of the test case that isn't split across multiple framework layers will fail.
Huzzah:
subprocess.CalledProcessError: Command '['/tmp/tmprb9f7asg/_export🦎/app-via-combined-layer/bin/python', '-X', 'utf8', '-Im', 'dynlib_import']' returned non-zero exit status 1
That's more like it:
framework-both-wheels
linux-vdso.so.1 (0x00007fff441dc000)
libcheckdynlib.so => /tmp/tmpl2y5512o/_export🦎/framework-both-wheels/lib/python3.11/site-packages/dynlib_publisher/libcheckdynlib.so (0x00007f0d0bc13000)
framework-only-consumer
linux-vdso.so.1 (0x00007ffdfc1a6000)
libcheckdynlib.so => not found
Now the test case fails as expected, I can finally get started on the actual task (making it pass)
Despite the excess of red crosses in CI, the draft PR at https://github.com/lmstudio-ai/venvstacks/pull/124 actually goes a long way towards finally proving the concept behind allowing shared object loading across layers.
It just also shows that I was right in the issue description in that a library exclusion mechanism would be needed to resolve naming conflicts.
Gah, poring over a generated shell script trying to figure out why it wasn't running properly in dash & zsh, only to eventually realise one of the commands had a &> /dev/null in it (bashism for 1> /dev/null 2>&1)
(Fedora never switched away from bash, so my local build was entirely fine, but CI failed on both Ubuntu and macOS)
sigh dash strikes again. Its exec builtin doesn't provide -a, so using /bin/sh as the wrapper script shebang fails on Ubuntu.
I guess forcing bash on Linux and zsh on macOS is strictly more accurate than using /bin/sh anyway, since I do genuinely need the exec -a feature.
Still some follow up work to be completed (release notes, docs updates, improving a couple of details), but 0.4.0 (once it is released) will support loading shared objects from other layers on both Linux (via bash) and macOS (via zsh). (This already works on Windows assuming os.add_dll_directory is called appropriately)
0.4.0 has been published: https://venvstacks.lmstudio.ai/changelog/#changelog-0-4-0
Notable additions:
- framework layers may now depend on other framework layers instead of directly on a runtime
- application layers may now depend directly on a runtime instead of on framework layers
- dynamic library loading now works across layers on Linux and macOS
venvstacks Changelog - venvstacks Documentation
Considering the comment I made here: #off-topic message
I'd been assuming it didn't make sense to publish a venvstacks-consumer client library/utility in Python, but I'm starting to wonder if that's a valid assumption.
Even an app written in Python may have valid reasons for wanting to embed a separate dedicated runtime for executing user or plugin code, and a Python reference implementation can still serve as a useful illustrative example for apps written in other languages.
Personally I'd encourage you to explore that. I feel like in general, building on top of your own "client library" leads to better internal architecture. And e.g. in the case of Pip there would be less misuse if people had had an explicit package-installation API to begin with, even if it's unclear to the maintainers what the use case is.
And I have at least the beginnings of that side, since the test suite needed them. Even if folks don't use it in their production deployments, they may find it useful for checking their stack builds actually worked.
Interesting: https://github.blog/changelog/2025-04-14-windows-arm64-hosted-runners-now-available-in-public-preview/
I don't want to add a 4th full CI platform (especially given the sample project dependencies most likely won't have windows ARM64 wheels on PyPI), but a "not slow" run could be a worthwhile addition to the config.
New bug fix release: https://github.com/lmstudio-ai/venvstacks/releases/tag/0.4.1
Mostly to make --reset-locks interact properly with --included, but a couple of other tweaks are in there as well.
Feature idea I plan to add to the issue tracker (prompted by #off-topic message): virtual layer archives.
When building layers in this mode,
instead of including the installed wheels in the layer archives, pip will be included in the runtime layers, the lock files will be included in each layer, and the post install scripts will install from the lock files using the PyPI index configuration specified at build time
Updating the declared CI dependencies to resolve a dependabot complaint about a h11 CVE revealed some rather significant gaps in the test coverage around handling changes to layer dependency declarations that aren't accompanied by a layer name change or lock reset: https://github.com/lmstudio-ai/venvstacks/issues/149
No new release for that yet (still needs release notes and additional test suite updates), so in the meantime, available workarounds are:
- use
--reset-lockto do full layer lock resets when the inputs change - use explicit layer versioning in the layer names (since the name changes effectively serve as layer lock resets)
New release has been published: https://github.com/lmstudio-ai/venvstacks/releases/tag/0.5.0
It's mostly assorted layer lock invalidation fixes, but a few other notable changes:
- with the improved layer lock invalidation, launch module changes in application layers will also bump the layer version when using implicit layer versioning
- resolving symlink conflicts should require fewer build iterations now, as the initial exception will report all of the ambiguities in the layer rather than just the first one encountered
➡️ PyPI page: venvstacks 0.5.0.
Changed
Layer locks are now invalidated for launch module changes. This also means that implicit versioning will update the layer version (resolves #89).
The excep...
Awesome stuff, will try it out this evening and see if I can package my code with it, wish me luck 🤞
With the benefit of hindsight, 0.5.0 really could have done with a beta cycle.
(assorted poor interactions with in-place upgrades of existing projects, as well as with the lock reset feature)
0.5.1 bug fix release has been published: https://github.com/lmstudio-ai/venvstacks/releases/tag/0.5.1
0.6.0 feature release has been published: https://github.com/lmstudio-ai/venvstacks/releases/tag/0.6.0
- Most notable changes are the additions of
support_modulesand preferring hardlinks in local export when the export destination is on the same filesystem as the build tree - There are also assorted adjustments to the way lock updates are handled for existing trees
Finally spending time on improving the console output to something more considered than constantly running in a verbose debugging mode: https://github.com/lmstudio-ai/venvstacks/pull/234
Continuing with console display improvements in https://github.com/lmstudio-ai/venvstacks/issues/159
While the stack definition format is relatively readable, it is presenting a directed acyclic graph as a flat list. This makes it entirely plausible that a complex stack may end up containing depen...
0.7.0 feature release has been published: https://github.com/lmstudio-ai/venvstacks/releases/tag/0.7.0
Primary changes are the console output improvements noted above, but keeping RECORD files around means that projects that expect to be able to access their own file listing metadata at runtime now work correctly when deployed with venvstacks.
I'm kinda regretting picking venvstacks.toml as the default stacks file name now, as it means I can't use it as the tool config file name.
I guess I could take the approach of:
- if there's a
[config]table in the stacks file, that gets used as the tool config - otherwise, look for
venvstacks-config.tomladjacent to the stacks file
That way, to share the same config across multiple stacks files, put it in a separate venvstacks-config.toml file. At some point in the future I could potentially define an inherit-config option to inherit settings from other config files, but I'd leave that out of the initial iteration.
As far as why I'm considering config files in the first place goes, it's in the context of allowing specification of package index URLs: https://github.com/lmstudio-ai/venvstacks/issues/144
I always thought the point of pyproject.toml was to act as a consolidation point for requirements and metadata around a Python project. While PEP 621 is mainly framed in terms of build backends, maybe it’s worth pushing the conversation further.
towards making it a general home for project-related configuration too.
Honestly, I’m getting a bit fatigued by the proliferation of tool-specific TOML files — ruff.toml, uv.toml, ty.toml, and now potentially venvstacks.toml/venvstacks-config.toml. It feels like we’re moving in the opposite direction of consolidation. I’d much prefer if all this project-related config lived in one place, with pyproject.toml being the obvious candidate for that “single source of truth.”
That said, I get why you want to keep a clean separation between “stacks definition” and “tool config” — it probably simplifies the mental model. But maybe the long-term solution should be encouraging projects (or the PyPA specs) to evolve pyproject.toml to explicitly support general-purpose tool configuration, rather than everyone inventing yet another *.toml.
Environment stack definitions aren't really Python projects in their own right (launch modules notwithstanding), so I never seriously considered using pyproject.toml. Too many of the standard metadata fields simply don't apply.
Most of the other tools do accept their config via the pyproject.toml [tool] table these days, but also accept dedicated config files for both backwards compatibility and for cases where there is no pyproject.toml
fair enough, thanks
At this point we're leaning towards needing an official or first-class sort of formatter for tool.xxx tables..... its getting to be massive (I have a 500 line configuration file for a project now)
I recommend https://github.com/tox-dev/pyproject-fmt
Taplo
0.8.0 is going to be a substantial release that invalidates all existing layer lock files by switching from requirements.txt to pylock.toml (the layer package summaries will still use the flat requirement format, though)
There's a large set of improvements coming alongside that inconvenience, though:
- cross-platform locking (no more per-platform layer locks)
- support for custom index configuration (include per-layer prioritisation of named indexes)
- support for package source overrides (primarily so different layers may pull torch from different indexes)
- accepting most other
uvsettings via thetool.uvtable invenvstacks.toml(or via an adjacentvenvstacks.uv.tomlfile) - using
uv pip installinstead ofpip installfor the layer build step (needed to make the above changes actually work)
Independently of the uv related changes:
pbs-installerhas been improved to always prefer the stripped CPython runtimes (novenvstacksupdate needed, just an update of its pinned dependencies)- much of the traceback spam when subprocess invocations fail has been eliminated
@alpine charm Are you aware of any compatibility issues with pdm and pip 25.3? I just got a super weird CI error in venvstacks trying to update the CI lock to the latest version of everything. Example stack trace (every platform did something similar in CI, but I couldn't reproduce the problem locally on Fedora):
ERRORS:
add pip failed:
Traceback (most recent call last):
File
"/opt/hostedtoolcache/Python/3.12.12/x64/lib/python3.12/site-packages/pdm/instal
lers/synchronizers.py", line 191, in synchronize
handlers(key, status.progress)
... snip a bunch of traceback lines ...
File
"/opt/hostedtoolcache/Python/3.12.12/x64/lib/python3.12/site-packages/pdm/enviro
nments/base.py", line 85, in _build_session
from pdm.models.session import PDMPyPIClient
File
"/opt/hostedtoolcache/Python/3.12.12/x64/lib/python3.12/site-packages/pdm/models
/session.py", line 14, in <module>
from pdm.models.serializers import MsgPackSerializer
File
"/opt/hostedtoolcache/Python/3.12.12/x64/lib/python3.12/site-packages/pdm/models
/serializers.py", line 8, in <module>
from hishel._serializers import Metadata
ModuleNotFoundError: No module named 'hishel._serializers'
The preceding PDM install looked like it finished without any problems (and hishel was installed):
Installing collected packages: distlib, urllib3, typing-extensions, truststore, tomlkit, socksio, sniffio, shellingham, resolvelib, python-dotenv, pyproject-hooks, pygments, platformdirs, pbs-installer, packaging, msgpack, mdurl, installer, idna, h11, filelock, charset-normalizer, certifi, blinker, virtualenv, requests, markdown-it-py, httpcore, hishel, findpython, dep-logic, anyio, rich, id, httpx, unearth, pdm
Successfully installed anyio-4.11.0 blinker-1.9.0 certifi-2025.10.5 charset-normalizer-3.4.4 dep-logic-0.5.2 distlib-0.4.0 filelock-3.20.0 findpython-0.7.0 h11-0.16.0 hishel-1.1.2 httpcore-1.0.9 httpx-0.28.1 id-1.5.0 idna-3.11 installer-0.7.0 markdown-it-py-4.0.0 mdurl-0.1.2 msgpack-1.1.2 packaging-25.0 pbs-installer-2025.8.27 pdm-2.25.9 platformdirs-4.5.0 pygments-2.19.2 pyproject-hooks-1.2.0 python-dotenv-1.2.1 requests-2.32.5 resolvelib-1.2.1 rich-14.2.0 shellingham-1.5.4 sniffio-1.3.1 socksio-1.0.0 tomlkit-0.13.3 truststore-0.10.4 typing-extensions-4.15.0 unearth-0.18.1 urllib3-2.5.0 virtualenv-20.35.4
pdm failure on CI lock update
Working on the source build documentation updates gave me a feature enhancement idea: https://github.com/lmstudio-ai/venvstacks/issues/320
#254 switched to using the pylock.toml locking format, which records the details of which wheels corresponding to which hashes (unlike the previous flat requirements file format). It should be feas...
@gaunt glacier I wrote up your layer template idea at https://github.com/lmstudio-ai/venvstacks/issues/328
After writing it up, I think it completely supercedes the old idea of figuring out a way to define matrix builds. I won't close the previous issue yet, but I'm certainly leaning that way.
0.8.0b1 has been tagged. Just a teeny-tiny release this one: https://github.com/lmstudio-ai/venvstacks/releases/tag/0.8.0b1
Some highlights:
- Cross-platform layer locks
uvconfiguration (including custom indexes with per-layer override options)- deriving layer lock times from
uv'sexclude-newersetting - layer target platforms are inferred from the layers they depend on
- respecting
MACOSX_DEPLOYMENT_TARGET - following
uv's baseline target for portable Linux environments
Demonstrating the old adage of "if it's not tested, it's broken", the layer lock package filtering in the beta had multiple issues when dealing with various environment marker combinations: https://github.com/lmstudio-ai/venvstacks/pull/335
That's a lot of layer lock file noise removed by the fixes, though (mostly from dropping the wheel listings for wheels imported from lower layers):
After finding that some of the example stacks didn't actually build after the --python-platform changes, I added a linux_target field (similar to macosx_target), so layer builds can target newer versions of glibc than 2.28: https://github.com/lmstudio-ai/venvstacks/pull/341
0.8.0b2 with the linux_target field and miscellaneous other fixes to the new cross-platform lock files: https://github.com/lmstudio-ai/venvstacks/releases/tag/0.8.0b2
The actual 0.8.0 final release is currently expected to happen after the resolution of https://github.com/lmstudio-ai/venvstacks/issues/326 lands (it turns out the new cross-platform locking makes it unfortunately easy to generate a lock file that seems to be cross-platform, but is actually missing wheels for some of the intended target platforms. The new changes add a post-lock check that fails if the lock file doesn't include a wheel for all of the expected platforms, without incurring all the environment marker noise in the lock file and package summaries that comes with requesting uv's native target environment enforcement.
Issue 326
This mostly affects @gaunt glacier (who already knows), but in the interests of transparency: I've left LM Studio for a role with Westpac here in Australia, so while I'll still be here to assist with any usage questions folks may have, I'm not actively developing venvstacks myself any more (Neil and other folks at LM Studio will be taking that over).
Was great collaborating with you @tepid lava , and wish you the best at the new role!
Not sure how clear it is to the community here, but for a year now LM Studio has been using venvstacks in production for all of our python functionality, including Apple's MLX and Openai's harmony. Alyssa has done a fantastic job of taking this project from zero to one. Thank you Alyssa!
@gaunt glacier I've been thinking a bit more about potential ways to get https://github.com/lmstudio-ai/venvstacks/blob/main/.github/workflows/prepare-release.yml to actually work properly (instead of creating the GH release without triggering the push to PyPI). The cleanest idea I've come up with would be to:
- submit a feature request & associated PR to add a
--draftoption toscriv github-release: https://scriv.readthedocs.io/en/latest/commands.html#scriv-github-release (which would amend the call in https://github.com/nedbat/scriv/blob/20a39b042d4f4e313a0f6567bc480121aeb53aa4/src/scriv/ghrel.py#L89 to setdraftbased on the new CLI option instead of hardcoding it toFalse) - update
pyproject.tomlto set a lowerscrivbound on whichever new release has that feature, then amend the workflow to pass the new CLI option when callingscriv github-release - amend the release process docs to cover going in and making any required edits (like fixing up issue and PR links), and then actually publishing the draft release (which will then actually publish to PyPI, since it won't be a workflow triggered release anymore)
I went ahead and submitted a feature request and PR for the scriv change: https://github.com/nedbat/scriv/pull/165
Published in scriv 1.8.0: https://github.com/nedbat/scriv/pull/165#issuecomment-3697870412