Example #1
0
void
pbs_python_ext_start_interpreter(
	struct python_interpreter_data *interp_data)
{
	static char func_id[] = "pbs_python_ext_start_interpreter";

#ifdef	PYTHON           /* -- BEGIN ONLY IF PYTHON IS CONFIGURED -- */

	struct stat sbuf;
	char pbs_python_home[MAXPATHLEN+1];
	char pbs_python_destlib[MAXPATHLEN+1];
	int  evtype;
	int  rc;

	/*
	 * initialize the convenience global pbs_python_daemon_name, as it is
	 * used everywhere
	 */

	pbs_python_daemon_name = interp_data->daemon_name;

	/* Need to make logging less verbose if pbs_python command */
	/* used, since it can get called many times in a pbs daemon, */
	/* and it would litter that daemon's logs */
	if (IS_PBS_PYTHON_CMD(pbs_python_daemon_name))
		evtype = PBSEVENT_DEBUG3;
	else
		evtype = PBSEVENT_DEBUG2;

	memset((char *)pbs_python_home, '\0', MAXPATHLEN+1);
	memset((char *)pbs_python_destlib, '\0', MAXPATHLEN+1);

	snprintf(pbs_python_home, MAXPATHLEN, "%s/python",
		pbs_conf.pbs_exec_path);
	snprintf(pbs_python_destlib, MAXPATHLEN, "%s/lib64/python/altair",
		pbs_conf.pbs_exec_path);
	rc = stat(pbs_python_destlib, &sbuf);
	if (rc != 0) {
		snprintf(pbs_python_destlib, MAXPATHLEN, "%s/lib/python/altair",
			pbs_conf.pbs_exec_path);
		rc = stat(pbs_python_destlib, &sbuf);
	}
	if (rc != 0) {
		log_err(-1, func_id,
			"--> PBS Python library directory not found <--");
		return;
	}
	if (!S_ISDIR(sbuf.st_mode)) {
		log_err(-1, func_id,
			"--> PBS Python library path is not a directory <--");
		return;
	}

	if (interp_data) {
		interp_data->init_interpreter_data(interp_data); /* to be safe */
		if (interp_data->interp_started) {
			log_event(evtype, PBS_EVENTCLASS_SERVER,
				LOG_INFO, interp_data->daemon_name,
				"--> Python interpreter already started <--");
			return;
		}
	} else { /* we need to allocate memory */
		log_err(-1, func_id,
			"--> Passed NULL for interpreter data <--");
		return;
	}

	Py_NoSiteFlag = 1;
	Py_FrozenFlag = 1;
	Py_OptimizeFlag = 2;            /* TODO make this a compile flag variable */
	Py_IgnoreEnvironmentFlag = 1;   /* ignore PYTHONPATH and PYTHONHOME */
	if (file_exists(pbs_python_home))
		Py_SetPythonHome(pbs_python_home);

	/* we make sure our top level module is initialized */
	if ((PyImport_ExtendInittab(pbs_python_inittab_modules) != 0)) {
		log_err(-1, "PyImport_ExtendInittab",
			"--> Failed to initialize Python interpreter <--");
		return;
	}


	Py_InitializeEx(1);  /* arg '1' means to not skip init of signals -    */
	/* we want signals to propagate to the executing  */
	/* Python script to be able to interrupt it       */

	if (Py_IsInitialized()) {
		interp_data->interp_started = 1; /* mark python as initialized */
		/* print only the first five characters, TODO check for NULL? */
		snprintf(log_buffer, LOG_BUF_SIZE-1,
			"--> Python Interpreter started, compiled with version:'%.*s' <--",
			5, Py_GetVersion());
		log_buffer[LOG_BUF_SIZE-1] = '\0';
		log_event(evtype, PBS_EVENTCLASS_SERVER,
			LOG_INFO, interp_data->daemon_name, log_buffer);
	} else {
		log_err(-1, "Py_InitializeEx",
			"--> Failed to initialize Python interpreter <--");
		goto ERROR_EXIT;
	}
	/*
	 * Add Altair python module directory to sys path. NOTE:
	 *  PBS_PYTHON_MODULE_DIR is a command line define, also insert
	 * standard required python modules
	 */
	if (pbs_python_modify_syspath(pbs_python_destlib, -1) == -1) {
		snprintf(log_buffer, LOG_BUF_SIZE-1,
			"could not insert %s into sys.path shutting down",
			pbs_python_destlib);
		log_buffer[LOG_BUF_SIZE-1] = '\0';
		log_err(-1, func_id, log_buffer);
		goto ERROR_EXIT;
	}

