Esempio n. 1
0
PyObject* PyTempleImporter::LoadModule(PyObject* self, PyObject* args) {

	char *fullname;
	if (!PyArg_ParseTuple(args, "s:PyTempleImporter.LoadModule", &fullname))
		return nullptr;

	auto moduleInfo = instance->GetModuleInfo(fullname);
	if (!moduleInfo.found) {
		// If it was found before, why not now?
		return nullptr;
	}

	// Try loading compiled code first
	if (moduleInfo.sourcePath.empty()) {
		throw TempleException("Bytecode not supported yet");
	}
	auto data = ReadData(moduleInfo.sourcePath);
	auto code = Py_CompileString(PyString_AsString(data), moduleInfo.sourcePath.c_str(), Py_file_input);

	if (!code) {
		return nullptr; // Compilation error
	}

	auto module = PyImport_AddModule(fullname);	
	if (!module) {
		Py_DECREF(code);
		return nullptr;
	}

	auto moduleDict = PyModule_GetDict(module);
	if (PyDict_SetItemString(moduleDict, "__loader__", self) != 0) {
		Py_DECREF(code);
		Py_DECREF(module);
		return nullptr;
	}

	if (moduleInfo.package) {
		PyObject *packagePath = PyString_FromString(moduleInfo.packagePath.c_str());
		PyObject *packagePathList = Py_BuildValue("[O]", packagePath);
		Py_DECREF(packagePath);
		if (!packagePathList) {
			Py_DECREF(code);
			Py_DECREF(module);
			return nullptr;
		}
		auto err = PyDict_SetItemString(moduleDict, "__path__", packagePathList);
		Py_DECREF(packagePathList);
		if (err != 0) {
			Py_DECREF(code);
			Py_DECREF(module);
			return nullptr;
		}
	}

	module = PyImport_ExecCodeModuleEx(fullname, code, const_cast<char*>(moduleInfo.sourcePath.c_str()));
	Py_DECREF(code);
	
	return module;
}
Esempio n. 2
0
static PyObject*
load_module(char *name, char *pathname, FILE *fp) {
	PyCodeObject* co = parse_source_module(pathname, fp);
	if (co == NULL)
		return NULL;
	if (Py_VerboseFlag)
		PySys_WriteStderr("import %s # from %s\n",
						  name, pathname);
	PyObject* m = PyImport_ExecCodeModuleEx(name, (PyObject *)co, pathname);
	Py_DECREF(co);
	return m;
}
Esempio n. 3
0
PyObject *
pyotherside_load_module(PyObject *self, PyObject *args) {

    qDebug() << "pyotherside_load_module called";


    char *fullname;
    PyArg_ParseTuple(args, "s", &fullname);
    PyObject *mod, *dict;
    PyObject *module_code;

    QString filename(fullname);

    mod = PyImport_AddModule(fullname);
    if (mod == NULL) {
        qDebug() << "Can't add module " + filename.toUtf8();
        Py_RETURN_NONE;
    }

    module_code = pyotherside_get_code_from_data(filename);
    if (module_code == NULL) {
        qDebug() << "Can't get module code " + filename.toUtf8();
        Py_RETURN_NONE;
    }

    // Set the __loader__ object to pyotherside module
    dict = PyModule_GetDict(mod);
    if (PyDict_SetItemString(dict, "__loader__", (PyObject *)self) != 0) {
        Py_RETURN_NONE;
    }

    mod = PyImport_ExecCodeModuleEx(fullname, module_code, fullname);
    Py_DECREF(module_code);
    Py_DECREF(dict);
    if (Py_VerboseFlag)
        PySys_WriteStderr("import %s # loaded from QRC\n",
                          fullname);

    return mod;
}
Esempio n. 4
0
/* Load and return the module named by 'fullname'. */
static PyObject *
zipimporter_load_module(PyObject *obj, PyObject *args)
{
    ZipImporter *self = (ZipImporter *)obj;
    PyObject *code, *mod, *dict;
    char *fullname, *modpath;
    int ispackage;

    if (!PyArg_ParseTuple(args, "s:zipimporter.load_module",
                          &fullname))
        return NULL;

    code = get_module_code(self, fullname, &ispackage, &modpath);
    if (code == NULL)
        return NULL;

    mod = PyImport_AddModule(fullname);
    if (mod == NULL) {
        Py_DECREF(code);
        return NULL;
    }
    dict = PyModule_GetDict(mod);

    /* mod.__loader__ = self */
    if (PyDict_SetItemString(dict, "__loader__", (PyObject *)self) != 0)
        goto error;

    if (ispackage) {
        /* add __path__ to the module *before* the code gets
           executed */
        PyObject *pkgpath, *fullpath;
        char *prefix = PyString_AsString(self->prefix);
        char *subname = get_subname(fullname);
        int err;

        fullpath = PyString_FromFormat("%s%c%s%s",
                                PyString_AsString(self->archive),
                                SEP,
                                *prefix ? prefix : "",
                                subname);
        if (fullpath == NULL)
            goto error;

        pkgpath = Py_BuildValue("[O]", fullpath);
        Py_DECREF(fullpath);
        if (pkgpath == NULL)
            goto error;
        err = PyDict_SetItemString(dict, "__path__", pkgpath);
        Py_DECREF(pkgpath);
        if (err != 0)
            goto error;
    }
    mod = PyImport_ExecCodeModuleEx(fullname, code, modpath);
    Py_DECREF(code);
    if (Py_VerboseFlag)
        PySys_WriteStderr("import %s # loaded from Zip %s\n",
                          fullname, modpath);
    return mod;
error:
    Py_DECREF(code);
    Py_DECREF(mod);
    return NULL;
}
Esempio n. 5
0
int
main(int argc, char **argv)
{
	int		 ch;
	char		*path;
	char		*buf;
	PyObject	*self, *code, *module;

	log_init(-1);

	while ((ch = getopt(argc, argv, "")) != -1) {
		switch (ch) {
		default:
			log_warnx("warn: filter-python: bad option");
			return (1);
			/* NOTREACHED */
		}
	}
	argc -= optind;
	argv += optind;

	if (argc == 0)
		errx(1, "missing path");
	path = argv[0];

	Py_Initialize();
	self = Py_InitModule("filter", py_methods);
	PyModule_AddIntConstant(self, "FILTER_OK", FILTER_OK);
	PyModule_AddIntConstant(self, "FILTER_FAIL", FILTER_FAIL);
	PyModule_AddIntConstant(self, "FILTER_CLOSE", FILTER_CLOSE);

	buf = loadfile(path);
	code = Py_CompileString(buf, path, Py_file_input);
	free(buf);

	if (code == NULL) {
		PyErr_Print();
		log_warnx("warn: filter-python: failed to compile %s", path);
		return (1);
	}

	module = PyImport_ExecCodeModuleEx("myfilter", code, path);

	if (module == NULL) {
		PyErr_Print();
		log_warnx("warn: filter-python: failed to install module %s", path);
		return (1);
	}

	log_debug("debug: filter-python: starting...");

	filter_api_on_connect(on_connect);

	py_on_connect = PyObject_GetAttrString(module, "on_connect");
	if (py_on_connect && PyCallable_Check(py_on_connect))
		filter_api_on_connect(on_connect);

	py_on_helo = PyObject_GetAttrString(module, "on_helo");
	if (py_on_helo && PyCallable_Check(py_on_helo))
		filter_api_on_helo(on_helo);

	py_on_mail = PyObject_GetAttrString(module, "on_mail");
	if (py_on_mail && PyCallable_Check(py_on_mail))
		filter_api_on_mail(on_mail);

	py_on_rcpt = PyObject_GetAttrString(module, "on_rcpt");
	if (py_on_rcpt && PyCallable_Check(py_on_rcpt))
		filter_api_on_rcpt(on_rcpt);

	py_on_data = PyObject_GetAttrString(module, "on_data");
	if (py_on_data && PyCallable_Check(py_on_data))
		filter_api_on_data(on_data);

	py_on_eom = PyObject_GetAttrString(module, "on_eom");
	if (py_on_eom && PyCallable_Check(py_on_eom))
		filter_api_on_eom(on_eom);

	py_on_commit = PyObject_GetAttrString(module, "on_commit");
	if (py_on_commit && PyCallable_Check(py_on_commit))
		filter_api_on_commit(on_commit);

	py_on_rollback = PyObject_GetAttrString(module, "on_rollback");
	if (py_on_rollback && PyCallable_Check(py_on_rollback))
		filter_api_on_rollback(on_rollback);

	py_on_dataline = PyObject_GetAttrString(module, "on_dataline");
	if (py_on_dataline && PyCallable_Check(py_on_dataline))
		filter_api_on_dataline(on_dataline);

	py_on_disconnect = PyObject_GetAttrString(module, "on_disconnect");
	if (py_on_disconnect && PyCallable_Check(py_on_disconnect))
		filter_api_on_disconnect(on_disconnect);

	filter_api_loop();

	log_debug("debug: filter-python: exiting");
	Py_Finalize();

	return (1);
}
Esempio n. 6
0
int
main(int argc, char **argv)
{
	int ch;
	char *path, *buf;
	PyObject *self, *code, *module;

	log_init(1);

	while ((ch = getopt(argc, argv, "")) != -1) {
		switch (ch) {
		default:
			fatalx("bad option");
			/* NOTREACHED */
		}
	}
	argc -= optind;
	argv += optind;

	if (argc == 0)
		fatalx("missing path");
	path = argv[0];

	Py_Initialize();
	self = Py_InitModule("table", py_methods);

	PyModule_AddIntConstant(self, "K_NONE", K_NONE);
	PyModule_AddIntConstant(self, "K_ALIAS", K_ALIAS);
	PyModule_AddIntConstant(self, "K_DOMAIN", K_DOMAIN);
	PyModule_AddIntConstant(self, "K_CREDENTIALS", K_CREDENTIALS);
	PyModule_AddIntConstant(self, "K_NETADDR", K_NETADDR);
	PyModule_AddIntConstant(self, "K_USERINFO", K_USERINFO);
	PyModule_AddIntConstant(self, "K_SOURCE", K_SOURCE);
	PyModule_AddIntConstant(self, "K_MAILADDR", K_MAILADDR);
	PyModule_AddIntConstant(self, "K_ADDRNAME", K_ADDRNAME);

	buf = loadfile(path);
	code = Py_CompileString(buf, path, Py_file_input);
	free(buf);

	if (code == NULL) {
		PyErr_Print();
		fatalx("failed to compile %s", path);
	}

	module = PyImport_ExecCodeModuleEx("mytable", code, path);

	if (module == NULL) {
		PyErr_Print();
		fatalx("failed to install module %s", path);
	}

	log_debug("debug: starting...");

	py_on_update = PyObject_GetAttrString(module, "table_update");
	py_on_check = PyObject_GetAttrString(module, "table_check");
	py_on_lookup = PyObject_GetAttrString(module, "table_lookup");
	py_on_fetch = PyObject_GetAttrString(module, "table_fetch");

	table_api_on_update(table_python_update);
	table_api_on_check(table_python_check);
	table_api_on_lookup(table_python_lookup);
	table_api_on_fetch(table_python_fetch);

	table_api_dispatch();

	log_debug("debug: exiting");
	Py_Finalize();

	return 1;
}
/*
 * This routine needs to emulate load_source_module in import.c in
 * python, but with DataSectionPtr using FILE*
 * However, we can't get an mTime (there's no interface for it in DataSection)
 * Need to resolve this before we can commit
 */
PyObject* PyResMgrImportLoader::load_source_module( const std::string& name, BinaryPtr py_data, DataSectionPtr pDirectory )
{
    std::string compiledExtension = "pyc";
    if ( Py_OptimizeFlag )
        compiledExtension = "pyo";
    std::string moduleName = name;
    std::string::size_type dotPos = name.rfind( "." );
    if ( dotPos != std::string::npos )
    {
        moduleName = name.substr( dotPos + 1 );
    }

    // Find source (.py) and object (.pyc/.pyo) files to
    // process for this source module or package.
    std::string modulePath;
    bool isPackage = false;
    std::string objectModuleName;
    if ( modules_[ name ].first == PKG_DIRECTORY )
    {
        isPackage = true;
        modulePath = path_ + "/" + moduleName + "/__init__.py";
        objectModuleName = "__init__." + compiledExtension;
    } else {
        modulePath = path_ + "/" + moduleName + ".py";
        objectModuleName = moduleName + "." +  compiledExtension;
    }
    // Remove this from the cache. We have it now, and will feed it to Python.
    // This ensures that a reload() call will work correctly.
    modules_.erase( name );

    // Fetch mtime of py file
    time_t pyModTime = static_cast< time_t >( -1 );
    IFileSystem::FileInfo fInfo;
    IFileSystem::FileType fType =
        BWResource::instance().fileSystem()->getFileType( modulePath, &fInfo );
    if ( fType != IFileSystem::FT_NOT_FOUND )
    {
        pyModTime = fInfo.modified;
    }
    // If possible, palm this off to load_compiled_module
    DataSectionPtr pycSection = pDirectory->openSection( objectModuleName );
    if ( pycSection && check_compiled_module( name, pycSection->asBinary() ))
    {
        if ( check_compiled_module_mtime( name, pycSection->asBinary(), pyModTime ) )
        {
            // We know the module was valid and up-to-date, so trust the loader
            // to either load it or fail noisily
            return load_compiled_module( name, pycSection->asBinary(), true );
        }
    }
    if ( pycSection )
    {
        // Get rid of our reference to the old compiled python file.
        // TODO: Purge this section from the DataSection cache, we're about
        // to replace it on disk
        pycSection = NULL;
    }

    // We got here, the object file for this source either doesn't exist, isn't
    // valid, or isn't as recent as the source.
    // Emulate parse_source_module
    // The code string needs to have (\n) as a line seperator, and needs an EOF
    // (-1) or null termination, and has to end in a newline.
    // Also, need to ensure there's no embedded nulls.
    // So have to make a copy of the string.
    // We shouldn't ever do this in release anyway.
    std::string codeString( py_data->cdata(), py_data->len() );
    if ( codeString.find( '\0' ) != std::string::npos )
    {
        PyErr_Format( PyExc_ImportError,
                      "%s contains an embedded null character",
                      modulePath.c_str()
                    );
        return NULL;
    }
    std::string::size_type winNLpos;
    // Convert any Windows newlines into UNIX newlines
    if ( ( winNLpos = codeString.find( "\r\n", 0 ) ) != std::string::npos )
    {
        do
        {
            codeString.replace( winNLpos, 2, "\n" );
            winNLpos = codeString.find( "\r\n", winNLpos );
        } while ( winNLpos != std::string::npos );
    }
    // Ensure we're newline-terminated
    codeString.append( "\n" );
    PyObject* codeObject = Py_CompileString( codeString.c_str(),
                           const_cast< char* >( modulePath.c_str() ),
                           Py_file_input );
    if ( codeObject == NULL )
        // Compiler didn't like it. Propagate the error up
        return NULL;

    // OK, we have a module, now we just execute it into the correct space.
    // Always call it a .py, even though we've created a .pyc
    PyObject* module = PyImport_ExecCodeModuleEx(
                           const_cast< char* >( name.c_str() ), codeObject,
                           const_cast< char* >( modulePath.c_str() )
                       );

    if ( module == NULL )
    {
        Py_DECREF( codeObject );
        return NULL;
    }

    // It executed OK, so write out an object file for later use, if possible
    // Emulates write_compiled_module( co, cpathname, mtime )
    do {
        PyObject* codeString = PyMarshal_WriteObjectToString( codeObject, Py_MARSHAL_VERSION );
        // XXX: Maybe we should care if _this_ fails, or at least report it?
        if ( codeString == NULL || !PyString_Check( codeString ) )
        {
            PyErr_Clear();
            break;
        }
        char* dataBlock = new char[ PyString_Size( codeString ) + 8 ];
        // XXX: On-disk format is little-endian, we're not checking that here
        reinterpret_cast< uint32* >(dataBlock)[ 0 ] = PyImport_GetMagicNumber();
        reinterpret_cast< int32* >(dataBlock)[ 1 ] = static_cast< int32 >( pyModTime );
        memcpy( dataBlock + 8, PyString_AsString( codeString ), PyString_Size( codeString ) );

        // The following is a little nasty, we end up copying the data a couple of times
        // Wrap dataBlock in a BinaryBlock (which takes a copy of it)
        BinaryPtr pycData = new BinaryBlock( dataBlock,
                                             PyString_Size( codeString ) + 8,
                                             "PyResMgrImportLoader::load_source_module" );
        delete[] dataBlock;
        if ( !pycData )
            break;
        // Save out our new pyc file
        pycSection = pDirectory->openSection( objectModuleName, true, BinSection::creator() );
        if ( !pycSection )
            break;
        pycSection->setBinary( pycData );
        pycSection->save();
    } while( false );

    Py_DECREF( codeObject );

    PyObject *moduleDict = PyModule_GetDict( module );
    if ( moduleDict != NULL )
    {
        int err = PyDict_SetItemString( moduleDict, "__loader__", this );
        if ( err != 0 )
        {
            Py_DECREF( module );
            return NULL;
        }
    }

//	TRACE_MSG( "PyResMgrImportLoader(%s)::load_source_module: loaded %s\n", path_.c_str(),
//		name.c_str() );
    return module;
}
/*
 * This routine needs to emulate load_compiled_module in import.c in
 * python, but with DataSectionPtr using FILE*
 */
PyObject* PyResMgrImportLoader::load_compiled_module( const std::string& name,
        BinaryPtr pyc_data, bool known_valid /* = false */ )
{
    std::string compiledExtension = "pyc";
    if ( Py_OptimizeFlag )
        compiledExtension = "pyo";
    std::string moduleName = name;
    std::string::size_type dotPos = name.rfind( "." );
    if ( dotPos != std::string::npos )
    {
        moduleName = name.substr( dotPos + 1 );
    }

    std::string modulePathStub;
    if ( modules_[ name ].first == PKG_DIRECTORY )
    {
        modulePathStub = path_ + "/" + moduleName + "/__init__";
    }
    else
    {
        modulePathStub = path_ + "/" + moduleName;
    }

    // Remove this from the cache. We have it now, and will feed it to Python.
    // This ensures that a reload() call will work correctly.
    modules_.erase( name );

    if ( !known_valid && !check_compiled_module( name, pyc_data ) )
    {
        PyErr_Format( PyExc_ImportError,
                      "%s.%s is not a valid Python Object file",
                      modulePathStub.c_str(), compiledExtension.c_str()
                    );
        return NULL;
    }

    // The first four bytes are magic
    // the second four are the source modification date
    // This does the same thing as read_compiled_module in import.c
    PyObject* codeObject = PyMarshal_ReadObjectFromString(
                               pyc_data->cdata() + 8, pyc_data->len() - 8 );
    if ( !PyCode_Check( codeObject ) )
    {
        PyErr_Format( PyExc_ImportError,
                      "%s.%s is a non-code object",
                      modulePathStub.c_str(), compiledExtension.c_str()
                    );
        Py_DECREF( codeObject );
        return NULL;
    }
    PyObject* module = PyImport_ExecCodeModuleEx(
                           const_cast< char* >( name.c_str() ), codeObject,
                           const_cast< char* >( ( modulePathStub + compiledExtension ).c_str() )
                       );
    Py_DECREF( codeObject );

    if ( module )
    {
        PyObject *moduleDict = PyModule_GetDict( module );
        int err = PyDict_SetItemString( moduleDict, "__loader__", this );
        if ( err != 0 )
        {
            Py_DECREF( module );
            return NULL;
        }

//		TRACE_MSG( "PyResMgrImportLoader(%s)::load_compiled_module: loaded %s\n",
//			path_.c_str(), name.c_str() );
    }
    return module;
}