oracle / graalpython

A Python 3 implementation built on GraalVM
Other
1.17k stars 101 forks source link

How do I identify the GraalPy version? #358

Closed kurtmckee closed 9 months ago

kurtmckee commented 9 months ago

I'm wanting to identify the GraalPy version (e.g. "23.1.0").

I've searched through the sys and platform modules but haven't yet found a way to cleanly identify this.

For comparison, PyPy has sys.pypy_version_info, which identifies the PyPy version.

msimacek commented 9 months ago

We have __graalpython__.get_graalvm_version().

@timfel should we add some better API like PyPy has? I think we generally don't want people to directly use __graalpython__.

kurtmckee commented 9 months ago

Thanks @msimacek! Understood that accessing that might not be supported and might change in the future.

My goal is to assist developers with cache-busting in CI, where virtual environments and build artifacts may take quite a bit of time to build but may be sensitive to API and ABI changes between Python implementations, architectures, and versions.

Are you aware of anything else that might be useful for cache-busting in this context? I've considered:

For example, my test script currently renders this human-readable output for various implementations:

3.10.13 [CPython 3.10.13; 64bit/ELF]
3.10.12 [PyPy 7.3.12; 64bit/ELF]
3.10.8 [GraalVM 23.1.0; 64bit/ELF]

If you're aware of things that will be helpful for effective cache-busting of virtual environments and build dependencies, please let me know.

For example, I'm curious if the Java version (like "21") is a significant consideration, too (and if there's a supported way to get that besides trying to access platform.java_ver() and grab the first element of the return tuple).

msimacek commented 9 months ago

If you want to cache built modules, then I think the most bulletproof thing at the moment is sysconfig.get_config_var("EXT_SUFFIX") (you'd remove the leading dot and probably the suffix too). It covers all four bullet points you mentioned (it includes the graalpy version for us). It is defined by https://peps.python.org/pep-3149/, so it can be considered standard and should be available on all major implementations. It even distinguishes CPython debug builds or GraalPy sandboxed mode. You could also use sysconfig.get_config_var("SOABI") but PyPy currently doesn't implement it correctly.

Java version is not significant for us.

timfel commented 9 months ago

I agree, sysconfig.get_config_var("EXT_SUFFIX") is the agreed upon method, I think that should work across all Pythons even.

kurtmckee commented 9 months ago

That is great information! It isn't sufficiently robust for the situation I'm working to overcome. I'll explain, but then I think this ticket can be closed.

For several of my projects, it's slow to checkout the repo, install the test dependencies, and have tox create the test environments just to run a 5-second test suite. I've therefore used the setup-python action to install all supported Python versions, then cache the .venv/ and .tox/ directories, and have tox run the test suite against all supported Python versions. This is a significant speedup, but the caches break if any of the underlying Python versions have a minor version change.

This happens because the CI runners install Pythons in version-specific subdirectories (like Python/3.11.5/x64 and Python/3.11.6/x64) and this breakage occurs whether the virtual environments are created using symlinks (in which case the .venv/bin/python symlinks break) or using the venv module's --copies argument (in which case the .venv/bin/python executable can't load its .so dependencies).

Therefore I'm working to create more robust cache-busting. sysconfig.get_config_var("EXT_SUFFIX") looks like it will get me a long way toward what I want, though it doesn't appear to be sufficient by itself because the value doesn't change between Python 3.11.5 and 3.11.6.

Thank you both for the excellent suggestion, and for the fast support!