	/*
	 * At this point it is safe to load the available server types from
	 * the python modules. since the syspath is setup correctly
	 */
	if ((pbs_python_load_python_types(interp_data) == -1)) {
		log_err(-1, func_id, "could not load python types into the interpreter");
		goto ERROR_EXIT;
	}

	interp_data->pbs_python_types_loaded = 1; /* just in case */
	return;

ERROR_EXIT:
	pbs_python_ext_shutdown_interpreter(interp_data);
	return;
#else  /* !PYTHON */
	log_event(PBSEVENT_SYSTEM|PBSEVENT_ADMIN |
		PBSEVENT_DEBUG, PBS_EVENTCLASS_SERVER,
		LOG_INFO, "start_python",
		"--> Python interpreter not built in <--");
	return;
#endif /* PYTHON */
}
Example #2
0
void
pbs_python_ext_quick_start_interpreter(void)
{
	static char func_id[] = "pbs_python_ext_quick_start_interpreter";

#ifdef	PYTHON           /* -- BEGIN ONLY IF PYTHON IS CONFIGURED -- */

	char pbs_python_home[MAXPATHLEN+1];
	char pbs_python_destlib[MAXPATHLEN+1];

	memset((char *)pbs_python_home, '\0', MAXPATHLEN+1);
	memset((char *)pbs_python_destlib, '\0', MAXPATHLEN+1);

	snprintf(pbs_python_home, MAXPATHLEN, "%s/python",
		pbs_conf.pbs_exec_path);
	snprintf(pbs_python_destlib, MAXPATHLEN, "%s/lib/python/altair",
		pbs_conf.pbs_exec_path);

	Py_NoSiteFlag = 1;
	Py_FrozenFlag = 1;
	Py_OptimizeFlag = 2;            /* TODO make this a compile flag variable */
	Py_IgnoreEnvironmentFlag = 1;   /* ignore PYTHONPATH and PYTHONHOME */
	if (file_exists(pbs_python_home))
		Py_SetPythonHome(pbs_python_home);

	/* we make sure our top level module is initialized */
	if ((PyImport_ExtendInittab(pbs_python_inittab_modules) != 0)) {
		log_err(-1, "PyImport_ExtendInittab",
			"--> Failed to initialize Python interpreter <--");
		return;
	}

	Py_InitializeEx(0);  /* SKIP initialization of signals */

	if (Py_IsInitialized()) {
		snprintf(log_buffer, LOG_BUF_SIZE-1,
			"--> Python Interpreter quick started, compiled with version:'%.*s' <--",
			5, Py_GetVersion());
		log_buffer[LOG_BUF_SIZE-1] = '\0';
		log_event(PBSEVENT_SYSTEM|PBSEVENT_ADMIN |
			PBSEVENT_DEBUG, PBS_EVENTCLASS_SERVER,
			LOG_INFO, func_id, log_buffer);
	} else {
		log_err(-1, "Py_InitializeEx",
			"--> Failed to quick initialize Python interpreter <--");
		goto ERROR_EXIT;
	}
	/*
	 * Add Altair python module directory to sys path. NOTE:
	 *  PBS_PYTHON_MODULE_DIR is a command line define, also insert
	 * standard required python modules
	 */
	if (pbs_python_modify_syspath(pbs_python_destlib, -1) == -1) {
		snprintf(log_buffer, LOG_BUF_SIZE-1,
			"could not insert %s into sys.path shutting down",
			pbs_python_destlib);
		log_buffer[LOG_BUF_SIZE-1] = '\0';
		log_err(-1, func_id, log_buffer);
		goto ERROR_EXIT;
	}

	snprintf(log_buffer, LOG_BUF_SIZE-1,
		"--> Inserted Altair PBS Python modules dir '%s' <--",
		pbs_python_destlib);
	log_buffer[LOG_BUF_SIZE-1] = '\0';
	log_event(PBSEVENT_SYSTEM|PBSEVENT_ADMIN |
		PBSEVENT_DEBUG, PBS_EVENTCLASS_SERVER,
		LOG_INFO, func_id, log_buffer);

	return;

ERROR_EXIT:
	pbs_python_ext_quick_shutdown_interpreter();
	return;
#else   /* !PYTHON */
	log_event(PBSEVENT_SYSTEM|PBSEVENT_ADMIN |
		PBSEVENT_DEBUG, PBS_EVENTCLASS_SERVER,
		LOG_INFO, "start_python",
		"--> Python interpreter not built in <--");
	return;
#endif  /* PYTHON */

}
Example #3
0
/* call BPY_context_set first */
void BPY_python_start(int argc, const char **argv)
{
#ifndef WITH_PYTHON_MODULE
	PyThreadState *py_tstate = NULL;

	/* not essential but nice to set our name */
	static wchar_t program_path_wchar[FILE_MAX]; /* python holds a reference */
	BLI_strncpy_wchar_from_utf8(program_path_wchar, BLI_program_path(), sizeof(program_path_wchar) / sizeof(wchar_t));
	Py_SetProgramName(program_path_wchar);

	/* must run before python initializes */
	PyImport_ExtendInittab(bpy_internal_modules);

	/* allow to use our own included python */
	PyC_SetHomePath(BLI_get_folder(BLENDER_SYSTEM_PYTHON, NULL));

	/* without this the sys.stdout may be set to 'ascii'
	 * (it is on my system at least), where printing unicode values will raise
	 * an error, this is highly annoying, another stumbling block for devs,
	 * so use a more relaxed error handler and enforce utf-8 since the rest of
	 * blender is utf-8 too - campbell */
	BLI_setenv("PYTHONIOENCODING", "utf-8:surrogateescape");

	/* Python 3.2 now looks for '2.xx/python/include/python3.2d/pyconfig.h' to
	 * parse from the 'sysconfig' module which is used by 'site',
	 * so for now disable site. alternatively we could copy the file. */
	Py_NoSiteFlag = 1;

	Py_Initialize();

	// PySys_SetArgv(argc, argv); // broken in py3, not a huge deal
	/* sigh, why do python guys not have a (char **) version anymore? */
	{
		int i;
		PyObject *py_argv = PyList_New(argc);
		for (i = 0; i < argc; i++) {
			/* should fix bug #20021 - utf path name problems, by replacing
			 * PyUnicode_FromString, with this one */
			PyList_SET_ITEM(py_argv, i, PyC_UnicodeFromByte(argv[i]));
		}

		PySys_SetObject("argv", py_argv);
		Py_DECREF(py_argv);
	}
	
	/* Initialize thread support (also acquires lock) */
	PyEval_InitThreads();
#else
	(void)argc;
	(void)argv;

	/* must run before python initializes */
	PyImport_ExtendInittab(bpy_internal_modules);
#endif

	bpy_intern_string_init();

	/* bpy.* and lets us import it */
	BPy_init_modules();

	bpy_import_init(PyEval_GetBuiltins());
	
	pyrna_alloc_types();

#ifndef WITH_PYTHON_MODULE
	/* py module runs atexit when bpy is freed */
	BPY_atexit_register(); /* this can init any time */

	py_tstate = PyGILState_GetThisThreadState();
	PyEval_ReleaseThread(py_tstate);
#endif
}
Example #4
0
void Slave::loadEmbeddedPython()
{
    LOG_5( "Loading Python" );
    /*
     * This structure specifies the names and initialisation functions of
     * the builtin modules.
     */
    struct _inittab builtin_modules[] = {
#ifdef Q_OS_WIN
        {"sip", initsip},
        {"blur.Stone",initStone},
        {"blur.Classes",initClasses},
#endif
        {"blur.Burner", initBurner},
        {NULL, NULL}
    };

    PyImport_ExtendInittab(builtin_modules);

    Py_Initialize();

    const char * builtinModuleImportStr =
#ifdef Q_OS_WIN
        "import imp,sys\n"
        "class MetaLoader(object):\n"
        "\tdef __init__(self):\n"
        "\t\tself.modules = {}\n"

        "\t\tself.modules['blur.Stone'] = imp.load_module('blur.Stone',None,'',('','',imp.C_BUILTIN))\n"
        "\t\tself.modules['blur.Classes'] = imp.load_module('blur.Classes',None,'',('','',imp.C_BUILTIN))\n"

        "\t\tself.modules['blur.Burner'] = imp.load_module('blur.Burner',None,'',('','',imp.C_BUILTIN))\n"
        "\tdef find_module(self,fullname,path=None):\n"
//      "\t\tprint 'MetaLoader.find_module: ', fullname, path\n"
        "\t\tif fullname in self.modules:\n"
        "\t\t\treturn self.modules[fullname]\n"
//      "\t\tprint 'MetaLoader.find_module: Returning None'\n"
        "sys.meta_path.append(MetaLoader())\n"
        "import blur\n"
        "blur.RedirectOutputToLog()\n";
#else
        "import imp,sys\n"
        "class MetaLoader(object):\n"
        "\tdef __init__(self):\n"
        "\t\tself.modules = {}\n"
//  blur.Stone and blur.Classes dynamically loaded
        "\t\tself.modules['blur.Burner'] = imp.load_module('blur.Burner',None,'',('','',imp.C_BUILTIN))\n"
        "\tdef find_module(self,fullname,path=None):\n"
//      "\t\tprint 'MetaLoader.find_module: ', fullname, path\n"
        "\t\tif fullname in self.modules:\n"
        "\t\t\treturn self.modules[fullname]\n"
//      "\t\tprint 'MetaLoader.find_module: Returning None'\n"
        "sys.meta_path.append(MetaLoader())\n"
        "import blur\n"
        "blur.RedirectOutputToLog()\n";
#endif
    PyRun_SimpleString(builtinModuleImportStr);

    LOG_5( "Loading python plugins" );

    QDir plugin_dir( "plugins" );
    QStringList el = plugin_dir.entryList(QStringList() << "*.py" << "*.pys" << "*.pyw", QDir::Files);
    foreach( QString plug, el ) {
        QString name("plugins/" + plug);
        LOG_5( "Loading plugin: " + name );
        QFile f( name );
        f.open( QIODevice::ReadOnly );
        QTextStream ts(&f);
        QString contents = ts.readAll();
        contents.replace("\r","");
        PyRun_SimpleString(contents.toLatin1());
    }
Example #5
0
void loadPythonPlugins()
{
	LOG_5( "Loading Python" );

#ifdef Q_OS_WIN
	/*
	 * This structure specifies the names and initialisation functions of
	 * the builtin modules.
	 */
	struct _inittab builtin_modules[] = {
		{"sip", initsip},
		{"blur.Stone",initStone},
		{"blur.Classes",initClasses},
		{"blur.Stonegui",initStonegui},
		{"blur.Classesui",initClassesui},
		{"blur.Freezer", initFreezer},
		{NULL, NULL}
	};

	PyImport_ExtendInittab(builtin_modules);
#endif
	
	Py_Initialize();

	const char * builtinModuleImportStr = 
#ifdef Q_OS_WIN
		"import imp,sys\n"
		"class MetaLoader(object):\n"
		"\tdef __init__(self):\n"
		"\t\tself.modules = {}\n"

		"\t\tself.modules['blur.Stone'] = imp.load_module('blur.Stone',None,'',('','',imp.C_BUILTIN))\n"
		"\t\tself.modules['blur.Classes'] = imp.load_module('blur.Classes',None,'',('','',imp.C_BUILTIN))\n"
		"\t\tself.modules['blur.Stonegui'] = imp.load_module('blur.Stonegui',None,'',('','',imp.C_BUILTIN))\n"
		"\t\tself.modules['blur.Classesui'] = imp.load_module('blur.Classesui',None,'',('','',imp.C_BUILTIN))\n"
		"\t\tself.modules['blur.absubmit'] = imp.load_module('blur.absubmit',None,'',('','',imp.C_BUILTIN))\n"
		"\t\tself.modules['blur.Freezer'] = imp.load_module('blur.Freezer',None,'',('','',imp.C_BUILTIN))\n"
		"\tdef find_module(self,fullname,path=None):\n"
		"\t\tif fullname in self.modules:\n"
		"\t\t\treturn self.modules[fullname]\n"
		"sys.meta_path.append(MetaLoader())\n"
		"import blur\n"
		"blur.RedirectOutputToLog()\n";
#else
		"import blur\n"
		"blur.RedirectOutputToLog()\n";
#endif
	PyRun_SimpleString(builtinModuleImportStr);

	LOG_5( "Loading python afplugins" );

    PyObject * sys_path = getModuleAttr("sys", "path");

    if (!sys_path) {
        LOG_1( "Python Initialization Failure: Failed to get sys.path" );
        return;
    }

    QString dir = QDir::currentPath();

    // Convert the directory to a Python object with native separators.
#if QT_VERSION >= 0x040200
    dir = QDir::toNativeSeparators(dir);
#else
    dir = QDir::convertSeparators(dir);
#endif

#if PY_MAJOR_VERSION >= 3
    // This is a copy of qpycore_PyObject_FromQString().

    PyObject *dobj = PyUnicode_FromUnicode(0, dir.length());

    if (!dobj)
    {
        PyErr_Print();
        return;
    }

    Py_UNICODE *pyu = PyUnicode_AS_UNICODE(dobj);

    for (int i = 0; i < dir.length(); ++i)
        *pyu++ = dir.at(i).unicode();
#else
        PyObject *dobj = PyString_FromString(dir.toAscii().constData());

        if (!dobj)
        {
            PyErr_Print();
            return;
        }
#endif

    // Add the directory to sys.path.
    int rc = PyList_Append(sys_path, dobj);
    Py_DECREF(dobj);

    if (rc < 0)
    {
        PyErr_Print();
        return;
    }

    PyObject *plug_mod = PyImport_ImportModule("afplugins");
    if (!plug_mod)
    {
        PyErr_Print();
        return;
    }
    Py_DECREF(plug_mod);

    PyEval_SaveThread();
}
Example #6
0
/* call BPY_context_set first */
void BPY_python_start(int argc, const char **argv)
{
#ifndef WITH_PYTHON_MODULE
	PyThreadState *py_tstate = NULL;
	const char *py_path_bundle = BKE_appdir_folder_id(BLENDER_SYSTEM_PYTHON, NULL);

	/* not essential but nice to set our name */
	static wchar_t program_path_wchar[FILE_MAX]; /* python holds a reference */
	BLI_strncpy_wchar_from_utf8(program_path_wchar, BKE_appdir_program_path(), ARRAY_SIZE(program_path_wchar));
	Py_SetProgramName(program_path_wchar);

	/* must run before python initializes */
	PyImport_ExtendInittab(bpy_internal_modules);

	/* allow to use our own included python */
	PyC_SetHomePath(py_path_bundle);

	/* without this the sys.stdout may be set to 'ascii'
	 * (it is on my system at least), where printing unicode values will raise
	 * an error, this is highly annoying, another stumbling block for devs,
	 * so use a more relaxed error handler and enforce utf-8 since the rest of
	 * blender is utf-8 too - campbell */
	Py_SetStandardStreamEncoding("utf-8", "surrogateescape");

	/* Update, Py3.3 resolves attempting to parse non-existing header */
#if 0
	/* Python 3.2 now looks for '2.xx/python/include/python3.2d/pyconfig.h' to
	 * parse from the 'sysconfig' module which is used by 'site',
	 * so for now disable site. alternatively we could copy the file. */
	if (py_path_bundle) {
		Py_NoSiteFlag = 1;
	}
#endif

	Py_FrozenFlag = 1;

	Py_Initialize();

	// PySys_SetArgv(argc, argv);  /* broken in py3, not a huge deal */
	/* sigh, why do python guys not have a (char **) version anymore? */
	{
		int i;
		PyObject *py_argv = PyList_New(argc);
		for (i = 0; i < argc; i++) {
			/* should fix bug #20021 - utf path name problems, by replacing
			 * PyUnicode_FromString, with this one */
			PyList_SET_ITEM(py_argv, i, PyC_UnicodeFromByte(argv[i]));
		}

		PySys_SetObject("argv", py_argv);
		Py_DECREF(py_argv);
	}
	
	/* Initialize thread support (also acquires lock) */
	PyEval_InitThreads();
#else
	(void)argc;
	(void)argv;

	/* must run before python initializes */
	/* broken in py3.3, load explicitly below */
	// PyImport_ExtendInittab(bpy_internal_modules);
#endif

	bpy_intern_string_init();


#ifdef WITH_PYTHON_MODULE
	{
		/* Manually load all modules */
		struct _inittab *inittab_item;
		PyObject *sys_modules = PyImport_GetModuleDict();

		for (inittab_item = bpy_internal_modules; inittab_item->name; inittab_item++) {
			PyObject *mod = inittab_item->initfunc();
			if (mod) {
				PyDict_SetItemString(sys_modules, inittab_item->name, mod);
			}
			else {
				PyErr_Print();
				PyErr_Clear();
			}
			// Py_DECREF(mod); /* ideally would decref, but in this case we never want to free */
		}
	}
#endif

	/* bpy.* and lets us import it */
	BPy_init_modules();

	bpy_import_init(PyEval_GetBuiltins());
	
	pyrna_alloc_types();

#ifndef WITH_PYTHON_MODULE
	/* py module runs atexit when bpy is freed */
	BPY_atexit_register(); /* this can init any time */

	py_tstate = PyGILState_GetThisThreadState();
	PyEval_ReleaseThread(py_tstate);
#endif
}
Example #7
0
int Py_FrozenMain(int argc, char **argv)
#endif
{
    char *p;
    int n, sts = 1;
    int inspect = 0;
    int unbuffered = 0;

#if PY_MAJOR_VERSION >= 3 && !defined(WIN_UNICODE)
    int i;
    char *oldloc;
    wchar_t **argv_copy = NULL;
    /* We need a second copies, as Python might modify the first one. */
    wchar_t **argv_copy2 = NULL;

    if (argc > 0) {
        argv_copy = (wchar_t **)alloca(sizeof(wchar_t *) * argc);
        argv_copy2 = (wchar_t **)alloca(sizeof(wchar_t *) * argc);
    }
#endif

#if defined(MS_WINDOWS) && PY_VERSION_HEX >= 0x03040000 && PY_VERSION_HEX < 0x03060000
    if (!supports_code_page(GetConsoleOutputCP()) ||
        !supports_code_page(GetConsoleCP())) {
      /* Revert to the active codepage, and tell Python to use the 'mbcs'
       * encoding (which always uses the active codepage).  In 99% of cases,
       * this will be the same thing anyway. */
      UINT acp = GetACP();
      SetConsoleCP(acp);
      SetConsoleOutputCP(acp);
      Py_SetStandardStreamEncoding("mbcs", NULL);
    }
#endif

    Py_FrozenFlag = 1; /* Suppress errors from getpath.c */
    Py_NoSiteFlag = 0;
    Py_NoUserSiteDirectory = 1;

    if ((p = Py_GETENV("PYTHONINSPECT")) && *p != '\0')
        inspect = 1;
    if ((p = Py_GETENV("PYTHONUNBUFFERED")) && *p != '\0')
        unbuffered = 1;

    if (unbuffered) {
        setbuf(stdin, (char *)NULL);
        setbuf(stdout, (char *)NULL);
        setbuf(stderr, (char *)NULL);
    }

#if PY_MAJOR_VERSION >= 3 && !defined(WIN_UNICODE)
    oldloc = setlocale(LC_ALL, NULL);
    setlocale(LC_ALL, "");
    for (i = 0; i < argc; i++) {
        argv_copy[i] = Py_DecodeLocale(argv[i], NULL);
        argv_copy2[i] = argv_copy[i];
        if (!argv_copy[i]) {
            fprintf(stderr, "Unable to decode the command line argument #%i\n",
                            i + 1);
            argc = i;
            goto error;
        }
    }
    setlocale(LC_ALL, oldloc);
#endif

#ifdef MS_WINDOWS
    PyImport_ExtendInittab(extensions);
#endif /* MS_WINDOWS */

    if (argc >= 1) {
#if PY_MAJOR_VERSION >= 3 && !defined(WIN_UNICODE)
        Py_SetProgramName(argv_copy[0]);
#else
        Py_SetProgramName(argv[0]);
#endif
    }

    Py_Initialize();
#ifdef MS_WINDOWS
    PyWinFreeze_ExeInit();
#endif

#if defined(MS_WINDOWS) && PY_VERSION_HEX < 0x03040000
    if (!supports_code_page(GetConsoleOutputCP()) ||
        !supports_code_page(GetConsoleCP())) {
      /* Same hack as before except for Python 2.7, which doesn't seem to have
       * a way to set the encoding ahead of time, and setting PYTHONIOENCODING
       * doesn't seem to work.  Fortunately, Python 2.7 doesn't usually start
       * causing codec errors until the first print statement. */
      PyObject *sys_stream;
      UINT acp = GetACP();
      SetConsoleCP(acp);
      SetConsoleOutputCP(acp);

      sys_stream = PySys_GetObject("stdin");
      if (sys_stream && PyFile_Check(sys_stream)) {
        PyFile_SetEncodingAndErrors(sys_stream, "mbcs", NULL);
      }
      sys_stream = PySys_GetObject("stdout");
      if (sys_stream && PyFile_Check(sys_stream)) {
        PyFile_SetEncodingAndErrors(sys_stream, "mbcs", NULL);
      }
      sys_stream = PySys_GetObject("stderr");
      if (sys_stream && PyFile_Check(sys_stream)) {
        PyFile_SetEncodingAndErrors(sys_stream, "mbcs", NULL);
      }
    }
#endif

    if (Py_VerboseFlag)
        fprintf(stderr, "Python %s\n%s\n",
            Py_GetVersion(), Py_GetCopyright());

#if PY_MAJOR_VERSION >= 3 && !defined(WIN_UNICODE)
    PySys_SetArgv(argc, argv_copy);
#else
    PySys_SetArgv(argc, argv);
#endif

#ifdef MACOS_APP_BUNDLE
    // Add the Frameworks directory to sys.path.
    char buffer[PATH_MAX];
    uint32_t bufsize = sizeof(buffer);
    if (_NSGetExecutablePath(buffer, &bufsize) != 0) {
      assert(false);
      return 1;
    }
    char resolved[PATH_MAX];
    if (!realpath(buffer, resolved)) {
      perror("realpath");
      return 1;
    }
    const char *dir = dirname(resolved);
    sprintf(buffer, "%s/../Frameworks", dir);

    PyObject *sys_path = PyList_New(1);
  #if PY_MAJOR_VERSION >= 3
    PyList_SET_ITEM(sys_path, 0, PyUnicode_FromString(buffer));
  #else
    PyList_SET_ITEM(sys_path, 0, PyString_FromString(buffer));
  #endif
    PySys_SetObject("path", sys_path);
    Py_DECREF(sys_path);

    // Now, store a path to the Resources directory into the main_dir pointer,
    // for ConfigPageManager to read out and assign to MAIN_DIR.
    sprintf(buffer, "%s/../Resources", dir);
    set_main_dir(buffer);
#endif

    n = PyImport_ImportFrozenModule("__main__");
    if (n == 0)
        Py_FatalError("__main__ not frozen");
    if (n < 0) {
        PyErr_Print();
        sts = 1;
    }
    else
        sts = 0;

    if (inspect && isatty((int)fileno(stdin)))
        sts = PyRun_AnyFile(stdin, "<stdin>") != 0;

#ifdef MS_WINDOWS
    PyWinFreeze_ExeTerm();
#endif
    Py_Finalize();

#if PY_MAJOR_VERSION >= 3 && !defined(WIN_UNICODE)
error:
    if (argv_copy2) {
        for (i = 0; i < argc; i++) {
#if PY_MINOR_VERSION >= 4
            PyMem_RawFree(argv_copy2[i]);
#else
            PyMem_Free(argv_copy2[i]);
#endif
        }
    }
#endif
    return sts;
}