Rhino8 python subprocess.check_output() error

Hi There,

In rhino7 I was used to running a piece of code that runs an external instance of python3.11, to perform functionality that wasn’t available in Ironpython2.7.

If I run the same piece of code in Rhino8 I get an error, likely related to the PYTHONHOME variable judging by this post.
To me it seems that Rhino8 has set the PYTHONHOME variable and I need to make sure that the check_output() call does not use this variable

Does anyone know how to solve this issue?

Thanks,
Tim

Status : CalledProcessError 1
Python path configuration:
  PYTHONHOME = '\\?\C:\Users\info\.rhinocode\py39-rh8'
  PYTHONPATH = (not set)
  program name = 'python'
  isolated = 0
  environment = 1
  user site = 1
  safe_path = 0
  import site = 1
  is in build tree = 0
  stdlib dir = 'C:\Users\info\.rhinocode\py39-rh8\Lib'
  sys._base_executable = 'C:\\Program Files\\Python311\\python.exe'
  sys.base_prefix = '\\\\?\\C:\\Users\\info\\.rhinocode\\py39-rh8'
  sys.base_exec_prefix = '\\\\?\\C:\\Users\\info\\.rhinocode\\py39-rh8'
  sys.platlibdir = 'DLLs'
  sys.executable = 'C:\\Program Files\\Python311\\python.exe'
  sys.prefix = '\\\\?\\C:\\Users\\info\\.rhinocode\\py39-rh8'
  sys.exec_prefix = '\\\\?\\C:\\Users\\info\\.rhinocode\\py39-rh8'
  sys.path = [
    'C:\\Program Files\\Python311\\python311.zip',
    'C:\\Users\\info\\.rhinocode\\py39-rh8\\Lib',
    'C:\\Users\\info\\.rhinocode\\py39-rh8\\DLLs',
  ]
Fatal Python error: init_fs_encoding: failed to get the Python codec of the filesystem encoding
Python runtime state: core initialized
ImportError: bad magic number in 'encodings': b'a\r\r\n'

Current thread 0x0000435c (most recent call first):
  <no Python frame>
#! python 2
# example_test_file.py
import json
import sys
from subprocess import check_output, STDOUT, CalledProcessError

def main():
    try:
        # example payload 
        input = { 'a':'my_value' }
        json_data = json.dumps(input, ensure_ascii=False).encode('utf-8')

        # Call external process in python3, send payload as json string
        filename = 'RunTestFile.py'
        output = check_output(['python', filename, '-i', json_data], stderr=STDOUT, shell=False, universal_newlines=True, creationflags = 0x08000000)

        # Temp disabled, try with exact executable path
        # path = r'C:\Program Files\Python311\python.exe'
        # output = check_output([path, filename, '-i', json_data], stderr=STDOUT, shell=False, universal_newlines=True, creationflags = 0x08000000)

        # process the output
        lines = output.split('\n')
        for line in lines:
            try:
                # try to capture any line that looks like a response in json
                response = json.loads(line)
                if response['status'] != None:
                    return response
            except Exception as exc:
                # print any other output
                print('py3 output : %s' % (line))

    except CalledProcessError as exc:
        # capture timeouts
        if exc.returncode == -1073741510:
            return {'status':False, 'msg':'API call timeout'}

        # print the external process error
        print("Status : CalledProcessError", exc.returncode)
        lines = exc.output.split('\n')
        for line in lines:
            print(line)

    except Exception as exc:
        print(exc)

if __name__ == '__main__':
    main()
#! python3
# example_file_to_execute.py
import sys
print('version from instance:', sys.version)

UPDATE 2023/12/13

I was able to bypass the issue by deleting the “PYTHONHOME” variable just before calling subprocess. I will further investigate if this affects the workings of Phino8 python engine

        # Remove PYTHONHOME variable
        if os.environ.get('PYTHONHOME'):
            del os.environ['PYTHONHOME']

        # Call external process in python3, send payload as json string
        filename = 'RunTestFile.py'
        output = check_output(['python', filename, '-i', json_data], stderr=STDOUT, shell=False, universal_newlines=True, creationflags = 0x08000000)

1 Like