Coder Social home page Coder Social logo

piotrdabkowski / js2py Goto Github PK

View Code? Open in Web Editor NEW
2.4K 2.4K 257.0 6.13 MB

JavaScript to Python Translator & JavaScript interpreter written in 100% pure Python🚀 Try it online:

Home Page: http://piter.io/projects/js2py

License: MIT License

Python 34.88% JavaScript 65.11% Shell 0.01% Dockerfile 0.01%

js2py's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

js2py's Issues

Using JS libraries with DOM object dependencies fails

I'm trying to use Leaflet so I can use it thus:

import urllib, js2py
x = urllib.urlopen("http://cdn.leafletjs.com/leaflet/v0.7.7/leaflet-src.js")
js = js2py.EvalJs()
js.execute(x.read())
script = """
function convert(lat, lng) {
  var latlng = L.latLng(lat, lng);
  var map = L.map('map');
  var point = map.project(latlng, 12).round();
  return point;
}"""
js.convert(52.7, 156.4)

The result is a "PyJsException: ReferenceError: L is not defined" error.

I believe it's due to the DOM dependancies (window and document) of the Leaflet library:

/*
 Leaflet, a JavaScript library for mobile-friendly interactive maps. http://leafletjs.com
 (c) 2010-2013, Vladimir Agafonkin
 (c) 2010-2011, CloudMade
*/
(function (window, document, undefined) {
var oldL = window.L,
    L = {};
 ...

JS is not my thing (hence my patronage of js2py 😃), so maybe someone with more knowledge can kick this in the right direction...

Invalid regular expression: missing /

Here is my test snippet with python:

temp = '''
function utf8_encode(e) {
    e = e.replace(/\r\n/g, "\n");
    for (var g = "", k = 0; k < e.length; k++) {
        var h = e.charCodeAt(k);
        128 > h ? g += String.fromCharCode(h) : (127 < h && 2048 > h ? g += String.fromCharCode(h >> 6 | 192) : (g += String.fromCharCode(h >> 12 | 224), g += String.fromCharCode(h >> 6 & 63 | 128)), g += String.fromCharCode(h & 63 | 128))
    }
    return g
}
'''

context = js2py.EvalJs()
context.execute(temp)

After executing I see exception like this:
js2py.base.PyJsException: SyntaxError: Line 3: Invalid regular expression: missing /

My setup:
win7-64bit
python-2.7
Js2Py (0.35)

Brackets don't work as expected

context = js2py.EvalJs()
context.execute("var a = (1);")

gives an error:

Traceback (most recent call last):
  File "/bin/user_wsgi_wrapper.py", line 154, in __call__
    app_iterator = self.app(environ, start_response)
  File "/usr/local/lib/python3.4/dist-packages/flask/app.py", line 1836, in __call__
    return self.wsgi_app(environ, start_response)
  File "/usr/local/lib/python3.4/dist-packages/flask/app.py", line 1820, in wsgi_app
    response = self.make_response(self.handle_exception(e))
  File "/usr/local/lib/python3.4/dist-packages/flask/app.py", line 1403, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/usr/local/lib/python3.4/dist-packages/flask/_compat.py", line 33, in reraise
    raise value
  File "/usr/local/lib/python3.4/dist-packages/flask/app.py", line 1817, in wsgi_app
    response = self.full_dispatch_request()
  File "/usr/local/lib/python3.4/dist-packages/flask/app.py", line 1478, in full_dispatch_request
    response = self.make_response(rv)
  File "/usr/local/lib/python3.4/dist-packages/flask/app.py", line 1577, in make_response
    rv = self.response_class.force_type(rv, request.environ)
  File "/usr/local/lib/python3.4/dist-packages/werkzeug/wrappers.py", line 827, in force_type
    response = BaseResponse(*_run_wsgi_app(response, environ))
  File "/usr/local/lib/python3.4/dist-packages/werkzeug/wrappers.py", line 57, in _run_wsgi_app
    return _run_wsgi_app(*args)
  File "/usr/local/lib/python3.4/dist-packages/werkzeug/test.py", line 855, in run_wsgi_app
    app_iter = app(environ, start_response)
  File "/home/PAuser/.local/lib/python3.4/site-packages/js2py/base.py", line 1056, in __call__
    return to_python(parent._obj.callprop(meth, *args))
  File "/home/PAuser/.local/lib/python3.4/site-packages/js2py/base.py", line 874, in callprop
    raise  MakeError('TypeError','%s is not a function'%cand.typeof())
js2py.base.PyJsException: TypeError: 'object' is not a function

wrapper script for standalone use ?

Hi, is there some kind of mode (or wrapper script) to use js2py as a standalone tool ?
Specifically, I want to port a bunch of existing javascript unit tests to Python, including the unit testing framework itself - I noticed, that you already have a import_js() API - would that be something that can be exposed for standalone use ?

Thank you

Support 'with statement'

Thanks for this good project. Very good one.
I try to convert Emmet.js to py and got err on "import emmet".

Zip file, run script "./conv.py" in Ubuntu 14.04. Py 3.4.

_emmet_conv.zip

Convert file

Hi, it's possible to convert javascript file to python with Js2Py?

Question about exposing Python classes to Javascript

Hello,

Is the following possible with Js2Py? I'm trying to access Python variables and a method from my Javascript code

import js2py
import random

class GlobalCtxt:
    def __init__(self):
        self.number_1 = random.randint(0, 9999)
        self.number_2 = random.randint(0, 9999)

        setattr(self, 'print', self._print)

    def _print(self, msg):
        print msg


class ScriptRunner:

    def run(self):
        ctxt = js2py.EvalJs(GlobalCtxt())
        response = ctxt.execute('''
print(number_1);
print(number_2);
var n = number_1 + number_2;
print(n);
''')
        print response



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

Array prototype concatenation

Running "(1+[])" will result "1[]" instead of "1" which it should be. I assume this is because of unfinished array prototype? Any plans to make this work? :)

Cannot handle to_dict() back to Js under certain conditions.

I am using the esprima translated example provided and have translated escodegen to allow me to rebuild code from the AST. I have noticed the following issue occur for certain scripts:

js2py.base.PyJsException: TypeError: Undefiend and null dont have properties!

This only occurs when I convert the datatype returned by esprima to a dictionary. If I then pass that converted data (without modification) back to escodegen it will throw the error above. If I don't convert to a dictionary it runs just fine. This only occurs with certain scripts, for example:

define(["definition"], function (foo) {
    "use strict";

    return foo(null, {
        declaredClass: "className",

        constructor: function () {
          this.var = 1;
        },

        id: function () {
            return 1;
        },

        type: function () {
            return 1;
        },

        namespace: function () {
            return 1;
        }
    });
});

EDIT: I am using Python 3.5

javascript code result and js2py code result not equal

Piotr,

I'm getting different results of the javascript calculation in browser and javascript calculation with js2py.

Here is small part of javascript (obfuscated) that calculated differently:

        k = function(b, a, d, c, e, f, h) {
            console.log(" b: " + b + " a: " + a + " d: " + d + " c: " + c + " e: " + e + " f: " + f + " h: " + h)
            b = g(b, g(g(a & d | ~a & c, e), h));
            console.log("result: " + g(b << f | b >>> 32 - f, a))
            return g(b << f | b >>> 32 - f, a)
        },

I added up console.log to the function to debug what is going on. And I got this.
output from browser execution of the script:

 b: 1732584193 a: 4023233417 d: 2562383102 c: 271733878 e: 909654321 f: 7 h: 3614090360
r: -1052999793
 b: 271733878 a: -1052999793 d: 4023233417 c: 2562383102 e: 892746040 f: 12 h: 3905402710
r: -1337176054
 b: 2562383102 a: -1337176054 d: -1052999793 c: 4023233417 e: 808794164 f: 17 h: 606105819
r: -1283602105
 b: 4023233417 a: -1283602105 d: -1337176054 c: -1052999793 e: 859058995 f: 22 h: 3250441966
r: -1062007728
 b: -1052999793 a: -1062007728 d: -1283602105 c: -1337176054 e: 912548728 f: 7 h: 4118548399
r: -1915188066
 b: -1337176054 a: -1915188066 d: -1062007728 c: -1283602105 e: 879587639 f: 12 h: 1200080426
r: -81503603
 b: -1283602105 a: -81503603 d: -1915188066 c: -1062007728 e: -2139918750 f: 17 h: 2821735955
r: 274015734
 b: -1062007728 a: 274015734 d: -81503603 c: -1915188066 e: undefined f: 22 h: 4249261313
r: -2018769024
 b: -1915188066 a: -2018769024 d: 274015734 c: -81503603 e: undefined f: 7 h: 1770035416
r: 913148215
 b: -81503603 a: 913148215 d: -2018769024 c: 274015734 e: undefined f: 12 h: 2336552879
r: -1913826815
 b: 274015734 a: -1913826815 d: 913148215 c: -2018769024 e: undefined f: 17 h: 4294925233
r: -1673691260
 b: -2018769024 a: -1673691260 d: -1913826815 c: 913148215 e: undefined f: 22 h: 2304563134
r: -122856144
 b: 913148215 a: -122856144 d: -1673691260 c: -1913826815 e: undefined f: 7 h: 1804603682
r: -1372976561
 b: -1913826815 a: -1372976561 d: -122856144 c: -1673691260 e: undefined f: 12 h: 4254626195
r: -499429749
 b: -1673691260 a: -499429749 d: -1372976561 c: -122856144 e: 216 f: 17 h: 2792965006
r: -1601746604
 b: -122856144 a: -1601746604 d: -499429749 c: -1372976561 e: 0 f: 22 h: 1236535329
r: 2009295999

and this is an output from js2py execution of that same script:

' b: 1732584193 a: 4023233417 d: 2562383102 c: 271733878 e: 909654321 f: 7 h: 3614090360'
'r: -1052999793'
' b: 271733878 a: -1052999793 d: 4023233417 c: 2562383102 e: 892746040 f: 12 h: 3905402710'
'r: -1337176054'
' b: 2562383102 a: -1337176054 d: -1052999793 c: 4023233417 e: 808794164 f: 17 h: 606105819'
'r: -1337210553'
' b: 4023233417 a: -1337210553 d: -1337176054 c: -1052999793 e: 859058995 f: 22 h: 3250441966'
'r: -1337894832'
' b: -1052999793 a: -1337894832 d: -1337210553 c: -1337176054 e: 912548728 f: 7 h: 4118548399'
'r: -1337894882'
' b: -1337176054 a: -1337894882 d: -1337894832 c: -1337210553 e: 879587639 f: 12 h: 1200080426'
'r: -1337895450'
' b: -1337210553 a: -1337895450 d: -1337894882 c: -1337894832 e: -2139918750 f: 17 h: 2821735955'
'r: -1337956281'
' b: -1337894832 a: -1337956281 d: -1337895450 c: -1337894882 e: undefined f: 22 h: 4249261313'
'r: 471325334'
' b: -1337894882 a: 471325334 d: -1337956281 c: -1337895450 e: undefined f: 7 h: 1770035416'
'r: 471325307'
' b: -1337895450 a: 471325307 d: 471325334 c: -1337956281 e: undefined f: 12 h: 2336552879'
'r: 471325176'
' b: -1337956281 a: 471325176 d: 471325307 c: 471325334 e: undefined f: 17 h: 4294925233'
'r: 471298727'
' b: 471325334 a: 471298727 d: 471325176 c: 471325307 e: undefined f: 22 h: 2304563134'
'r: 470275529'
' b: 471325307 a: 470275529 d: 471298727 c: 471325176 e: undefined f: 7 h: 1804603682'
'r: 470275482'
' b: 471325176 a: 470275482 d: 470275529 c: 471298727 e: undefined f: 12 h: 4254626195'
'r: -1606723338'
' b: 471298727 a: -1606723338 d: 470275482 c: 470275529 e: 216 f: 17 h: 2792965006'
'r: -1606740441'
' b: 470275529 a: -1606740441 d: -1606723338 c: 470275482 e: 0 f: 22 h: 1236535329'
'r: -1975282414'

I wonder does shift operation >>> supported in js2py?

AttributeError: PyJsNumber instance has no attribute '__trunc__'

I am trying to use this (http://pastebin.com/30stpGzM) script with Js2Py but I get this traceback:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "requests\sessions.py", line 477, in get
    return self.request('GET', url, **kwargs)
  File "requests\sessions.py", line 465, in request
    resp = self.send(prep, **send_kwargs)
  File "requests\sessions.py", line 573, in send
    r = adapter.send(request, **kwargs)
  File "scraper.py", line 26, in send
    return self.solve_cf_challenge(resp, request.headers, resp.cookies, **kwargs)
  File "scraper.py", line 69, in solve_cf_challenge
    answer = str(int(js2py.eval_js(js)) + len(domain))
AttributeError: PyJsNumber instance has no attribute '__trunc__'

The value in js variable is:

var t,r,a,f, XbMvhKS={"mKW":+(String(1+1+1+1+0)+String(1+1+1+1+1+1+1+1))};        ;XbMvhKS.mKW+=+(String(1+1+1+0)+String(1+1+1+1));XbMvhKS.mKW+=+(String(+1+0)+String(1+1+1+1+1+1+1));XbMvhKS.mKW*=+(String(1+1+1+1+1+0)+String(+0));XbMvhKS.mKW+=+(String(1+1+0)+String(1+1+1)); parseInt(XbMvhKS.mKW, 10)

I don't understand the problem because if I use js2py.eval_js(js) manually in console with the same js code works perfectly

function.toString enhancement

Here is the test code and functioning equivalent:
js2py.eval_js('''console.log(eval('('+function(){return "works!"}+')')())''')
js2py.eval_js('''console.log(eval((function(){return "works!"}))())''')

Still trying to find this in the spec and understand what's missing, from what I gather js2py can't yet parse mixed code/text function declaration and tries to handle it as an argumentlist

Traceback (most recent call last):
File "", line 1, in
File "js2py/evaljs.py", line 167, in execute
exec(compiled, self._context)
File "", line 8, in
File "js2py/base.py", line 835, in call
return self.call(self.GlobalObject, args)
File "js2py/base.py", line 1281, in call
return Js(self.code(*args))
File "js2py/host/jseval.py", line 16, in Eval
py_code = translate_js(code.to_string().value, '')
File "js2py/translators/translator.py", line 62, in translate_js
parsed = parser.parse(js) # js to esprima syntax tree
File "js2py/translators/pyjsparser.py", line 2862, in parse
program = self.parseProgram();
File "js2py/translators/pyjsparser.py", line 2833, in parseProgram
body = self.parseScriptBody()
File "js2py/translators/pyjsparser.py", line 2822, in parseScriptBody
statement = self.parseStatementListItem();
File "js2py/translators/pyjsparser.py", line 1978, in parseStatementListItem
return self.parseFunctionDeclaration(Node());
File "js2py/translators/pyjsparser.py", line 2738, in parseFunctionDeclaration
body = self.parseFunctionSourceElements();
File "js2py/translators/pyjsparser.py", line 2627, in parseFunctionSourceElements
body.append(self.parseStatementListItem())
File "js2py/translators/pyjsparser.py", line 1983, in parseStatementListItem
return self.parseStatement();
File "js2py/translators/pyjsparser.py", line 2568, in parseStatement
expr = self.parseExpression();
File "js2py/translators/pyjsparser.py", line 1949, in parseExpression
expr = self.isolateCoverGrammar(self.parseAssignmentExpression)
File "js2py/translators/pyjsparser.py", line 1126, in isolateCoverGrammar
result = parser()
File "js2py/translators/pyjsparser.py", line 1916, in parseAssignmentExpression
expr = self.parseConditionalExpression();
File "js2py/translators/pyjsparser.py", line 1817, in parseConditionalExpression
expr = self.inheritCoverGrammar(self.parseBinaryExpression);
File "js2py/translators/pyjsparser.py", line 1141, in inheritCoverGrammar
result = parser()
File "js2py/translators/pyjsparser.py", line 1765, in parseBinaryExpression
left = self.inheritCoverGrammar(self.parseUnaryExpression);
File "js2py/translators/pyjsparser.py", line 1141, in inheritCoverGrammar
result = parser()
File "js2py/translators/pyjsparser.py", line 1741, in parseUnaryExpression
expr = self.parsePostfixExpression()
File "js2py/translators/pyjsparser.py", line 1694, in parsePostfixExpression
expr = self.inheritCoverGrammar(self.parseLeftHandSideExpressionAllowCall)
File "js2py/translators/pyjsparser.py", line 1141, in inheritCoverGrammar
result = parser()
File "js2py/translators/pyjsparser.py", line 1631, in parseLeftHandSideExpressionAllowCall
expr = self.inheritCoverGrammar(self.parseNewExpression if self.matchKeyword('new') else self.parsePrimaryExpression)
File "js2py/translators/pyjsparser.py", line 1141, in inheritCoverGrammar
result = parser()
File "js2py/translators/pyjsparser.py", line 1525, in parsePrimaryExpression
return self.inheritCoverGrammar(self.parseArrayInitialiser)
File "js2py/translators/pyjsparser.py", line 1141, in inheritCoverGrammar
result = parser()
File "js2py/translators/pyjsparser.py", line 1241, in parseArrayInitialiser
self.expect(',')
File "js2py/translators/pyjsparser.py", line 1024, in expect
self.throwUnexpectedToken(token)
File "js2py/translators/pyjsparser.py", line 1013, in throwUnexpectedToken
raise self.unexpectedTokenError(token, message)

NotImplementedError while calling Javascript function with date argument

'function test(cronjob) { [python code] }'
later.data('* * 1 1 * _/2')
Traceback (most recent call last):
File "", line 1, in
File "/home/darshitp/.local/lib/python2.7/site-packages/js2py/base.py", line 1056, in call
return to_python(parent._obj.callprop(meth, *args))
File "/home/darshitp/.local/lib/python2.7/site-packages/js2py/base.py", line 875, in callprop
return cand.call(self, args)
File "/home/darshitp/.local/lib/python2.7/site-packages/js2py/base.py", line 1281, in call
return Js(self.code(args))
File "later.py", line 2346, in PyJs_test_227

var.put(u'next_date', var.get(u'later').callprop(u'schedule', var.get(u'schedule')).callprop(u'next', Js(10.0), var.get(u'Date').create()))
File "/home/darshitp/.local/lib/python2.7/site-packages/js2py/base.py", line 875, in callprop
return cand.call(self, args)
File "/home/darshitp/.local/lib/python2.7/site-packages/js2py/base.py", line 1281, in call
return Js(self.code(args))
File "later.py", line 1346, in PyJs_anonymous_155

return var.get(u'getInstances')(Js(u'next'), (var.get(u'count') or Js(1.0)), var.get(u'startDate'), var.get(u'endDate'))
File "/home/darshitp/.local/lib/python2.7/site-packages/js2py/base.py", line 835, in call
return self.call(self.GlobalObject, args)
File "/home/darshitp/.local/lib/python2.7/site-packages/js2py/base.py", line 1281, in call
return Js(self.code(args))
File "later.py", line 1181, in PyJsHoisted_getInstances

var.put(u'startDate', (var.get(u'Date').create(var.get(u'startDate')) if var.get(u'startDate') else var.get(u'Date').create()))
File "/home/darshitp/.local/lib/python2.7/site-packages/js2py/constructors/jsdate.py", line 104, in date_constructor
return date_constructor1(args[0])
File "/home/darshitp/.local/lib/python2.7/site-packages/js2py/constructors/jsdate.py", line 119, in date_constructor1
return PyJsDate(TimeClip(v), prototype=DatePrototype)
File "/home/darshitp/.local/lib/python2.7/site-packages/js2py/constructors/time_helpers.py", line 178, in TimeClip
if t!=t or abs(t)==float('inf'):
TypeError: bad operand type for abs(): 'exceptions.NotImplementedError'

Javascript function is:
data = function test(exp){
var schedule = later.parse.cron(exp);
var next_date = later.schedule(schedule).next(10, new Date());
return next_date
}

Question about improving performance

Hello,

I'm enjoying using Js2Py but I'm finding it slow, especially when I start to load large Javascript libraries into the context. Unfortunately some of the work I am doing has to be synchronous and the delay is noticeable

Would it be possible to cache (or return) the translated code to avoid the penalty of translating just before I need to execute it?

Thanks

JS code wasn't translated correctly to Python

Hello,

I'm getting an odd results after performing the JS code translation: like "JS_BUILTINS", "PyJsHoisted", "PyJs_Object_0_", ":Js()", "var". This is obviously a translation bug.

This is the detailed info about translation process:

python

import js2py
x = """
... /* -- Mode: JS2; indent-tabs-mode: nil; js2-basic-offset: 4 -- /
... /
vim: set et ts=4 sw=4: /
... /

... * Copyright (c) 2011, 2012, 2013 Red Hat, Inc.
... *
... * GNOME Maps is free software; you can redistribute it and/or modify
... * it under the terms of the GNU General Public License as published by the
... * Free Software Foundation; either version 2 of the License, or (at your
... * option) any later version.
... *
... * GNOME Maps is distributed in the hope that it will be useful, but
... * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
... * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
... * for more details.
... *
... * You should have received a copy of the GNU General Public License along
... * with GNOME Maps; if not, see http://www.gnu.org/licenses/.
... *
... * Author: Cosimo Cecchi [email protected]
... * Zeeshan Ali (Khattak) [email protected]
... */
...
... pkg.initGettext();
... pkg.initFormat();
... pkg.require({ 'cairo': '1.0',
... 'Champlain': '0.12',
... 'Clutter': '1.0',
... 'Cogl': '1.0',
... 'GeocodeGlib': '1.0',
... 'Gdk': '3.0',
... 'GdkPixbuf': '2.0',
... 'GFBGraph': '0.2',
... 'Gio': '2.0',
... 'GLib': '2.0',
... 'Goa': '1.0',
... 'GObject': '2.0',
... 'Gtk': '3.0',
... 'GtkChamplain': '0.12',
... 'GtkClutter': '1.0',
... 'Rest': '0.7',
... 'Soup': '2.4' });
...
... const Application = imports.application;
...
... function main(args) {
... var application = new Application.Application();
... return application.run(args);
... }
... """
js2py.translate_js(x)
"from js2py.pyjs import *\n# setting scope\nvar = Scope( JS_BUILTINS )\nset_global_object(var)\n\n# Code follows:\nvar.registers(['main', 'Application'])\n@Js\ndef PyJsHoisted_main_(args, this, arguments, var=var):\n var = Scope({'arguments':arguments, 'args':args, 'this':this}, var)\n var.registers(['application', 'args'])\n var.put('application', var.get('Application').get('Application').create())\n return var.get('application').callprop('run', var.get('args'))\nPyJsHoisted_main_.func_name = 'main'\nvar.put('main', PyJsHoisted_main_)\nvar.get('pkg').callprop('initFormat')\nPyJs_Object_0_ = Js({'cairo':Js('1.0'),'Champlain':Js('0.12'),'Clutter':Js('1.0'),'Cogl':Js('1.0'),'GeocodeGlib':Js('1.0'),'Gdk':Js('3.0'),'GdkPixbuf':Js('2.0'),'GFBGraph':Js('0.2'),'Gio':Js('2.0'),'GLib':Js('2.0'),'Goa':Js('1.0'),'GObject':Js('2.0'),'Gtk':Js('3.0'),'GtkChamplain':Js('0.12'),'GtkClutter':Js('1.0'),'Rest':Js('0.7'),'Soup':Js('2.4')})\nvar.get('pkg').callprop('require', PyJs_Object_0_)\nvar.put('Application', var.get('imports').get('application'))\npass\npass\n"

Please fix this bug as soon as possible.

Thanks.

Disable pyimport by default, for security

I'm exploring the use of this library for a project I'm working on, and it looks amazing. I am interested in using this library to parse and execute functions from potentially untrusted JavaScript files, so I am concerned by the availability of the pyimport keyword. Is it possible to add an option to enable/disable this feature, and have it disabled by default?

Doing this would make the default behaviour of Js2Py much safer and similar to standard JavaScript.

FFI bridge

Hello, is there an example of using functions defined elsewhere in Python? In my example, I'd like a very simple way to call into python libraries for the sake of writing Vim plugins.

For the longest time, developers were locked into using VimScript or Python to build Vim plugins. But with this project, it is theoretically possible for people to use virtually any language (that compiles to JS - so basically all of them) in order to write Vim plugins (or Sublime plugins!)

Code to handle backspace character breaks \b in regex patterns

Here is my test for it:

import js2py
t = r"function test() {return 'failed!'.replace(new RegExp('failed\b','g'), 'passed!')}"
print js2py.eval_js(t)()

Commenting out lines 517 and 518 in pyjsparser.py seems to fix the issue, it's not a proper fix though.

Apparent bug or problem

I am having problems getting this js code https://gist.github.com/kekscom/10925007 to run properly in Python using Js2Py. It might possibly be a character array vs string vs unicode issue.

It does run fine in js - as seen in this fiddle: http://jsfiddle.net/7Laut8gq/1/

Thank you for taking a look at this, and let me know if I can support your efforts.

--- This is my python code:

import sys, glob, os, js2py
javascript_function = open("fJson.js").read()
jsTryToFix = js2py.eval_js(javascript_function)
json_data_raw = open(filename_to_fix).read()
json_data_fixed = jsTryToFix(json_data_raw)


In the javascript - in my local file version of the fixJson(stuff) in http://jsfiddle.net/7Laut8gq/1/ -right before the return, I placed
console.log(json);
But it prints empty; it works fine for a "Test string".
json_data_fixed returns empty; but if change the javascript_function to return "Test string",
it returns as expected in json_data_fixed

webgl js demo makes some quite scary looking python code

I thought I'd try this bit of code
https://developer.mozilla.org/samples/webgl/sample5/webgl-demo.js

Some of the output is a bit scary - (see end)

  • Lots of 'pass'
  • Maybe some of the 'val arrays' could just be python lists, or at a push use the array module or numpy ?
  • could this sort of thing 'var.put(u'mvTranslate', PyJsLvalTempHoisted)' just become something like mvTranslate = PyJsvalTempHoised .... ?
from js2py.pyjs import *
var = Scope( JS_BUILTINS )
set_global_object(var)
var.registers([u'canvas', u'gl', u'cubeVerticesBuffer', u'cubeVerticesColorBuffer', u'cubeVerticesIndexBuffer', u'cubeVerticesIndexBuffer', u'cubeRotation', u'cubeXOffset', u'cubeYOffset', u'cubeZOffset', u'lastCubeUpdateTime', u'xIncValue', u'yIncValue', u'zIncValue', u'mvMatrix', u'shaderProgram', u'vertexPositionAttribute', u'vertexColorAttribute', u'perspectiveMatrix', u'mvMatrixStack', u'initBuffers', u'multMatrix', u'getShader', u'mvTranslate', u'initWebGL', u'loadIdentity', u'drawScene', u'start', u'mvPushMatrix', u'initShaders', u'setMatrixUniforms', u'mvRotate', u'mvPopMatrix'])
@Js
def PyJsLvalTempHoisted(this, arguments, var=var):
    var = Scope({'this':this, 'arguments':arguments}, var)
    var.registers([u'vertices', u'colors', u'generatedColors', u'c', u'i', u'cubeVertexIndices'])
    var.put(u'cubeVerticesBuffer', var.get(u'gl').callprop(u'createBuffer'))
    var.get(u'gl').callprop(u'bindBuffer',var.get(u'gl').get(u'ARRAY_BUFFER'),var.get(u'cubeVerticesBuffer'))
    PyJsLvalArray1_ = Js([(-Js(1.0)),(-Js(1.0)),Js(1.0),Js(1.0),(-Js(1.0)),Js(1.0),Js(1.0),Js(1.0),Js(1.0),(-Js(1.0)),Js(1.0),Js(1.0),(-Js(1.0)),(-Js(1.0)),(-Js(1.0)),(-Js(1.0)),Js(1.0),(-Js(1.0)),Js(1.0),Js(1.0),(-Js(1.0)),Js(1.0),(-Js(1.0)),(-Js(1.0)),(-Js(1.0)),Js(1.0),(-Js(1.0)),(-Js(1.0)),Js(1.0),Js(1.0),Js(1.0),Js(1.0),Js(1.0),Js(1.0),Js(1.0),(-Js(1.0)),(-Js(1.0)),(-Js(1.0)),(-Js(1.0)),Js(1.0),(-Js(1.0)),(-Js(1.0)),Js(1.0),(-Js(1.0)),Js(1.0),(-Js(1.0)),(-Js(1.0)),Js(1.0),Js(1.0),(-Js(1.0)),(-Js(1.0)),Js(1.0),Js(1.0),(-Js(1.0)),Js(1.0),Js(1.0),Js(1.0),Js(1.0),(-Js(1.0)),Js(1.0),(-Js(1.0)),(-Js(1.0)),(-Js(1.0)),(-Js(1.0)),(-Js(1.0)),Js(1.0),(-Js(1.0)),Js(1.0),Js(1.0),(-Js(1.0)),Js(1.0),(-Js(1.0))])
    var.put(u'vertices', PyJsLvalArray1_)
    var.get(u'gl').callprop(u'bufferData',var.get(u'gl').get(u'ARRAY_BUFFER'),var.get(u'Float32Array').create(var.get(u'vertices')),var.get(u'gl').get(u'STATIC_DRAW'))
    PyJsLvalArray15_ = Js([Js(1.0),Js(1.0),Js(0.0),Js(1.0)])
    PyJsLvalArray14_ = Js([Js(0.0),Js(0.0),Js(1.0),Js(1.0)])
    PyJsLvalArray13_ = Js([Js(0.0),Js(1.0),Js(0.0),Js(1.0)])
    PyJsLvalArray12_ = Js([Js(1.0),Js(0.0),Js(0.0),Js(1.0)])
    PyJsLvalArray11_ = Js([Js(1.0),Js(1.0),Js(1.0),Js(1.0)])
    PyJsLvalArray16_ = Js([Js(1.0),Js(0.0),Js(1.0),Js(1.0)])
    PyJsLvalArray2_ = Js([PyJsLvalArray11_,PyJsLvalArray12_,PyJsLvalArray13_,PyJsLvalArray14_,PyJsLvalArray15_,PyJsLvalArray16_])
    var.put(u'colors', PyJsLvalArray2_)
    PyJsLvalArray3_ = Js([None])
    var.put(u'generatedColors', PyJsLvalArray3_)
    #for JS loop
    var.put(u'j', Js(0))
    while (var.get(u'j')<Js(6)):
        var.put(u'c', var.get(u'colors').get(var.get(u'j')))
        #for JS loop
        var.put(u'i', Js(0))
        while (var.get(u'i')<Js(4)):
            var.put(u'generatedColors', var.get(u'generatedColors').callprop(u'concat',var.get(u'c')))
            pass
            (var.put(u'i',var.get(u'i')+Js(1))-Js(1))

        pass
        (var.put(u'j',var.get(u'j')+Js(1))-Js(1))

    var.put(u'cubeVerticesColorBuffer', var.get(u'gl').callprop(u'createBuffer'))
    var.get(u'gl').callprop(u'bindBuffer',var.get(u'gl').get(u'ARRAY_BUFFER'),var.get(u'cubeVerticesColorBuffer'))
    var.get(u'gl').callprop(u'bufferData',var.get(u'gl').get(u'ARRAY_BUFFER'),var.get(u'Float32Array').create(var.get(u'generatedColors')),var.get(u'gl').get(u'STATIC_DRAW'))
    var.put(u'cubeVerticesIndexBuffer', var.get(u'gl').callprop(u'createBuffer'))
    var.get(u'gl').callprop(u'bindBuffer',var.get(u'gl').get(u'ELEMENT_ARRAY_BUFFER'),var.get(u'cubeVerticesIndexBuffer'))
    PyJsLvalArray4_ = Js([Js(0),Js(1),Js(2),Js(0),Js(2),Js(3),Js(4),Js(5),Js(6),Js(4),Js(6),Js(7),Js(8),Js(9),Js(10),Js(8),Js(10),Js(11),Js(12),Js(13),Js(14),Js(12),Js(14),Js(15),Js(16),Js(17),Js(18),Js(16),Js(18),Js(19),Js(20),Js(21),Js(22),Js(20),Js(22),Js(23)])
    var.put(u'cubeVertexIndices', PyJsLvalArray4_            gl.callprop(u'bufferData',var.get(u'gl').get(u'ELEMENT_ARRAY_BUFFER'),var.get(u'Uint16Array').create(var.get(u'cubeVertexIndices')),var.get(u'gl').get(u'STATIC_DRAW')))
    pass
    pass
PyJsLvalTempHoisted.func_name = u'initBuffers'

var.put(u'initBuffers', PyJsLvalTempHoisted)
@Js
def PyJsLvalTempHoisted(m, this, arguments, var=var):
    var = Scope({'this':this, 'arguments':arguments, u'm':m}, var)
    var.put(u'mvMatrix', var.get(u'mvMatrix').callprop(u'x',var.get(u'm')))
    pass
    pass
PyJsLvalTempHoisted.func_name = u'multMatrix'

var.put(u'multMatrix', PyJsLvalTempHoisted)
@Js
def PyJsLvalTempHoisted(gl, id, this, arguments, var=var):
    var = Scope({'this':this, 'arguments':arguments, u'gl':gl, u'id':id}, var)
    var.registers([u'shaderScript', u'theSource', u'currentChild', u'shader'])
    var.put(u'shaderScript', var.get(u'document').callprop(u'getElementById',var.get(u'id')))
    if var.get(u'shaderScript').neg():
        return var.get(u'null')
        pass
    var.put(u'theSource', Js(u""))
    var.put(u'currentChild', var.get(u'shaderScript').get(u'firstChild'))
    while var.get(u'currentChild'):
        if (var.get(u'currentChild').get(u'nodeType')==Js(3)):
            var.put(u'theSource', var.get(u'currentChild').get(u'textContent'),u'+')
            pass
        var.put(u'currentChild', var.get(u'currentChild').get(u'nextSibling'))
        pass
    pass
    if (var.get(u'shaderScript').get(u'type')==Js(u"x-shader/x-fragment")):
        var.put(u'shader', var.get(u'gl').callprop(u'createShader',var.get(u'gl').get(u'FRAGMENT_SHADER')))
        pass
    elif (var.get(u'shaderScript').get(u'type')==Js(u"x-shader/x-vertex")):
        var.put(u'shader', var.get(u'gl').callprop(u'createShader',var.get(u'gl').get(u'VERTEX_SHADER')))
        pass
    else:
        return var.get(u'null')
        pass
    var.get(u'gl').callprop(u'shaderSource',var.get(u'shader'),var.get(u'theSource'))
    var.get(u'gl').callprop(u'compileShader',var.get(u'shader'))
    if var.get(u'gl').callprop(u'getShaderParameter',var.get(u'shader'),var.get(u'gl').get(u'COMPILE_STATUS')).neg():
        var.get(u'alert')((Js(u"An error occurred compiling the shaders: ")+var.get(u'gl').callprop(u'getShaderInfoLog',var.get(u'shader'))))
        return var.get(u'null')
        pass
    return var.get(u'shader')
    pass
    pass
PyJsLvalTempHoisted.func_name = u'getShader'

var.put(u'getShader', PyJsLvalTempHoisted)
@Js
def PyJsLvalTempHoisted(v, this, arguments, var=var):
    var = Scope({'this':this, 'arguments':arguments, u'v':v}, var)
    PyJsLvalArray8_ = Js([var.get(u'v').get(Js(0)),var.get(u'v').get(Js(1)),var.get(u'v').get(Js(2))])
    var.get(u'multMatrix')(var.get(u'Matrix').callprop(u'Translation',var.get(u'$V')(PyJsLvalArray8_)).callprop(u'ensure4x4'))
    pass
    pass
PyJsLvalTempHoisted.func_name = u'mvTranslate'

var.put(u'mvTranslate', PyJsLvalTempHoisted)
@Js
def PyJsLvalTempHoisted(this, arguments, var=var):
    var = Scope({'this':this, 'arguments':arguments}, var)
    var.put(u'gl', var.get(u'null'))
    try:
        var.put(u'gl', var.get(u'canvas').callprop(u'getContext',Js(u"experimental-webgl")))
        pass
    except PyJsException as PyJsTempException:
        PyJsHolder_65_75469814 = var.own.get(u'e')
        var.force_own_put(u'e', PyExceptionToJs(PyJsTempException))
        try:
            pass
        finally:
            if PyJsHolder_65_75469814 is not None:
                var.own[u'e'] = PyJsHolder_65_75469814
            else:
                del var.own[u'e']
            del PyJsHolder_65_75469814
    if var.get(u'gl').neg():
        var.get(u'alert')(Js(u"Unable to initialize WebGL. Your browser may not support it."))
        pass
    pass
    pass
PyJsLvalTempHoisted.func_name = u'initWebGL'

var.put(u'initWebGL', PyJsLvalTempHoisted)
@Js
def PyJsLvalTempHoisted(this, arguments, var=var):
    var = Scope({'this':this, 'arguments':arguments}, var)
    var.put(u'mvMatrix', var.get(u'Matrix').callprop(u'I',Js(4)))
    pass
    pass
PyJsLvalTempHoisted.func_name = u'loadIdentity'

var.put(u'loadIdentity', PyJsLvalTempHoisted)
@Js
def PyJsLvalTempHoisted(this, arguments, var=var):
    var = Scope({'this':this, 'arguments':arguments}, var)
    var.registers([u'currentTime', u'delta'])
    var.get(u'gl').callprop(u'clear',(var.get(u'gl').get(u'COLOR_BUFFER_BIT')|var.get(u'gl').get(u'DEPTH_BUFFER_BIT')))
    var.put(u'perspectiveMatrix', var.get(u'makePerspective')(Js(45),(Js(640.0)/Js(480.0)),Js(0.1),Js(100.0)))
    var.get(u'loadIdentity')()
    PyJsLvalArray5_ = Js([(-Js(0.0)),Js(0.0),(-Js(6.0))])
    var.get(u'mvTranslate')(PyJsLvalArray5_)
    var.get(u'mvPushMatrix')()
    PyJsLvalArray6_ = Js([Js(1),Js(0),Js(1)])
    var.get(u'mvRotate')(var.get(u'cubeRotation'),PyJsLvalArray6_)
    PyJsLvalArray7_ = Js([var.get(u'cubeXOffset'),var.get(u'cubeYOffset'),var.get(u'cubeZOffset')])
    var.get(u'mvTranslate')(PyJsLvalArray7_)
    var.get(u'gl').callprop(u'bindBuffer',var.get(u'gl').get(u'ARRAY_BUFFER'),var.get(u'cubeVerticesBuffer'))
    var.get(u'gl').callprop(u'vertexAttribPointer',var.get(u'vertexPositionAttribute'),Js(3),var.get(u'gl').get(u'FLOAT'),var.get(u'false'),Js(0),Js(0))
    var.get(u'gl').callprop(u'bindBuffer',var.get(u'gl').get(u'ARRAY_BUFFER'),var.get(u'cubeVerticesColorBuffer'))
    var.get(u'gl').callprop(u'vertexAttribPointer',var.get(u'vertexColorAttribute'),Js(4),var.get(u'gl').get(u'FLOAT'),var.get(u'false'),Js(0),Js(0))
    var.get(u'gl').callprop(u'bindBuffer',var.get(u'gl').get(u'ELEMENT_ARRAY_BUFFER'),var.get(u'cubeVerticesIndexBuffer'))
    var.get(u'setMatrixUniforms')()
    var.get(u'gl').callprop(u'drawElements',var.get(u'gl').get(u'TRIANGLES'),Js(36),var.get(u'gl').get(u'UNSIGNED_SHORT'),Js(0))
    var.get(u'mvPopMatrix')()
    var.put(u'currentTime', (var.get(u'Date').create()).callprop(u'getTime'))
    if var.get(u'lastCubeUpdateTime'):
        var.put(u'delta', (var.get(u'currentTime')-var.get(u'lastCubeUpdateTime')))
        var.put(u'cubeRotation', (((Js(30)*var.get(u'delta')))/Js(1000.0)),u'+')
        var.put(u'cubeXOffset', (var.get(u'xIncValue')*((((Js(30)*var.get(u'delta')))/Js(1000.0)))),u'+')
        var.put(u'cubeYOffset', (var.get(u'yIncValue')*((((Js(30)*var.get(u'delta')))/Js(1000.0)))),u'+')
        var.put(u'cubeZOffset', (var.get(u'zIncValue')*((((Js(30)*var.get(u'delta')))/Js(1000.0)))),u'+')
        if (var.get(u'Math').callprop(u'abs',var.get(u'cubeYOffset'))>Js(2.5)):
            var.put(u'xIncValue', (-var.get(u'xIncValue')))
            var.put(u'yIncValue', (-var.get(u'yIncValue')))
            var.put(u'zIncValue', (-var.get(u'zIncValue')))
            pass
        pass
    var.put(u'lastCubeUpdateTime', var.get(u'currentTime'))
    pass
    pass
PyJsLvalTempHoisted.func_name = u'drawScene'

var.put(u'drawScene', PyJsLvalTempHoisted)
@Js
def PyJsLvalTempHoisted(this, arguments, var=var):
    var = Scope({'this':this, 'arguments':arguments}, var)
    var.put(u'canvas', var.get(u'document').callprop(u'getElementById',Js(u"glcanvas")))
    var.get(u'initWebGL')(var.get(u'canvas'))
    if var.get(u'gl'):
        var.get(u'gl').callprop(u'clearColor',Js(0.0),Js(0.0),Js(0.0),Js(1.0))
        var.get(u'gl').callprop(u'clearDepth',Js(1.0))
        var.get(u'gl').callprop(u'enable',var.get(u'gl').get(u'DEPTH_TEST'))
        var.get(u'gl').callprop(u'depthFunc',var.get(u'gl').get(u'LEQUAL'))
        var.get(u'initShaders')()
        var.get(u'initBuffers')()
        var.get(u'setInterval')(var.get(u'drawScene'),Js(15))
        pass
    pass
    pass
PyJsLvalTempHoisted.func_name = u'start'

var.put(u'start', PyJsLvalTempHoisted)
@Js
def PyJsLvalTempHoisted(m, this, arguments, var=var):
    var = Scope({'this':this, 'arguments':arguments, u'm':m}, var)
    if var.get(u'm'):
        var.get(u'mvMatrixStack').callprop(u'push',var.get(u'm').callprop(u'dup'))
        var.put(u'mvMatrix', var.get(u'm').callprop(u'dup'))
        pass
    else:
        var.get(u'mvMatrixStack').callprop(u'push',var.get(u'mvMatrix').callprop(u'dup'))
        pass
    pass
    pass
PyJsLvalTempHoisted.func_name = u'mvPushMatrix'

var.put(u'mvPushMatrix', PyJsLvalTempHoisted)
@Js
def PyJsLvalTempHoisted(this, arguments, var=var):
    var = Scope({'this':this, 'arguments':arguments}, var)
    var.registers([u'fragmentShader', u'vertexShader'])
    var.put(u'fragmentShader', var.get(u'getShader')(var.get(u'gl'),Js(u"shader-fs")))
    var.put(u'vertexShader', var.get(u'getShader')(var.get(u'gl'),Js(u"shader-vs")))
    var.put(u'shaderProgram', var.get(u'gl').callprop(u'createProgram'))
    var.get(u'gl').callprop(u'attachShader',var.get(u'shaderProgram'),var.get(u'vertexShader'))
    var.get(u'gl').callprop(u'attachShader',var.get(u'shaderProgram'),var.get(u'fragmentShader'))
    var.get(u'gl').callprop(u'linkProgram',var.get(u'shaderProgram'))
    if var.get(u'gl').callprop(u'getProgramParameter',var.get(u'shaderProgram'),var.get(u'gl').get(u'LINK_STATUS')).neg():
        var.get(u'alert')(Js(u"Unable to initialize the shader program."))
        pass
    var.get(u'gl').callprop(u'useProgram',var.get(u'shaderProgram'))
    var.put(u'vertexPositionAttribute', var.get(u'gl').callprop(u'getAttribLocation',var.get(u'shaderProgram'),Js(u"aVertexPosition")))
    var.get(u'gl').callprop(u'enableVertexAttribArray',var.get(u'vertexPositionAttribute'))
    var.put(u'vertexColorAttribute', var.get(u'gl').callprop(u'getAttribLocation',var.get(u'shaderProgram'),Js(u"aVertexColor")))
    var.get(u'gl').callprop(u'enableVertexAttribArray',var.get(u'vertexColorAttribute'))
    pass
    pass
PyJsLvalTempHoisted.func_name = u'initShaders'

var.put(u'initShaders', PyJsLvalTempHoisted)
@Js
def PyJsLvalTempHoisted(this, arguments, var=var):
    var = Scope({'this':this, 'arguments':arguments}, var)
    var.registers([u'pUniform', u'mvUniform'])
    var.put(u'pUniform', var.get(u'gl').callprop(u'getUniformLocation',var.get(u'shaderProgram'),Js(u"uPMatrix")))
    var.get(u'gl').callprop(u'uniformMatrix4fv',var.get(u'pUniform'),var.get(u'false'),var.get(u'Float32Array').create(var.get(u'perspectiveMatrix').callprop(u'flatten')))
    var.put(u'mvUniform', var.get(u'gl').callprop(u'getUniformLocation',var.get(u'shaderProgram'),Js(u"uMVMatrix")))
    var.get(u'gl').callprop(u'uniformMatrix4fv',var.get(u'mvUniform'),var.get(u'false'),var.get(u'Float32Array').create(var.get(u'mvMatrix').callprop(u'flatten')))
    pass
    pass
PyJsLvalTempHoisted.func_name = u'setMatrixUniforms'

var.put(u'setMatrixUniforms', PyJsLvalTempHoisted)
@Js
def PyJsLvalTempHoisted(angle, v, this, arguments, var=var):
    var = Scope({'this':this, 'arguments':arguments, u'angle':angle, u'v':v}, var)
    var.registers([u'inRadians', u'm'])
    var.put(u'inRadians', ((var.get(u'angle')*var.get(u'Math').get(u'PI'))/Js(180.0)))
    PyJsLvalArray10_ = Js([var.get(u'v').get(Js(0)),var.get(u'v').get(Js(1)),var.get(u'v').get(Js(2))])
    var.put(u'm', var.get(u'Matrix').callprop(u'Rotation',var.get(u'inRadians'),var.get(u'$V')(PyJsLvalArray10_)).callprop(u'ensure4x4'))
    var.get(u'multMatrix')(var.get(u'm'))
    pass
    pass
PyJsLvalTempHoisted.func_name = u'mvRotate'

var.put(u'mvRotate', PyJsLvalTempHoisted)
@Js
def PyJsLvalTempHoisted(this, arguments, var=var):
    var = Scope({'this':this, 'arguments':arguments}, var)
    if var.get(u'mvMatrixStack').get(u'length').neg():
        PyJsTempException = JsToPyException((Js(u"Can't pop from an empty matrix stack.")))
        raise PyJsTempException
        pass
    var.put(u'mvMatrix', var.get(u'mvMatrixStack').callprop(u'pop'))
    return var.get(u'mvMatrix')
    pass
    pass
PyJsLvalTempHoisted.func_name = u'mvPopMatrix'

var.put(u'mvPopMatrix', PyJsLvalTempHoisted)
pass
pass
pass
pass
pass
pass
var.put(u'cubeRotation', Js(0.0))
var.put(u'cubeXOffset', Js(0.0))
var.put(u'cubeYOffset', Js(0.0))
var.put(u'cubeZOffset', Js(0.0))
var.put(u'lastCubeUpdateTime', Js(0))
var.put(u'xIncValue', Js(0.2))
var.put(u'yIncValue', (-Js(0.4)))
var.put(u'zIncValue', Js(0.3))
pass
pass
pass
pass
pass
PyJsLvalArray9_ = Js([None])
var.put(u'mvMatrixStack', PyJsLvalArray9_)
pass

Possible bug: unicode encoding

Hello,

I tried running js2py on rita.js (https://raw.githubusercontent.com/dhowe/RiTaJS/master/src/rita.js) and got the following error.

Traceback (most recent call last):
  File "<pyshell#33>", line 1, in <module>
    lib = js2py.eval_js(l)
  File "..\python-3.4.3\lib\site-packages\js2py-0.35-py3.4.egg\js2py\evaljs.py", line 46, in eval_js
    return e.eval(js)
  File "..\python-3.4.3\lib\site-packages\js2py-0.35-py3.4.egg\js2py\evaljs.py", line 108, in eval
    self.execute(code, use_compilation_plan=use_compilation_plan)
  File "..\python-3.4.3\lib\site-packages\js2py-0.35-py3.4.egg\js2py\evaljs.py", line 97, in execute
    hashkey = hashlib.md5(js).digest()
TypeError: Unicode-objects must be encoded before hashing

Would you be able to help me figure the issue out, please? Thanks!

For record, js2py.translate_js works successfully.

I tried js2py.evaljs.EvalJs and got the following error:

context = context.__dict__
AttributeError: 'str' object has no attribute '__dict__'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<pyshell#42>", line 1, in <module>
    res = js2py.evaljs.EvalJs(l)
  File "...\python-3.4.3\lib\site-packages\js2py-0.35-py3.4.egg\js2py\evaljs.py", line 76, in __init__
    raise TypeError('context has to be either a dict or have __dict__ attr')
TypeError: context has to be either a dict or have __dict__ 

Is there anything I'm doing incorrectly/is my understanding of js2py flawed? I understand the 'use strict' limitation, but I'd figured that wouldn't hinder here...

Invalid Syntax

import js2py
Traceback (most recent call last):
File "", line 1, in
File "/usr/lib/python2.6/site-packages/Js2Py-0.35-py2.6.egg/js2py/init.py", line 67, in
from .evaljs import *
File "/usr/lib/python2.6/site-packages/Js2Py-0.35-py2.6.egg/js2py/evaljs.py", line 4, in
from .translators import translate_js, DEFAULT_HEADER
File "/usr/lib/python2.6/site-packages/Js2Py-0.35-py2.6.egg/js2py/translators/init.py", line 25, in
from .pyjsparser import PyJsParser, Node, WrappingNode, node_to_dict
File "/usr/lib/python2.6/site-packages/Js2Py-0.35-py2.6.egg/js2py/translators/pyjsparser.py", line 25
REGEXP_SPECIAL_SINGLE = {'^', '$', '*', '+', '?', '.', '[', ']', '(', ')', '{', '{', '|', '-'}
^
SyntaxError: invalid syntax

Crash when checking if String.replace accepts a function as a replacement value

Here is the test code:

import js2py
t = r'''function test() { if (!''.replace(/^/, String)) { console.log("passed!"); };}'''
js2py.eval_js(t)()

And the trace:

Traceback (most recent call last):
File "test.py", line 12, in
js2py.eval_js(t)()
File "/home/anon/Projects/libvid/js2py/base.py", line 999, in call
return to_python(parent._obj.callprop(meth, _args))
File "/home/anon/Projects/libvid/js2py/base.py", line 821, in callprop
return cand.call(self, args)
File "/home/anon/Projects/libvid/js2py/base.py", line 1191, in call
return Js(self.code(args))
File "", line 6, in PyJsHoisted_test

File "/home/anon/Projects/libvid/js2py/base.py", line 821, in callprop
return cand.call(self, args)
File "/home/anon/Projects/libvid/js2py/base.py", line 1191, in call
return Js(self.code(*args))
File "/home/anon/Projects/libvid/js2py/prototypes/jsstring.py", line 191, in replace
args = tuple(this.Js(x) for x in args)
File "/home/anon/Projects/libvid/js2py/prototypes/jsstring.py", line 191, in
args = tuple(this.Js(x) for x in args)
NameError: global name 'this' is not defined

This check is most commonly used with packer http://dean.edwards.name/packer/ with Base62 encoding enabled. It runs correctly if I remove the check and optimised code, but crashes again if I remove the check and fallback code. Packer without Base62 does not work due to lack of radix support for Number.toString, but works fine otherwise.

SyntaxError: invalid syntax for identifier named "not"

Hey, I have been playing around with transpiling the compiled neodoc output to python. However when I run it, I get this SyntaxError:

>>> context.eval(js)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python2.7/site-packages/js2py/evaljs.py", line 85, in eval
    self.execute(code)
  File "/usr/local/lib/python2.7/site-packages/js2py/evaljs.py", line 80, in execute
    exec(code, self._context)
  File "<string>", line 4, in <module>
  File "<string>", line 3, in PyJs_LONG_0_
  File "/usr/local/lib/python2.7/site-packages/js2py/base.py", line 827, in __call__
    return self.call(self.GlobalObject, args)
  File "/usr/local/lib/python2.7/site-packages/js2py/base.py", line 1267, in call
    return Js(self.code(*args))
  File "/usr/local/lib/python2.7/site-packages/js2py/host/jseval.py", line 42, in Eval
    executor(py_code)
  File "/usr/local/lib/python2.7/site-packages/js2py/host/jseval.py", line 49, in executor
    exec(code, globals())
  File "<string>", line 429
    def PyJs_anonymous_47_(PyJsArg_5f5f7375706572636c6173735f5072656c75646524646f74426f756e6465645f30_, conj, disj, not, this, arguments, var=var):
                                                                                                                      ^
SyntaxError: invalid syntax
>>>

I assume it has today with "not" being a python keyword? You can grab a copy of the source JS from here: https://registry.npmjs.org/neodoc/-/neodoc-0.3.0.tgz ("dist/docopt.purs.js").

Support generic use of Array.prototype.forEach?

Here is the test case:

import js2py
t = r'''[].forEach.call("test", function(ch) { console.log(ch) });'''
js2py.eval_js(t)

Information from the spec:

NOTE The forEach function is intentionally generic; it does not require that its this value be an Array object. Therefore it can be transferred to other kinds of objects for use as a method. Whether the forEach function can be applied successfully to a host object is implementation-dependent.

I'm asking about this because I'm working on the unimplemented functions in prototypes/jsarray.py and this issue is making some of my (pre-submission) tests fail.

Tidying up the license info.

I've opened a pull request #8 to clean up the license information a little bit.
Having a license file say the code is under MIT, but setup.py indicate that it is under GPL creates confusion.

I've changed setup.py from GPL to MIT in the linked pull request, since you have only recently added the explicit license.txt file where as the GPL keyword in setup.py was in the first commit of that file, and choosing to add an entire license file seems like a clear decision on which license you actually wanted to use for the project.

unable to import js2py python 2.6

installed with PIP . Python 2.6
All packages are installed automatically
Error :

import js2py

Traceback (most recent call last):
File "<pyshell#20>", line 1, in
import js2py
File "C:\Python26\lib\site-packages\js2py__init__.py", line 67, in
from .evaljs import *
File "C:\Python26\lib\site-packages\js2py\evaljs.py", line 4, in
from .translators import translate_js, DEFAULT_HEADER
File "C:\Python26\lib\site-packages\js2py\translators__init__.py", line 25, in
from .pyjsparser import PyJsParser, Node, WrappingNode, node_to_dict
File "C:\Python26\lib\site-packages\js2py\translators\pyjsparser.py", line 25
REGEXP_SPECIAL_SINGLE = {'', '^', '$', '*', '+', '?', '.', '[', ']', '(', ')', '{', '{', '|'}
^
SyntaxError: invalid syntax

incomplete js date constructor

The JS "Date" constructor seems incomplete. Can't create a date from ISO string using new Date(str) or Date.parse(str). The reason is that parse_date returns NotImplementedError.

pip install fails with FileNotFoundError

Complete output from command python setup.py egg_info:
    Traceback (most recent call last):
      File "<string>", line 20, in <module>
      File "/private/tmp/pip-build-qfdeesuo/js2py/setup.py", line 14, in <module>
        long_description=open('README.rst', 'rt').read()
    FileNotFoundError: [Errno 2] No such file or directory: 'README.rst'

    ----------------------------------------
Command "python setup.py egg_info" failed with error code 1 in /private/tmp/pip-build-qfdeesuo/js2py

Pip and setuptools are all up to date.

Perhaps I have something else set up wrong?

Support "require"

If js file has lines like

var emmet = reqiure "lib/emmet.js"

then require-lines not compiled: I see errors about "Syntax error: Line 4: Unexpected string". Is it right?
It is very much needed to support require. Eg, Emmet variant (one of) has nn js files and main file calls nn-1 js files via "require"

Quick question: is there any reason you can think of that this translator would not be an optimal translation path to port JS code to C/C++ using Cython or simuliar?

Setting aside of course web platform features being specifically supported in the translation, could one feasibly think the resultant code should be at least something in the same ballpark as the efficiency of handwritten (by a stupid like me) C/C++?

Everything is focused on C/C++ to JS, but I have an equal (perhaps greater) need for just the opposite.

KeyError: 0.9722222222222222

Hello, I got a error when I run the following script:

import js2py

js = r'''
eval(function(p,a,c,k,e,d){e=function(c){return(c<a?"":e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)d[e(c)]=k[c]||e(c);k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1;};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p;}('M l={"m":3,"n":"i","j":"3.0","k":r,"s":t,"o":"6","p":["q.0","9.0","8.0","7.0","f.0","g.0","h.0","e.0","b.0","c.0","d.0","a.0","u.0","L.0","D.0","K.0","I.0","J.0","N.0","R.0","S.0","O(1).0","P.0","Q.0","%2%5%4%2%5%4%H%y%A.0"],"x":v,"w":B,"F":"/G/z/E/6/","C":1}||{};',55,55,'jpg||E8|20275|8C|90|第04回|0003|0002|0001|0011|0008|0009|0010|0007|0004|0005|0006|终末的后宫|bpic|burl|cInfo|bid|bname|cname|files|0000|null|cid|241532|0012|false|len|finished|93||92|25|status|0014|zhongmodehougong_link|path|ps1|E5|0016|0017|0015|0013|var|0018|0021v2|0022|0023|0019|0020'.split('|'),0,{}))
'''

context = js2py.EvalJs()
context.execute(js)  # ERROR
context.eval('cInfo')

If success, this js script will write a global variable cInfo in javascript context. but i got ...

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.4/dist-packages/js2py/evaljs.py", line 131, in execute
    exec(compiled, self._context)
  File "<EvalJS snippet>", line 40, in <module>
  File "<EvalJS snippet>", line 39, in PyJs_LONG_5_
  File "/usr/local/lib/python3.4/dist-packages/js2py/base.py", line 835, in __call__
    return self.call(self.GlobalObject, args)
  File "/usr/local/lib/python3.4/dist-packages/js2py/base.py", line 1275, in call
    return Js(self.code(*args))
  File "<EvalJS snippet>", line 17, in PyJs_anonymous_1_
  File "/usr/local/lib/python3.4/dist-packages/js2py/base.py", line 835, in __call__
    return self.call(self.GlobalObject, args)
  File "/usr/local/lib/python3.4/dist-packages/js2py/base.py", line 1275, in call
    return Js(self.code(*args))
  File "<EvalJS snippet>", line 12, in PyJs_anonymous_2_
  File "/usr/local/lib/python3.4/dist-packages/js2py/base.py", line 875, in callprop
    return cand.call(self, args)
  File "/usr/local/lib/python3.4/dist-packages/js2py/base.py", line 1275, in call
    return Js(self.code(*args))
  File "/usr/local/lib/python3.4/dist-packages/js2py/prototypes/jsnumber.py", line 45, in toString
    s = RADIX_SYMBOLS[num % r]
KeyError: 0.9722222222222222

The Key not a integer or str... Maybe cause by str <-> int <-> float converting? But not really sure.

I also run this js code in node.js to make sure it is a valid script:

user@mycompute ~/test/execjs $ nodejs
> eval(function(p,a,c,k,e,d){e=function(c){return(c<a?"":e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)d[e(c)]=k[c]||e(c);k=[> eval(function(p,a,c,k,e,d){e=function(c){return(c<a?"":e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)d[e(c)]=k[c]||e(c);k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1;};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p;}('M l={"m":3,"n":"i","j":"3.0","k":r,"s":t,"o":"6","p":["q.0","9.0","8.0","7.0","f.0","g.0","h.0","e.0","b.0","c.0","d.0","a.0","u.0","L.0","D.0","K.0","I.0","J.0","N.0","R.0","S.0","O(1).0","P.0","Q.0","%2%5%4%2%5%4%H%y%A.0"],"x":v,"w":B,"F":"/G/z/E/6/","C":1}||{};',55,55,'jpg||E8|20275|8C|90|第04回|0003|0002|0001|0011|0008|0009|0010|0007|0004|0005|0006|终末的后宫|bpic|burl|cInfo|bid|bname|cname|files|0000|null|cid|241532|0012|en|finished|93||92|25|status|0014|zhongmodehougong_link|path|ps1|E5|0016|0017|0015|0013|var|0018|0021v2|0022|0023|0019|0020'.split('|'),0,{}))
undefined
> cInfo
{ bid: 20275,
  bname: '终末的后宫',
  bpic: '20275.jpg',
  burl: null,
  cid: 241532,
  cname: '第04回',
  files: 
   [ '0000.jpg',
     '0001.jpg',
     '0002.jpg',
     '0003.jpg',
     '0004.jpg',
     '0005.jpg',
     '0006.jpg',
     '0007.jpg',
     '0008.jpg',
     '0009.jpg',
     '0010.jpg',
     '0011.jpg',
     '0012.jpg',
     '0013.jpg',
     '0014.jpg',
     '0015.jpg',
     '0016.jpg',
     '0017.jpg',
     '0018.jpg',
     '0019.jpg',
     '0020.jpg',
     '0021v2(1).jpg',
     '0022.jpg',
     '0023.jpg',
     '%E8%90%8C%E8%90%8C%E5%93%92.jpg' ],
  finished: false,
  len: 25,
  path: '/ps1/z/zhongmodehougong_link/第04回/',
  status: 1 }
> 

System Info

  • ubuntu 15.10
  • python: 3.4.3
  • Js2Py version: 0.36
  • how to install js2py: sudo -H pip3 install js2py

Thank you so!

Feature suggestion

This is a secondary issue. If there's a file ending in

,"created_at":"2015-07-11 22:45:53"},{

Your fixer will cure the problem and place any {}[] characters as needed for completion.

However, if in the above example the file ends in

,"creat

The closing quote will be placed, however the value part of the key : value pair will be missing, and prevent json from parsing.

My temporary suggested fix is to iterate through your fixer, removing the last character until I get the fixed json to validate; but perhaps there's a better method.

Use context with `translate_file`

Is there a way to provide your own context in combination with using translate_file? I want to translate a file up front with translate_file, but the functions in the file call global methods that aren't built in, and therefore want to define from within Python.

Recursion depth error on large Js files using translated esprima.js

SOLUTION:

Change python's recursion limit to ~4k.


Found a potential issue while parsing large files such as angular.js (1.5.8).

file = open("angular.js")
input = file.read()
file.close()

#import esprima
ast = esprima.parse(input)

This produces a RecursionError: maximum recursion depth exceeded error with a stack trace showing calls to the following:

return Js(self.code(*args))
var.put('result', var.get('parser')())
return self.call(self.GlobalObject, args)
arguments = PyJsArguments(args, self) # tuple will be converted to arguments object.
RecursionError: maximum recursion depth exceeded

In python 3 the following error is also thrown:

During handling of the above exception, another exception occurred:
.
.
.
return Js(self.code(*args))
var.put('expr', var.get('inheritCoverGrammar')((var.get('parseNewExpression') if var.get('matchKeyword')(Js('new')) else var.get('parsePrimaryExpression'))))
return self.call(self.GlobalObject, args)
raise MakeError('RangeError', e.message if not isinstance(e, NotImplementedError) else 'Not  implemented!')
AttributeError: 'RecursionError' object has no attribute 'message'

The parse_js() function can parse the input without error.

Error running basic example

Hi Piotr, I installes OK however running example gives error

See dump, any suggestions ?

many thanks,

André
Python 3.6.0b1 (default, Sep 12 2016, 18:11:36) [MSC v.1900 64 bit (AMD64)] on win32
Type "copyright", "credits" or "license()" for more information.

import js2py
js2py.eval_js('console.log( "Hello World!" )')
Traceback (most recent call last):
File "<pyshell#1>", line 1, in
js2py.eval_js('console.log( "Hello World!" )')
File "C:\Users\andre\AppData\Local\Programs\Python\Python36\lib\site-packages\js2py\evaljs.py", line 109, in eval_js
e = EvalJs()
File "C:\Users\andre\AppData\Local\Programs\Python\Python36\lib\site-packages\js2py\evaljs.py", line 134, in init
exec(DEFAULT_HEADER, self._context)
File "", line 1, in
File "C:\Users\andre\AppData\Local\Programs\Python\Python36\lib\site-packages\js2py\pyjs.py", line 1, in
from .base import *
File "C:\Users\andre\AppData\Local\Programs\Python\Python36\lib\site-packages\js2py\base.py", line 1564, in
FunctionPrototype = PyJsFunction(Empty, ObjectPrototype)
File "C:\Users\andre\AppData\Local\Programs\Python\Python36\lib\site-packages\js2py\base.py", line 1216, in init
cand = fix_js_args(func)
File "C:\Users\andre\AppData\Local\Programs\Python\Python36\lib\site-packages\js2py\utils\injector.py", line 23, in fix_js_args
code = append_arguments(six.get_function_code(func), ('this','arguments'))
File "C:\Users\andre\AppData\Local\Programs\Python\Python36\lib\site-packages\js2py\utils\injector.py", line 84, in append_arguments
raise ValueError("a name was lost in translation")
ValueError: a name was lost in translation

Error while using with Bezier.js

I have used Js2Py with Bezier.js, writing code as below:

js = js2py.EvalJs(open('bezier.js').read())
js.execute("""
  var curve = new Bezier(100, 25, 10, 90, 110, 100, 132, 192);
  curve.offset(25);  // it cause TypeError: PyJsLvalInline() takes exactly 2 arguments (4 given)
""")

then I switched to PyV8, it works fine. I don't know why, just tell u.

Python 2.6 not supported

Python 2.6 is not supported.

The included translator pyjsparser.py is not supporting 2.6. Also I don't know what else...

Also in setup.py , in nstall_requires = ['tzlocal>=1.2', 'six>=1.10'],
the pyjsparser is not stated although it included in your source tree...

If you could depent on pyjsparser externally in this project I could fix python 2.6 support of pyjsparser.

Unable to import js2py

After cloning the package and adding its path in sys.path I am not able to import the library.

>>> import Js2Py.js2py
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/Js2Py/js2py/__init__.py", line 67, in <module>
    from js2py.evaljs import *
ImportError: No module named 'js2py'
>>> sys.path.append('/Users/Js2Py')
>>> import js2py
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/Js2Py/js2py/__init__.py", line 67, in <module>
    from js2py.evaljs import *
  File "/Users/Js2Py/js2py/evaljs.py", line 56
    exec DEFAULT_HEADER in self._context
                      ^
SyntaxError: Missing parentheses in call to 'exec'
>>> 

operated on python3.4 on Mac

import error: jsparserdata

in \js2py\translators\translating_nodes.py:
from pyjsparserdata import *

should be:
from pyjsparser.pyjsparserdata import *

Forward slash handling broken

Here is the test case:

import js2py
t = r'''function test() {return "test failed!".replace(new RegExp('\sfailed','g'), ' passed')}'''
print js2py.eval_js(t)()

Running it returns "test failed!", but if you change the pattern to '\\sfailed' it will return "test passed!". I recorded what passed through PyJsString.init() and it spit out:

test failed!
\sfailed
g
sfailed
passed
test failed!

It it unescapes once (which I think is the correct behavior), but does it again later for some reason. Sorry I don't have any more information, I just found this program last night and don't know enough to effectively track down bugs yet.

Possible to disable "pyimport"

I have a quick question regarding this project, it looks great by the way. My question is two fold, first is it possible to disable the pyimport statement? Secondly, if it is possible, to your knowledge would this effectively create an execution sandbox that would be suitable for running untrusted code? Thanks!

Uint32Array

I get an error while using Uint32Array in JScript.
Can you add support for that?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.