static void py_locals(lua_State *L) { PyObject *locals; if (lua_gettop(L) != 0) { lua_error(L, "invalid arguments"); } locals = PyEval_GetLocals(); if (!locals) { py_globals(L); return; } py_convert_custom(L, locals, 1); }
/** * Returns the locals dictionary **/ static void py_locals(lua_State *L) { PyObject *locals; if (lua_gettop(L) != 0) { lua_error(L, "invalid arguments"); } locals = PyEval_GetLocals(); if (!locals) { py_globals(L); return; } Py_INCREF(locals); push_pyobject_container(L, locals, 1); }
/** * 完成import... **/ PyObject* Ps_Import(PyObject *self, PyObject *args, PyObject *kws) { //struct _ts *state; char *module; char *arglist[] = {"module", 0}; FILE *f; PyObject *m; //PyObject *local = NULL, *global = NULL; if(!PyArg_ParseTupleAndKeywords(args, kws, "s:import", arglist, &module)) { Ps_Log("Import args or kws is faile, function is that ps_import(module)\n", Ps_LOG_WARING); return NULL; } if((f = (open_file(NULL, module))) == NULL) { Ps_LogFormat("Open file %s failed\n", Ps_LOG_WARING, module); goto error; } /*state = PyThreadState_Get(); if(state->frame) { local = state->frame->f_locals; global = state->frame->f_globals; }*/ if((m = __import__(f, module, NULL, NULL, PyEval_GetLocals(), PyEval_GetGlobals())) == NULL) { if(PyErr_Occurred()) { return NULL; } goto error; } Py_INCREF(Py_True); return Py_True; error: PyErr_SetString(PyExc_ImportError, "Import error"); return NULL; }
static PyObject * NA_detailed_repr(SlopNAObject *self) { PyObject* type_repr = PyObject_Repr(self->exc_type); PyObject* value_repr = PyObject_Repr(self->exc_value); PyObject* cur_locals = PyEval_GetLocals(); PyObject* locals_repr = PyObject_Repr(cur_locals); PyObject* repr = PyTuple_Pack(4, type_repr, value_repr, self->exc_traceback_str, locals_repr); PyObject* fmt = PyString_FromString("{NA %s %s\n %s\nLocals: %s\n}"); PyObject* ret = PyString_Format(fmt, repr); Py_DECREF(fmt); Py_DECREF(repr); Py_DECREF(locals_repr); Py_DECREF(value_repr); Py_DECREF(type_repr); return ret; }
PyObject* SlopNA_New(PyObject* exc_type, PyObject* exc_value, PyObject* exc_traceback) { assert(pg_activated); // TODO: use a free list like intobject and friends SlopNAObject* self = (SlopNAObject*)PyObject_MALLOC(sizeof(SlopNAObject)); if (self == NULL) return (PyObject *)PyErr_NoMemory(); PyObject_INIT(self, &SlopNA_Type); // we can directly take these 2 fields, since they're picklable self->exc_type = exc_type; // could be NULL, in which case use Py_None if (exc_value) { self->exc_value = exc_value; } else { self->exc_value = Py_None; } Py_INCREF(self->exc_type); Py_INCREF(self->exc_value); // unfortunately exc_traceback isn't picklable, so we'll need to // call PyTraceBack_Print to print the traceback into a // cStringIO buffer, then convert that to a string if (!PycStringIO) { PycString_IMPORT; // don't repeat imports } PyObject* buf = PycStringIO->NewOutput(128); PyTraceBack_Print(exc_traceback, buf); self->exc_traceback_str = PycStringIO->cgetvalue(buf); Py_DECREF(buf); self->next_NA = NULL; // log this creation event in both verbose and binary logs: // for verbose log: PyObject* repr = NA_detailed_repr(self); PG_LOG(PyString_AsString(repr)); Py_DECREF(repr); // for binary log, each line is: // base64.b64encode(cPickle.dumps(context, -1)) // // where context is a dict with the following fields: // exc_type, exc_value, locals PyObject* context = PyDict_New(); PyObject* type_repr = PyObject_Repr(self->exc_type); PyObject* value_repr = PyObject_Repr(self->exc_value); PyDict_SetItemString(context, "exc_type", type_repr); PyDict_SetItemString(context, "exc_value", value_repr); PyDict_SetItemString(context, "locals", PyEval_GetLocals()); // pass in -1 to force cPickle to use a binary protocol PyObject* negative_one = PyInt_FromLong(-1); PyObject* pickled_context = PyObject_CallFunctionObjArgs(cPickle_dumpstr_func, context, negative_one, NULL); if (!pickled_context) { assert(PyErr_Occurred()); PyErr_Clear(); // hmmm, let's try removing locals and seeing if it's now picklable PyDict_DelItemString(context, "locals"); pickled_context = PyObject_CallFunctionObjArgs(cPickle_dumpstr_func, context, negative_one, NULL); } if (!pickled_context) { assert(PyErr_Occurred()); PyErr_Clear(); fprintf(stderr, "ERROR: pickled_context is unpicklable\n"); Py_Exit(1); } PyObject* encoded_line = PyObject_CallFunctionObjArgs(b64encode_func, pickled_context, NULL); fprintf(binary_log_file, "%s\n", PyString_AsString(encoded_line)); Py_DECREF(encoded_line); Py_DECREF(negative_one); Py_DECREF(context); Py_DECREF(value_repr); Py_DECREF(type_repr); return (PyObject*)self; }
static PyObject* Dispatcher_call(DispatcherObject *self, PyObject *args, PyObject *kws) { PyObject *tmptype, *retval = NULL; int *tys; int argct; int i; int prealloc[24]; int matches; PyObject *cfunc; PyThreadState *ts = PyThreadState_Get(); PyObject *locals = NULL; if (ts->use_tracing && ts->c_profilefunc) locals = PyEval_GetLocals(); if (self->fold_args) { if (find_named_args(self, &args, &kws)) return NULL; } else Py_INCREF(args); /* Now we own a reference to args */ argct = PySequence_Fast_GET_SIZE(args); if (argct < (Py_ssize_t) (sizeof(prealloc) / sizeof(int))) tys = prealloc; else tys = malloc(argct * sizeof(int)); for (i = 0; i < argct; ++i) { tmptype = PySequence_Fast_GET_ITEM(args, i); tys[i] = typeof_typecode((PyObject *) self, tmptype); if (tys[i] == -1) { if (self->can_fallback){ /* We will clear the exception if fallback is allowed. */ PyErr_Clear(); } else { goto CLEANUP; } } } /* If compilation is enabled, ensure that an exact match is found and if * not compile one */ self->exact_match_required |= self->can_compile; /* We only allow unsafe conversions if compilation of new specializations has been disabled. */ cfunc = dispatcher_resolve(self->dispatcher, tys, &matches, !self->can_compile, self->exact_match_required); if (matches == 0 && !self->can_compile) { /* * If we can't compile a new specialization, look for * matching signatures for which conversions haven't been * registered on the C++ TypeManager. */ int res = search_new_conversions((PyObject *) self, args, kws); if (res < 0) { retval = NULL; goto CLEANUP; } if (res > 0) { /* Retry with the newly registered conversions */ cfunc = dispatcher_resolve(self->dispatcher, tys, &matches, !self->can_compile, self->exact_match_required); } } if (matches == 1) { /* Definition is found */ retval = call_cfunc(self, cfunc, args, kws, locals); } else if (matches == 0) { /* No matching definition */ if (self->can_compile) { retval = compile_and_invoke(self, args, kws, locals); } else if (self->fallbackdef) { /* Have object fallback */ retval = call_cfunc(self, self->fallbackdef, args, kws, locals); } else { /* Raise TypeError */ explain_matching_error((PyObject *) self, args, kws); retval = NULL; } } else if (self->can_compile) { /* Ambiguous, but are allowed to compile */ retval = compile_and_invoke(self, args, kws, locals); } else { /* Ambiguous */ explain_ambiguous((PyObject *) self, args, kws); retval = NULL; } CLEANUP: if (tys != prealloc) free(tys); Py_DECREF(args); return retval; }
/*调用这个函数前必须加锁*/ static PyObject* from_web_import_as(char *website, char *module, char *as) { #define Ps_NAME_MAX (sizeof(unsigned int) << 1 + 10) #define WEB_PATH_MAX 1024 char buffer[WEB_PATH_MAX]; char file_name[Ps_NAME_MAX]; /*加载函数的函数指针*/ PyObject* (*loader)(FILE *f, char *name, char *path, char *as, PyObject *local, PyObject *global); FILE *f; PyObject *m; assert(website); assert(module); #if (PLATFORM & WIN32) || (PLATFORM & WIN64) sprintf(file_name, "cache\\%X", file_name_no); #elif (PLATFORM & LINUX32) || (PLATFORM & LINUX64) sprintf(file_name, "cache/%X", file_name_no); #endif #ifdef IMPORT_DEBUG Ps_LogFormat("Creat temp file %s\n", Ps_LOG_NORMAL, file_name); Ps_LogFormat("From %s import %s\n", Ps_LOG_NORMAL, website, module); #endif file_name_no ++; if((f = fopen((char*)file_name, "w")) == NULL) { Ps_Log("Create temp file failed\n", Ps_LOG_WARING); PyErr_SetString(PyExc_ImportError, "Create temp file failed"); return NULL; } /*下载py文件*/ if(!get_url(website, module, FALSE, buffer, WEB_PATH_MAX)) { Ps_Log("Get url failed\n", Ps_LOG_WARING); PyErr_SetString(PyExc_ImportError, "The path to get python module is too long"); return NULL; } loader = __import__; if(!Ps_DownloadTimeout(buffer, f, TIME_OUT)) { Ps_Log("Cannot download %s's py file\n", Ps_LOG_WARING); /*再次尝试下载pyc文件*/ // (void)get_url(website, module, TRUE, buffer, WEB_PATH_MAX); if(!Ps_DownloadTimeout(buffer, f, TIME_OUT)) { Ps_Log("Download pyc file also failed\n", Ps_LOG_WARING); PyErr_Format(PyExc_ImportError, "Cannot download module %s file from %s\n", module, website); return NULL; } /*使用加载pyc文件的加载函数*/ loader = __import__compiled; } /*加载py文件*/ fclose(f); if((f = fopen(file_name, "r")) == NULL) { Ps_Log("Open temp file failed\n", Ps_LOG_WARING); PyErr_SetString(PyExc_ImportError, "open temp file failed"); return NULL; } if(!(m = loader(f, module, NULL, as, PyEval_GetLocals(), PyEval_GetGlobals()))) { fclose(f); return NULL; } #ifdef IMPORT_DEBUG Ps_Log("******************************************", Ps_LOG_NORMAL); Ps_LogObject(m, Ps_LOG_NORMAL); Ps_Log("******************************************", Ps_LOG_NORMAL); #endif Py_INCREF(Py_True); return Py_True; }
PyObject * PyObject_Dir(PyObject *arg) { /* Set exactly one of these non-NULL before the end. */ PyObject *result = NULL; /* result list */ PyObject *masterdict = NULL; /* result is masterdict.keys() */ /* If NULL arg, return the locals. */ if (arg == NULL) { PyObject *locals = PyEval_GetLocals(); if (locals == NULL) goto error; result = PyDict_Keys(locals); if (result == NULL) goto error; } /* Elif this is some form of module, we only want its dict. */ else if (PyModule_Check(arg)) { masterdict = PyObject_GetAttrString(arg, "__dict__"); if (masterdict == NULL) goto error; if (!PyDict_Check(masterdict)) { PyErr_SetString(PyExc_TypeError, "module.__dict__ is not a dictionary"); goto error; } } /* Elif some form of type or class, grab its dict and its bases. We deliberately don't suck up its __class__, as methods belonging to the metaclass would probably be more confusing than helpful. */ else if (PyType_Check(arg) || PyClass_Check(arg)) { masterdict = PyDict_New(); if (masterdict == NULL) goto error; if (merge_class_dict(masterdict, arg) < 0) goto error; } /* Else look at its dict, and the attrs reachable from its class. */ else { PyObject *itsclass; /* Create a dict to start with. CAUTION: Not everything responding to __dict__ returns a dict! */ masterdict = PyObject_GetAttrString(arg, "__dict__"); if (masterdict == NULL) { PyErr_Clear(); masterdict = PyDict_New(); } else if (!PyDict_Check(masterdict)) { Py_DECREF(masterdict); masterdict = PyDict_New(); } else { /* The object may have returned a reference to its dict, so copy it to avoid mutating it. */ PyObject *temp = PyDict_Copy(masterdict); Py_DECREF(masterdict); masterdict = temp; } if (masterdict == NULL) goto error; /* Merge in __members__ and __methods__ (if any). XXX Would like this to go away someday; for now, it's XXX needed to get at im_self etc of method objects. */ if (merge_list_attr(masterdict, arg, "__members__") < 0) goto error; if (merge_list_attr(masterdict, arg, "__methods__") < 0) goto error; /* Merge in attrs reachable from its class. CAUTION: Not all objects have a __class__ attr. */ itsclass = PyObject_GetAttrString(arg, "__class__"); if (itsclass == NULL) PyErr_Clear(); else { int status = merge_class_dict(masterdict, itsclass); Py_DECREF(itsclass); if (status < 0) goto error; } } assert((result == NULL) ^ (masterdict == NULL)); if (masterdict != NULL) { /* The result comes from its keys. */ assert(result == NULL); result = PyDict_Keys(masterdict); if (result == NULL) goto error; } assert(result); if (PyList_Sort(result) != 0) goto error; else goto normal_return; error: Py_XDECREF(result); result = NULL; /* fall through */ normal_return: Py_XDECREF(masterdict); return result; }