brython-dev / brython

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

Issue with jinja 2 potentially #1411

Closed ghost closed 4 years ago

ghost commented 4 years ago

I saw another issue about flask and jinja problems. I am not entirely sure what is happening but I get an error about recursion keeps happening with end. I am pretty sure my Brython code is correct. The only thing I can think of is that on page load brython interferes with jinja somehow. I get an error about recursion, and it lists plotly.js in the message as well. However, I have another working page with both plotly and brython that does not use jinja. I am not entirely sure what is going on.

PierreQuentel commented 4 years ago

@Frick-David It's hard to tell without an example of code that doesn't work. Could you create such example, if necessary as a temporary Github project ?

ghost commented 4 years ago

I actually am not sure it is jinja. It might just be plotly. I get an error about too much recursion Has anyone else made an issue about this source of thing? I have looked over the code quite and bit and see no errors. I believe calling the plotly library using window.Plotly.newplot(...) causes this. Unsure of why.

ghost commented 4 years ago

@PierreQuentel so the issue was this.

Using Plotly I could pass the list of a python dict like so

# Python
py_data = {
    'x' : [1,2,3,4]
}

# pass to javascript
js_data = JSON.parse({{py_data}})
layout = {
    x : js_data['x']
}

With brython, if I just translate the code like so:

py_data = {
    'x' : [1,2,3,4]
}

# pass to brython
by_data = window.SON.parse({{py_data}})
layout = {
    'x' : by_data['x']
}

# Error

I get an error about too much recursion I have to explicitly convert the js_data to a list like so:

py_data = {
    'x' : [1,2,3,4]
}

# pass to javascript
by_data = window.SON.parse({{py_data}})
layout = {
    'x' : list(by_data['x'])
}

When I inspect the error data in the second code block, it shows what should be the list as a dict, where one key/value pair is the data, and a bunch of other data stuff ( I am assuming so brython can work) has been tacked on.) To me, the issue is not that I have to explicitly convert it to a list but rather that the error message gives no indication of what went wrong.

PierreQuentel commented 4 years ago

I would really like to help or find if there is an issue, but with the code in your post it's not possible to reproduce it:

Can you provide an example where the bug can be reproduced ?

ghost commented 4 years ago

So here is a complete, rough example. Will be checking for typos and otherwise.

My structure is:

brython-project
  -- run.py
  -- templates
     -- index.html

where run.py is:

from flask import Flask, render_template,json

app = Flask(__name__)

@app.route('/')
def index():
    py_data = {
        "x": [3,6,9,12],
        "y": [5,10,15,20]
    }
    return render_template('index.html', data=json.dumps(py_data))

if __name__ == '__main__':
    app.run()

and index.html is:

<!doctype html>
<html>

<head>
    <meta charset="utf-8">
    <script type="text/javascript"
        src="https://cdn.jsdelivr.net/npm/brython@3.8.9/brython.min.js">
    </script>
    <script src='https://cdn.plot.ly/plotly-latest.min.js'></script></head>

<body onload="brython()">

<div id="bar-chart-div"> </div>

<script type="text/python">
from browser import document, window

plotly = window.Plotly
br_data = window.JSON.parse({{data | tojson}})

bar_chart_data = [
  {
    "x": list(br_data["x"]),
    "y": list(br_data["y"]),
    "type": "bar"
  }
]
plotly.newPlot("bar-chart-div", bar_chart_data)

</script>

</body>

</html>

This is following a simple Flask app and a simple Plotly graph found here. https://plotly.com/javascript/bar-charts/

My issue is that it seems Brython is quite to throw out a too much recursion issue whereas Javascript would say 'this is mispelledorthis variable is not defined` or some other general error.

And I reran the code and then it worked. I only deleted the plotly = window.Plotly line. So I am not sure why it spits out too much recursion somethings and then works other times. Very odd. Let me know what you think. Sorry for the typos above, I typed in in Github rather than an editor. This sort of error seems to pop up a lot for me and my team when we code. and It occurs for misspellings or not forcing a type such as the list(), whereas regualr python would accept it.

The above example gets that same recusion error if I do not use list(), so it seems multiple types of errors want to throw the recursion error which can be very frustrating.

PierreQuentel commented 4 years ago

I tried the example and everything worked as expected:

issue1411

Can you copy the complete error traceback ?

ghost commented 4 years ago

So taking out the forcing of the data to be a list(), gives me

Javascript error InternalError: too much recursion
    clean https://cdn.plot.ly/plotly-latest.min.js:61
     ...
test is js exc is recursion error InternalError: too much recursion
    clean https://cdn.plot.ly/plotly-latest.min.js:61
    ... 
InternalError: too much recursion

handle error 
Object { __class__: {…}, __mro__: (4) […], "$is_class": true, "$infos": {…}, "$factory": $factory()
, __module__: "builtins" }

Array [ "too much recursion" ]
brython.js:5380:8
Traceback (most recent call last):
RecursionError: too much recursion

where the clean plotly statement is repeated a couple hundred times. Like I said, I have run into this same error for a misspelling and for something like this. If it helps, I am running firefox as well. I do not know if that could cause something as well.

Is it not downloading the plotly.js file? I have no idea what is going on with it at this point tbh.

PierreQuentel commented 4 years ago

I see. You posted a code that works, and the issue happens if you replace list(br_data["x"]) by just br_data["x"], right ?

For unrelated reasons, I have modified the interface with Javascript objects used inside Brython programs, such as the one returned by

br_data = window.JSON.parse({{data | tojson}})

You can test your code with the latest development version, by replacing

    <script type="text/javascript"
        src="https://cdn.jsdelivr.net/npm/brython@3.8.9/brython.min.js">

by

    <script type="text/javascript" 
        src="https://raw.githack.com/brython-dev/brython/master/www/src/brython.js">
    </script>

On my PC the program works with or without the call to list(). Can you confirm ?

ghost commented 4 years ago

It does indeed work. Thanks! You can go ahead and close this issue if you like