@@ -20,7 +20,7 @@ using namespace node;
2020class PythonObject : public ObjectWrap {
2121 PyObject* _object;
2222
23- static Persistent<ObjectTemplate> python_object_template_ ;
23+ static Persistent<FunctionTemplate> python_function_template_ ;
2424 public:
2525 PythonObject (PyObject* obj) : _object(obj) { }
2626 virtual ~PythonObject () {
@@ -31,15 +31,19 @@ class PythonObject : public ObjectWrap {
3131 static void Initialize (Handle<Object> target) {
3232 HandleScope scope;
3333
34- python_object_template_ = Persistent<ObjectTemplate>::New (MakePythonObjectTemplate ());
34+
35+ Local<FunctionTemplate> pytpl = FunctionTemplate::New ();
36+ MakePythonObjectTemplate (pytpl);
37+ python_function_template_ = Persistent<FunctionTemplate>::New (pytpl);
38+
3539 Handle<FunctionTemplate> t = FunctionTemplate::New (New);
3640 target->Set (String::NewSymbol (" import" ), t->GetFunction ());
3741
3842 };
3943
40- static Handle<ObjectTemplate> MakePythonObjectTemplate () {
44+ static Handle<ObjectTemplate> MakePythonObjectTemplate (Local<FunctionTemplate>& t ) {
4145 HandleScope scope;
42- Handle<ObjectTemplate> result = ObjectTemplate::New ();
46+ Handle<ObjectTemplate> result = t-> InstanceTemplate ();
4347 result->SetInternalFieldCount (1 );
4448 result->SetNamedPropertyHandler (MapGet, MapSet);
4549
@@ -53,7 +57,6 @@ class PythonObject : public ObjectWrap {
5357 result->SetCallAsFunctionHandler (Call, Handle<Value>());
5458 // result->SetAccessor(String::New("getAttribute"), get_attribute->GetFunction());
5559 // result->SetAccessor(String::New("CALL_NON_FUNCTION"), call->GetFunction());
56- return scope.Close (result);
5760 };
5861
5962 NODEPY_ACCESSOR (ToString)
@@ -91,14 +94,38 @@ class PythonObject : public ObjectWrap {
9194 };
9295
9396 PyObject* ConvertArgToPyObject (const Handle<Value>& value) {
97+ int len;
9498 if (value->IsString ()) {
9599 return PyString_FromString (*String::Utf8Value (value->ToString ()));
96100 } else if (value->IsNumber ()) {
97101 return PyFloat_FromDouble (value->NumberValue ());
98102 } else if (value->IsObject ()) {
103+ Local<Object> obj = value->ToObject ();
104+ if (!obj->FindInstanceInPrototypeChain (python_function_template_).IsEmpty ()) {
105+ PythonObject* python_object = ObjectWrap::Unwrap<PythonObject>(value->ToObject ());
106+ PyObject* pyobj = python_object->GetValue ();
107+ return pyobj;
108+ } else {
109+ Local<Array> property_names = obj->GetPropertyNames ();
110+ len = property_names->Length ();
111+ PyObject* py_dict = PyDict_New ();
112+ for (int i = 0 ; i < len; ++i) {
113+ Local<String> str = property_names->Get (i)->ToString ();
114+ Local<Value> js_val = obj->Get (str);
115+ PyDict_SetItemString (py_dict, *String::Utf8Value (str), ConvertArgToPyObject (js_val));
116+ }
117+ return py_dict;
118+ }
99119 return NULL ;
100120 } else if (value->IsArray ()) {
101- return NULL ;
121+ Local<Array> array = Array::Cast (*value);
122+ len = array->Length ();
123+ PyObject* py_list = PyList_New (len);
124+ for (int i = 0 ; i < len; ++i) {
125+ Local<Value> js_val = array->Get (i);
126+ PyList_SET_ITEM (py_list, i, ConvertArgToPyObject (js_val));
127+ }
128+ return py_list;
102129 }
103130 return NULL ;
104131 }
@@ -107,20 +134,26 @@ class PythonObject : public ObjectWrap {
107134 HandleScope scope;
108135 int len = args.Length ();
109136 PyObject* py_args_as_list = PyTuple_New (len);
110- std::vector<PyObject*> py_args_to_decref (len);
137+ std::vector<PyObject*> py_args_to_decref (len);
111138 for (int i = 0 ; i < len; ++i) {
112139 PyObject* py_arg_n = ConvertArgToPyObject (args[i]);
113140 PyTuple_SET_ITEM (py_args_as_list, i, py_arg_n);
114141 py_args_to_decref.push_back (py_arg_n);
115142 }
116143 PyObject* py_result = PyObject_CallObject (_object, py_args_as_list);
144+ if (!py_result) {
145+ PyErr_Print ();
146+ return ThrowException (
147+ Exception::TypeError (String::New (" UH OH WILL ROGER" ))
148+ );
149+ }
117150 /* for(std::vector<PyObject*>::iterator i = py_args_to_decref.begin(); i != py_args_to_decref.end(); ++i) {
118151 if(*i != NULL) {
119152 Py_DECREF(*i);
120153 }
121154 }*/
122155
123- Handle<Object> result = python_object_template_ ->NewInstance ();
156+ Handle<Object> result = python_function_template_-> GetFunction () ->NewInstance ();
124157 result->SetInternalField (0 , External::New (new PythonObject (py_result)));
125158 return scope.Close (result);
126159 }
@@ -148,9 +181,9 @@ class PythonObject : public ObjectWrap {
148181 String::Utf8Value utf_module_name (args[0 ]->ToString ());
149182 py_module_name = PyString_FromString (*utf_module_name),
150183 py_module = PyImport_Import (py_module_name);
151- Py_DECREF (py_module_name);
184+ Py_XDECREF (py_module_name);
152185 if (py_module != NULL ) {
153- Handle<Object> result = python_object_template_ ->NewInstance ();
186+ Handle<Object> result = python_function_template_-> GetFunction () ->NewInstance ();
154187 result->SetInternalField (0 , External::New (new PythonObject (py_module)));
155188 return scope.Close (result);
156189 }
@@ -169,7 +202,7 @@ class PythonObject : public ObjectWrap {
169202 PyObject* attr = object->GetAttr (key_string);
170203 Handle<Object> result;
171204 if (attr) {
172- result = python_object_template_ ->NewInstance ();
205+ result = python_function_template_-> GetFunction () ->NewInstance ();
173206 PythonObject* obj_out = new PythonObject (attr);
174207 result->SetInternalField (0 , External::New (obj_out));
175208 return result;
@@ -193,7 +226,7 @@ class PythonObject : public ObjectWrap {
193226 PyObject* attr = object->GetAttr (key_string);
194227 Handle<Object> result;
195228 if (attr) {
196- result = python_object_template_ ->NewInstance ();
229+ result = python_function_template_-> GetFunction () ->NewInstance ();
197230 PythonObject* obj_out = new PythonObject (attr);
198231 result->SetInternalField (0 , External::New (obj_out));
199232 return scope.Close (result);
@@ -212,7 +245,7 @@ class PythonObject : public ObjectWrap {
212245 };
213246};
214247
215- Persistent<ObjectTemplate > PythonObject::python_object_template_ ;
248+ Persistent<FunctionTemplate > PythonObject::python_function_template_ ;
216249
217250static Handle<Value>
218251Shutdown (const Arguments& args) {
0 commit comments