Hi all,
first post here. My name is Angelo and I am the maintainer of STPyV8, a
Google V8 Python wrapper [1].
I already had a private a conversation with Camillo Bruni about this issue
and he suggested me to post details here as I reasonably spotted a bug
in V8 branch 8.7.
While attempting to generate a STPyV8 release for the V8 branch 8.7
(v8.7.220.25), 3 STPyV8 tests failed (see later for details).
While diving into details I noticed that the issue reasonably happens at
In particular I noticed that if STPyV8 is compiled versus V8 <= 8.6 the else
branch is executed. Using V8 8.7 the if branch is executed instead. Which
seems to indicate some changes in IsExternal.
Tried taking a look at the git log and it seems like IsExternal went through
some changes in the 8.7 branch. But, at the same time, it seems like this
just happened for String objects and not for Object objects (double-checked
that in all the three failing tests info.Data() is an object). Camillo confirmed
that changes affected String::IsExternal and not Value::IsExternal.
Spent some time looking at the latest changes (the latest working release
embeds V8 v8.6.395.25) but unfortunately I was not able to figure out which
changes are potentially breaking my code.
I performed another quick and dirty test and built STPyV8 using V8 v8.8.278.3.
And the STPyV8 tests are working fine again. And again the correct if branch
is executed in STPyV8.
I have still not performed tests using a debug build to try to figure out some
potentially additional details but the last test seems to confirm the presence
of a bug in the branch 8.7.
Thanks and regards,
Angelo
---- STPyV8 tests logs ----
============================= test session starts ==============================
platform linux -- Python 3.7.9, pytest-6.0.1, py-1.9.0, pluggy-0.13.1
rootdir: /home/buffer/development/stpyv8
plugins: mock-3.1.1, cov-2.10.1
collected 52 items
tests/test_Context.py .... [ 7%]
tests/test_Engine.py ......... [ 25%]
tests/test_Isolate.py .. [ 28%]
tests/test_Multithread.py .. [ 32%]
tests/test_Wrapper.py ...F.........F....................F [100%]
=================================== FAILURES ===================================
_____________________________ TestWrapper.testCall _____________________________
self = <test_Wrapper.TestWrapper testMethod=testCall>
def testCall(self):
class Hello(object):
def __call__(self, name):
return "hello " + name
class Global(STPyV8.JSClass):
hello = Hello()
with STPyV8.JSContext(Global()) as ctxt:
> self.assertEqual("hello world", ctxt.eval("hello('world')"))
E TypeError: TypeError: 'JSObject' object is not callable ( @ 1 : 0 ) -> hello('world')
tests/test_Wrapper.py:210: TypeError
_______________________ TestWrapper.testGetterAndSetter ________________________
self = <test_Wrapper.TestWrapper testMethod=testGetterAndSetter>
def testGetterAndSetter(self):
class Global(STPyV8.JSClass):
def __init__(self, testval):
self.testval = testval
with STPyV8.JSContext(Global("Test Value A")) as ctxt:
self.assertEqual("Test Value A", ctxt.locals.testval)
ctxt.eval("""
this.__defineGetter__("test", function() {
return this.testval;
});
this.__defineSetter__("test", function(val) {
this.testval = val;
});
""")
> self.assertEqual("Test Value A", ctxt.locals.test)
E AttributeError: '[object Object]' object has no attribute 'test'
tests/test_Wrapper.py:784: AttributeError
____________________________ TestWrapper.testWatch _____________________________
self = <test_Wrapper.TestWrapper testMethod=testWatch>
def testWatch(self):
class Obj(STPyV8.JSClass):
def __init__(self):
self.p = 1
class Global(STPyV8.JSClass):
def __init__(self):
self.o = Obj()
with STPyV8.JSContext(Global()) as ctxt:
ctxt.eval("""
o.watch("p", function (id, oldval, newval) {
return oldval + newval;
});
""")
self.assertEqual(1, ctxt.eval("o.p"))
> ctxt.eval("o.p = 2;")
E TypeError: TypeError: 'Obj' object is not callable ( @ 1 : 4 ) -> o.p = 2;
tests/test_Wrapper.py:876: TypeError
=========================== short test summary info ============================
FAILED tests/test_Wrapper.py::TestWrapper::testCall - TypeError: TypeError: '...
FAILED tests/test_Wrapper.py::TestWrapper::testGetterAndSetter - AttributeErr...
FAILED tests/test_Wrapper.py::TestWrapper::testWatch - TypeError: TypeError: ...
========================= 3 failed, 49 passed in 3.25s =========================