brython-dev / brython

Brython (Browser Python) is an implementation of Python 3 running in the browser
BSD 3-Clause "New" or "Revised" License
6.36k stars 507 forks source link

Brython not playing well with Opal. #1336

Closed dkgof closed 4 years ago

dkgof commented 4 years ago

I am trying to get Opal (Ruby for JS) to play well with Brython.

But for some reason if Opal is loaded before Brython, and i then try to import datetime, i get an error.

If i remove the script that loads Opal, the error goes away again.

Minimal example that has the error:

<!doctype html>
<html>
  <head>
    <script src="https://cdn.opalrb.com/opal/1.0.0/opal.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/brython@3.8.8/brython.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/brython@3.8.8/brython_stdlib.js"></script>
  </head>
  <body onload="brython(1)">
    <script type="text/python">
    import datetime
    </script>
  </body>
</html>

The error is:

Javascript exception: TypeError: Cannot read property 'length' of undefined
    at Object.$B.$getattr (brython.js:6908)
    at _is_dst3982 (eval at exec_module (brython.js:9272), <anonymous>:428:91)
    at eval (eval at exec_module (brython.js:9272), <anonymous>:733:65)
    at exec_module (brython.js:9272)
    at t (brython.js:6570)
    at s (brython.js:6574)
    at Object.e.import_hooks (brython.js:13989)
    at $B.$__import__ (brython.js:9428)
    at Object.$B.$import (brython.js:9472)
    at eval (eval at exec_module (brython.js:9272), <anonymous>:16:8)
PierreQuentel commented 4 years ago

@dkgof Interesting !

In Brython, the class of an object is usually determined by its attribute __class__ but, for a reason that I don't remember, the attribute $class was used instead for a particular class (module), so this attribute $class was tested in the function that gets an object's class.

Unfortunately, it seems that Opal sets an attribute $class to Javascript's Date objects...

In the commit referenced above I have removed the use of $class in Brython, and your code now works. I leave the issue open for the moment, in case you find other incompatibilities.

dkgof commented 4 years ago

Thanks alot for the quick fix!

I will be sure to come back with any other incompatibilities i find :)

dkgof commented 4 years ago

Found another one, if i add the Opal-Parser module, it again gives me an error:

<!doctype html>
<html>
<head>
<script src="https://cdn.opalrb.com/opal/1.0.0/opal.min.js"></script>
<script src="https://cdn.opalrb.com/opal/1.0.0/opal-parser.min.js" onload="Opal.load('opal-parser')"></script>

<script src="brython.js"></script>
<script src="brython_stdlib.js"></script>
</head>
<body onload="brython(1)">
<script type="text/python">
import datetime
</script>
</body>
</html>

The error is:

ValueError: argument of long_int must be a string, not function

brython.js:5368 Uncaught Error
    at Object._b_.ValueError.$factory (eval at $make_exc (brython.js:7897), <anonymous>:171:322)
    at Object.long_int.$factory (brython.js:10699)
    at int.__mul__ (brython.js:10050)
    at Object.$B.rich_op (brython.js:6455)
    at eval (eval at exec_module (brython.js:9284), <anonymous>:735:35)
    at exec_module (brython.js:9284)
    at f (brython.js:6581)
    at method (brython.js:6585)
    at Object.import_hooks (brython.js:14042)
    at $B.$__import__ (brython.js:9440)
PierreQuentel commented 4 years ago

The latest commit changes an internal attribute $value used by Brython for instances of subclasses of int or float to a more specific $brython_value. Opal apparently sets the attribute $value for numbers, which caused the incompatibility.

dkgof commented 4 years ago

Cool, works great now!