beeware / Python-Apple-support

A meta-package for building a version of Python that can be embedded into a macOS, iOS, tvOS or watchOS project.
MIT License
1.1k stars 159 forks source link

ModuleNotFoundError: No module named 'encodings' #142

Closed CarlosNano closed 2 years ago

CarlosNano commented 2 years ago

Describe the bug When I run Py_Initialize(); the app crashes and I get:

Fatal Python error: init_fs_encoding: failed to get the Python codec of the filesystem encoding
Python runtime state: core initialized
ModuleNotFoundError: No module named 'encodings'

Current thread 0x0000000103083880 (most recent call first):
  <no Python frame>

I've found this other ticket: https://github.com/beeware/Python-Apple-support/issues/21 which advised how to set up python.

My code is a copy of the main file:

    NSString * resourcePath = [[NSBundle mainBundle] resourcePath];

    // Special environment to prefer .pyo; also, don't write bytecode
    // because the process will not have write permissions on the device.
    putenv("PYTHONOPTIMIZE=1");
    putenv("PYTHONDONTWRITEBYTECODE=1");
    putenv("PYTHONUNBUFFERED=1");

    // Set the home for the Python interpreter
    python_home = [NSString stringWithFormat:@"%@/Library/Python", resourcePath, nil];
    NSLog(@"PythonHome is: %@", python_home);
    wpython_home = Py_DecodeLocale([python_home UTF8String], NULL);
    Py_SetPythonHome(wpython_home);

    // Set the PYTHONPATH
    python_path = [NSString stringWithFormat:@"PYTHONPATH=%@/Library/Application Support/com.mycompany.PythonHelloWorld/app:%@/Library/Application Support/com.mycompany.PythonHelloWorld/app_packages", resourcePath, resourcePath, nil];
    NSLog(@"PYTHONPATH is: %@", python_path);
    putenv((char *)[python_path UTF8String]);

    // iOS provides a specific directory for temp files.
    tmp_path = [NSString stringWithFormat:@"TMP=%@/tmp", resourcePath, nil];
    putenv((char *)[tmp_path UTF8String]);

    NSLog(@"Initializing Python runtime...");
    Py_Initialize();

    // Set the name of the python NSLog bootstrap script
    nslog_script = [
        [[NSBundle mainBundle] pathForResource:@"Library/Application Support/com.mycompany.PythonHelloWorld/app_packages/nslog"
                                        ofType:@"py"] cStringUsingEncoding:NSUTF8StringEncoding];

    if (nslog_script == NULL) {
        NSLog(@"Unable to locate NSLog bootstrap script.");
        exit(-2);
    }
    PyRun_SimpleString("from time import time,ctime\n"
                       "print('Today is', ctime(time()))\n");
    if (Py_FinalizeEx() < 0) {
        exit(120);
    }
    PyMem_RawFree(wpython_home);
    if (python_argv) {
        PyMem_RawFree(python_argv);
    }
    NSLog(@"Leaving...");
    return 0;

I've replaced the execution of the python code with PyRun_SimpleString, but the problem is happening in Py_Initialize

Any advise how to find where the problem is? For what I could find in searching it could be to do with the PYTHONHOME or PYTHONPATH

Thanks

Expected behavior No crash neither errors in the console

Environment:

Operating System: 12.2.1 Python version: 3.10

freakboy3742 commented 2 years ago

It's difficult to come to any conclusions based on the detail you've provided; I'm guessing the issue is with the project configuration, and what has actually been included in your app bundle. The bootstrap script looks reasonable - but you also need to ensure that all the Python stdlib resources are included - and if you've built a project from scratch, they won't be.

At this time, the only usage of this package that is officially supported is usage from within Briefcase. If you're able to reproduce this error from the Briefcase bootstrap, then I'd consider that a bug; any usage outside that falls into the "do what Briefcase does, and it will work" category.

CarlosNano commented 2 years ago

Oh so I guess I could follow this tutorial: https://docs.beeware.org/en/latest/tutorial/tutorial-5/iOS.html to create an app with Briefcase.

Thanks for the response.