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.11k stars 160 forks source link

No module named '__numpy_core__multiarray_umath' #78

Closed rakeeb-hossain closed 2 years ago

rakeeb-hossain commented 5 years ago

After following all the steps to build Numpy using the Python 3.6 branch, my project failed to find the Numpy module.

I successfully built the library using make numpy-iOS and linked it by including it in my project and changing my main.m file accordingly, as stated in https://github.com/beeware/Python-Apple-support/blob/3.6/patch/numpy/README.rst. This is my main.m file:

//
//  main.m
//  A main module for starting Python projects under iOS.
//

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import "python_call.h"
#include <Python.h>
#include <dlfcn.h>

@implementation RunScript : NSObject

void numpy_importer() {
    PyRun_SimpleString(
                       "import sys, importlib\n" \
                       "class NumpyImporter(object):\n" \
                       "    def find_module(self, fullname, mpath=None):\n" \
                       "        if fullname in (" \
                       "                   'numpy.core._multiarray_umath', " \
                       "                    'numpy.fft.fftpack_lite', " \
                       "                    'numpy.linalg._umath_linalg', " \
                       "                    'numpy.linalg.lapack_lite', " \
                       "                    'numpy.random.mtrand', " \
                       "                ):\n" \
                       "            return self\n" \
                       "        return\n" \
                       "    def load_module(self, fullname):\n" \
                       "        f = '__' + fullname.replace('.', '_')\n" \
                       "        mod = sys.modules.get(f)\n" \
                       "        if mod is None:\n" \
                       "            mod = importlib.__import__(f)\n" \
                       "            sys.modules[fullname] = mod\n" \
                       "            return mod\n" \
                       "        return mod\n" \
                       "sys.meta_path.append(NumpyImporter())"
                       );
}

extern PyMODINIT_FUNC PyInit__multiarray_umath(void);
extern PyMODINIT_FUNC PyInit_fftpack_lite(void);
extern PyMODINIT_FUNC PyInit__umath_linalg(void);
extern PyMODINIT_FUNC PyInit_lapack_lite(void);
extern PyMODINIT_FUNC PyInit_mtrand(void);

+(int)Run:(int) argc: (char * []) argv {
    int ret = 0;
    unsigned int i;
    NSString *tmp_path;
    NSString *python_home;
    NSString *python_path;
    wchar_t *wpython_home;
    const char* nslog_script;
    const char* main_script;
    wchar_t** python_argv;

    @autoreleasepool {

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

        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/twentybn.UnityTest/app:%@/Library/Application Support/twentybn.UnityTest/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]);

        // Configure Numpy
        PyImport_AppendInittab("__numpy_core_multiarray", &PyInit__multiarray_umath);
        PyImport_AppendInittab("__numpy_fft_fftpack_lite", &PyInit_fftpack_lite);
        PyImport_AppendInittab("__numpy_linalg__umath_linalg", &PyInit__umath_linalg);
        PyImport_AppendInittab("__numpy_linalg_lapack_lite", &PyInit_lapack_lite);
        PyImport_AppendInittab("__numpy_random_mtrand", &PyInit_mtrand);

        Py_Initialize();

        // Set the name of the python NSLog bootstrap script

        nslog_script = [
                        [[NSBundle mainBundle] pathForResource:@"Library/Application Support/twentybn.UnityTest/app_packages/nslog"
                                                        ofType:@"py"] cStringUsingEncoding:NSUTF8StringEncoding];

        if (nslog_script == NULL) {
            NSLog(@"Unable to locate NSLog bootstrap script.");
            exit(-2);
        }

        // Set the name of the main script
        main_script = [
                       [[NSBundle mainBundle] pathForResource:@"Library/Application Support/twentybn.UnityTest/app/UnityTest/__main__"
                                                       ofType:@"py"] cStringUsingEncoding:NSUTF8StringEncoding];

        if (main_script == NULL) {
            NSLog(@"Unable to locate UnityTest main module file.");
            exit(-1);
        }

        // Construct argv for the interpreter
        python_argv = PyMem_RawMalloc(sizeof(wchar_t*) * argc);

        python_argv[0] = Py_DecodeLocale(main_script, NULL);
        for (i = 1; i < argc; i++) {
            python_argv[i] = Py_DecodeLocale(argv[i], NULL);
        }

        PySys_SetArgv(2, python_argv);

        // If other modules are using threads, initialize them.
        PyEval_InitThreads();

        numpy_importer();

        @try {
            //NSLog(@"Installing Python NSLog handler...");
            FILE* fd = fopen(nslog_script, "r");
            if (fd == NULL) {
                ret = 1;
                NSLog(@"Unable to open nslog.py; abort.");
            } else {
                ret = PyRun_SimpleFileEx(fd, nslog_script, 1);
                fclose(fd);
                if (ret != 0) {
                    NSLog(@"Unable to install Python NSLog handler; abort.");
                } else {
                    // Start the main.py script
                    //NSLog(@"Running '%s'...", main_script);

                    fd = fopen(main_script, "r");
                    if (fd == NULL) {
                        ret = 1;
                        //NSLog(@"Unable to open '%s'; abort.", main_script);
                    } else {
                        ret = PyRun_SimpleFileEx(fd, main_script, 1);
                        fclose(fd);
                        if (ret != 0) {
                            //NSLog(@"Application quit abnormally!");
                        }
                    }
                }
            }
        }
        @catch (NSException *exception) {
            //NSLog(@"Python runtime error: %@", [exception reason]);
        }
        @finally {
            Py_Finalize();
        }

        PyMem_RawFree(wpython_home);
        if (python_argv) {
            for (i = 0; i < argc; i++) {
                PyMem_RawFree(python_argv[i]);
            }
            PyMem_RawFree(python_argv);
        }
        //NSLog(@"Leaving...");
    }

    return ret;
}

@end

The error I receive after importing numpy in my main.py via import numpy as np is:

Original error was: No module named '__numpy_core__multiarray_umath' Does anyone know how to fix this?

freakboy3742 commented 2 years ago

Closing as we're deprecating the numpy build system provided by this project, in favour of a more comprehensive approach to support binary packages.