Skip to content

Introduce platform.vm_info (or similar) as a replacement for recently deprecated platform.java_ver. #116504

Open

Description

@Stewori

Feature or enhancement

Proposal:

There exist alternative Python implementations that run on a virtual machine (vm) or a comparable middleware. The platform module currently lacks an implementation-independent API to retrieve (version-)information of an underlying vm. Examples are IronPython, Jython (3 possibly one day), RustPython. The proposal is to add a replacement for the recently deprecated function platform.java_ver under a generic name platform.vm_info that can optionally be implemented by a Python implementation. The return value of such a function would be a tuple inspired by what used to be returned by platform.java_ver.

The doc of that function states:

""" Version interface for Jython. 

 Returns a tuple (release, vendor, vminfo, osinfo) with vminfo being 
 a tuple (vm_name, vm_release, vm_vendor) and osinfo being a 
 tuple (os_name, os_version, os_arch). 

 Values which cannot be determined are set to the defaults 
 given as parameters (which all default to ''). 

"""

IMO only the vm_info part should be returned by the propsed function platform.vm_info, hence the name. Os info should be obtainable from the os module, release should be obtainable similar to CPython's release. For vendor I do honestly not understand what the difference to vm_vendor would supposed to be.
As a consequence, I suggest the following definition:

def vm_info(vm_name='', vm_release='', vm_vendor=''): 
  
     """ Version interface for Python implementations on virtual machines. 
  
         Returns a tuple (vm_name, vm_release, vm_vendor).
  
         Values which cannot be determined are set to the defaults 
         given as parameters (which all default to '').
  
     """ 

Apparently, this is plainly the old java_ver refactured to the relevant subset.
This definition is merely intended as an entry point for discussion. E.g. I would be fine with a different naming etc. if as a result more use cases can be covered. E.g. I am not sure whether for RustPython the notion of a vm would be accurate, so a broader name may be suggested. Also the parameters vm_name, vm_release and vm_vendor are placed here for discussion. For Java this makes sense because there exists e.g. Java implementations by Oracle and IBM (and many more in fact), which is relevant to know besides the release version number. I am rather confident about the idea that a tuple should be returned and that a plain version number would be an insufficiently narrow information. Perhaps even more fields should be defined, e.g. the build-type of the vm.

As many maintainers of alternative Python implementations as possible should be noticed to take a look at this proposal to make sure it covers as many use cases as possible.

Note:

Most enhancements and bug fixes don’t need a PEP and can be submitted directly to the Python issue tracker. (from: PEP 1)

Given that with java_ver a special case of this proposal has already been part of Python STL for well over a decade, evidence demands the inevitable conclusion that a PEP would be an overkill for this proposal. Even if not, the discussion in this issue would be a necessary prerequisite for a PEP.

Has this already been discussed elsewhere?

This is a minor feature, which does not need previous discussion elsewhere

Links to previous discussion of this feature:

#116349

Activity

  1. Stewori commented on Mar 8, 2024

    @Stewori
    Author

    @sobolevn @malemburg according to your posts in #116349 I hope this proposal addresses your API concerns. Please feel free to ping relevant devs for this discussion.

  2. sobolevn commented on Mar 8, 2024

    @sobolevn
    Member

    I would suggest using some other name, not vm, because RustPython doesn't have a vm, it uses rustc compiler 🤔

    tooling_version()?

  3. Stewori commented on Mar 8, 2024

    @Stewori
    Author

    @slozier and @BCSharp , what is your perspective on this for IronPython (please feel free to ping further IronPython devs)?

  4. Stewori commented on Mar 8, 2024

    @Stewori
    Author

    @sobolevn sure, the name "vm" is placed for discussion. Let's collect a couple of ideas.

  5. Stewori commented on Mar 8, 2024

    @Stewori
    Author

    @cfbolz @mattip @arigo pinging you just in case there is some point to make from PyPy perspective (not running on a vm, I know).

  6. Stewori commented on Mar 8, 2024

    @Stewori
    Author

    @jeff5 @fwierzbicki @jimbaker pinging you to make you aware.

  7. sobolevn commented on Mar 8, 2024

    @sobolevn
    Member

    @youknowone and @coolreader18 for RustPython

  8. JelleZijlstra commented on Mar 8, 2024

    @JelleZijlstra
    Member

    I'd caution against using a tuple as the return value, because it will be difficult to change in the future in a backwards-compatible way. Instead I would suggest a simple object with a documented set of attributes (e.g. using types.SimpleNamespace).

  9. Stewori commented on Mar 8, 2024

    @Stewori
    Author

    What about a named tuple? What is the advantage of SimpleNamespace over named tuple?

    @sobolevn Regarding RustPython, it occurred to me that there is platform.python_compiler(). On Linux I get "GCC [version]" as output from CPython. Perhaps that is better suited to expose a rust compiler version and this proposal would really target vm/middleware info. Just thinking...

  10. JelleZijlstra commented on Mar 8, 2024

    @JelleZijlstra
    Member

    Namedtuples are still tuples and therefore make it difficult to add new values. You can hack around it by adding a new property that isn't part of the tuple, but that's hacky. For a use case like this the API that tuple provides is mostly not very useful.

  11. sobolevn commented on Mar 9, 2024

    @sobolevn
    Member

    Related discussion about deprecating 'Java' as platform.system(): https://discuss.python.org/t/lets-deprecate-platform-system-java/48026

  12. Stewori commented on Mar 14, 2024

    @Stewori
    Author

    Looking at https://docs.python.org/3/library/types.html#types.SimpleNamespace it appears that elements would be mutable, which should be avoided. The property should have strict read-only character, which may be a reason for using a tuple in the first place. I know, there are techniques to make class attributes read-only but that would complicate the minimalistic intention. Probably the best way is to specify that the function creates a new object every time. (It could actively set the values of a returned singleton to its supposed values. But then, if a user stores the returned object and modifies its attributes they might magically change back later, which can be a nasty side effect.) Or is there an elegant way to have SimpleNamespace with immutable attributes?
    Another advantage of tuple is that print(platform.vm_info) would directly produce something useful. SimpleNamespace appears to provide only a __repr__ implementation, so a proper __str__ would need to be added as well (AFAIK the default __str__ would not provide attribute values). That's certainly doable, but again makes it a little more complicated.

  13. youknowone commented on Mar 15, 2024

    @youknowone
    Contributor

    Can platform refer another implementation-depend either c-written or python-written module _platform(or _python, _variant or any _something_good_name) and put everything CPython-specific literals in it? Then every other implementation only can write its own _platform. Here are the places RustPython hard-code its name:

    Making interface for them will be easier once we gather those variants into a single spot.

  14. Stewori commented on Mar 15, 2024

    @Stewori
    Author

    That would demand a bigger change in CPython than was intended with this issue (would probably be hard to convince them for such a change). That said, providing a custom version of platform is what also Jython is doing. You may be right that the path to a proper implementation-independent interface would be to collect and consider all variants but that is well beyond the ambition of this feature request.

  15. 18 remaining items

  16. Stewori commented on Jun 14, 2025

    @Stewori
    Author

    Thx, Marc-André, for taking a look.

    Is that about right ?

    Not only "about right", it precisely nails the point.

    Other things which could be of interest

    Nice thought, but it appears that the available info for most implementations is fairly limited. For Java-based Pythons there is the rich info from Java's System.properties dict, but for IronPython and browser-based Pythons there is apparently only one string available (RuntimeInformation.FrameworkDescription for .net; the user agent for browser-based Python). So, without the perspective that at least, say, three Python implementations would likely provide the API (additional info beyond one single info string), I think it's probably not sufficiently founded by demand.

    Repeating myself, my conclusion was that just one single plain string value is the common denominator of what existing implementations could reasonably and realistically provide. Also, I suppose providing just one single string is not asked too much, so that this would minimize the hurdle for adoption.

    My proposal from #116504 (comment) still stands with the amendment that I would consider an empty string the more canonical default value for CPython rather than None.

    embedded into sys.version

    This proposal is a chance to clarify the role of sys.version to refer to the actual system, rather than to a potential vm/middleware. From my Jython experience it is unrealistic that a vm would sufficiently abstract away the underlying system to successfully get away with having such info refer to the vm.

  17. jeff5 commented on Jun 15, 2025

    @jeff5
    Contributor

    Repeating myself, my conclusion was that just one single plain string value is the common denominator of what existing implementations could reasonably and realistically provide. Also, I suppose providing just one single string is not asked too much, so that this would minimize the hurdle for adoption.

    But that is only common in the sense that it has a single data type. It pushes the problem onto a thousand other developers to parse that string for every implementation they care about. And strings attract extra data. There have to be conventions on how that string is composed, and once you do that, you are back to tying to design a data structure, just with less effective tools than if you were to use classes.

    You can see the platform module has wrestled with the problem that the data necessary to describe the different implementations of Python have a structure that depends on the implementation, yet have commonalities you'd like to exploit.

    A false turn when describing Jython is that we have tried and failed to make Java the platform. Actually, I don't know what a "platform" is. A lot of the time it is used to mean OS. Perhaps it means a layer to supply all your most fundamental needs: no need to dig any lower. It would be lovely if Java did that, and insulated us entirely from the "real" OS, but we acknowledge it doesn't. I think platform.system()=="Java" is therefore a bad idea, like os.name=="Java", which we have seen make packages unusable on Jython on Windows.

    I think an adequate representation of platform has to have optional layers in the description. It appears the first and last are always the version of the Python language and the OS respectively, but there is sometimes one (just one?) inbetween, that could be a VM. I think it is worth attempting some structure here, even if it is just the guarantee of certain named members (if the whole layer is not None), with others contingent on those. Or does each layer give a clue to the existence of one lower? E.g. it is Jython, so I will be able to ask (particular things) about a VM.

    CPython does not see a need to describe more than the top and bottom layers ... but then, what is platform.python_compiler()? And I suppose I can ask whether I'm on the free-threading implementation somehow.

  18. Stewori commented on Jun 15, 2025

    @Stewori
    Author

    All good and valid thoughts, Jeff, although I am not really sure what alternative you are actually proposing.

    I think what truly matters is what libraries and implementors will make of this API. The interest in maintaining this feature turned out fairly low (which I don't quite understand but it is what it is), e.g. IronPython devs indicated close to zero ambition to maintain such a thing.

    So, I conclude, if there is a chance for this feature at all, it has to be as simplistic as possible. A thin wrapper to a specific call to middleware API. That doesn't have to be a bad thing - aren't other functions in the module thin wrappers to system properties as well?

    I agree it would be nice if more help could be provided for users to make structural sense of the provided data. But that would require more ambition from implementors which I currently don't see.

    I still think that having a commonly defined way to expose an info string would be an improvement over the status quo. Perhaps the thin-wrapper-approach could be a starting point to propose a more sophisticated API in the future once the thin wrapper has been widely adopted.

    whether I'm on the free-threading implementation somehow

    We should indeed check whether such a flag has been introduced so Jython can set it to indicate free-threaded behavior.

  19. jeff5 commented on Jun 18, 2025

    @jeff5
    Contributor

    Not a positive alternative, just not keen on the idea of a string users have to parse.

    A structure reflecting some easily interrogated properties doesn't seem too much to ask of the team that chose that layer. It would be the same across all JVM implementations, and different for a different VM/intermediate layer. If there's really only one thing to say (at present) about a given class of layer it could contain one attribute. I think you need to be able to inspect the layer for its type, but that could be its __class__.

    CPython seems not to need such a layer, but I think it has places where the C nature is assumed and attributes can be interrogated, e.g. sysconfig and https://docs.python.org/3/howto/free-threading-python.html#identifying-free-threaded-python

  20. Stewori commented on Jun 18, 2025

    @Stewori
    Author

    doesn't seem too much to ask of the team

    Standard browser API does apparently expose middleware info only through the user agent string and user agent parsing is a mess science for itself.

  21. youknowone commented on Jun 18, 2025

    @youknowone
    Contributor

    Perhaps the core of the issue is better addressed by allowing each implementation some space to add arbitrary functions to the platform module as needed.
    The reason Jython and IronPython struggle to share a common interface is fundamentally because Java and .NET cannot return the same kind of information through vm_info.
    In any case, users will have no way to meaningfully use the result of platform.vm_info() without also querying platform.python_implementation().
    So why not simply leave the return type of vm_info() undefined?
    If we allow Jython and IronPython the freedom to define the return format in a way that suits their respective implementations, then users can first check platform.python_implementation() and then proceed with further logic based on vm_info().
    This approach may seem irresponsible at first glance, but in practice, since no user can handle vm_info() meaningfully without first checking platform.python_implementation(), I believe it causes no real issues.

  22. jeff5 commented on Jun 18, 2025

    @jeff5
    Contributor

    doesn't seem too much to ask of the team

    Standard browser API does apparently expose middleware info only through the user agent string and user agent parsing is a mess science for itself.

    Let's not create another similar mess by having a string (that will surely get fatter over time).

  23. jeff5 commented on Jun 18, 2025

    @jeff5
    Contributor

    This approach may seem irresponsible at first glance, but in practice, since no user can handle vm_info() meaningfully without first checking platform.python_implementation(), I believe it causes no real issues.

    I favour this idea, although I think it would help if an attribute of the object returned, which attribute could be its Python type, would tell you what you otherwise need to work out from platform.python_implementation(), mapping potentially several implementations to one VM type.

  24. Stewori commented on Jun 18, 2025

    @Stewori
    Author

    that will surely get fatter over time

    That would be prevented by the convention that it has to be a thin wrapper or name<space>version for cases where there is nothing conclusive to wrap (conveniently, for IronPython both cases yield the same result). An undefined return type is harder to use than a string.

  25. youknowone commented on Jun 18, 2025

    @youknowone
    Contributor

    An undefined return type is harder to use than a string.

    This is the opposite: it is undefined at the Python standard level but must be defined at the Python implementation level. Jython and IronPython must define their own concrete types; otherwise, it would be a disaster. A well-defined struct sequence type is much easier to work with than a simple string type. It's just defined differently by each Python implementation.

  26. youknowone commented on Jun 18, 2025

    @youknowone
    Contributor

    Probably defining the return type as a free-length tuple will encourage the VmInfo type to be struct sequence.
    The return type forces not to return a single string, and the actual users of the function still can rely on the implementation-defined struct sequence.

  27. sobolevn commented on Jun 18, 2025

    @sobolevn
    Member

    Structs / tuples are hard, because people can use name, version = ver() and adding new fields to tuple will be a breaking change. So, dict is almost always a better choice.

  28. youknowone commented on Jun 18, 2025

    @youknowone
    Contributor

    Python already has a struct sequence, which is a tuple but accessible by field names, which can prevent more mistakes than dict

    >>> import sys
    >>> sys.version_info
    sys.version_info(major=3, minor=12, micro=0, releaselevel='final', serial=0)
    >>> isinstance(sys.version_info, tuple)
    True

    This is also a lot used for *Info types

  29. Stewori commented on Jun 18, 2025

    @Stewori
    Author

    This is the opposite: it is undefined at the Python standard level but must be defined at the Python implementation level.

    You would have to condition the use of the return value every time, which would diminish the advantage of a standardization approach. Asking implementations to implement custom types is over-engineering for a simple info feature and chances are that the API is just ignored by implementers and will be removed again in some years.

    Perhaps there can be two functions. One returns a string under a thin wrapper convention, which is readily justified for debugging, and one that returns a dict-like object (but should not be writable). Then this can be consolidated in a couple of years depending on adoption. The latter one should have a somewhat even more optional character (although both are optional).

    Python already has a struct sequence...

    Can this be made read-only?

    I think it might be helpful to draft anticipated example outputs as implementation recommendations for the main foreseeable frameworks/use cases:

    • JVM-based (GraalPy, Jython)
    • .net-based (IronPython)
    • browser-based (PyScript, Brython)

    I did this in #116504 (comment) for the thin-wrapper approach. What would a dict-like return type contain for these examples concretely? By means of an initial recommendation. Founded on an actually existing API call of the respective framework. It's not too hard to look into the API specs for these three cases: Java API, .net API, HTML5 API. I can provide links if you like.

    My point is to assert that there is actually a meaningful implementation perspective.

  30. youknowone commented on Jun 18, 2025

    @youknowone
    Contributor

    Can this be made read-only?

    Python 3.12.2 (main, Apr  1 2024, 00:27:28) [Clang 15.0.0 (clang-1500.3.9.4)] on darwin
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import sys
    >>> sys.version_info
    sys.version_info(major=3, minor=12, micro=2, releaselevel='final', serial=0)
    >>> sys.version_info.major = 10
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    AttributeError: readonly attribute
    >>> 

    Even though it is not readonly, if Python is already using it for VersionInfo, I can't say VmInfo have to be more strict than any other info functions under sys module.

    I also agree dict has enough benefits except for the consistency.

    Note: I am not a real potential provider/user of this API. The real provider/user's voice need to be more seriously accepted.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    stdlibStandard Library Python modules in the Lib/ directorytype-featureA feature request or enhancement

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions