From a84653affe200c2f8d222a56006eeeab16c7c29f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Calixte?= Date: Thu, 6 Dec 2018 12:27:25 -0500 Subject: [PATCH] Module imports --- import.go | 141 ++++++++++++++++++++++++++++++++++++++++ import_test.go | 172 +++++++++++++++++++++++++++++++++++++++++++++++++ module.go | 61 ++++++++++++++++++ 3 files changed, 374 insertions(+) create mode 100644 import.go create mode 100644 import_test.go create mode 100644 module.go diff --git a/import.go b/import.go new file mode 100644 index 0000000..b7faed8 --- /dev/null +++ b/import.go @@ -0,0 +1,141 @@ +package python3 + +/* +#include "Python.h" +*/ +import "C" + +import ( + "unsafe" +) + +//PyImport_ImportModule : https://docs.python.org/3/c-api/import.html#c.PyImport_ImportModule +func PyImport_ImportModule(name string) *PyObject { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + + return togo(C.PyImport_ImportModule(cname)) +} + +//PyImport_ImportModuleEx : https://docs.python.org/3/c-api/import.html#c.PyImport_ImportModuleEx +func PyImport_ImportModuleEx(name string, globals, locals, fromlist *PyObject) *PyObject { + return PyImport_ImportModuleLevel(name, globals, locals, fromlist, 0) +} + +//PyImport_ImportModuleLevelObject : https://docs.python.org/3/c-api/import.html#c.PyImport_ImportModuleLevelObject +func PyImport_ImportModuleLevelObject(name, globals, locals, fromlist *PyObject, level int) *PyObject { + return togo(C.PyImport_ImportModuleLevelObject(toc(name), toc(globals), toc(locals), toc(fromlist), C.int(level))) +} + +//PyImport_ImportModuleLevel : https://docs.python.org/3/c-api/import.html#c.PyImport_ImportModuleLevel +func PyImport_ImportModuleLevel(name string, globals, locals, fromlist *PyObject, level int) *PyObject { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + + return togo(C.PyImport_ImportModuleLevel(cname, toc(globals), toc(locals), toc(fromlist), C.int(level))) +} + +//PyImport_Import : https://docs.python.org/3/c-api/import.html#c.PyImport_Import +func PyImport_Import(name *PyObject) *PyObject { + return togo(C.PyImport_Import(toc(name))) +} + +//PyImport_ReloadModule : https://docs.python.org/3/c-api/import.html#c.PyImport_ReloadModule +func PyImport_ReloadModule(name *PyObject) *PyObject { + return togo(C.PyImport_ReloadModule(toc(name))) +} + +//PyImport_AddModuleObject : https://docs.python.org/3/c-api/import.html#c.PyImport_AddModuleObject +func PyImport_AddModuleObject(name *PyObject) *PyObject { + return togo(C.PyImport_AddModuleObject(toc(name))) +} + +//PyImport_AddModule : https://docs.python.org/3/c-api/import.html#c.PyImport_AddModule +func PyImport_AddModule(name string) *PyObject { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + + return togo(C.PyImport_AddModule(cname)) +} + +//PyImport_ExecCodeModule : https://docs.python.org/3/c-api/import.html#c.PyImport_ExecCodeModule +func PyImport_ExecCodeModule(name string, co *PyObject) *PyObject { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + + return togo(C.PyImport_ExecCodeModule(cname, toc(co))) +} + +//PyImport_ExecCodeModuleEx : https://docs.python.org/3/c-api/import.html#c.PyImport_ExecCodeModuleEx +func PyImport_ExecCodeModuleEx(name string, co *PyObject, pathname string) *PyObject { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + + cpathname := C.CString(pathname) + defer C.free(unsafe.Pointer(cpathname)) + + return togo(C.PyImport_ExecCodeModuleEx(cname, toc(co), cpathname)) +} + +//PyImport_ExecCodeModuleObject : https://docs.python.org/3/c-api/import.html#c.PyImport_ExecCodeModuleObject +func PyImport_ExecCodeModuleObject(name, co, pathname, cpathname *PyObject) *PyObject { + return togo(C.PyImport_ExecCodeModuleObject(toc(name), toc(co), toc(pathname), toc(cpathname))) +} + +//PyImport_ExecCodeModuleWithPathnames : https://docs.python.org/3/c-api/import.html#c.PyImport_ExecCodeModuleWithPathnames +func PyImport_ExecCodeModuleWithPathnames(name string, co *PyObject, pathname string, cpathname string) *PyObject { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + + cspathname := C.CString(pathname) + defer C.free(unsafe.Pointer(cspathname)) + + ccpathname := C.CString(cpathname) + defer C.free(unsafe.Pointer(ccpathname)) + + return togo(C.PyImport_ExecCodeModuleWithPathnames(cname, toc(co), cspathname, ccpathname)) +} + +//PyImport_GetMagicNumber : https://docs.python.org/3/c-api/import.html#c.PyImport_GetMagicNumber +func PyImport_GetMagicNumber() int { + return int(C.PyImport_GetMagicNumber()) +} + +//PyImport_GetMagicTag : https://docs.python.org/3/c-api/import.html#c.PyImport_GetMagicTag +func PyImport_GetMagicTag() string { + cmagicTag := C.PyImport_GetMagicTag() + + return C.GoString(cmagicTag) +} + +//PyImport_GetModuleDict : https://docs.python.org/3/c-api/import.html#c.PyImport_GetModuleDict +func PyImport_GetModuleDict() *PyObject { + return togo(C.PyImport_GetModuleDict()) +} + +//PyImport_GetModule : https://docs.python.org/3/c-api/import.html#c.PyImport_GetModule +func PyImport_GetModule(name *PyObject) *PyObject { + return togo(C.PyImport_GetModule(toc(name))) + +} + +//PyImport_GetImporter : https://docs.python.org/3/c-api/import.html#c.PyImport_GetImporter +func PyImport_GetImporter(path *PyObject) *PyObject { + return togo(C.PyImport_GetImporter(toc(path))) + +} + +//PyImport_ImportFrozenModuleObject : https://docs.python.org/3/c-api/import.html#c.PyImport_ImportFrozenModuleObject +func PyImport_ImportFrozenModuleObject(name *PyObject) int { + return int(C.PyImport_ImportFrozenModuleObject(toc(name))) + +} + +//PyImport_ImportFrozenModule : https://docs.python.org/3/c-api/import.html#c.PyImport_ImportFrozenModule +func PyImport_ImportFrozenModule(name string) int { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + + return int(C.PyImport_ImportFrozenModule(cname)) + +} diff --git a/import_test.go b/import_test.go new file mode 100644 index 0000000..d09ccc9 --- /dev/null +++ b/import_test.go @@ -0,0 +1,172 @@ +package python3 + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestImportModule(t *testing.T) { + Py_Initialize() + + os := PyImport_ImportModule("os") + assert.NotNil(t, os) + os.DecRef() +} + +func TestImportModuleEx(t *testing.T) { + Py_Initialize() + + test := PyImport_ImportModuleEx("test", nil, nil, nil) + assert.NotNil(t, test) + test.DecRef() +} + +func TestImportModuleLevelObject(t *testing.T) { + Py_Initialize() + + mathName := PyUnicode_FromString("math") + defer mathName.DecRef() + + math := PyImport_ImportModuleLevelObject(mathName, nil, nil, nil, 0) + assert.NotNil(t, math) + math.DecRef() +} + +func TestImportModuleLevel(t *testing.T) { + Py_Initialize() + + sys := PyImport_ImportModuleLevel("sys", nil, nil, nil, 0) + assert.NotNil(t, sys) + sys.DecRef() +} + +func TestImportImport(t *testing.T) { + Py_Initialize() + + platformName := PyUnicode_FromString("platform") + defer platformName.DecRef() + + platform := PyImport_Import(platformName) + assert.NotNil(t, platform) + platform.DecRef() +} + +func TestReloadModule(t *testing.T) { + Py_Initialize() + + os := PyImport_ImportModule("os") + assert.NotNil(t, os) + defer os.DecRef() + + newOs := PyImport_ReloadModule(os) + assert.NotNil(t, newOs) + defer newOs.DecRef() + + // PyImport_ReloadModule return a new reference, pointer should be the same + assert.Equal(t, os, newOs) +} + +func TestAddModuleObject(t *testing.T) { + Py_Initialize() + + os := PyImport_ImportModule("os") + assert.NotNil(t, os) + defer os.DecRef() + + pyName := PyUnicode_FromString("os.new") + defer pyName.DecRef() + + new := PyImport_AddModuleObject(pyName) + assert.NotNil(t, new) +} + +func TestAddModule(t *testing.T) { + Py_Initialize() + + os := PyImport_ImportModule("os") + assert.NotNil(t, os) + defer os.DecRef() + + new := PyImport_AddModule("os.new") + assert.NotNil(t, new) +} + +func TestExecCodeModule(t *testing.T) { + Py_Initialize() + + // fake module + source := PyUnicode_FromString("__version__ = '2.0'") + defer source.DecRef() + filename := PyUnicode_FromString("test_module.py") + defer filename.DecRef() + mode := PyUnicode_FromString("exec") + defer mode.DecRef() + + // perform module load + builtins := PyEval_GetBuiltins() + assert.True(t, PyDict_Check(builtins)) + + compile := PyDict_GetItemString(builtins, "compile") + assert.True(t, PyCallable_Check(compile)) + + code := compile.CallFunctionObjArgs(source, filename, mode) + assert.NotNil(t, code) + defer code.DecRef() + + module := PyImport_ExecCodeModule("test_module", code) + assert.NotNil(t, module) + +} + +func TestGetMagicNumber(t *testing.T) { + Py_Initialize() + + magicNumber := PyImport_GetMagicNumber() + assert.NotNil(t, magicNumber) +} + +func TestGetMagicTag(t *testing.T) { + Py_Initialize() + + magicTag := PyImport_GetMagicTag() + assert.NotNil(t, magicTag) +} + +func TestGetModuleDict(t *testing.T) { + Py_Initialize() + + moduleDict := PyImport_GetModuleDict() + defer moduleDict.DecRef() + + assert.True(t, PyDict_Check(moduleDict)) + +} + +func TestGetModule(t *testing.T) { + Py_Initialize() + + os := PyImport_ImportModule("os") + assert.NotNil(t, os) + defer os.DecRef() + + name := PyUnicode_FromString("os") + defer name.DecRef() + + new := PyImport_GetModule(name) + assert.Equal(t, new, os) +} + +func TestGetImporter(t *testing.T) { + Py_Initialize() + + paths := PySys_GetObject("path") + path := PyList_GetItem(paths, 0) + + assert.NotNil(t, path) + importer := PyImport_GetImporter(path) + defer importer.DecRef() + + assert.NotNil(t, importer) + +} diff --git a/module.go b/module.go new file mode 100644 index 0000000..3c74d48 --- /dev/null +++ b/module.go @@ -0,0 +1,61 @@ +package python3 + +/* +#include "Python.h" +#include "macro.h" +#include "type.h" +*/ +import "C" +import "unsafe" + +//Module : https://docs.python.org/3/c-api/module.html#c.PyModule_Type +var Module = togo(C._go_PyModule_Type) + +//PyModule_Check : https://docs.python.org/3/c-api/module.html#c.PyModule_Check +func PyModule_Check(p *PyObject) bool { + return C._go_PyModule_Check(toc(p)) != 0 +} + +//PyModule_CheckExact : https://docs.python.org/3/c-api/module.html#c.PyModule_CheckExact +func PyModule_CheckExact(p *PyObject) bool { + return C._go_PyModule_CheckExact(toc(p)) != 0 +} + +//PyModule_NewObject : https://docs.python.org/3/c-api/module.html#c.PyModule_NewObject +func PyModule_NewObject(name *PyObject) *PyObject { + return togo(C.PyModule_NewObject(toc(name))) +} + +//PyModule_New : https://docs.python.org/3/c-api/module.html#c.PyModule_New +func PyModule_New(name string) *PyObject { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + + return togo(C.PyModule_New(cname)) +} + +//PyModule_GetDict : https://docs.python.org/3/c-api/module.html#c.PyModule_GetDict +func PyModule_GetDict(module *PyObject) *PyObject { + return togo(C.PyModule_GetDict(toc(module))) +} + +//PyModule_GetNameObject : https://docs.python.org/3/c-api/module.html#c.PyModule_GetNameObject +func PyModule_GetNameObject(module *PyObject) *PyObject { + return togo(C.PyModule_GetNameObject(toc(module))) +} + +//PyModule_GetName : https://docs.python.org/3/c-api/module.html#c.PyModule_GetName +func PyModule_GetName(module *PyObject) string { + cname := C.PyModule_GetName(toc(module)) + return C.GoString(cname) +} + +//PyModule_GetState : https://docs.python.org/3/c-api/module.html#c.PyModule_GetState +func PyModule_GetState(module *PyObject) unsafe.Pointer { + return unsafe.Pointer(C.PyModule_GetNameObject(toc(module))) +} + +//PyModule_GetFilenameObject : https://docs.python.org/3/c-api/module.html#c.PyModule_GetFilenameObject +func PyModule_GetFilenameObject(module *PyObject) *PyObject { + return togo(C.PyModule_GetFilenameObject(toc(module))) +}