Skip to content

Instantly share code, notes, and snippets.

@Hoikas
Created May 7, 2011 04:29
Show Gist options
  • Save Hoikas/960200 to your computer and use it in GitHub Desktop.
Save Hoikas/960200 to your computer and use it in GitHub Desktop.
PEP 302 Import Hook for External.Release
/////////////////////////////////////////////////////////////////////////////
// PEP 302 Import Hook
/////////////////////////////////////////////////////////////////////////////
#ifndef BUILDING_PYPLASMA
struct ptImportHook
{
PyObject_HEAD
};
// First three functions are just so I can be lazy
// and use the already existing macros to do my dirty
// work. I'm seriously lazy.
static PyObject* ptImportHook_new(PyTypeObject* type, PyObject* args, PyObject*)
{
ptImportHook* self = (ptImportHook*)type->tp_alloc(type, 0);
return (PyObject*)self;
}
PYTHON_NO_INIT_DEFINITION(ptImportHook)
static void ptImportHook_dealloc(ptImportHook *self)
{
self->ob_type->tp_free((PyObject*)self);
}
PYTHON_METHOD_DEFINITION(ptImportHook, find_module, args)
{
char* module_name;
PyObject* module_path; // Ignored
if (!PyArg_ParseTuple(args, "s|O", &module_name, &module_path))
{
PyErr_SetString(PyExc_TypeError, "find_module expects string, string");
PYTHON_RETURN_ERROR;
}
if (PythonPack::IsItPythonPacked(module_name))
return (PyObject*)self;
else
PYTHON_RETURN_NONE;
}
PYTHON_METHOD_DEFINITION(ptImportHook, load_module, args)
{
char* module_name;
if (!PyArg_ParseTuple(args, "s", &module_name))
{
PyErr_SetString(PyExc_TypeError, "load_module expects string");
PYTHON_RETURN_ERROR;
}
// Grab sys.__dict__ so we can get started
PyObject* sys_mod = PyImport_ImportModule("sys");
PyObject* sys_dict = PyModule_GetDict(sys_mod);
Py_INCREF(sys_dict);
// We want to check sys.modules for the module first
// If it's not in there, we have to load the module
// and add it to the sys.modules dict for future reference,
// otherwise reload() will not work properly.
PyObject* result = nil;
PyObject* modules = PyDict_GetItemString(sys_dict, "modules");
Py_INCREF(modules);
hsAssert(PyDict_Check(modules), "sys.modules is not a dict");
if (result = PyDict_GetItemString(modules, module_name))
{
if (!PyModule_Check(result))
{
hsAssert(false, "PEP 302 hook found module in sys.modules, but it isn't a module! O.o");
result = nil;
PyErr_SetString(PyExc_TypeError, "module in sys.modules isn't a module");
}
}
else
{
if (result = PythonPack::OpenPythonPacked(module_name))
{
PyModule_AddStringConstant(result, "__name__", module_name);
PyModule_AddStringConstant(result, "__file__", module_name);
PyModule_AddObject(result, "__dict__", PyDict_New());
PyDict_SetItemString(modules, module_name, result);
}
else
PyErr_SetString(PyExc_ImportError, "module not found in python.pak");
}
Py_DECREF(modules);
Py_DECREF(sys_dict);
if (result)
return result;
else
PYTHON_RETURN_ERROR;
}
PYTHON_START_METHODS_TABLE(ptImportHook)
PYTHON_METHOD(ptImportHook, find_module, "Params: module_name,package_path\nChecks to see if a given module exists (NOTE: package_path is not used!)"),
PYTHON_METHOD(ptImportHook, load_module, "Params: module_name \\nReturns the module given by module_name, if it exists in python.pak"),
PYTHON_END_METHODS_TABLE;
PYTHON_TYPE_START(ptImportHook)
0,
"Plasma.ptImportHook",
sizeof(ptImportHook), /* tp_basicsize */
0, /* tp_itemsize */
(destructor)ptImportHook_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
0, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
"PEP 302 Import Hook", /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
PYTHON_DEFAULT_METHODS_TABLE(ptImportHook), /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
PYTHON_DEFAULT_INIT(ptImportHook), /* tp_init */
0, /* tp_alloc */
ptImportHook_new /* tp_new */
PYTHON_TYPE_END;
void ptImportHook_AddPlasmaClasses(PyObject* m)
{
PYTHON_CLASS_IMPORT_START(m);
PYTHON_CLASS_IMPORT(m, ptImportHook);
PYTHON_CLASS_IMPORT_END(m);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment