node-python
Advanced tools
| language: node_js | ||
| node_js: | ||
| - "0.11" | ||
| - "0.10" | ||
| - "0.8" | ||
| - "0.6" |
| #include <node.h> | ||
| #include <Python.h> | ||
| #include "py_object_wrapper.h" | ||
| #include "utils.h" | ||
| using namespace v8; | ||
| using namespace node; | ||
| using std::string; | ||
| Handle<Value> import(const Arguments& args) { | ||
| HandleScope scope; | ||
| if(args.Length() < 1 || !args[0]->IsString()) { | ||
| return ThrowException( | ||
| Exception::Error(String::New("I don't know how to import that.")) | ||
| ); | ||
| } | ||
| PyObject* module_name = PyString_FromString(*String::Utf8Value(args[0]->ToString())); | ||
| PyObject* module = PyImport_Import(module_name); | ||
| if(!module) { | ||
| return ThrowPythonException(); | ||
| } | ||
| Py_XDECREF(module_name); | ||
| return scope.Close(PyObjectWrapper::New(module)); | ||
| } | ||
| void init (Handle<Object> exports) { | ||
| HandleScope scope; | ||
| Py_Initialize(); | ||
| PyObjectWrapper::Initialize(); | ||
| // module.exports.import | ||
| exports->Set( | ||
| String::NewSymbol("import"), | ||
| FunctionTemplate::New(import)->GetFunction() | ||
| ); | ||
| // module.exports.PyObject | ||
| exports->Set( | ||
| String::NewSymbol("PyObject"), | ||
| PyObjectWrapper::py_function_template->GetFunction() | ||
| ); | ||
| } | ||
| NODE_MODULE(binding, init) |
| #ifndef JS_OBJECT_WRAPPER_H | ||
| #define JS_OBJECT_WRAPPER_H | ||
| class JSObjectWrapper { | ||
| // | ||
| }; | ||
| #endif |
| #include "py_object_wrapper.h" | ||
| #include "utils.h" | ||
| Persistent<FunctionTemplate> PyObjectWrapper::py_function_template; | ||
| void PyObjectWrapper::Initialize() { | ||
| HandleScope scope; | ||
| Local<FunctionTemplate> fn_tpl = FunctionTemplate::New(); | ||
| Local<ObjectTemplate> proto = fn_tpl->PrototypeTemplate(); | ||
| Local<ObjectTemplate> obj_tpl = fn_tpl->InstanceTemplate(); | ||
| obj_tpl->SetInternalFieldCount(1); | ||
| // this has first priority. see if the properties already exist on the python object | ||
| obj_tpl->SetNamedPropertyHandler(Get, Set); | ||
| // If we're calling `toString`, delegate to our version of ToString | ||
| proto->SetAccessor(String::NewSymbol("toString"), ToStringAccessor); | ||
| // likewise for valueOf | ||
| obj_tpl->SetAccessor(String::NewSymbol("valueOf"), ValueOfAccessor); | ||
| // Python objects can be called as functions. | ||
| obj_tpl->SetCallAsFunctionHandler(Call, Handle<Value>()); | ||
| py_function_template = Persistent<FunctionTemplate>::New(fn_tpl); | ||
| } | ||
| Handle<Value> PyObjectWrapper::New(PyObject* obj) { | ||
| HandleScope scope; | ||
| Local<Value> jsVal; | ||
| // undefined | ||
| if(obj == Py_None) { | ||
| jsVal = Local<Value>::New(Undefined()); | ||
| } | ||
| // double | ||
| else if(PyFloat_CheckExact(obj)) { | ||
| double d = PyFloat_AsDouble(obj); | ||
| jsVal = Local<Value>::New(Number::New(d)); | ||
| } | ||
| // integer (can be 64b) | ||
| else if(PyInt_CheckExact(obj)) { | ||
| long i = PyInt_AsLong(obj); | ||
| jsVal = Local<Value>::New(Number::New((double) i)); | ||
| } | ||
| // string | ||
| else if(PyString_CheckExact(obj)) { | ||
| // ref to internal representation: no need to dealloc | ||
| char *str = PyString_AsString(obj); | ||
| if(str) { | ||
| jsVal = Local<Value>::New(String::New(str)); | ||
| } | ||
| } | ||
| else if(PyBool_Check(obj)) { | ||
| int b = PyObject_IsTrue(obj); | ||
| if(b != -1) { | ||
| jsVal = Local<Value>::New(Boolean::New(b)); | ||
| } | ||
| } | ||
| if(PyErr_Occurred()) { | ||
| Py_XDECREF(obj); | ||
| return ThrowPythonException(); | ||
| } | ||
| if(jsVal.IsEmpty()) { | ||
| Local<Object> jsObj = py_function_template->GetFunction()->NewInstance(); | ||
| PyObjectWrapper* wrapper = new PyObjectWrapper(obj); | ||
| wrapper->Wrap(jsObj); | ||
| jsVal = Local<Value>::New(jsObj); | ||
| } | ||
| else { | ||
| Py_XDECREF(obj); | ||
| } | ||
| return scope.Close(jsVal); | ||
| } | ||
| Handle<Value> PyObjectWrapper::Get(Local<String> key, const AccessorInfo& info) { | ||
| // returning an empty Handle<Value> object signals V8 that we didn't | ||
| // find the property here, and we should check the "NamedAccessor" functions | ||
| HandleScope scope; | ||
| PyObjectWrapper* wrapper = ObjectWrap::Unwrap<PyObjectWrapper>(info.Holder()); | ||
| String::Utf8Value utf8_key(key); | ||
| string value(*utf8_key); | ||
| PyObject* result = wrapper->InstanceGet(value); | ||
| if(result) { | ||
| return PyObjectWrapper::New(result); | ||
| } | ||
| return Handle<Value>(); | ||
| } | ||
| Handle<Value> PyObjectWrapper::Set(Local<String> key, Local<Value> value, const AccessorInfo& info) { | ||
| // we don't know what to do. | ||
| return Undefined(); | ||
| } | ||
| Handle<Value> PyObjectWrapper::CallAccessor(Local<String> property, const AccessorInfo& info) { | ||
| HandleScope scope; | ||
| Local<FunctionTemplate> func = FunctionTemplate::New(Call); | ||
| return scope.Close(func->GetFunction()); | ||
| } | ||
| Handle<Value> PyObjectWrapper::ToStringAccessor(Local<String> property, const AccessorInfo& info) { | ||
| HandleScope scope; | ||
| Local<FunctionTemplate> func = FunctionTemplate::New(ToString); | ||
| return scope.Close(func->GetFunction()); | ||
| } | ||
| Handle<Value> PyObjectWrapper::ValueOfAccessor(Local<String> property, const AccessorInfo& info) { | ||
| HandleScope scope; | ||
| Local<FunctionTemplate> func = FunctionTemplate::New(ValueOf); | ||
| return scope.Close(func->GetFunction()); | ||
| } | ||
| Handle<Value> PyObjectWrapper::Call(const Arguments& args) { | ||
| HandleScope scope; | ||
| PyObjectWrapper* pyobjwrap = ObjectWrap::Unwrap<PyObjectWrapper>(args.This()); | ||
| Handle<Value> result = pyobjwrap->InstanceCall(args); | ||
| return scope.Close(result); | ||
| } | ||
| Handle<Value> PyObjectWrapper::ToString(const Arguments& args) { | ||
| HandleScope scope; | ||
| PyObjectWrapper* pyobjwrap = ObjectWrap::Unwrap<PyObjectWrapper>(args.This()); | ||
| Local<String> result = String::New(pyobjwrap->InstanceToString(args).c_str()); | ||
| return scope.Close(result); | ||
| } | ||
| Handle<Value> PyObjectWrapper::ValueOf(const Arguments& args) { | ||
| HandleScope scope; | ||
| PyObjectWrapper* pyobjwrap = ObjectWrap::Unwrap<PyObjectWrapper>(args.This()); | ||
| PyObject* py_obj = pyobjwrap->InstanceGetPyObject(); | ||
| if(PyCallable_Check(py_obj)) { | ||
| Local<FunctionTemplate> call = FunctionTemplate::New(Call); | ||
| return scope.Close(call->GetFunction()); | ||
| } else if (PyNumber_Check(py_obj)) { | ||
| long long_result = PyLong_AsLong(py_obj); | ||
| return scope.Close(Integer::New(long_result)); | ||
| } else if (PySequence_Check(py_obj)) { | ||
| int len = PySequence_Length(py_obj); | ||
| Local<Array> array = Array::New(len); | ||
| for(int i = 0; i < len; ++i) { | ||
| Handle<Object> jsobj = PyObjectWrapper::py_function_template->GetFunction()->NewInstance(); | ||
| PyObject* py_obj_out = PySequence_GetItem(py_obj, i); | ||
| PyObjectWrapper* obj_out = new PyObjectWrapper(py_obj_out); | ||
| obj_out->Wrap(jsobj); | ||
| array->Set(i, jsobj); | ||
| } | ||
| return scope.Close(array); | ||
| } else if (PyMapping_Check(py_obj)) { | ||
| int len = PyMapping_Length(py_obj); | ||
| Local<Object> object = Object::New(); | ||
| PyObject* keys = PyMapping_Keys(py_obj); | ||
| PyObject* values = PyMapping_Values(py_obj); | ||
| for(int i = 0; i < len; ++i) { | ||
| PyObject *key = PySequence_GetItem(keys, i), | ||
| *value = PySequence_GetItem(values, i), | ||
| *key_as_string = PyObject_Str(key); | ||
| char* cstr = PyString_AsString(key_as_string); | ||
| Local<Object> jsobj = PyObjectWrapper::py_function_template->GetFunction()->NewInstance(); | ||
| PyObjectWrapper* obj_out = new PyObjectWrapper(value); | ||
| obj_out->Wrap(jsobj); | ||
| Py_XDECREF(key); | ||
| Py_XDECREF(key_as_string); | ||
| } | ||
| Py_XDECREF(keys); | ||
| Py_XDECREF(values); | ||
| return scope.Close(object); | ||
| } | ||
| return Undefined(); | ||
| } | ||
| PyObject* PyObjectWrapper::ConvertToPython(const Handle<Value>& value) { | ||
| int len; | ||
| HandleScope scope; | ||
| if(value->IsString()) { | ||
| return PyString_FromString(*String::Utf8Value(value->ToString())); | ||
| } else if(value->IsNumber()) { | ||
| return PyFloat_FromDouble(value->NumberValue()); | ||
| } else if(value->IsObject()) { | ||
| Local<Object> obj = value->ToObject(); | ||
| if(!obj->FindInstanceInPrototypeChain(PyObjectWrapper::py_function_template).IsEmpty()) { | ||
| PyObjectWrapper* python_object = ObjectWrap::Unwrap<PyObjectWrapper>(value->ToObject()); | ||
| PyObject* pyobj = python_object->InstanceGetPyObject(); | ||
| return pyobj; | ||
| } else { | ||
| Local<Array> property_names = obj->GetPropertyNames(); | ||
| len = property_names->Length(); | ||
| PyObject* py_dict = PyDict_New(); | ||
| for(int i = 0; i < len; ++i) { | ||
| Local<String> str = property_names->Get(i)->ToString(); | ||
| Local<Value> js_val = obj->Get(str); | ||
| PyDict_SetItemString(py_dict, *String::Utf8Value(str), ConvertToPython(js_val)); | ||
| } | ||
| return py_dict; | ||
| } | ||
| return NULL; | ||
| } else if(value->IsArray()) { | ||
| Local<Array> array = Array::Cast(*value); | ||
| len = array->Length(); | ||
| PyObject* py_list = PyList_New(len); | ||
| for(int i = 0; i < len; ++i) { | ||
| Local<Value> js_val = array->Get(i); | ||
| PyList_SET_ITEM(py_list, i, ConvertToPython(js_val)); | ||
| } | ||
| return py_list; | ||
| } else if(value->IsUndefined()) { | ||
| Py_RETURN_NONE; | ||
| } | ||
| return NULL; | ||
| } | ||
| Handle<Value> PyObjectWrapper::InstanceCall(const Arguments& args) { | ||
| // for now, we don't do anything. | ||
| HandleScope scope; | ||
| int len = args.Length(); | ||
| PyObject* args_tuple = PyTuple_New(len); | ||
| for(int i = 0; i < len; ++i) { | ||
| PyObject* py_arg = ConvertToPython(args[i]); | ||
| PyTuple_SET_ITEM(args_tuple, i, py_arg); | ||
| } | ||
| PyObject* result = PyObject_CallObject(mPyObject, args_tuple); | ||
| Py_XDECREF(args_tuple); | ||
| if(result) { | ||
| return scope.Close(PyObjectWrapper::New(result)); | ||
| } else { | ||
| return ThrowPythonException(); | ||
| } | ||
| } | ||
| string PyObjectWrapper::InstanceToString(const Arguments& args) { | ||
| PyObject* as_string = PyObject_Str(mPyObject); | ||
| string native_string(PyString_AsString(as_string)); | ||
| Py_XDECREF(as_string); | ||
| return native_string; | ||
| } | ||
| PyObject* PyObjectWrapper::InstanceGet(const string& key) { | ||
| if(PyObject_HasAttrString(mPyObject, key.c_str())) { | ||
| PyObject* attribute = PyObject_GetAttrString(mPyObject, key.c_str()); | ||
| return attribute; | ||
| } | ||
| return (PyObject*)NULL; | ||
| } |
| #ifndef PY_OBJECT_WRAPPER_H | ||
| #define PY_OBJECT_WRAPPER_H | ||
| #include <string> | ||
| #include <node.h> | ||
| #include <Python.h> | ||
| #include "utils.h" | ||
| using namespace v8; | ||
| using std::string; | ||
| class PyObjectWrapper : public node::ObjectWrap { | ||
| PyObject* mPyObject; | ||
| public: | ||
| static Persistent<FunctionTemplate> py_function_template; | ||
| PyObjectWrapper(PyObject* obj) : node::ObjectWrap(), mPyObject(obj) {}; | ||
| virtual ~PyObjectWrapper() { | ||
| Py_XDECREF(mPyObject); | ||
| mPyObject = NULL; | ||
| } | ||
| static void Initialize(); | ||
| static Handle<Value> New(PyObject* obj); | ||
| static Handle<Value> New(const Arguments& args); | ||
| static Handle<Value> Get(Local<String> key, const AccessorInfo& info); | ||
| static Handle<Value> Set(Local<String> key, Local<Value> value, const AccessorInfo& info); | ||
| static Handle<Value> CallAccessor(Local<String> property, const AccessorInfo& info); | ||
| static Handle<Value> ToStringAccessor(Local<String> property, const AccessorInfo& info); | ||
| static Handle<Value> ValueOfAccessor(Local<String> property, const AccessorInfo& info); | ||
| static Handle<Value> Call(const Arguments& args); | ||
| static Handle<Value> ToString(const Arguments& args); | ||
| static Handle<Value> ValueOf(const Arguments& args); | ||
| static PyObject* ConvertToPython(const Handle<Value>& value); | ||
| PyObject* InstanceGetPyObject() { | ||
| return mPyObject; | ||
| }; | ||
| Handle<Value> InstanceCall(const Arguments& args); | ||
| string InstanceToString(const Arguments& args); | ||
| PyObject* InstanceGet(const string& key); | ||
| }; | ||
| #endif |
+43
| #include <Python.h> | ||
| #include <pyerrors.h> | ||
| #include "utils.h" | ||
| Handle<Value> ThrowPythonException() { | ||
| PyObject *ptype, *pvalue, *ptraceback; | ||
| PyErr_Fetch(&ptype, &pvalue, &ptraceback); | ||
| // maybe useless to protect against bad use of ThrowPythonException ? | ||
| if(!ptype) { | ||
| return ThrowException( | ||
| Exception::Error(String::New("No exception found")) | ||
| ); | ||
| } | ||
| // handle exception message | ||
| Local<String> msg; | ||
| if(pvalue && PyObject_TypeCheck(pvalue, &PyString_Type)) { | ||
| msg = String::New(PyString_AsString(pvalue)); | ||
| } | ||
| Local<Value> err; | ||
| if(PyErr_GivenExceptionMatches(ptype, PyExc_ReferenceError)) { | ||
| err = Exception::ReferenceError(msg); | ||
| } | ||
| else if(PyErr_GivenExceptionMatches(ptype, PyExc_SyntaxError)) { | ||
| err = Exception::SyntaxError(msg); | ||
| } | ||
| else if(PyErr_GivenExceptionMatches(ptype, PyExc_TypeError)) { | ||
| err = Exception::TypeError(msg); | ||
| } | ||
| else { | ||
| err = Exception::Error(msg); | ||
| } | ||
| // @TODO : handle stacktrace | ||
| Py_XDECREF(ptype); | ||
| Py_XDECREF(pvalue); | ||
| Py_XDECREF(ptraceback); | ||
| return ThrowException(err); | ||
| } |
| #include <v8.h> | ||
| using namespace v8; | ||
| Handle<Value> ThrowPythonException(); |
| require('../index.js'); |
+5
-4
| { | ||
| "name": "node-python", | ||
| "version": "0.0.2", | ||
| "version": "0.0.3", | ||
| "description": "Call python stuff from nodejs", | ||
| "main": "index.js", | ||
| "scripts": { | ||
| "install": "node-gyp rebuild" | ||
| }, | ||
| "repository": { | ||
@@ -13,2 +10,3 @@ "type": "git", | ||
| }, | ||
| "bugs": "https://github.com/JeanSebTr/node-python/issues", | ||
| "keywords": [ | ||
@@ -29,2 +27,5 @@ "python", | ||
| ], | ||
| "scripts": { | ||
| "test": "node test/linker.js" | ||
| }, | ||
| "license": "BSD", | ||
@@ -31,0 +32,0 @@ "gypfile": true, |
+2
-0
@@ -5,2 +5,4 @@ # node-python binding | ||
| [](https://travis-ci.org/JeanSebTr/node-python) | ||
| Forked from [chrisdickinson/node-python](https://github.com/chrisdickinson/node-python) and updated to use node-gyp | ||
@@ -7,0 +9,0 @@ |
-275
| // binding.cc | ||
| #include <v8.h> | ||
| #include <string> | ||
| #include <iostream> | ||
| #define RETURN_NEW_PYOBJ(scope,pyobject) \ | ||
| Local<Object> jsobject = python_function_template_->GetFunction()->NewInstance(); \ | ||
| PyObjectWrapper* py_object_wrapper = new PyObjectWrapper(pyobject); \ | ||
| py_object_wrapper->Wrap(jsobject);\ | ||
| return scope.Close(jsobject); | ||
| using namespace v8; | ||
| using std::string; | ||
| #include <python2.6/Python.h> | ||
| #include <node_object_wrap.h> | ||
| using namespace node; | ||
| class PyObjectWrapper : public ObjectWrap { | ||
| PyObject* mPyObject; | ||
| public: | ||
| static Persistent<FunctionTemplate> python_function_template_; | ||
| PyObjectWrapper(PyObject* obj) : mPyObject(obj), ObjectWrap() { } | ||
| virtual ~PyObjectWrapper() { | ||
| Py_XDECREF(mPyObject); | ||
| mPyObject = NULL; | ||
| } | ||
| static void | ||
| Initialize(Handle<Object> target) { | ||
| HandleScope scope; | ||
| Local<FunctionTemplate> fn_tpl = FunctionTemplate::New(); | ||
| Local<ObjectTemplate> obj_tpl = fn_tpl->InstanceTemplate(); | ||
| obj_tpl->SetInternalFieldCount(1); | ||
| // this has first priority. see if the properties already exist on the python object | ||
| obj_tpl->SetNamedPropertyHandler(Get, Set); | ||
| // If we're calling `toString`, delegate to our version of ToString | ||
| obj_tpl->SetAccessor(String::NewSymbol("toString"), ToStringAccessor); | ||
| // likewise for valueOf | ||
| obj_tpl->SetAccessor(String::NewSymbol("valueOf"), ValueOfAccessor); | ||
| // Python objects can be called as functions. | ||
| obj_tpl->SetCallAsFunctionHandler(Call, Handle<Value>()); | ||
| python_function_template_ = Persistent<FunctionTemplate>::New(fn_tpl); | ||
| // let's also export "import" | ||
| Local<FunctionTemplate> import = FunctionTemplate::New(Import); | ||
| target->Set(String::New("import"), import->GetFunction()); | ||
| }; | ||
| static Handle<Value> | ||
| Get(Local<String> key, const AccessorInfo& info) { | ||
| // returning an empty Handle<Value> object signals V8 that we didn't | ||
| // find the property here, and we should check the "NamedAccessor" functions | ||
| HandleScope scope; | ||
| PyObjectWrapper* wrapper = ObjectWrap::Unwrap<PyObjectWrapper>(info.Holder()); | ||
| String::Utf8Value utf8_key(key); | ||
| string value(*utf8_key); | ||
| PyObject* result = wrapper->InstanceGet(value); | ||
| if(result) { | ||
| RETURN_NEW_PYOBJ(scope, result); | ||
| } | ||
| return Handle<Value>(); | ||
| } | ||
| static Handle<Value> | ||
| Set(Local<String> key, Local<Value> value, const AccessorInfo& info) { | ||
| // we don't know what to do. | ||
| return Undefined(); | ||
| }; | ||
| static Handle<Value> | ||
| CallAccessor(Local<String> property, const AccessorInfo& info) { | ||
| HandleScope scope; | ||
| Local<FunctionTemplate> func = FunctionTemplate::New(Call); | ||
| return scope.Close(func->GetFunction()); | ||
| }; | ||
| static Handle<Value> | ||
| ToStringAccessor(Local<String> property, const AccessorInfo& info) { | ||
| HandleScope scope; | ||
| Local<FunctionTemplate> func = FunctionTemplate::New(ToString); | ||
| return scope.Close(func->GetFunction()); | ||
| }; | ||
| static Handle<Value> | ||
| ValueOfAccessor(Local<String> property, const AccessorInfo& info) { | ||
| HandleScope scope; | ||
| Local<FunctionTemplate> func = FunctionTemplate::New(ValueOf); | ||
| return scope.Close(func->GetFunction()); | ||
| } | ||
| static Handle<Value> | ||
| Call(const Arguments& args) { | ||
| HandleScope scope; | ||
| Local<Object> this_object = args.This(); | ||
| PyObjectWrapper* pyobjwrap = ObjectWrap::Unwrap<PyObjectWrapper>(args.This()); | ||
| Handle<Value> result = pyobjwrap->InstanceCall(args); | ||
| return scope.Close(result); | ||
| } | ||
| static Handle<Value> | ||
| ToString(const Arguments& args) { | ||
| HandleScope scope; | ||
| Local<Object> this_object = args.This(); | ||
| PyObjectWrapper* pyobjwrap = ObjectWrap::Unwrap<PyObjectWrapper>(args.This()); | ||
| Local<String> result = String::New(pyobjwrap->InstanceToString(args).c_str()); | ||
| return scope.Close(result); | ||
| } | ||
| static Handle<Value> ValueOf(const Handle<Object>& obj) { | ||
| }; | ||
| static Handle<Value> | ||
| ValueOf(const Arguments& args) { | ||
| HandleScope scope; | ||
| Local<Object> this_object = args.This(); | ||
| PyObjectWrapper* pyobjwrap = ObjectWrap::Unwrap<PyObjectWrapper>(args.This()); | ||
| PyObject* py_obj = pyobjwrap->InstanceGetPyObject(); | ||
| if(PyCallable_Check(py_obj)) { | ||
| Local<FunctionTemplate> call = FunctionTemplate::New(Call); | ||
| return scope.Close(call->GetFunction()); | ||
| } else if (PyNumber_Check(py_obj)) { | ||
| long long_result = PyLong_AsLong(py_obj); | ||
| return scope.Close(Integer::New(long_result)); | ||
| } else if (PySequence_Check(py_obj)) { | ||
| int len = PySequence_Length(py_obj); | ||
| Local<Array> array = Array::New(len); | ||
| for(int i = 0; i < len; ++i) { | ||
| Handle<Object> jsobj = python_function_template_->GetFunction()->NewInstance(); | ||
| PyObject* py_obj_out = PySequence_GetItem(py_obj, i); | ||
| PyObjectWrapper* obj_out = new PyObjectWrapper(py_obj_out); | ||
| obj_out->Wrap(jsobj); | ||
| array->Set(i, jsobj); | ||
| } | ||
| return scope.Close(array); | ||
| } else if (PyMapping_Check(py_obj)) { | ||
| int len = PyMapping_Length(py_obj); | ||
| Local<Object> object = Object::New(); | ||
| PyObject* keys = PyMapping_Keys(py_obj); | ||
| PyObject* values = PyMapping_Values(py_obj); | ||
| for(int i = 0; i < len; ++i) { | ||
| PyObject *key = PySequence_GetItem(keys, i), | ||
| *value = PySequence_GetItem(values, i), | ||
| *key_as_string = PyObject_Str(key); | ||
| char* cstr = PyString_AsString(key_as_string); | ||
| Local<Object> jsobj = python_function_template_->GetFunction()->NewInstance(); | ||
| PyObjectWrapper* obj_out = new PyObjectWrapper(value); | ||
| obj_out->Wrap(jsobj); | ||
| Py_XDECREF(key); | ||
| Py_XDECREF(key_as_string); | ||
| } | ||
| Py_XDECREF(keys); | ||
| Py_XDECREF(values); | ||
| return scope.Close(object); | ||
| } | ||
| return Undefined(); | ||
| } | ||
| static Handle<Value> | ||
| Import(const Arguments& args) { | ||
| HandleScope scope; | ||
| if(args.Length() < 1 || !args[0]->IsString()) { | ||
| return ThrowException( | ||
| Exception::Error(String::New("I don't know how to import that.")) | ||
| ); | ||
| } | ||
| PyObject* module_name = PyString_FromString(*String::Utf8Value(args[0]->ToString())); | ||
| PyObject* module = PyImport_Import(module_name); | ||
| Py_XDECREF(module_name); | ||
| PyObjectWrapper* pyobject_wrapper = new PyObjectWrapper(module); | ||
| RETURN_NEW_PYOBJ(scope, module); | ||
| } | ||
| static PyObject* | ||
| ConvertToPython(const Handle<Value>& value) { | ||
| int len; | ||
| HandleScope scope; | ||
| if(value->IsString()) { | ||
| return PyString_FromString(*String::Utf8Value(value->ToString())); | ||
| } else if(value->IsNumber()) { | ||
| return PyFloat_FromDouble(value->NumberValue()); | ||
| } else if(value->IsObject()) { | ||
| Local<Object> obj = value->ToObject(); | ||
| if(!obj->FindInstanceInPrototypeChain(python_function_template_).IsEmpty()) { | ||
| PyObjectWrapper* python_object = ObjectWrap::Unwrap<PyObjectWrapper>(value->ToObject()); | ||
| PyObject* pyobj = python_object->InstanceGetPyObject(); | ||
| return pyobj; | ||
| } else { | ||
| Local<Array> property_names = obj->GetPropertyNames(); | ||
| len = property_names->Length(); | ||
| PyObject* py_dict = PyDict_New(); | ||
| for(int i = 0; i < len; ++i) { | ||
| Local<String> str = property_names->Get(i)->ToString(); | ||
| Local<Value> js_val = obj->Get(str); | ||
| PyDict_SetItemString(py_dict, *String::Utf8Value(str), ConvertToPython(js_val)); | ||
| } | ||
| return py_dict; | ||
| } | ||
| return NULL; | ||
| } else if(value->IsArray()) { | ||
| Local<Array> array = Array::Cast(*value); | ||
| len = array->Length(); | ||
| PyObject* py_list = PyList_New(len); | ||
| for(int i = 0; i < len; ++i) { | ||
| Local<Value> js_val = array->Get(i); | ||
| PyList_SET_ITEM(py_list, i, ConvertToPython(js_val)); | ||
| } | ||
| return py_list; | ||
| } else if(value->IsUndefined()) { | ||
| Py_INCREF(Py_None); | ||
| return Py_None; | ||
| } | ||
| return NULL; | ||
| } | ||
| PyObject* | ||
| InstanceGetPyObject() { | ||
| return mPyObject; | ||
| } | ||
| Handle<Value> InstanceCall(const Arguments& args) { | ||
| // for now, we don't do anything. | ||
| HandleScope scope; | ||
| int len = args.Length(); | ||
| PyObject* args_tuple = PyTuple_New(len); | ||
| for(int i = 0; i < len; ++i) { | ||
| PyObject* py_arg = ConvertToPython(args[i]); | ||
| PyTuple_SET_ITEM(args_tuple, i, py_arg); | ||
| } | ||
| PyObject* result = PyObject_CallObject(mPyObject, args_tuple); | ||
| Py_XDECREF(args_tuple); | ||
| if(!result) { | ||
| PyErr_Clear(); | ||
| return ThrowException( | ||
| Exception::Error( | ||
| String::New("Python exception") | ||
| ) | ||
| ); | ||
| } else { | ||
| RETURN_NEW_PYOBJ(scope, result); | ||
| } | ||
| return Undefined(); | ||
| } | ||
| string InstanceToString(const Arguments& args) { | ||
| PyObject* as_string = PyObject_Str(mPyObject); | ||
| string native_string(PyString_AsString(as_string)); | ||
| Py_XDECREF(as_string); | ||
| return native_string; | ||
| } | ||
| PyObject* InstanceGet(const string& key) { | ||
| if(PyObject_HasAttrString(mPyObject, key.c_str())) { | ||
| PyObject* attribute = PyObject_GetAttrString(mPyObject, key.c_str()); | ||
| return attribute; | ||
| } | ||
| return (PyObject*)NULL; | ||
| } | ||
| }; | ||
| Persistent<FunctionTemplate> PyObjectWrapper::python_function_template_; | ||
| // all v8 plugins must emit | ||
| // a "init" function | ||
| extern "C" void | ||
| init (Handle<Object> target) { | ||
| HandleScope scope; | ||
| Py_Initialize(); | ||
| PyObjectWrapper::Initialize(target); | ||
| } | ||
-62
| var sys = require('sys'), | ||
| puts = sys.puts, | ||
| binding = require('./binding'), | ||
| path_additions = require('./path_additions'), | ||
| http = require('http'), | ||
| url = require('url'), | ||
| stdin = process.openStdin(); | ||
| var sys = binding.import('sys'); | ||
| var os = binding.import('os'); | ||
| os.environ.update({ | ||
| 'DJANGO_SETTINGS_MODULE':'project.development', | ||
| }); | ||
| /* | ||
| var gary_busey = binding.import("gary_busey"); | ||
| var result = gary_busey.say_hey("man i suck"); | ||
| */ | ||
| var django_wsgi = binding.import('django.core.handlers.wsgi'); | ||
| var wsgi_handler = django_wsgi.WSGIHandler() | ||
| wsgi_handler.load_middleware(); | ||
| var server = http.createServer(function (req, res) { | ||
| var path_and_query = url.parse(req.url); | ||
| if(!path_and_query.pathname.match(/^\/media/)) { | ||
| var wsgi_request = django_wsgi.WSGIRequest({ | ||
| 'PATH_INFO':path_and_query.pathname, | ||
| 'QUERY_STRING':path_and_query.query, | ||
| 'HTTP_VERSION':req.httpVersion, | ||
| 'HTTP_ACCEPT':req.headers['http-accept'], | ||
| 'HTTP_ACCEPT_CHARSET':req.headers['http-accept-charset'], | ||
| 'HTTP_ACCEPT_ENCODING':req.headers['http-accept-encoding'], | ||
| 'HTTP_ACCEPT_LANGUAGE':req.headers['http-accept-language'], | ||
| 'HTTP_CACHE_CONTROL':req.headers['http-cache-control'], | ||
| 'REQUEST_METHOD':req.method, | ||
| 'HTTP_HOST':req.headers['http-host'] | ||
| }); | ||
| var response = wsgi_handler.get_response(wsgi_request), | ||
| headers = response._headers.valueOf(), | ||
| content = response.content.toString(), | ||
| headers_out = {}, | ||
| status_code = response.status_code.valueOf(); | ||
| for(var i in headers) { | ||
| var as_array = headers[i].valueOf(); | ||
| headers_out[as_array[0]] = as_array[1].toString(); | ||
| }; | ||
| res.writeHead(status_code, headers_out); | ||
| res.write(content); | ||
| res.end(); | ||
| } else { | ||
| res.writeHead(200, {"Content-Type":"text/html"}); | ||
| res.write("<h1>sorry, no images.</h1>"); | ||
| res.end(); | ||
| } | ||
| }).listen(8000); | ||
| process.addListener('SIGINT', function () { | ||
| server.close(); | ||
| puts("Shutting down..."); | ||
| }); |
Sorry, the diff of this file is not supported yet
Trivial Package
Supply chain riskPackages less than 10 lines of code are easily copied into your own project and may not warrant the additional supply chain risk of an external dependency.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
No bug tracker
MaintenancePackage does not have a linked bug tracker in package.json.
Found 1 instance in 1 package
18195
2.49%14
75%53
3.92%2
-96.49%