RoamUniverse / pyv8

Automatically exported from code.google.com/p/pyv8
0 stars 0 forks source link

Error while converting JSObject to python's dict #28

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
SVN r201, V8 2.0.5.4 static, python 2.6.2 on ubuntu jaunty

-begin script-
import PyV8

class Global(PyV8.JSClass):
    pass

script = """
({
    'abla': function(){
        return  {
            '1': 'abla',
            '2': 'ajkss',
        }
    }
})
"""

with PyV8.JSContext(Global()) as ctxt:
    obj = ctxt.eval(script)
    print PyV8.convert(obj.abla())
-end script-

gauss@pmain:~/Projects/pyv8test$ ./helloworld.py
Traceback (most recent call last):
  File "./helloworld.py", line 20, in <module>
    print PyV8.convert(obj.abla())
  File "/usr/local/lib/python2.6/dist-packages/PyV8.py", line 433, in 
convert
    return dict([[k, convert(obj.__getattr__(k))] for k in 
obj.__members__])
Boost.Python.ArgumentError: Python argument types in
    JSObject.__getattr__(JSObject, int)
did not match C++ signature:
    __getattr__(CJavascriptObject {lvalue}, std::string)

Original issue reported on code.google.com by gauss...@gmail.com on 12 Jan 2010 at 6:07

GoogleCodeExporter commented 9 years ago
Looks like it's a type conversion problem. If key in returned object is not a 
number - 
no exception raised.

Original comment by gauss...@gmail.com on 12 Jan 2010 at 6:24

GoogleCodeExporter commented 9 years ago

Original comment by flier...@gmail.com on 13 Jan 2010 at 9:23

GoogleCodeExporter commented 9 years ago
The root cause is that Javascript will performs automatic type conversion as 
needed. 
It means, the object that you return will contain two number key, when PyV8 
fetch the 
key with "for k in obj.__members__", the key '1' will return as number 1, and 
the 
convert function will use number 1 as key to call obj.__getattr__ will cause 
the 
crash.

So, one workaround is to force convert function use string as key, like

def convert(obj):    
    if type(obj) == _PyV8.JSArray:
        return [convert(v) for v in obj]

    if type(obj) == _PyV8.JSObject:
        return dict([[str(k), convert(obj.__getattr__(str(k)))] for k in 
obj.__members__])

    return obj

and wait v8 API to provide full supports, because it only support the string 
version 
Object::Has method

  // TODO(1245389): Replace the type-specific versions of these
  // functions with generic ones that accept a Handle<Value> key.
  bool Has(Handle<String> key);

Please check verify the code from SVN after r204, Thanks

Original comment by flier...@gmail.com on 13 Jan 2010 at 10:18

GoogleCodeExporter commented 9 years ago
It's ok now, thank you.

Original comment by gauss...@gmail.com on 13 Jan 2010 at 9:32

GoogleCodeExporter commented 9 years ago
Thanks

Original comment by flier...@gmail.com on 14 Jan 2010 at 2:14