ironpython2 icon indicating copy to clipboard operation
ironpython2 copied to clipboard

"failed to parse CPython sys.version..." error when running under .Net 6

Open andyste1 opened this issue 3 years ago • 4 comments

We have a large .Net 4.x WPF desktop application that is in the process of being migrated to .Net 6. The app calls numerous py modules, one of which contains the following line of code:

import platform

...

print 'Using Python {0}'.format(platform.python_version())

This works fine with the .Net 4.x app, but the .Net 6 app fails with a ValueErrorException:

failed to parse CPython sys.version: '2.7.12 (2.7.12.1000)\n[.NETCoreApp,Version=v3.1 on .NET 6.0.6 (64-bit)]

The above line of code is really only there for informational purposes, and in theory could be removed. However we have a large customer base, and it's possible that this particular py module might contain customer-specific code, so I can't go replacing this module as part of our installation process.

I have found that I can hack the Python 2.7 \Lib\platform.py file, changing the _sys_version() function to return some hardcoded version values. If all else fails then I could deploy this modded file as part of the .Net 6 app installer. However I was just wondering if there might be a way to fix this from the .Net side? Clutching at straws, but perhaps being able to modify that offending version information via one of the IronPython classes?

andyste1 avatar Jul 05 '22 07:07 andyste1

I've found one solution, which is to execute the following script right after creating the ScriptEngine object:

_scriptEngine.Execute(@"
import sys
version_bak = sys.version
sys.version = '2.7.12 (IronPython 2.7.12 (2.7.12.1000) on .NET 6.0.0.0 (64-bit))'
import platform
platform.python_implementation()
platform._sys_version_cache[version_bak] = platform._sys_version_cache[sys.version]
sys.version = version_bak
");

It fixes the issue (I'll refine it to insert the correct version no.s rather than hardcode) but is there a better approach?

andyste1 avatar Jul 05 '22 08:07 andyste1

@andyste1 Sorry for the late reply. I guess you're not using the IronPython version of the standard library? I think you can override the version string via _scriptEngine.SetHostVariables.

slozier avatar Jul 30 '22 20:07 slozier

@slozier, no problem. When you say "standard library", I assume you mean the C:\Python27\ folder that was installed by Python. I don't see a SetHostVariables method on the ScriptEngine class but there is an extension method for ScriptRuntime if that's what you mean. What would I pass in to the three args (prefix, executable, version)?

andyste1 avatar Aug 01 '22 08:08 andyste1

When you say "standard library", I assume you mean the C:\Python27\ folder that was installed by Python.

Yes and no. I am referring to C:\Python27\Lib, but IronPython has its own branch of that contains changes to make it work better with IronPython (for example, platform.python_implementation() works without any hacks). You can get it via NuGet IronPython.StdLib, download it from the releases page, or from C:\Program Files\IronPython 2.7\Lib (if you installed IronPython).

I don't see a SetHostVariables method on the ScriptEngine class but there is an extension method for ScriptRuntime if that's what you mean. What would I pass in to the three args (prefix, executable, version)?

Yes, that's the method. The arguments will map to sys.prefix, sys.executable and sys.version. I think you can just pass in the empty string to the first two arguments - for the 3rd argument I guess you need to pass in something that your platform will like...

slozier avatar Aug 01 '22 13:08 slozier