-
-
Notifications
You must be signed in to change notification settings - Fork 32k
Introduce platform.vm_info (or similar) as a replacement for recently deprecated platform.java_ver. #116504
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
@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. |
I would suggest using some other name, not
|
@sobolevn sure, the name "vm" is placed for discussion. Let's collect a couple of ideas. |
@jeff5 @fwierzbicki @jimbaker pinging you to make you aware. |
@youknowone and @coolreader18 for RustPython |
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 |
What about a named tuple? What is the advantage of SimpleNamespace over named tuple? @sobolevn Regarding RustPython, it occurred to me that there is |
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. |
Related discussion about deprecating |
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 |
Can platform refer another implementation-depend either c-written or python-written module
Making interface for them will be easier once we gather those variants into a single spot. |
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. |
After you suggestion in python/cpython#116504 (comment) I went to take a look at `test_cmd_line` in RustPython (it was so long ago I contributed to this amazing project, so may thing had changed!), and I've noticed this. This is a problem, here' the simplest demo: ```python import unittest class TestMe(unittest.TestCase): @unittest.expectedFailure def test_me(self): def run(): raise ValueError with self.subTest(run=run): run() if __name__ == '__main__': unittest.main() ``` This works as expected: ``` » ./python.exe ex.py x ---------------------------------------------------------------------- Ran 1 test in 0.001s OK (expected failures=1) ``` This does not: ```python import unittest class TestMe(unittest.TestCase): def test_me(self): @unittest.expectedFailure def run(): raise ValueError with self.subTest(run=run): run() if __name__ == '__main__': unittest.main() ``` Produces: ``` » ./python.exe ex.py E ====================================================================== ERROR: test_me (__main__.TestMe.test_me) (run=<function TestMe.test_me.<locals>.run at 0x1057a2150>) ---------------------------------------------------------------------- Traceback (most recent call last): File "/Users/sobolev/Desktop/cpython2/ex.py", line 10, in test_me run() ~~~^^ File "/Users/sobolev/Desktop/cpython2/ex.py", line 7, in run raise ValueError ValueError ---------------------------------------------------------------------- Ran 1 test in 0.001s FAILED (errors=1) ``` So, I propose to remove these decorators, let's only keep `TODO` comments to indicate separate failures.
Btw, I added several skips on our side for |
After you suggestion in python/cpython#116504 (comment) I went to take a look at `test_cmd_line` in RustPython (it was so long ago I contributed to this amazing project, so may thing had changed!), and I've noticed this. This is a problem, here' the simplest demo: ```python import unittest class TestMe(unittest.TestCase): @unittest.expectedFailure def test_me(self): def run(): raise ValueError with self.subTest(run=run): run() if __name__ == '__main__': unittest.main() ``` This works as expected: ``` » ./python.exe ex.py x ---------------------------------------------------------------------- Ran 1 test in 0.001s OK (expected failures=1) ``` This does not: ```python import unittest class TestMe(unittest.TestCase): def test_me(self): @unittest.expectedFailure def run(): raise ValueError with self.subTest(run=run): run() if __name__ == '__main__': unittest.main() ``` Produces: ``` » ./python.exe ex.py E ====================================================================== ERROR: test_me (__main__.TestMe.test_me) (run=<function TestMe.test_me.<locals>.run at 0x1057a2150>) ---------------------------------------------------------------------- Traceback (most recent call last): File "/Users/sobolev/Desktop/cpython2/ex.py", line 10, in test_me run() ~~~^^ File "/Users/sobolev/Desktop/cpython2/ex.py", line 7, in run raise ValueError ValueError ---------------------------------------------------------------------- Ran 1 test in 0.001s FAILED (errors=1) ``` So, I propose to remove these decorators, let's only keep `TODO` comments to indicate separate failures.
…#5201) After you suggestion in python/cpython#116504 (comment) I went to take a look at `test_cmd_line` in RustPython (it was so long ago I contributed to this amazing project, so may thing had changed!), and I've noticed this. This is a problem, here' the simplest demo: ```python import unittest class TestMe(unittest.TestCase): @unittest.expectedFailure def test_me(self): def run(): raise ValueError with self.subTest(run=run): run() if __name__ == '__main__': unittest.main() ``` This works as expected: ``` » ./python.exe ex.py x ---------------------------------------------------------------------- Ran 1 test in 0.001s OK (expected failures=1) ``` This does not: ```python import unittest class TestMe(unittest.TestCase): def test_me(self): @unittest.expectedFailure def run(): raise ValueError with self.subTest(run=run): run() if __name__ == '__main__': unittest.main() ``` Produces: ``` » ./python.exe ex.py E ====================================================================== ERROR: test_me (__main__.TestMe.test_me) (run=<function TestMe.test_me.<locals>.run at 0x1057a2150>) ---------------------------------------------------------------------- Traceback (most recent call last): File "/Users/sobolev/Desktop/cpython2/ex.py", line 10, in test_me run() ~~~^^ File "/Users/sobolev/Desktop/cpython2/ex.py", line 7, in run raise ValueError ValueError ---------------------------------------------------------------------- Ran 1 test in 0.001s FAILED (errors=1) ``` So, I propose to remove these decorators, let's only keep `TODO` comments to indicate separate failures.
From the IronPython perspective, the .NET runtime doesn't really provide a great way to get the information required to populate this so I'm not sure if we'd be able to make use of it. Also trying hard to keep changes to the standard library to a minimum, so pulling the info from an implementation-dependant module would be preferable to modifying |
This is just about interfacing. Adding a hook that alternative Python implementations can implement if it makes sense. Only a minimal, almost empty (that is, returning a dummy value) function header would be added, so users can access the info within official Python API. The main purpose would be to define the API and probably to host the API doc and spec. I never worked with IronPython, but I suppose it should not be too difficult to insert a workable custom implementation for that API then, or to monkeypatch the platform module accordingly.
It surprises me that the .net runtime would not expose its version number and some info. It is not possible for a .net application to know (without dirty tricks, perhaps) whether it is running on Mono or Microsoft .net? |
Right, but implementation does matter (I'm not proposing either of these, they're just serving as examples). If this simply adds def vm_info(vm_name='', vm_release='', vm_vendor=''):
return vm_name, vm_release, vm_vendor to def vm_info(vm_name='', vm_release='', vm_vendor=''):
try:
from _platform import vm_info
return vm_info(vm_name=vm_name, vm_release=vm_release, vm_vendor=vm_vendor)
except ImportError:
return vm_name, vm_release, vm_vendor then we could implement it without touching the Python part of standard library. Side note, I'm not familiar with how this is used with Java, but what purpose do the function arguments serve? Why would you pass in your own values?
I am aware of that API and we expose it via Anyway, don't let IronPython hold you back, we're far enough behind that by the time we get to whatever version implements this .NET might have proper APIs. 😄 |
What do you think of this API: def implementation_info():
try:
import _implementation_platform
except ImportError:
return None
else:
return _implementation_platform.implementation_info() Design:
|
@Stewori : Python maintains support for the possibility of multiple implementations through >>> System.getProperty('java.version')
u'1.8.0_321'
>>> System.getProperty('java.specification.version')
u'1.8'
>>> System.getProperty('java.vm.specification.version')
u'1.8'
>>> System.getProperty('java.vm.version')
u'25.321-b07' I think I am most likely to want the Perhaps GraalVM cannot do exactly this, but that implementation could have its own access to the properties that applications need to know. Edit: I think I am basically suggesting that there may not be a sufficiently uniform idea of the VM information, for the standard library to offer a uniform API to it. |
@jeff5 By that logic, it would be enough to expose
I thought that a name and version would not be asked too much and that it would be the minimal kind of information every framework would provide. (I added vendor mainly because it was in java_ver, it's probably not so important). Since this is apparently not even feasible on .net, what about a single info String? @slozier If IronPython already exposes the info as @sobolevn, @youknowone |
Placing this draft for discussion:
|
I don't think this analogy holds because Python does not expose to us analogous things to those we are discussing, e.g. version when My instinct is for a tuple (pair), but show it used in a plausible application and it will be clearer why these items are the correct choice and the form. |
What I'm saying is that the platform module provides easy and standardized access to platform and machine information, even things like
I'm sure there are existing system library calls (e.g. via ctypes) via which one could get that information in platform-specific ways (platform module itself somehow gets the info). Of course that would be much more complicated and require system knowledge. So why should the users go through that hassle to get info about an underlying vm? Is that info less relevant? Then, what relevance does the processor string have. I suppose the use case is diagnostics but who knows? Apparently there was a use case to introduce
I think the same applies for various properties of the platform module. Do you mean by "tuple" Reading the platform doc, I notice that an empty string seems to be the preferred result if info is not available. So the above draft should probably return the empty string instead of |
This seems better fit for compiler case. By looking the thread, implementations running on VM needs more information than compiled to native one. |
I found a few uses of
That's right. Making it requires a split operation for IronPython. Making the string requires a join from a Java implementation. If the user always has to pick the string apart then they must understand to split on the rightmost space. My conjecture that a tuple would be more convenient stands or falls by how the result is to be used. |
A tuple has been criticized earlier in this thread; a simple object with read-only attributes seems to be preferred for better backwards compatibility if more fields should be introduced. However, that seems overly complicated to me - the intention was simplistic.
I thought this field might also be populated by Python running in the browser (Brython, e.g.). I looked up browser/Jvascript/html5 API and it seems that the relevant info is only exposed as the user agent string. That string is a different kind of beast - it may also contain rendering engine/version, perhaps also system/version. There are some attempts to parse it but they are complicated and need adjustment every some years. So I thought it might be best to expose an info string unaltered if a middleware exposes only a single string. That seems to be a typical case (.net, browsers). Then users can make of it what they want. For cases like Java where there are plenty of info-properties, the convention "name version" is proposed. That combination seems to me most flexible for unknown further cases of middleware, so the API would not require adjustment in the future. Also, the idea of providing a simple string fits well with most functions in the platform module (IIRC), perhaps with the exception of uname. |
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 nameplatform.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 byplatform.java_ver
.The doc of that function states:
IMO only the
vm_info
part should be returned by the propsed functionplatform.vm_info
, hence the name. Os info should be obtainable from the os module, release should be obtainable similar to CPython's release. Forvendor
I do honestly not understand what the difference tovm_vendor
would supposed to be.As a consequence, I suggest the following definition:
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
andvm_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:
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
The text was updated successfully, but these errors were encountered: