/* -*- C -*- */ /* vim: set expandtab shiftwidth=4 softtabstop=4 cinoptions='\:2=2': */ #include "EXTERN.h" #include "perl.h" #include "XSUB.h" #include "Python.h" #include "py2pl.h" #include "util.h" #ifdef EXPOSE_PERL #include "perlmodule.h" #endif /* To save a little time, I check the calling context and don't convert * the arguments if I'm in void context, flatten lists in list context, * and return only one element in scalar context. * * If this turns out to be a bad idea, it's easy enough to turn off. */ #define CHECK_CONTEXT #ifdef CREATE_PYTHON void do_pyinit() { #ifdef EXPOSE_PERL PyObject *main_dict; PyObject *perl_obj; PyObject *dummy1; PyObject *dummy2; #endif /* sometimes Python needs to know about argc and argv to be happy */ int _python_argc = 1; #if PY_MAJOR_VERSION >= 3 wchar_t *_python_argv[] = {L"python",}; #else char *_python_argv[] = {"python",}; #endif #if PY_VERSION_HEX < 0x03080000 Py_SetProgramName(_python_argv[0]); Py_Initialize(); PySys_SetArgv(_python_argc, _python_argv); /* Tk needs this */ #else PyConfig config; PyConfig_InitPythonConfig(&config); PyConfig_SetString(&config, &config.program_name, _python_argv[0]); PyConfig_SetArgv(&config, _python_argc, _python_argv); Py_InitializeFromConfig(&config); PyConfig_Clear(&config); #endif #ifdef EXPOSE_PERL #if PY_MAJOR_VERSION >= 3 dummy1 = PyBytes_FromString(""), dummy2 = PyBytes_FromString("main"); #else dummy1 = PyString_FromString(""), dummy2 = PyString_FromString("main"); #endif /* create the perl module and add functions */ initperl(); /* now -- create the main 'perl' object and add it to the dictionary. */ perl_obj = newPerlPkg_object(dummy1, dummy2); main_dict = PyModule_GetDict(PyImport_AddModule("__main__")); PyDict_SetItemString(main_dict, "perl", perl_obj); Py_DECREF(perl_obj); Py_DECREF(dummy1); Py_DECREF(dummy2); #endif } #endif MODULE = Inline::Python PACKAGE = Inline::Python BOOT: #ifndef PERL_USE_SAFE_PUTENV PL_use_safe_putenv = 1; #endif py_true = perl_get_sv("Inline::Python::Boolean::true", FALSE); py_false = perl_get_sv("Inline::Python::Boolean::false", FALSE); #ifdef CREATE_PYTHON do_pyinit(); #endif PROTOTYPES: DISABLE void py_initialize() CODE: do_pyinit(); void py_study_package(PYPKG="__main__") char* PYPKG PREINIT: PyObject *mod; PyObject *dict; PyObject *keys; int len; int i; AV* const functions = newAV(); HV* const classes = newHV(); PPCODE: mod = PyImport_AddModule(PYPKG); dict = PyModule_GetDict(mod); keys = PyMapping_Keys(dict); len = PyObject_Length(dict); Printf(("py_study_package: dict length: %i\n", len)); for (i=0; i= 3 PyObject* bytes_key = PyUnicode_AsUTF8String(key); char * const key_c_str = PyBytes_AsString(bytes_key); printf("py_study_package: #%i (%s) callable\n", i, key_c_str); Py_DECREF(bytes_key); #else printf("py_study_package: #%i (%s) callable\n", i, PyString_AsString(key)); #endif printf("val:\n\t"); PyObject_Print(val, stdout, Py_PRINT_RAW); printf("\n"); printf("object type check gives: %i\n", PyType_Check(val)); #endif if (PyFunction_Check(val)) { #if PY_MAJOR_VERSION >= 3 PyObject* bytes_key = PyUnicode_AsUTF8String(key); char * const name = PyBytes_AsString(bytes_key); #else char * const name = PyString_AsString(key); #endif Printf(("Found a function: %s\n", name)); av_push(functions, newSVpv(name,0)); #if PY_MAJOR_VERSION >= 3 Py_DECREF(bytes_key); #endif } /* elw: if we just could get it to go through here! */ else if (PyType_Check(val) || PyClass_Check(val)) { #if PY_MAJOR_VERSION >= 3 PyObject* bytes_key = PyUnicode_AsUTF8String(key); char * const name = PyBytes_AsString(bytes_key); // In P3.4, __loader__ mapping is not easy to handle... Skip for now if(strcmp(name, "__loader__") == 0) continue; #else char * const name = PyString_AsString(key); #endif PyObject * const cls_dict = PyObject_GetAttrString(val,"__dict__"); PyObject * const cls_keys = PyMapping_Keys(cls_dict); int const dict_len = PyObject_Length(cls_dict); int j; /* array of method names */ AV * const methods = newAV(); Printf(("Found a class: %s\n", name)); /* populate the array */ for (j=0; j= 3 PyObject* bytes_cls_key = PyUnicode_AsUTF8String(cls_key); char * const fname = PyBytes_AsString(bytes_cls_key); #else char * const fname = PyString_AsString(cls_key); #endif if (PyFunction_Check(cls_val)) { Printf(("Found a method of %s: %s\n", name, fname)); av_push(methods,newSVpv(fname,0)); } else { Printf(("not a method %s: %s\n", name, fname)); } #if PY_MAJOR_VERSION >= 3 Py_DECREF(bytes_cls_key); #endif } #if PY_MAJOR_VERSION >= 3 Py_DECREF(bytes_key); #endif hv_store(classes,name,strlen(name),newRV_noinc((SV*)methods), 0); } } } /* return an expanded hash */ XPUSHs(newSVpv("functions",0)); XPUSHs(newRV_noinc((SV*)functions)); XPUSHs(newSVpv("classes", 0)); XPUSHs(newRV_noinc((SV*)classes)); void py_eval(str, type=1) char *str int type PREINIT: PyObject *main_module; PyObject *globals; PyObject *locals; PyObject *py_result; int context; SV* ret = NULL; PPCODE: Printf(("py_eval: code: %s\n", str)); /* doc: if the module wasn't already loaded, you will get an empty * module object. */ main_module = PyImport_AddModule("__main__"); if(main_module == NULL) { croak("Error -- Import_AddModule of __main__ failed"); } Printf(("py_eval: main_module=%p\n", main_module)); globals = PyModule_GetDict(main_module); Printf(("py_eval: globals=%p\n", globals)); locals = globals; context = (type == 0) ? Py_eval_input : (type == 1) ? Py_file_input : Py_single_input; Printf(("py_eval: type=%i\n", type)); Printf(("py_eval: context=%i\n", context)); py_result = PyRun_String(str, context, globals, locals); if (!py_result) { PyErr_Print(); croak("Error -- py_eval raised an exception"); XSRETURN_EMPTY; } ret = Py2Pl(py_result); if (! sv_isobject(ret)) sv_2mortal(ret); /* if ret is an object, this already gets done by the following line */ Py_DECREF(py_result); if (type == 0) XPUSHs(ret); else XSRETURN_EMPTY; #undef NUM_FIXED_ARGS #define NUM_FIXED_ARGS 2 void py_call_function(PYPKG, FNAME, ...) char* PYPKG; char* FNAME; PREINIT: int i; PyObject * const mod = PyImport_AddModule(PYPKG); PyObject * const dict = PyModule_GetDict(mod); PyObject * const func = PyMapping_GetItemString(dict,FNAME); PyObject *o = NULL; PyObject *py_retval = NULL; PyObject *tuple = NULL; SV* ret = NULL; PPCODE: Printf(("py_call_function\n")); Printf(("package: %s\n", PYPKG)); Printf(("function: %s\n", FNAME)); if (!PyCallable_Check(func)) { croak("'%s' is not a callable object", FNAME); XSRETURN_EMPTY; } Printf(("function '%s' is callable!\n", FNAME)); tuple = PyTuple_New(items-NUM_FIXED_ARGS); for (i=NUM_FIXED_ARGS; i