JavaScript library-related issue "AttributeError: 'Javascript Promise' object has no attribute..."
tjnaughton opened this issue · comments
Hi,
There seems to be a regression using some JavaScript libraries, or at least the specific JavaScript library GSAP I've tried. For example, with a html file containing something like this
<head>
<meta charset="utf-8">
<script src="https://cdn.jsdelivr.net/npm/gsap@3.12.5/dist/gsap.min.js"></script>
<script src="brython.js"></script>
<script src="brython_stdlib.js"></script>
</head>
<body onload="brython({debug: 1, cache: false})">
<script type='text/python' src='test.py'></script>
<div id='div_id'>
<img id='image' src='image.svg'>
</div>
</body>
</html>
and a test.py
with something like this
from browser import document, window
gsap = window.gsap
tl = gsap.timeline({'defaults': {'duration': 1, 'ease': 'sine.inOut'}})
tl.to(document['image'], {'x': 100})
the image is animated.
The code above works with release Brython-3.12.1 (#45b714b 2023-11-27) and earlier, but raises the exception below with the development version from earlier today #be12eec, but also with the development version from a month ago #2bf694b (2024-02-10).
brython.js:10958 Traceback (most recent call last):
File "test.py", line 26, in <module>
tl.to(document['image'], {'x': 100})
^^^^^
AttributeError: 'Javascript Promise' object has no attribute 'to'
Thank you!
Hey @tjnaughton!
I think it might be related to commit #25e0317, since timeline objects support the Thenable interface [1]. [2]
I'll take a look at it.
As I said, timeline objects have support for the Thenable interface, so you could change your code like this:
<html>
<head>
<meta charset="utf-8">
<script src="https://cdn.jsdelivr.net/npm/gsap@3.12.5/dist/gsap.min.js"></script>
<script type="text/javascript"
src="https://cdn.jsdelivr.net/npm/brython@3.12/brython.min.js">
</script>
<script type="text/javascript"
src="https://cdn.jsdelivr.net/npm/brython@3.12/brython_stdlib.js">
</script>
</head>
<body onload="brython({debug: 1, cache: false})">
<script type='text/python'>
from browser import document, window, aio
async def main():
gsap = window.gsap
tl = await gsap.timeline({'defaults': {'duration': 1, 'ease': 'sine.inOut'}})
tl.to(document['image'], {'x': 100})
aio.run(main())
</script>
<div id='div_id'>
<img id='image' src='https://upload.wikimedia.org/wikipedia/commons/1/14/Animated_PNG_example_bouncing_beach_ball.png'>
</div>
</body>
</html>
Thanks for reporting this!
Looks like I introduced the bug some time ago while fixing another bug. Sorry about that! 🙈
The latest development snapshot should fix the problem, and both ways should work now, as you can see in the following example:
<html>
<head>
<meta charset="utf-8">
<script src="https://cdn.jsdelivr.net/npm/gsap@3.12.5/dist/gsap.min.js"></script>
<script src="https://raw.githack.com/brython-dev/brython/master/www/src/brython.js"
crossorigin="anonymous">
</script>
<script src="https://raw.githack.com/brython-dev/brython/master/www/src/brython_stdlib.js"
crossorigin="anonymous">
</script>
</head>
<body onload="brython({debug: 1, cache: false})">
<script type='text/python'>
from browser import document, window, aio
async def main():
tl = await gsap.timeline({'defaults': {'duration': 1, 'ease': 'sine.inOut'}})
tl.to(document['image2'], {'x': 100})
gsap = window.gsap
aio.run(main())
tl = gsap.timeline({'defaults': {'duration': 1, 'ease': 'sine.inOut'}})
tl.to(document['image1'], {'x': 250})
</script>
<div id='div_id'>
<img id='image1' src='https://upload.wikimedia.org/wikipedia/commons/1/14/Animated_PNG_example_bouncing_beach_ball.png'>
<img id='image2' src='https://upload.wikimedia.org/wikipedia/commons/1/14/Animated_PNG_example_bouncing_beach_ball.png'>
</div>
</body>
</html>
I will write a test for this to make sure it does not happen again.
Good night!
That's great, thanks so much for such a quick reaction. Brython makes it so convenient to use existing JavaScript libraries, and using syntax that's basically identical to that in the documentation of those libraries. Amazing!