From 89a088f9d7711a0c0a08cd8d9ebac6849776f9e3 Mon Sep 17 00:00:00 2001 From: hartsantler Date: Tue, 15 Jul 2014 01:41:25 -0700 Subject: [PATCH 001/100] `float('NaN')` and `float('Inf')` are now allowed. --- pythonjs/pythonjs.js | 89 ++++++++++++++++++++---------------- pythonjs/runtime/builtins.py | 15 ++++-- regtests/lang/builtins.py | 13 ++++++ regtests/run.py | 19 ++++++-- 4 files changed, 87 insertions(+), 49 deletions(-) create mode 100644 regtests/lang/builtins.py diff --git a/pythonjs/pythonjs.js b/pythonjs/pythonjs.js index 12796fe..876163a 100644 --- a/pythonjs/pythonjs.js +++ b/pythonjs/pythonjs.js @@ -1614,7 +1614,7 @@ int16 = function(a) { } float = function(args, kwargs) { - + var b; var __sig__,__args__; __sig__ = { kwargs:{},args:["a"] }; if (args instanceof Array && ( Object.prototype.toString.call(kwargs) ) == "[object Object]" && ( arguments.length ) == 2) { @@ -1625,11 +1625,20 @@ float = function(args, kwargs) { } __args__ = __getargs__("float", __sig__, args, kwargs); var a = __args__['a']; - a = Number(a); - if (__test_if_true__(isNaN(a))) { - throw new ValueError("not a number"); + if (( typeof(a) ) == "string") { + if (( a.lower() ) == "nan") { + return NaN; + } else { + if (( a.lower() ) == "inf") { + return Infinity; + } + } } - return a; + b = Number(a); + if (__test_if_true__(isNaN(b))) { + throw new ValueError(("can not convert to float: " + a)); + } + return b; } ;float.is_wrapper = true; round = function(args, kwargs) { @@ -2291,7 +2300,7 @@ sum = function(args, kwargs) { var arr = __args__['arr']; a = 0; var b,__iterator__40; - __iterator__40 = __get__(__get__(arr, "__iter__", "no iterator - line 1013: for b in arr:"), "__call__")([], __NULL_OBJECT__); + __iterator__40 = __get__(__get__(arr, "__iter__", "no iterator - line 1019: for b in arr:"), "__call__")([], __NULL_OBJECT__); var __next__40; __next__40 = __get__(__iterator__40, "next"); while (( __iterator__40.index ) < __iterator__40.length) { @@ -2349,7 +2358,7 @@ next = function(args, kwargs) { } __args__ = __getargs__("next", __sig__, args, kwargs); var obj = __args__['obj']; - return __get__(__get__(obj, "next", "missing attribute `next` - line 1031: return obj.next()"), "__call__")(); + return __get__(__get__(obj, "next", "missing attribute `next` - line 1037: return obj.next()"), "__call__")(); } ;next.is_wrapper = true; map = function(args, kwargs) { @@ -2367,7 +2376,7 @@ map = function(args, kwargs) { var objs = __args__['objs']; arr = []; var ob,__iterator__41; - __iterator__41 = __get__(__get__(objs, "__iter__", "no iterator - line 1034: for ob in objs:"), "__call__")([], __NULL_OBJECT__); + __iterator__41 = __get__(__get__(objs, "__iter__", "no iterator - line 1040: for ob in objs:"), "__call__")([], __NULL_OBJECT__); var __next__41; __next__41 = __get__(__iterator__41, "next"); while (( __iterator__41.index ) < __iterator__41.length) { @@ -2393,7 +2402,7 @@ filter = function(args, kwargs) { var objs = __args__['objs']; arr = []; var ob,__iterator__42; - __iterator__42 = __get__(__get__(objs, "__iter__", "no iterator - line 1041: for ob in objs:"), "__call__")([], __NULL_OBJECT__); + __iterator__42 = __get__(__get__(objs, "__iter__", "no iterator - line 1047: for ob in objs:"), "__call__")([], __NULL_OBJECT__); var __next__42; __next__42 = __get__(__iterator__42, "next"); while (( __iterator__42.index ) < __iterator__42.length) { @@ -2419,7 +2428,7 @@ min = function(args, kwargs) { var lst = __args__['lst']; a = null; var value,__iterator__43; - __iterator__43 = __get__(__get__(lst, "__iter__", "no iterator - line 1048: for value in lst:"), "__call__")([], __NULL_OBJECT__); + __iterator__43 = __get__(__get__(lst, "__iter__", "no iterator - line 1054: for value in lst:"), "__call__")([], __NULL_OBJECT__); var __next__43; __next__43 = __get__(__iterator__43, "next"); while (( __iterator__43.index ) < __iterator__43.length) { @@ -2449,7 +2458,7 @@ max = function(args, kwargs) { var lst = __args__['lst']; a = null; var value,__iterator__44; - __iterator__44 = __get__(__get__(lst, "__iter__", "no iterator - line 1054: for value in lst:"), "__call__")([], __NULL_OBJECT__); + __iterator__44 = __get__(__get__(lst, "__iter__", "no iterator - line 1060: for value in lst:"), "__call__")([], __NULL_OBJECT__); var __next__44; __next__44 = __get__(__iterator__44, "next"); while (( __iterator__44.index ) < __iterator__44.length) { @@ -2559,7 +2568,7 @@ __Iterator___init__ = function(args, kwargs) { self.obj = obj; self.index = index; self.length = len([obj], __NULL_OBJECT__); - self.obj_get = __get__(obj, "get", "missing attribute `get` - line 1082: self.obj_get = obj.get ## cache this for speed"); + self.obj_get = __get__(obj, "get", "missing attribute `get` - line 1088: self.obj_get = obj.get ## cache this for speed"); } ;__Iterator___init__.is_wrapper = true; __Iterator_attrs.__init__ = __Iterator___init__; @@ -2666,27 +2675,27 @@ __dict___init__ = function(args, kwargs) { ob = js_object; if (__test_if_true__(ob instanceof Array)) { var o,__iterator__45; - __iterator__45 = __get__(__get__(ob, "__iter__", "no iterator - line 1125: for o in ob:"), "__call__")([], __NULL_OBJECT__); + __iterator__45 = __get__(__get__(ob, "__iter__", "no iterator - line 1131: for o in ob:"), "__call__")([], __NULL_OBJECT__); var __next__45; __next__45 = __get__(__iterator__45, "next"); while (( __iterator__45.index ) < __iterator__45.length) { o = __next__45(); if (__test_if_true__(o instanceof Array)) { - __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1127: self.__setitem__( o[0], o[1] )"), "__call__")([((o instanceof Array) ? o[0] : __get__(o, "__getitem__", "line 1127: self.__setitem__( o[0], o[1] )")([0], __NULL_OBJECT__)), ((o instanceof Array) ? o[1] : __get__(o, "__getitem__", "line 1127: self.__setitem__( o[0], o[1] )")([1], __NULL_OBJECT__))], __NULL_OBJECT__); + __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1133: self.__setitem__( o[0], o[1] )"), "__call__")([((o instanceof Array) ? o[0] : __get__(o, "__getitem__", "line 1133: self.__setitem__( o[0], o[1] )")([0], __NULL_OBJECT__)), ((o instanceof Array) ? o[1] : __get__(o, "__getitem__", "line 1133: self.__setitem__( o[0], o[1] )")([1], __NULL_OBJECT__))], __NULL_OBJECT__); } else { - __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1129: self.__setitem__( o['key'], o['value'] )"), "__call__")([((o instanceof Array) ? o["key"] : __get__(o, "__getitem__", "line 1129: self.__setitem__( o['key'], o['value'] )")(["key"], __NULL_OBJECT__)), ((o instanceof Array) ? o["value"] : __get__(o, "__getitem__", "line 1129: self.__setitem__( o['key'], o['value'] )")(["value"], __NULL_OBJECT__))], __NULL_OBJECT__); + __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1135: self.__setitem__( o['key'], o['value'] )"), "__call__")([((o instanceof Array) ? o["key"] : __get__(o, "__getitem__", "line 1135: self.__setitem__( o['key'], o['value'] )")(["key"], __NULL_OBJECT__)), ((o instanceof Array) ? o["value"] : __get__(o, "__getitem__", "line 1135: self.__setitem__( o['key'], o['value'] )")(["value"], __NULL_OBJECT__))], __NULL_OBJECT__); } } } else { if (__test_if_true__(isinstance([ob, dict], __NULL_OBJECT__))) { var key,__iterator__46; - __iterator__46 = __get__(__get__(__jsdict_keys(ob), "__iter__", "no iterator - line 1131: for key in ob.keys():"), "__call__")([], __NULL_OBJECT__); + __iterator__46 = __get__(__get__(__jsdict_keys(ob), "__iter__", "no iterator - line 1137: for key in ob.keys():"), "__call__")([], __NULL_OBJECT__); var __next__46; __next__46 = __get__(__iterator__46, "next"); while (( __iterator__46.index ) < __iterator__46.length) { key = __next__46(); - value = ((ob instanceof Array) ? ob[key] : __get__(ob, "__getitem__", "line 1132: value = ob[ key ]")([key], __NULL_OBJECT__)); - __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1133: self.__setitem__( key, value )"), "__call__")([key, value], __NULL_OBJECT__); + value = ((ob instanceof Array) ? ob[key] : __get__(ob, "__getitem__", "line 1138: value = ob[ key ]")([key], __NULL_OBJECT__)); + __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1139: self.__setitem__( key, value )"), "__call__")([key, value], __NULL_OBJECT__); } } else { console.log("ERROR init dict from:", js_object); @@ -2712,15 +2721,15 @@ __dict_jsify = function(args, kwargs) { var self = __args__['self']; keys = __object_keys__([self["$wrapped"]], __NULL_OBJECT__); var key,__iterator__47; - __iterator__47 = __get__(__get__(keys, "__iter__", "no iterator - line 1140: for key in keys:"), "__call__")([], __NULL_OBJECT__); + __iterator__47 = __get__(__get__(keys, "__iter__", "no iterator - line 1146: for key in keys:"), "__call__")([], __NULL_OBJECT__); var __next__47; __next__47 = __get__(__iterator__47, "next"); while (( __iterator__47.index ) < __iterator__47.length) { key = __next__47(); - value = __get__(self["$wrapped"], "__getitem__", "line 1141: value = self[...][key]")([key], __NULL_OBJECT__); + value = __get__(self["$wrapped"], "__getitem__", "line 1147: value = self[...][key]")([key], __NULL_OBJECT__); if (( typeof(value) ) == "object") { if (__test_if_true__(hasattr([value, "jsify"], __NULL_OBJECT__))) { - __get__(__get__(self["$wrapped"], "__setitem__"), "__call__")([key, __get__(__get__(value, "jsify", "missing attribute `jsify` - line 1144: self[...][key] = value.jsify()"), "__call__")()], {}); + __get__(__get__(self["$wrapped"], "__setitem__"), "__call__")([key, __get__(__get__(value, "jsify", "missing attribute `jsify` - line 1150: self[...][key] = value.jsify()"), "__call__")()], {}); } } else { if (( typeof(value) ) == "function") { @@ -2779,7 +2788,7 @@ __dict_has_key = function(args, kwargs) { var key = __args__['key']; __dict = self["$wrapped"]; if (__test_if_true__(typeof(key) === 'object' || typeof(key) === 'function')) { - key = __get__(key, "__uid__", "missing attribute `__uid__` - line 1157: key = key.__uid__"); + key = __get__(key, "__uid__", "missing attribute `__uid__` - line 1163: key = key.__uid__"); } if (__test_if_true__(key in __dict)) { return true; @@ -2803,12 +2812,12 @@ __dict_update = function(args, kwargs) { var self = __args__['self']; var other = __args__['other']; var key,__iterator__48; - __iterator__48 = __get__(__get__(other, "__iter__", "no iterator - line 1163: for key in other:"), "__call__")([], __NULL_OBJECT__); + __iterator__48 = __get__(__get__(other, "__iter__", "no iterator - line 1169: for key in other:"), "__call__")([], __NULL_OBJECT__); var __next__48; __next__48 = __get__(__iterator__48, "next"); while (( __iterator__48.index ) < __iterator__48.length) { key = __next__48(); - __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1164: self.__setitem__( key, other[key] )"), "__call__")([key, ((other instanceof Array) ? other[key] : __get__(other, "__getitem__", "line 1164: self.__setitem__( key, other[key] )")([key], __NULL_OBJECT__))], __NULL_OBJECT__); + __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1170: self.__setitem__( key, other[key] )"), "__call__")([key, ((other instanceof Array) ? other[key] : __get__(other, "__getitem__", "line 1170: self.__setitem__( key, other[key] )")([key], __NULL_OBJECT__))], __NULL_OBJECT__); } } ;__dict_update.is_wrapper = true; @@ -2827,12 +2836,12 @@ __dict_items = function(args, kwargs) { var self = __args__['self']; arr = []; var key,__iterator__49; - __iterator__49 = __get__(__get__(__jsdict_keys(self), "__iter__", "no iterator - line 1167: for key in self.keys():"), "__call__")([], __NULL_OBJECT__); + __iterator__49 = __get__(__get__(__jsdict_keys(self), "__iter__", "no iterator - line 1173: for key in self.keys():"), "__call__")([], __NULL_OBJECT__); var __next__49; __next__49 = __get__(__iterator__49, "next"); while (( __iterator__49.index ) < __iterator__49.length) { key = __next__49(); - __get__(__get__(arr, "append", "missing attribute `append` - line 1168: arr.append( [key, self[key]] )"), "__call__")([[key, __get__(self, "__getitem__")([key], __NULL_OBJECT__)]], __NULL_OBJECT__); + __get__(__get__(arr, "append", "missing attribute `append` - line 1174: arr.append( [key, self[key]] )"), "__call__")([[key, __get__(self, "__getitem__")([key], __NULL_OBJECT__)]], __NULL_OBJECT__); } return arr; } @@ -2875,7 +2884,7 @@ __dict_set = function(args, kwargs) { var self = __args__['self']; var key = __args__['key']; var value = __args__['value']; - __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1176: self.__setitem__(key, value)"), "__call__")([key, value], __NULL_OBJECT__); + __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1182: self.__setitem__(key, value)"), "__call__")([key, value], __NULL_OBJECT__); } ;__dict_set.is_wrapper = true; __dict_attrs.set = __dict_set; @@ -3169,7 +3178,7 @@ __array___init__ = function(args, kwargs) { var initializer = __args__['initializer']; var little_endian = __args__['little_endian']; self.typecode = typecode; - self.itemsize = __get__(__get__(self, "typecodes", "missing attribute `typecodes` - line 1344: self.itemsize = self.typecodes[ typecode ]"), "__getitem__", "line 1344: self.itemsize = self.typecodes[ typecode ]")([typecode], __NULL_OBJECT__); + self.itemsize = __get__(__get__(self, "typecodes", "missing attribute `typecodes` - line 1350: self.itemsize = self.typecodes[ typecode ]"), "__getitem__", "line 1350: self.itemsize = self.typecodes[ typecode ]")([typecode], __NULL_OBJECT__); self.little_endian = little_endian; if (__test_if_true__(initializer)) { self.length = len([initializer], __NULL_OBJECT__); @@ -3193,7 +3202,7 @@ __array___init__ = function(args, kwargs) { buff = new ArrayBuffer(size); self.dataview = new DataView(buff); self.buffer = buff; - __get__(__get__(self, "fromlist", "missing attribute `fromlist` - line 1365: self.fromlist( initializer )"), "__call__")([initializer], __NULL_OBJECT__); + __get__(__get__(self, "fromlist", "missing attribute `fromlist` - line 1371: self.fromlist( initializer )"), "__call__")([initializer], __NULL_OBJECT__); } ;__array___init__.is_wrapper = true; __array_attrs.__init__ = __array___init__; @@ -3226,7 +3235,7 @@ __array___contains__ = function(args, kwargs) { __args__ = __getargs__("__array___contains__", __sig__, args, kwargs); var self = __args__['self']; var value = __args__['value']; - arr = __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1371: arr = self.to_array()"), "__call__")(); + arr = __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1377: arr = self.to_array()"), "__call__")(); if (( arr.indexOf(value) ) == -1) { return false; } else { @@ -3251,7 +3260,7 @@ __array___getitem__ = function(args, kwargs) { step = self.itemsize; offset = (step * index); dataview = self.dataview; - func_name = ("get" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1379: func_name = 'get'+self.typecode_names[ self.typecode ]"), "__getitem__", "line 1379: func_name = 'get'+self.typecode_names[ self.typecode ]")([self.typecode], __NULL_OBJECT__)); + func_name = ("get" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1385: func_name = 'get'+self.typecode_names[ self.typecode ]"), "__getitem__", "line 1385: func_name = 'get'+self.typecode_names[ self.typecode ]")([self.typecode], __NULL_OBJECT__)); func = dataview[func_name].bind(dataview); if (( offset ) < self.bytes) { value = func(offset); @@ -3289,7 +3298,7 @@ __array___setitem__ = function(args, kwargs) { } offset = (step * index); dataview = self.dataview; - func_name = ("set" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1395: func_name = 'set'+self.typecode_names[ self.typecode ]"), "__getitem__", "line 1395: func_name = 'set'+self.typecode_names[ self.typecode ]")([self.typecode], __NULL_OBJECT__)); + func_name = ("set" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1401: func_name = 'set'+self.typecode_names[ self.typecode ]"), "__getitem__", "line 1401: func_name = 'set'+self.typecode_names[ self.typecode ]")([self.typecode], __NULL_OBJECT__)); func = dataview[func_name].bind(dataview); if (( offset ) < self.bytes) { if (( self.typecode ) == "float8") { @@ -3357,13 +3366,13 @@ __array_fromlist = function(args, kwargs) { typecode = self.typecode; size = (length * step); dataview = self.dataview; - func_name = ("set" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1415: func_name = 'set'+self.typecode_names[ typecode ]"), "__getitem__", "line 1415: func_name = 'set'+self.typecode_names[ typecode ]")([typecode], __NULL_OBJECT__)); + func_name = ("set" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1421: func_name = 'set'+self.typecode_names[ typecode ]"), "__getitem__", "line 1421: func_name = 'set'+self.typecode_names[ typecode ]")([typecode], __NULL_OBJECT__)); func = dataview[func_name].bind(dataview); if (( size ) <= self.bytes) { i = 0; offset = 0; while (( i ) < length) { - item = ((lst instanceof Array) ? lst[i] : __get__(lst, "__getitem__", "line 1420: item = lst[i]")([i], __NULL_OBJECT__)); + item = ((lst instanceof Array) ? lst[i] : __get__(lst, "__getitem__", "line 1426: item = lst[i]")([i], __NULL_OBJECT__)); if (( typecode ) == "float8") { item *= self._norm_set; } else { @@ -3421,7 +3430,7 @@ __array_append = function(args, kwargs) { var self = __args__['self']; var value = __args__['value']; length = self.length; - __get__(__get__(self, "resize", "missing attribute `resize` - line 1443: self.resize( self.length + 1 )"), "__call__")([(self.length + 1)], __NULL_OBJECT__); + __get__(__get__(self, "resize", "missing attribute `resize` - line 1449: self.resize( self.length + 1 )"), "__call__")([(self.length + 1)], __NULL_OBJECT__); __get__(__get__(self, "__setitem__"), "__call__")([length, value], {}); } ;__array_append.is_wrapper = true; @@ -3440,12 +3449,12 @@ __array_extend = function(args, kwargs) { var self = __args__['self']; var lst = __args__['lst']; var value,__iterator__54; - __iterator__54 = __get__(__get__(lst, "__iter__", "no iterator - line 1446: for value in lst:"), "__call__")([], __NULL_OBJECT__); + __iterator__54 = __get__(__get__(lst, "__iter__", "no iterator - line 1452: for value in lst:"), "__call__")([], __NULL_OBJECT__); var __next__54; __next__54 = __get__(__iterator__54, "next"); while (( __iterator__54.index ) < __iterator__54.length) { value = __next__54(); - __get__(__get__(self, "append", "missing attribute `append` - line 1447: self.append( value )"), "__call__")([value], __NULL_OBJECT__); + __get__(__get__(self, "append", "missing attribute `append` - line 1453: self.append( value )"), "__call__")([value], __NULL_OBJECT__); } } ;__array_extend.is_wrapper = true; @@ -3485,7 +3494,7 @@ __array_to_list = function(args, kwargs) { } __args__ = __getargs__("__array_to_list", __sig__, args, kwargs); var self = __args__['self']; - return __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1457: return self.to_array()"), "__call__")(); + return __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1463: return self.to_array()"), "__call__")(); } ;__array_to_list.is_wrapper = true; __array_attrs.to_list = __array_to_list; @@ -3502,9 +3511,9 @@ __array_to_ascii = function(args, kwargs) { __args__ = __getargs__("__array_to_ascii", __sig__, args, kwargs); var self = __args__['self']; string = ""; - arr = __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1460: arr = self.to_array()"), "__call__")(); + arr = __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1466: arr = self.to_array()"), "__call__")(); i = 0; - length = __get__(arr, "length", "missing attribute `length` - line 1461: i = 0; length = arr.length"); + length = __get__(arr, "length", "missing attribute `length` - line 1467: i = 0; length = arr.length"); while (( i ) < length) { var num = arr[i]; var char = String.fromCharCode(num); diff --git a/pythonjs/runtime/builtins.py b/pythonjs/runtime/builtins.py index 5feb40d..972b179 100644 --- a/pythonjs/runtime/builtins.py +++ b/pythonjs/runtime/builtins.py @@ -752,10 +752,17 @@ def int16(a): ## used by glsljit when packing structs. def float(a): with javascript: - a = Number(a) - if isNaN(a): - raise ValueError('not a number') - return a + if typeof(a)=='string': + if a.lower()=='nan': + return NaN + elif a.lower()=='inf': + return Infinity + + b = Number(a) + if isNaN(b): + ## invalid strings also convert to NaN, throw error ## + raise ValueError('can not convert to float: '+a) + return b def round(a, places): with javascript: diff --git a/regtests/lang/builtins.py b/regtests/lang/builtins.py new file mode 100644 index 0000000..df562bb --- /dev/null +++ b/regtests/lang/builtins.py @@ -0,0 +1,13 @@ +''' +builtin functions +''' + + +def main(): + n = float('1.1') + TestError( n==1.1 ) + + n = float('NaN') + TestError( isNaN(n)==True ) + + diff --git a/regtests/run.py b/regtests/run.py index d78399f..127b182 100755 --- a/regtests/run.py +++ b/regtests/run.py @@ -361,9 +361,12 @@ def TestWarning(file, line, result, test): """ _python_only_extra_header = """ -import threading -threading.start_webworker = lambda f,a: threading._start_new_thread(f,a) -threading.start_new_thread = threading._start_new_thread +try: + import threading + threading.start_webworker = lambda f,a: threading._start_new_thread(f,a) + threading.start_new_thread = threading._start_new_thread +except ImportError: + pass class __faker__(object): def __enter__(self, *args): pass @@ -391,8 +394,14 @@ def int16(a): return int(a) try: import numpy -except: - import numpypy as numpy +except ImportError: + try: + import numpypy as numpy + except ImportError: + pass + +from math import isnan as isNaN + """ From d55fa0b352d1013543b09f9b823277b7bc9d7616 Mon Sep 17 00:00:00 2001 From: hartsantler Date: Tue, 15 Jul 2014 01:50:37 -0700 Subject: [PATCH 002/100] added new eval regtest. --- regtests/lang/eval.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 regtests/lang/eval.py diff --git a/regtests/lang/eval.py b/regtests/lang/eval.py new file mode 100644 index 0000000..f68b971 --- /dev/null +++ b/regtests/lang/eval.py @@ -0,0 +1,12 @@ +''' +eval +''' + +def foo(): return 42 +bar = lambda: 42 + +def main(): + eval('a = bar()') # This one works + eval('b = foo()') # 'foo' is undefined in normal mode under NodeJS but works in NodeWebkit and Chrome!? + TestError( a==42 ) + TestError( b==42 ) From ca3edc03244071163571b60137d3c867ad26c083 Mon Sep 17 00:00:00 2001 From: hartsantler Date: Tue, 15 Jul 2014 02:11:23 -0700 Subject: [PATCH 003/100] fixed __init__ with keyword args in javascript mode. --- pythonjs/python_to_pythonjs.py | 6 +++--- regtests/class/init_keyword.py | 11 +++++++++++ 2 files changed, 14 insertions(+), 3 deletions(-) create mode 100644 regtests/class/init_keyword.py diff --git a/pythonjs/python_to_pythonjs.py b/pythonjs/python_to_pythonjs.py index 295695d..d3b564f 100755 --- a/pythonjs/python_to_pythonjs.py +++ b/pythonjs/python_to_pythonjs.py @@ -2266,12 +2266,12 @@ def visit_Call(self, node): elif isinstance(node.func, Name) and node.func.id in self._js_classes: if node.keywords: - kwargs = [ '%s=%s'%(x.arg, self.visit(x.value)) for x in node.keywords ] + kwargs = [ '%s:%s'%(x.arg, self.visit(x.value)) for x in node.keywords ] if args: a = ','.join(args) - return 'new( %s(%s, %s) )' %( self.visit(node.func), a, ','.join(kwargs) ) + return 'new( %s(%s, {%s}) )' %( self.visit(node.func), a, ','.join(kwargs) ) else: - return 'new( %s(%s) )' %( self.visit(node.func), ','.join(kwargs) ) + return 'new( %s({%s}) )' %( self.visit(node.func), ','.join(kwargs) ) else: a = ','.join(args) diff --git a/regtests/class/init_keyword.py b/regtests/class/init_keyword.py new file mode 100644 index 0000000..3a01559 --- /dev/null +++ b/regtests/class/init_keyword.py @@ -0,0 +1,11 @@ +''' +test __init__ with keyword arg +''' + +def main(): + class Cell: + def __init__(self, x=1): + self.x = x + + a = Cell(x=2) + TestError(a.x == 2) \ No newline at end of file From 25db4d637a0231534c7abcec75100ddfa66ab4da Mon Sep 17 00:00:00 2001 From: hartsantler Date: Tue, 15 Jul 2014 06:22:17 -0700 Subject: [PATCH 004/100] improved printing errors in second stage translation --- pythonjs/pythonjs.py | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/pythonjs/pythonjs.py b/pythonjs/pythonjs.py index aa72bb6..71dde99 100755 --- a/pythonjs/pythonjs.py +++ b/pythonjs/pythonjs.py @@ -1100,8 +1100,35 @@ def generate_runtime(): return '\n'.join( lines ) def main(script, requirejs=True, insert_runtime=True, webworker=False, function_expressions=False): - #print(script) - tree = ast.parse( script ) + try: + tree = ast.parse( script ) + except SyntaxError: + import traceback + err = traceback.format_exc() + sys.stderr.write( err ) + sys.stderr.write( '\n--------------error in second stage translation--------------\n' ) + + lineno = 0 + for line in err.splitlines(): + if "" in line: + lineno = int(line.split()[-1]) + + + lines = script.splitlines() + if lineno > 10: + for i in range(lineno-5, lineno+5): + sys.stderr.write( 'line %s->'%i ) + sys.stderr.write( lines[i] ) + if i==lineno-1: + sys.stderr.write(' <>') + sys.stderr.write( '\n' ) + + else: + sys.stderr.write( lines[lineno] ) + sys.stderr.write( '\n' ) + + sys.exit(1) + return JSGenerator( requirejs=requirejs, insert_runtime=insert_runtime, webworker=webworker, function_expressions=function_expressions ).visit(tree) From 93596dbe4a7ab482be21801b1fece89a36ab51e0 Mon Sep 17 00:00:00 2001 From: hartsantler Date: Tue, 15 Jul 2014 17:59:44 -0700 Subject: [PATCH 005/100] fixed **kwargs for class __init__ in javascript mode. --- pythonjs/python_to_pythonjs.py | 2 ++ regtests/calling/variable_kwargs_class.py | 11 +++++++++++ regtests/calling/variable_kwargs_class_init.py | 11 +++++++++++ 3 files changed, 24 insertions(+) create mode 100644 regtests/calling/variable_kwargs_class.py create mode 100644 regtests/calling/variable_kwargs_class_init.py diff --git a/pythonjs/python_to_pythonjs.py b/pythonjs/python_to_pythonjs.py index d3b564f..4879f03 100755 --- a/pythonjs/python_to_pythonjs.py +++ b/pythonjs/python_to_pythonjs.py @@ -892,6 +892,8 @@ def _visit_js_classdef(self, node): if init: args = [self.visit(arg) for arg in init.args.args] node._cached_init = init + if init.args.kwarg: + args.append( init.args.kwarg ) else: args = [] diff --git a/regtests/calling/variable_kwargs_class.py b/regtests/calling/variable_kwargs_class.py new file mode 100644 index 0000000..dff64f9 --- /dev/null +++ b/regtests/calling/variable_kwargs_class.py @@ -0,0 +1,11 @@ +"""variable keywords""" +class A: + def f2(self, **kw): + a = 0 + for key in kw: + a += kw[key] + return a + +def main(): + a = A() + TestError( a.f2(x=1,y=2) == 3 ) \ No newline at end of file diff --git a/regtests/calling/variable_kwargs_class_init.py b/regtests/calling/variable_kwargs_class_init.py new file mode 100644 index 0000000..8086762 --- /dev/null +++ b/regtests/calling/variable_kwargs_class_init.py @@ -0,0 +1,11 @@ +"""variable keywords""" +class A: + def __init__(self, **kw): + a = 0 + for key in kw: + a += kw[key] + self.value = a + +def main(): + a = A(x=1,y=2) + TestError( a.value == 3 ) \ No newline at end of file From 764a5799ab720e060ca9cf801ed2d6a92fc16884 Mon Sep 17 00:00:00 2001 From: hartsantler Date: Tue, 15 Jul 2014 18:20:30 -0700 Subject: [PATCH 006/100] fixed **kwargs in new class in javascript mode. --- pythonjs/python_to_pythonjs.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pythonjs/python_to_pythonjs.py b/pythonjs/python_to_pythonjs.py index 4879f03..0e44d53 100755 --- a/pythonjs/python_to_pythonjs.py +++ b/pythonjs/python_to_pythonjs.py @@ -2274,8 +2274,10 @@ def visit_Call(self, node): return 'new( %s(%s, {%s}) )' %( self.visit(node.func), a, ','.join(kwargs) ) else: return 'new( %s({%s}) )' %( self.visit(node.func), ','.join(kwargs) ) - else: + if node.kwargs: + args.append( self.visit(node.kwargs) ) + a = ','.join(args) return 'new( %s(%s) )' %( self.visit(node.func), a ) From d53dcf75fc26084c40ffb6c1e70fb3470943867e Mon Sep 17 00:00:00 2001 From: hartsantler Date: Tue, 15 Jul 2014 20:25:59 -0700 Subject: [PATCH 007/100] refactoring dddom.py and testing new library threepy.py --- regtests/html/dddom.py | 40 ++- regtests/html/threepy.py | 354 +++++++++++++++++++ regtests/html/webgl_css3d_editor.html | 82 +++++ regtests/html/webgl_css3d_simple_editor.html | 1 + 4 files changed, 459 insertions(+), 18 deletions(-) create mode 100644 regtests/html/threepy.py create mode 100644 regtests/html/webgl_css3d_editor.html diff --git a/regtests/html/dddom.py b/regtests/html/dddom.py index 7d4d7ef..8caadb4 100644 --- a/regtests/html/dddom.py +++ b/regtests/html/dddom.py @@ -254,24 +254,28 @@ def create_dropdown_button( name, options ): CLICKABLES = [] -def _on_mouse_up(evt): - x = ( event.clientX / window.innerWidth ) * 2 - 1; - y = - ( event.clientY / window.innerHeight ) * 2 + 1; - vector = new THREE.Vector3( x, y, 0.5 ); - projector = new THREE.Projector(); - projector.unprojectVector( vector, camera ); - raycaster = new THREE.Raycaster( camera.position, vector.sub( camera.position ).normalize() ); - intersects = raycaster.intersectObjects( CLICKABLES ); - #if intersects.length > 0: - # ob = intersects[0].object - for inter in intersects: - ob = inter.object - print(ob) - if hasattr(ob, 'onclick'): - ob.onclick( inter ) - - -document.addEventListener('mouseup', _on_mouse_up, false) +class SelectManager: + def __init__(self, camera): + self.camera = camera + document.addEventListener('mouseup', self.on_mouse_up.bind(self), false) + + def on_mouse_up(self, evt): + x = ( event.clientX / window.innerWidth ) * 2 - 1; + y = - ( event.clientY / window.innerHeight ) * 2 + 1; + vector = new THREE.Vector3( x, y, 0.5 ); + projector = new THREE.Projector(); + projector.unprojectVector( vector, self.camera ); + raycaster = new THREE.Raycaster( self.camera.position, vector.sub( self.camera.position ).normalize() ); + intersects = raycaster.intersectObjects( CLICKABLES ); + #if intersects.length > 0: + # ob = intersects[0].object + for inter in intersects: + ob = inter.object + print(ob) + if hasattr(ob, 'onclick'): + ob.onclick( inter ) + + class Window3D: def __init__(self, element, scene, shadow_scene, interact_scene, position, scale ): diff --git a/regtests/html/threepy.py b/regtests/html/threepy.py new file mode 100644 index 0000000..09c8379 --- /dev/null +++ b/regtests/html/threepy.py @@ -0,0 +1,354 @@ +# Three.js HTML UI Generator +# by Brett Hartshorn - copyright 2014 +# You may destribute this file using the "New BSD" or MIT license + +pythonjs.configure(javascript=True) +from dddom import * ## provides Window3D and SelectManager + + +class Editor( Window3D ): + def __init__(self, engine, position=None): + element = document.createElement( 'div' ) + Window3D.__init__(self, element, engine.scene, engine.scene2, engine.scene3, position, [1,1,1] ) + element.setAttribute('class', 'well') + self.engine = engine + + b = document.createElement('button') + b.appendChild(document.createTextNode('run script')) + b.setAttribute('class', 'btn btn-inverse btn-small') + element.appendChild(b) + + opts = ['javascript', 'python'] + element.appendChild(document.createTextNode(' mode:')) + element.appendChild( self.create_select_dropdown(opts) ) + + element.appendChild(document.createElement('br')) + + con = document.createElement('div') + element.appendChild(con) + ta = create_textarea() + con.appendChild( ta ) + + def ondrop(evt): + print(evt) + evt.preventDefault() + if evt.dataTransfer.files.length==0: + url = evt.dataTransfer.getData("text/plain") + iframe = self.create_iframe( url, self.engine.renderer3.domElement ) + self.element.appendChild(iframe) + else: + self.handle_drop_event(evt.dataTransfer.files) + + element.ondrop = ondrop.bind( self ) + element.ondragover = lambda evt: evt.preventDefault() + + + def onclick(evt): + eval( ta.value ) + b.onclick = onclick.bind(self) + + + + + def _gen_ui_multi(self, arr): pass + + def _gen_ui_single(self, o): pass + + def _gen_ui(self, o): + + if instanceof(o, Array): + return self._gen_ui_multi(o) + elif instanceof(o, THREE.Object3D): + return self._gen_ui_single(o) + else: + raise RuntimeError('can not generate ui for type:'+o) + + + + def handle_drop_event(self, files): + images = [] + videos = [] + for file in files: + ## note: `file.path` is only available in NodeWebkit, + ## for simple testing we will fake it here. + file.path = '/home/brett/Desktop/'+file.name + + if file.path.endswith('.dae'): + loader = new THREE.ColladaLoader(); + loader.options.convertUpAxis = true; + #def on_load(collada): + # print(collada) + # element3D.root.add( collada.scene ) + #loader.load( 'http://localhost:8000'+file.path, on_load ) + + def onload(evt): + parser = new DOMParser() + collada = loader.parse( parser.parseFromString(evt.target.result, "application/xml") ) + print(collada.scene) + collada.scene.scale.set(0.25, 0.25, 0.25) + collada.scene.position.set(0, -100, 200) + element3D.root.add( collada.scene ) + element3D.collada = collada.scene + + menu = element3D.create_tab_menu() + container.appendChild( menu.root ) + + + for i,model in enumerate(collada.scene.children): + print(model) + page = menu.add_tab( model.name ) + div = document.createElement('div') + div.setAttribute('class', 'well') + page.appendChild( div ) + #div.id = element3D.newid() + + h3 = document.createElement('h3') + h3.appendChild( document.createTextNode(model.name) ) + div.appendChild( h3 ) + + if hasattr(model, 'material'): ## could be THREE.Mesh or THREE.SkinnedMesh + print(model.material) + ui = gen_material_ui(model) + div.appendChild( ui ) + + reader = new FileReader() + reader.onload = onload + reader.readAsText( file ) + + elif file.path.endswith('.html'): + iframe = element3D.create_iframe( file.path, renderer3.domElement ) + container.appendChild(iframe) + + elif file.path.endswith('.css'): + print( 'TODO css' ) + elif file.path.endswith('.js'): + print( 'TODO js' ) + elif file.path.endswith('.jpg') or file.path.endswith('.png'): + + li = document.createElement('li') + images.append(li) + img = document.createElement('img') + img.setAttribute('src', file.path) + img.setAttribute('class', 'well img-rounded') + li.appendChild( img ) + + + elif file.path.endswith('.mp4'): + li = document.createElement('li') + video = element3D.create_video( mp4=file.path ) + li.appendChild( video ) + videos.append( li ) + + elif file.path.endswith('.ogv'): + #li = document.createElement('li') + video = element3D.create_video( ogv=file.path ) + container.appendChild(video) + #li.appendChild( video ) + #videos.append( li ) + + elif file.path.endswith('.py'): + def on_load(event): + contents = event.target.result + py_body_editor.setValue( contents ) + + Reader.onload = on_load + Reader.readAsText( file ) + + if images: + print('loading images') + ul = document.createElement('ul') + container.appendChild(ul) + for li in images: + ul.appendChild(li) + + if videos: + print('loading videos') + ul = document.createElement('ul') + container.appendChild(ul) + for li in videos: + ul.appendChild(li) + +if False: + camera = scene = renderer = None + geometry = material = mesh = None + scene2 = renderer2 = renderer3 = None + controls = gizmo = composer = None + Elements = [] + +class Engine: + def Editor(self, **kw): + e = Editor(self, **kw) + self.windows.append( e ) + return e + + #def create_editor(self, position=None): + # return Editor(self, position=position) + + + def __init__(self): + self.windows = [] + + SCREEN_WIDTH = window.innerWidth + SCREEN_HEIGHT = window.innerHeight + + self.camera = camera = new THREE.PerspectiveCamera( 35, window.innerWidth / window.innerHeight, 1, 10000 ); + camera.position.set( 200, 150, 800 ); + + self._selectman = SelectManager(self.camera) + + self.controls = controls = new THREE.TrackballControls( camera ); + camera.smooth_target = controls.target.clone() + + controls.rotateSpeed = 1.0; + controls.zoomSpeed = 1.2; + controls.panSpeed = 0.8; + + controls.noZoom = false; + controls.noPan = false; + + controls.staticMoving = false; + controls.dynamicDampingFactor = 0.3; + + controls.keys = [ 65, 83, 68 ]; + + self.scene = scene = new THREE.Scene(); + self.scene3 = scene3 = new THREE.Scene(); + + + + geometry = new THREE.BoxGeometry( 800, 400, 3800 ); + material = new THREE.MeshPhongMaterial( color=0xc1c1c1, transparent=true, opacity=0.27 ); + mesh = new THREE.Mesh( geometry, material ); + mesh.position.z = -400 + mesh.position.y = -220 + scene.add( mesh ); + mesh.receiveShadow = true; + + self.renderer = renderer = new THREE.WebGLRenderer(alpha=True); + renderer.shadowMapEnabled = true + renderer.shadowMapType = THREE.PCFSoftShadowMap + renderer.shadowMapSoft = true + + + renderer.setSize( window.innerWidth, window.innerHeight ); + renderer.domElement.style.position = 'absolute'; + renderer.domElement.style.top = 0; + renderer.domElement.style.zIndex = 1; + + self.gizmo = new THREE.TransformControls( camera, renderer.domElement ) + scene.add( self.gizmo ) + + self.spotlight = light = new( + THREE.SpotLight( 0xffffff, 1, 0, Math.PI / 2, 1 ) + ) + light.position.set( 0, 1400, 400 ) + light.target.position.set( 0, 0, 0 ) + + light.castShadow = True + light.shadowCameraNear = 400 + light.shadowCameraFar = 1900 + light.shadowCameraFov = 64 + light.shadowCameraVisible = True + + light.shadowBias = 0.0001 + light.shadowDarkness = 0.4 + + light.shadowMapWidth = 512 + light.shadowMapHeight = 512 + + scene.add( light ); + + self.pointlight = pointlight = new( THREE.PointLight(0xffffff, 2, 500) ) + pointlight.position.set( 10, 100, 300 ) + scene.add( pointlight ) + + renderer.sortObjects = false + renderer.autoClear = false + + renderTarget = new( + THREE.WebGLRenderTarget( + SCREEN_WIDTH, + SCREEN_HEIGHT, + minFilter = THREE.LinearFilter, + magFilter = THREE.LinearFilter, + format = THREE.RGBAFormat, ## RGBA format is required to composite over css3d render + stencilBuffer = false + ) + ) + + + hblur = new(THREE.ShaderPass( THREE.HorizontalTiltShiftShader )) + vblur = new(THREE.ShaderPass( THREE.VerticalTiltShiftShader )) + + bluriness = 1.7; + hblur.uniforms[ 'h' ].value = bluriness / SCREEN_WIDTH; + vblur.uniforms[ 'v' ].value = bluriness / SCREEN_HEIGHT; + + hblur.uniforms[ 'r' ].value = 0.1 + vblur.uniforms[ 'r' ].value = 0.1 + + + self.composer = composer = new(THREE.EffectComposer( renderer, renderTarget )) + + renderModel = new(THREE.RenderPass( scene, camera )) + + vblur.renderToScreen = true; + composer.addPass( renderModel ); + composer.addPass( hblur ); + composer.addPass( vblur ); + + + self.scene2 = scene2 = new THREE.Scene(); + + + self.renderer2 = renderer2 = new THREE.CSS3DRenderer(); + renderer2.setSize( window.innerWidth, window.innerHeight ); + renderer2.domElement.style.position = 'absolute'; + renderer2.domElement.style.top = 0; + renderer2.domElement.style.zIndex = 0; + document.body.appendChild( renderer2.domElement ); + + self.renderer3 = renderer3 = new THREE.CSS3DRenderer(); + renderer3.setSize( window.innerWidth, window.innerHeight ); + renderer3.domElement.style.position = 'absolute'; + renderer3.domElement.style.top = 0; + renderer3.domElement.style.opacity = 0.1; + renderer3.domElement.style.zIndex=4; + + document.body.appendChild( renderer2.domElement ); + document.body.appendChild( renderer.domElement ); + document.body.appendChild( renderer3.domElement ); + + + + def gen_material_ui(model): + print('gen material ui') + def onchange(val): + model.material.opacity = val + slider = create_slider( model.material.opacity, onchange=onchange ) + return slider + + def animate(self): + requestAnimationFrame( self.animate.bind(self) ); + self.gizmo.update() + + d = self.camera.smooth_target.clone() + d.sub(self.controls.target) + self.controls.target.add( d.multiplyScalar(0.03) ) + self.controls.update() + + for win in self.windows: win.update() + self.renderer2.render( self.scene2, self.camera ) + self.renderer.clear() + self.composer.render( self.scene, self.camera ) + self.renderer3.render( self.scene3, self.camera ) + + def run(self): + self.animate() + +threepy = { + 'Engine' : lambda : Engine(), +} + +#pythonjs.configure(javascript=False) +#threepy.Editor = lambda **kw: Engine(**kw) diff --git a/regtests/html/webgl_css3d_editor.html b/regtests/html/webgl_css3d_editor.html new file mode 100644 index 0000000..02b6a77 --- /dev/null +++ b/regtests/html/webgl_css3d_editor.html @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/regtests/html/webgl_css3d_simple_editor.html b/regtests/html/webgl_css3d_simple_editor.html index 164f948..f81cbdb 100644 --- a/regtests/html/webgl_css3d_simple_editor.html +++ b/regtests/html/webgl_css3d_simple_editor.html @@ -91,6 +91,7 @@ camera = new THREE.PerspectiveCamera( 35, window.innerWidth / window.innerHeight, 1, 10000 ); camera.position.set( 200, 150, 800 ); + selectman = SelectManager( camera ) controls = new THREE.TrackballControls( camera ); camera.smooth_target = controls.target.clone() From 529ba11289a3cd2b126d25a16c51a0831014ef3a Mon Sep 17 00:00:00 2001 From: hartsantler Date: Wed, 16 Jul 2014 00:26:38 -0700 Subject: [PATCH 008/100] threepy and dddom: call onchange callback when new item is picked in a dropdown 3d popup. --- regtests/html/dddom.py | 11 ++- regtests/html/threepy.py | 99 ++++++++++++++++++--------- regtests/html/webgl_css3d_editor.html | 3 +- 3 files changed, 78 insertions(+), 35 deletions(-) diff --git a/regtests/html/dddom.py b/regtests/html/dddom.py index 8caadb4..ad704aa 100644 --- a/regtests/html/dddom.py +++ b/regtests/html/dddom.py @@ -473,7 +473,7 @@ def create_dropdown(self, e, options): ## this needs to be done anyways because `sel` must be given a height in pixels, ## to force it to display all the options, and not display a scroll bar (which are not synced). H = 12 * options.length - #if H < 150: H = 150 + if H < 100: H = 100 sel.style.height = int(H * 0.95) X = e.offsetLeft / 2 Y = ((self.element.clientHeight-H) / 2) - (e.offsetHeight + e.offsetTop) @@ -494,10 +494,19 @@ def create_dropdown(self, e, options): sel.focus() # required? + ## this is used to capture a click on the dropdown popup, and copy selectedIndex + ## from the clone to the source, and if the source has an onchange callback, call it. def onclick(evt): #sel.focus() ## this triggers a bug that offsets the interactive layer print(evt.toElement.getAttribute('index')) e.selectedIndex = sel.selectedIndex = int(evt.toElement.getAttribute('index')) + ## setting `selectedIndex` on the source e will not trigger its `onchange` callback to fire, + ## so call onchange directly. Note that the event `evt` from the clone is passed the source + ## as the first argument. end-user code inside e.onchange should not modify elements referenced in the event. + ## note that the calling context is set to the source by `e.onchange(evt)` so it is safe to use `this` + ## inside of onchange. + if e.onchange: + e.onchange( evt ) sel.onclick = onclick def onscroll(evt): ## this hack is required to capture the scroll position diff --git a/regtests/html/threepy.py b/regtests/html/threepy.py index 09c8379..fb6143b 100644 --- a/regtests/html/threepy.py +++ b/regtests/html/threepy.py @@ -50,9 +50,70 @@ def onclick(evt): - def _gen_ui_multi(self, arr): pass - def _gen_ui_single(self, o): pass + + def _gen_material_ui(self, model): + print(model.material) + div = document.createElement('div') + + ## Material.js + faceopts = ['FrontSide', 'BackSide', 'DoubleSide'] + div.appendChild(document.createTextNode(' face direction:')) + dd = self.create_select_dropdown(faceopts) + div.appendChild( dd ) + div.appendChild( document.createElement('br') ) + def onchange(evt): + opt = faceopts[this.selectedIndex] + print(opt) + model.material.side = eval('THREE.'+opt) + dd.onchange = onchange + + blendopts = ['NormalBlending', 'AdditiveBlending', 'SubtractiveBlending', 'NoBlending'] + div.appendChild(document.createTextNode(' blending:')) + dd = self.create_select_dropdown(blendopts) + div.appendChild( dd ) + div.appendChild( document.createElement('br') ) + def change_blending(evt): + opt = blendopts[this.selectedIndex] + print(opt) + model.material.blending = eval('THREE.'+opt) + dd.onchange = change_blending + + + + def change_opacity(val): + model.material.opacity = val + slider = create_slider( model.material.opacity, onchange=change_opacity ) + div.appendChild( document.createTextNode('opacity:') ) + div.appendChild( slider ) + + ## MeshBasicMaterial.js + + + ## MeshPhongMaterial.js + + return div + + + def _gen_ui_single(self, model): + div = document.createElement('div') + div.setAttribute('class', 'well') + h3 = document.createElement('h3') + h3.appendChild( document.createTextNode(model.name) ) + div.appendChild( h3 ) + + if hasattr(model, 'material'): ## could be THREE.Mesh or THREE.SkinnedMesh + ui = self._gen_material_ui(model) + div.appendChild( ui ) + return div + + def _gen_ui_multi(self, arr): + menu = self.create_tab_menu() + for i,model in enumerate(arr): + page = menu.add_tab( model.name ) + div = self._gen_ui_single( model ) + page.appendChild( div ) + return menu.root def _gen_ui(self, o): @@ -87,32 +148,13 @@ def onload(evt): print(collada.scene) collada.scene.scale.set(0.25, 0.25, 0.25) collada.scene.position.set(0, -100, 200) - element3D.root.add( collada.scene ) - element3D.collada = collada.scene - - menu = element3D.create_tab_menu() - container.appendChild( menu.root ) - + self.root.add( collada.scene ) + self.collada = collada.scene - for i,model in enumerate(collada.scene.children): - print(model) - page = menu.add_tab( model.name ) - div = document.createElement('div') - div.setAttribute('class', 'well') - page.appendChild( div ) - #div.id = element3D.newid() - - h3 = document.createElement('h3') - h3.appendChild( document.createTextNode(model.name) ) - div.appendChild( h3 ) - - if hasattr(model, 'material'): ## could be THREE.Mesh or THREE.SkinnedMesh - print(model.material) - ui = gen_material_ui(model) - div.appendChild( ui ) + self.element.appendChild( self._gen_ui(collada.scene.children) ) reader = new FileReader() - reader.onload = onload + reader.onload = onload.bind(self) reader.readAsText( file ) elif file.path.endswith('.html'): @@ -321,13 +363,6 @@ def __init__(self): - def gen_material_ui(model): - print('gen material ui') - def onchange(val): - model.material.opacity = val - slider = create_slider( model.material.opacity, onchange=onchange ) - return slider - def animate(self): requestAnimationFrame( self.animate.bind(self) ); self.gizmo.update() diff --git a/regtests/html/webgl_css3d_editor.html b/regtests/html/webgl_css3d_editor.html index 02b6a77..92dea0b 100644 --- a/regtests/html/webgl_css3d_editor.html +++ b/regtests/html/webgl_css3d_editor.html @@ -73,8 +73,7 @@ from threepy import * engine = threepy.Engine() -a = engine.Editor( position=[0,0,0] ) -#a = engine.create_editor( position=[0,0,0] ) +a = engine.Editor( position=[0,150,0] ) engine.run() From 5117d79c2f945552995efb8aeb7dafa50efb2762 Mon Sep 17 00:00:00 2001 From: hartsantler Date: Wed, 16 Jul 2014 04:52:25 -0700 Subject: [PATCH 009/100] threepy and dddom: testing HTML color picker and checkbox --- regtests/html/dddom.py | 3 +- regtests/html/threepy.py | 67 ++++++++++++++++++++++++++- regtests/html/webgl_css3d_editor.html | 2 +- 3 files changed, 68 insertions(+), 4 deletions(-) diff --git a/regtests/html/dddom.py b/regtests/html/dddom.py index ad704aa..93fbc8f 100644 --- a/regtests/html/dddom.py +++ b/regtests/html/dddom.py @@ -218,11 +218,12 @@ def func(): ta.focus() ## this allows normal keyboard input ta.setAttribute('class', 'focused alert alert-info') return ta -def create_checkbox( checked ): +def create_checkbox( checked, onchange=None ): ## no special hacks required for checkboxes ## c = document.createElement('input') c.setAttribute('type', 'checkbox') if checked: c.setAttribute('checked', 'true') + if onchange: c.onchange = onchange return c def create_dropdown_button( name, options ): diff --git a/regtests/html/threepy.py b/regtests/html/threepy.py index fb6143b..c10bce2 100644 --- a/regtests/html/threepy.py +++ b/regtests/html/threepy.py @@ -79,18 +79,81 @@ def change_blending(evt): model.material.blending = eval('THREE.'+opt) dd.onchange = change_blending - - def change_opacity(val): model.material.opacity = val slider = create_slider( model.material.opacity, onchange=change_opacity ) div.appendChild( document.createTextNode('opacity:') ) div.appendChild( slider ) + div.appendChild( document.createElement('br') ) + + def change_wireframe(evt): model.material.wireframe = this.checked + div.appendChild(document.createTextNode(' wireframe:')) + checkbox = create_checkbox( model.material.wireframe, onchange=change_wireframe ) + #checkbox.onchange = change_wireframe + div.appendChild( checkbox ) + + div.appendChild( document.createElement('br') ) + ## MeshBasicMaterial.js + div.appendChild(document.createTextNode(' diffuse:')) + input = document.createElement('input') + input.setAttribute('type', 'color') + input.style.width=64; input.style.height=32 + div.appendChild( input ) + def change_diffuse(evt): + hex = int( '0x'+this.value[1:] ) + model.material.color.setHex( hex ) + print(model.material.color) + ## oninput fails, can only get update after use has picked color + input.onchange = change_diffuse ## MeshPhongMaterial.js + if hasattr(model.material, 'ambient'): + div.appendChild(document.createTextNode(' ambient:')) + input = document.createElement('input') + input.setAttribute('type', 'color') + input.style.width=64; input.style.height=32 + div.appendChild( input ) + def change_ambient(evt): + hex = int( '0x'+this.value[1:] ) + model.material.ambient.setHex( hex ) + print(model.material.ambient) + input.onchange = change_ambient + + if hasattr(model.material, 'emissive'): + div.appendChild(document.createTextNode(' emissive:')) + input = document.createElement('input') + input.setAttribute('type', 'color') + input.style.width=64; input.style.height=32 + div.appendChild( input ) + def change_emissive(evt): + hex = int( '0x'+this.value[1:] ) + model.material.emissive.setHex( hex ) + print(model.material.emissive) + input.onchange = change_emissive + + if hasattr(model.material, 'specular'): + div.appendChild( document.createElement('br') ) + + div.appendChild(document.createTextNode(' specular:')) + input = document.createElement('input') + input.setAttribute('type', 'color') + input.style.width=64; input.style.height=32 + div.appendChild( input ) + def change_specular(evt): + hex = int( '0x'+this.value[1:] ) + model.material.specular.setHex( hex ) + print(model.material.specular) + input.onchange = change_specular + + def change_shininess(val): + model.material.shininess = val * 100 + slider = create_slider( model.material.shininess*0.01, onchange=change_shininess ) + div.appendChild( document.createTextNode(' shininess:') ) + div.appendChild( slider ) + return div diff --git a/regtests/html/webgl_css3d_editor.html b/regtests/html/webgl_css3d_editor.html index 92dea0b..bec0501 100644 --- a/regtests/html/webgl_css3d_editor.html +++ b/regtests/html/webgl_css3d_editor.html @@ -73,7 +73,7 @@ from threepy import * engine = threepy.Engine() -a = engine.Editor( position=[0,150,0] ) +a = engine.Editor( position=[0,250,0] ) engine.run() From e24924b68ce0080ce0453810874dc086393fd20b Mon Sep 17 00:00:00 2001 From: hartsantler Date: Wed, 16 Jul 2014 18:01:52 -0700 Subject: [PATCH 010/100] fixed translator output with firefox 26+, TODO test other browsers. --- pythonjs/package.json | 2 +- pythonjs/pythonjs.js | 100 ++++++++++++++++++++--------------- pythonjs/runtime/builtins.py | 23 +++++--- 3 files changed, 74 insertions(+), 51 deletions(-) diff --git a/pythonjs/package.json b/pythonjs/package.json index 7b6edbc..45aafae 100644 --- a/pythonjs/package.json +++ b/pythonjs/package.json @@ -2,7 +2,7 @@ "author": "Brett Hartshorn ", "name": "python-js", "description": "python multi-translator: javascript, dart, coffee, lua, vis.js", - "version": "0.9.7", + "version": "0.9.8", "license": "BSD-3-Clause", "repository": { "type": "git", diff --git a/pythonjs/pythonjs.js b/pythonjs/pythonjs.js index 876163a..7b55cfc 100644 --- a/pythonjs/pythonjs.js +++ b/pythonjs/pythonjs.js @@ -979,14 +979,26 @@ __split_method = function(ob, delim) { } } ;__split_method.is_wrapper = true; +__dom_array_types__ = []; +if (( typeof(NodeList) ) == "function") { + __dom_array_types__ = [NodeList, FileList, DOMStringList, HTMLCollection, SVGNumberList, SVGTransformList]; + if (( typeof(DataTransferItemList) ) == "function") { + __dom_array_types__.push(DataTransferItemList); + } + if (( typeof(HTMLAllCollection) ) == "function") { + __dom_array_types__.push(HTMLAllCollection); + } + if (( typeof(SVGElementInstanceList) ) == "function") { + __dom_array_types__.push(SVGElementInstanceList); + } + if (( typeof(ClientRectList) ) == "function") { + __dom_array_types__.push(ClientRectList); + } +} __is_some_array = function(ob) { - var dom_array_types; - if (( typeof(NodeList) ) == "function") { - dom_array_types = [NodeList, FileList, ClientRectList, DOMStringList, HTMLCollection, HTMLAllCollection, SVGElementInstanceList, SVGNumberList, SVGTransformList]; - if (( typeof(DataTransferItemList) ) == "function") { - dom_array_types.append(DataTransferItemList); - } - var __iter14 = dom_array_types; + + if (( __dom_array_types__.length ) > 0) { + var __iter14 = __dom_array_types__; if (! (__iter14 instanceof Array || typeof __iter14 == "string" || __is_typed_array(__iter14) || __is_some_array(__iter14) )) { __iter14 = __object_keys__(__iter14) } for (var __idx14=0; __idx14 < __iter14.length; __idx14++) { var t = __iter14[ __idx14 ]; @@ -1546,8 +1558,8 @@ issubclass = function(args, kwargs) { } bases = C.__bases__; i = 0; - while (( i ) < __get__(bases, "length", "missing attribute `length` - line 610: while i < bases.length:")) { - if (__test_if_true__(issubclass([((bases instanceof Array) ? bases[i] : __get__(bases, "__getitem__", "line 611: if issubclass( bases[i], B ):")([i], __NULL_OBJECT__)), B], __NULL_OBJECT__))) { + while (( i ) < __get__(bases, "length", "missing attribute `length` - line 620: while i < bases.length:")) { + if (__test_if_true__(issubclass([((bases instanceof Array) ? bases[i] : __get__(bases, "__getitem__", "line 621: if issubclass( bases[i], B ):")([i], __NULL_OBJECT__)), B], __NULL_OBJECT__))) { return true; } i += 1; @@ -2300,7 +2312,7 @@ sum = function(args, kwargs) { var arr = __args__['arr']; a = 0; var b,__iterator__40; - __iterator__40 = __get__(__get__(arr, "__iter__", "no iterator - line 1019: for b in arr:"), "__call__")([], __NULL_OBJECT__); + __iterator__40 = __get__(__get__(arr, "__iter__", "no iterator - line 1029: for b in arr:"), "__call__")([], __NULL_OBJECT__); var __next__40; __next__40 = __get__(__iterator__40, "next"); while (( __iterator__40.index ) < __iterator__40.length) { @@ -2358,7 +2370,7 @@ next = function(args, kwargs) { } __args__ = __getargs__("next", __sig__, args, kwargs); var obj = __args__['obj']; - return __get__(__get__(obj, "next", "missing attribute `next` - line 1037: return obj.next()"), "__call__")(); + return __get__(__get__(obj, "next", "missing attribute `next` - line 1047: return obj.next()"), "__call__")(); } ;next.is_wrapper = true; map = function(args, kwargs) { @@ -2376,7 +2388,7 @@ map = function(args, kwargs) { var objs = __args__['objs']; arr = []; var ob,__iterator__41; - __iterator__41 = __get__(__get__(objs, "__iter__", "no iterator - line 1040: for ob in objs:"), "__call__")([], __NULL_OBJECT__); + __iterator__41 = __get__(__get__(objs, "__iter__", "no iterator - line 1050: for ob in objs:"), "__call__")([], __NULL_OBJECT__); var __next__41; __next__41 = __get__(__iterator__41, "next"); while (( __iterator__41.index ) < __iterator__41.length) { @@ -2402,7 +2414,7 @@ filter = function(args, kwargs) { var objs = __args__['objs']; arr = []; var ob,__iterator__42; - __iterator__42 = __get__(__get__(objs, "__iter__", "no iterator - line 1047: for ob in objs:"), "__call__")([], __NULL_OBJECT__); + __iterator__42 = __get__(__get__(objs, "__iter__", "no iterator - line 1057: for ob in objs:"), "__call__")([], __NULL_OBJECT__); var __next__42; __next__42 = __get__(__iterator__42, "next"); while (( __iterator__42.index ) < __iterator__42.length) { @@ -2428,7 +2440,7 @@ min = function(args, kwargs) { var lst = __args__['lst']; a = null; var value,__iterator__43; - __iterator__43 = __get__(__get__(lst, "__iter__", "no iterator - line 1054: for value in lst:"), "__call__")([], __NULL_OBJECT__); + __iterator__43 = __get__(__get__(lst, "__iter__", "no iterator - line 1064: for value in lst:"), "__call__")([], __NULL_OBJECT__); var __next__43; __next__43 = __get__(__iterator__43, "next"); while (( __iterator__43.index ) < __iterator__43.length) { @@ -2458,7 +2470,7 @@ max = function(args, kwargs) { var lst = __args__['lst']; a = null; var value,__iterator__44; - __iterator__44 = __get__(__get__(lst, "__iter__", "no iterator - line 1060: for value in lst:"), "__call__")([], __NULL_OBJECT__); + __iterator__44 = __get__(__get__(lst, "__iter__", "no iterator - line 1070: for value in lst:"), "__call__")([], __NULL_OBJECT__); var __next__44; __next__44 = __get__(__iterator__44, "next"); while (( __iterator__44.index ) < __iterator__44.length) { @@ -2568,7 +2580,7 @@ __Iterator___init__ = function(args, kwargs) { self.obj = obj; self.index = index; self.length = len([obj], __NULL_OBJECT__); - self.obj_get = __get__(obj, "get", "missing attribute `get` - line 1088: self.obj_get = obj.get ## cache this for speed"); + self.obj_get = __get__(obj, "get", "missing attribute `get` - line 1098: self.obj_get = obj.get ## cache this for speed"); } ;__Iterator___init__.is_wrapper = true; __Iterator_attrs.__init__ = __Iterator___init__; @@ -2675,27 +2687,27 @@ __dict___init__ = function(args, kwargs) { ob = js_object; if (__test_if_true__(ob instanceof Array)) { var o,__iterator__45; - __iterator__45 = __get__(__get__(ob, "__iter__", "no iterator - line 1131: for o in ob:"), "__call__")([], __NULL_OBJECT__); + __iterator__45 = __get__(__get__(ob, "__iter__", "no iterator - line 1141: for o in ob:"), "__call__")([], __NULL_OBJECT__); var __next__45; __next__45 = __get__(__iterator__45, "next"); while (( __iterator__45.index ) < __iterator__45.length) { o = __next__45(); if (__test_if_true__(o instanceof Array)) { - __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1133: self.__setitem__( o[0], o[1] )"), "__call__")([((o instanceof Array) ? o[0] : __get__(o, "__getitem__", "line 1133: self.__setitem__( o[0], o[1] )")([0], __NULL_OBJECT__)), ((o instanceof Array) ? o[1] : __get__(o, "__getitem__", "line 1133: self.__setitem__( o[0], o[1] )")([1], __NULL_OBJECT__))], __NULL_OBJECT__); + __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1143: self.__setitem__( o[0], o[1] )"), "__call__")([((o instanceof Array) ? o[0] : __get__(o, "__getitem__", "line 1143: self.__setitem__( o[0], o[1] )")([0], __NULL_OBJECT__)), ((o instanceof Array) ? o[1] : __get__(o, "__getitem__", "line 1143: self.__setitem__( o[0], o[1] )")([1], __NULL_OBJECT__))], __NULL_OBJECT__); } else { - __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1135: self.__setitem__( o['key'], o['value'] )"), "__call__")([((o instanceof Array) ? o["key"] : __get__(o, "__getitem__", "line 1135: self.__setitem__( o['key'], o['value'] )")(["key"], __NULL_OBJECT__)), ((o instanceof Array) ? o["value"] : __get__(o, "__getitem__", "line 1135: self.__setitem__( o['key'], o['value'] )")(["value"], __NULL_OBJECT__))], __NULL_OBJECT__); + __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1145: self.__setitem__( o['key'], o['value'] )"), "__call__")([((o instanceof Array) ? o["key"] : __get__(o, "__getitem__", "line 1145: self.__setitem__( o['key'], o['value'] )")(["key"], __NULL_OBJECT__)), ((o instanceof Array) ? o["value"] : __get__(o, "__getitem__", "line 1145: self.__setitem__( o['key'], o['value'] )")(["value"], __NULL_OBJECT__))], __NULL_OBJECT__); } } } else { if (__test_if_true__(isinstance([ob, dict], __NULL_OBJECT__))) { var key,__iterator__46; - __iterator__46 = __get__(__get__(__jsdict_keys(ob), "__iter__", "no iterator - line 1137: for key in ob.keys():"), "__call__")([], __NULL_OBJECT__); + __iterator__46 = __get__(__get__(__jsdict_keys(ob), "__iter__", "no iterator - line 1147: for key in ob.keys():"), "__call__")([], __NULL_OBJECT__); var __next__46; __next__46 = __get__(__iterator__46, "next"); while (( __iterator__46.index ) < __iterator__46.length) { key = __next__46(); - value = ((ob instanceof Array) ? ob[key] : __get__(ob, "__getitem__", "line 1138: value = ob[ key ]")([key], __NULL_OBJECT__)); - __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1139: self.__setitem__( key, value )"), "__call__")([key, value], __NULL_OBJECT__); + value = ((ob instanceof Array) ? ob[key] : __get__(ob, "__getitem__", "line 1148: value = ob[ key ]")([key], __NULL_OBJECT__)); + __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1149: self.__setitem__( key, value )"), "__call__")([key, value], __NULL_OBJECT__); } } else { console.log("ERROR init dict from:", js_object); @@ -2721,15 +2733,15 @@ __dict_jsify = function(args, kwargs) { var self = __args__['self']; keys = __object_keys__([self["$wrapped"]], __NULL_OBJECT__); var key,__iterator__47; - __iterator__47 = __get__(__get__(keys, "__iter__", "no iterator - line 1146: for key in keys:"), "__call__")([], __NULL_OBJECT__); + __iterator__47 = __get__(__get__(keys, "__iter__", "no iterator - line 1156: for key in keys:"), "__call__")([], __NULL_OBJECT__); var __next__47; __next__47 = __get__(__iterator__47, "next"); while (( __iterator__47.index ) < __iterator__47.length) { key = __next__47(); - value = __get__(self["$wrapped"], "__getitem__", "line 1147: value = self[...][key]")([key], __NULL_OBJECT__); + value = __get__(self["$wrapped"], "__getitem__", "line 1157: value = self[...][key]")([key], __NULL_OBJECT__); if (( typeof(value) ) == "object") { if (__test_if_true__(hasattr([value, "jsify"], __NULL_OBJECT__))) { - __get__(__get__(self["$wrapped"], "__setitem__"), "__call__")([key, __get__(__get__(value, "jsify", "missing attribute `jsify` - line 1150: self[...][key] = value.jsify()"), "__call__")()], {}); + __get__(__get__(self["$wrapped"], "__setitem__"), "__call__")([key, __get__(__get__(value, "jsify", "missing attribute `jsify` - line 1160: self[...][key] = value.jsify()"), "__call__")()], {}); } } else { if (( typeof(value) ) == "function") { @@ -2788,7 +2800,7 @@ __dict_has_key = function(args, kwargs) { var key = __args__['key']; __dict = self["$wrapped"]; if (__test_if_true__(typeof(key) === 'object' || typeof(key) === 'function')) { - key = __get__(key, "__uid__", "missing attribute `__uid__` - line 1163: key = key.__uid__"); + key = __get__(key, "__uid__", "missing attribute `__uid__` - line 1173: key = key.__uid__"); } if (__test_if_true__(key in __dict)) { return true; @@ -2812,12 +2824,12 @@ __dict_update = function(args, kwargs) { var self = __args__['self']; var other = __args__['other']; var key,__iterator__48; - __iterator__48 = __get__(__get__(other, "__iter__", "no iterator - line 1169: for key in other:"), "__call__")([], __NULL_OBJECT__); + __iterator__48 = __get__(__get__(other, "__iter__", "no iterator - line 1179: for key in other:"), "__call__")([], __NULL_OBJECT__); var __next__48; __next__48 = __get__(__iterator__48, "next"); while (( __iterator__48.index ) < __iterator__48.length) { key = __next__48(); - __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1170: self.__setitem__( key, other[key] )"), "__call__")([key, ((other instanceof Array) ? other[key] : __get__(other, "__getitem__", "line 1170: self.__setitem__( key, other[key] )")([key], __NULL_OBJECT__))], __NULL_OBJECT__); + __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1180: self.__setitem__( key, other[key] )"), "__call__")([key, ((other instanceof Array) ? other[key] : __get__(other, "__getitem__", "line 1180: self.__setitem__( key, other[key] )")([key], __NULL_OBJECT__))], __NULL_OBJECT__); } } ;__dict_update.is_wrapper = true; @@ -2836,12 +2848,12 @@ __dict_items = function(args, kwargs) { var self = __args__['self']; arr = []; var key,__iterator__49; - __iterator__49 = __get__(__get__(__jsdict_keys(self), "__iter__", "no iterator - line 1173: for key in self.keys():"), "__call__")([], __NULL_OBJECT__); + __iterator__49 = __get__(__get__(__jsdict_keys(self), "__iter__", "no iterator - line 1183: for key in self.keys():"), "__call__")([], __NULL_OBJECT__); var __next__49; __next__49 = __get__(__iterator__49, "next"); while (( __iterator__49.index ) < __iterator__49.length) { key = __next__49(); - __get__(__get__(arr, "append", "missing attribute `append` - line 1174: arr.append( [key, self[key]] )"), "__call__")([[key, __get__(self, "__getitem__")([key], __NULL_OBJECT__)]], __NULL_OBJECT__); + __get__(__get__(arr, "append", "missing attribute `append` - line 1184: arr.append( [key, self[key]] )"), "__call__")([[key, __get__(self, "__getitem__")([key], __NULL_OBJECT__)]], __NULL_OBJECT__); } return arr; } @@ -2884,7 +2896,7 @@ __dict_set = function(args, kwargs) { var self = __args__['self']; var key = __args__['key']; var value = __args__['value']; - __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1182: self.__setitem__(key, value)"), "__call__")([key, value], __NULL_OBJECT__); + __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1192: self.__setitem__(key, value)"), "__call__")([key, value], __NULL_OBJECT__); } ;__dict_set.is_wrapper = true; __dict_attrs.set = __dict_set; @@ -3178,7 +3190,7 @@ __array___init__ = function(args, kwargs) { var initializer = __args__['initializer']; var little_endian = __args__['little_endian']; self.typecode = typecode; - self.itemsize = __get__(__get__(self, "typecodes", "missing attribute `typecodes` - line 1350: self.itemsize = self.typecodes[ typecode ]"), "__getitem__", "line 1350: self.itemsize = self.typecodes[ typecode ]")([typecode], __NULL_OBJECT__); + self.itemsize = __get__(__get__(self, "typecodes", "missing attribute `typecodes` - line 1360: self.itemsize = self.typecodes[ typecode ]"), "__getitem__", "line 1360: self.itemsize = self.typecodes[ typecode ]")([typecode], __NULL_OBJECT__); self.little_endian = little_endian; if (__test_if_true__(initializer)) { self.length = len([initializer], __NULL_OBJECT__); @@ -3202,7 +3214,7 @@ __array___init__ = function(args, kwargs) { buff = new ArrayBuffer(size); self.dataview = new DataView(buff); self.buffer = buff; - __get__(__get__(self, "fromlist", "missing attribute `fromlist` - line 1371: self.fromlist( initializer )"), "__call__")([initializer], __NULL_OBJECT__); + __get__(__get__(self, "fromlist", "missing attribute `fromlist` - line 1381: self.fromlist( initializer )"), "__call__")([initializer], __NULL_OBJECT__); } ;__array___init__.is_wrapper = true; __array_attrs.__init__ = __array___init__; @@ -3235,7 +3247,7 @@ __array___contains__ = function(args, kwargs) { __args__ = __getargs__("__array___contains__", __sig__, args, kwargs); var self = __args__['self']; var value = __args__['value']; - arr = __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1377: arr = self.to_array()"), "__call__")(); + arr = __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1387: arr = self.to_array()"), "__call__")(); if (( arr.indexOf(value) ) == -1) { return false; } else { @@ -3260,7 +3272,7 @@ __array___getitem__ = function(args, kwargs) { step = self.itemsize; offset = (step * index); dataview = self.dataview; - func_name = ("get" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1385: func_name = 'get'+self.typecode_names[ self.typecode ]"), "__getitem__", "line 1385: func_name = 'get'+self.typecode_names[ self.typecode ]")([self.typecode], __NULL_OBJECT__)); + func_name = ("get" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1395: func_name = 'get'+self.typecode_names[ self.typecode ]"), "__getitem__", "line 1395: func_name = 'get'+self.typecode_names[ self.typecode ]")([self.typecode], __NULL_OBJECT__)); func = dataview[func_name].bind(dataview); if (( offset ) < self.bytes) { value = func(offset); @@ -3298,7 +3310,7 @@ __array___setitem__ = function(args, kwargs) { } offset = (step * index); dataview = self.dataview; - func_name = ("set" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1401: func_name = 'set'+self.typecode_names[ self.typecode ]"), "__getitem__", "line 1401: func_name = 'set'+self.typecode_names[ self.typecode ]")([self.typecode], __NULL_OBJECT__)); + func_name = ("set" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1411: func_name = 'set'+self.typecode_names[ self.typecode ]"), "__getitem__", "line 1411: func_name = 'set'+self.typecode_names[ self.typecode ]")([self.typecode], __NULL_OBJECT__)); func = dataview[func_name].bind(dataview); if (( offset ) < self.bytes) { if (( self.typecode ) == "float8") { @@ -3366,13 +3378,13 @@ __array_fromlist = function(args, kwargs) { typecode = self.typecode; size = (length * step); dataview = self.dataview; - func_name = ("set" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1421: func_name = 'set'+self.typecode_names[ typecode ]"), "__getitem__", "line 1421: func_name = 'set'+self.typecode_names[ typecode ]")([typecode], __NULL_OBJECT__)); + func_name = ("set" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1431: func_name = 'set'+self.typecode_names[ typecode ]"), "__getitem__", "line 1431: func_name = 'set'+self.typecode_names[ typecode ]")([typecode], __NULL_OBJECT__)); func = dataview[func_name].bind(dataview); if (( size ) <= self.bytes) { i = 0; offset = 0; while (( i ) < length) { - item = ((lst instanceof Array) ? lst[i] : __get__(lst, "__getitem__", "line 1426: item = lst[i]")([i], __NULL_OBJECT__)); + item = ((lst instanceof Array) ? lst[i] : __get__(lst, "__getitem__", "line 1436: item = lst[i]")([i], __NULL_OBJECT__)); if (( typecode ) == "float8") { item *= self._norm_set; } else { @@ -3430,7 +3442,7 @@ __array_append = function(args, kwargs) { var self = __args__['self']; var value = __args__['value']; length = self.length; - __get__(__get__(self, "resize", "missing attribute `resize` - line 1449: self.resize( self.length + 1 )"), "__call__")([(self.length + 1)], __NULL_OBJECT__); + __get__(__get__(self, "resize", "missing attribute `resize` - line 1459: self.resize( self.length + 1 )"), "__call__")([(self.length + 1)], __NULL_OBJECT__); __get__(__get__(self, "__setitem__"), "__call__")([length, value], {}); } ;__array_append.is_wrapper = true; @@ -3449,12 +3461,12 @@ __array_extend = function(args, kwargs) { var self = __args__['self']; var lst = __args__['lst']; var value,__iterator__54; - __iterator__54 = __get__(__get__(lst, "__iter__", "no iterator - line 1452: for value in lst:"), "__call__")([], __NULL_OBJECT__); + __iterator__54 = __get__(__get__(lst, "__iter__", "no iterator - line 1462: for value in lst:"), "__call__")([], __NULL_OBJECT__); var __next__54; __next__54 = __get__(__iterator__54, "next"); while (( __iterator__54.index ) < __iterator__54.length) { value = __next__54(); - __get__(__get__(self, "append", "missing attribute `append` - line 1453: self.append( value )"), "__call__")([value], __NULL_OBJECT__); + __get__(__get__(self, "append", "missing attribute `append` - line 1463: self.append( value )"), "__call__")([value], __NULL_OBJECT__); } } ;__array_extend.is_wrapper = true; @@ -3494,7 +3506,7 @@ __array_to_list = function(args, kwargs) { } __args__ = __getargs__("__array_to_list", __sig__, args, kwargs); var self = __args__['self']; - return __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1463: return self.to_array()"), "__call__")(); + return __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1473: return self.to_array()"), "__call__")(); } ;__array_to_list.is_wrapper = true; __array_attrs.to_list = __array_to_list; @@ -3511,9 +3523,9 @@ __array_to_ascii = function(args, kwargs) { __args__ = __getargs__("__array_to_ascii", __sig__, args, kwargs); var self = __args__['self']; string = ""; - arr = __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1466: arr = self.to_array()"), "__call__")(); + arr = __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1476: arr = self.to_array()"), "__call__")(); i = 0; - length = __get__(arr, "length", "missing attribute `length` - line 1467: i = 0; length = arr.length"); + length = __get__(arr, "length", "missing attribute `length` - line 1477: i = 0; length = arr.length"); while (( i ) < length) { var num = arr[i]; var char = String.fromCharCode(num); diff --git a/pythonjs/runtime/builtins.py b/pythonjs/runtime/builtins.py index 972b179..4f32eb2 100644 --- a/pythonjs/runtime/builtins.py +++ b/pythonjs/runtime/builtins.py @@ -349,13 +349,24 @@ def __split_method( ob, delim ): with javascript: - def __is_some_array( ob ): - if typeof(NodeList) == 'function': ## NodeList is only available in browsers - dom_array_types = [ NodeList, FileList, ClientRectList, DOMStringList, HTMLCollection, HTMLAllCollection, SVGElementInstanceList, SVGNumberList, SVGTransformList] - if typeof(DataTransferItemList) == 'function': ## missing in NodeWebkit - dom_array_types.append( DataTransferItemList ) + __dom_array_types__ = [] + if typeof(NodeList) == 'function': ## NodeList is only available in browsers + ## minimal dom array types common to allow browsers ## + __dom_array_types__ = [ NodeList, FileList, DOMStringList, HTMLCollection, SVGNumberList, SVGTransformList] + + ## extra dom array types ## + if typeof(DataTransferItemList) == 'function': ## missing in NodeWebkit + __dom_array_types__.push( DataTransferItemList ) + if typeof(HTMLAllCollection) == 'function': ## missing in Firefox + __dom_array_types__.push( HTMLAllCollection ) + if typeof(SVGElementInstanceList) == 'function':## missing in Firefox + __dom_array_types__.push( SVGElementInstanceList ) + if typeof(ClientRectList) == 'function': ## missing in Firefox-trunk + __dom_array_types__.push( ClientRectList ) - for t in dom_array_types: + def __is_some_array( ob ): + if __dom_array_types__.length > 0: + for t in __dom_array_types__: if instanceof(ob, t): return True return False From 0169877b005b95f3c29b2c4712ea9b212e5f3502 Mon Sep 17 00:00:00 2001 From: hartsantler Date: Wed, 16 Jul 2014 18:48:42 -0700 Subject: [PATCH 011/100] threepy: more material controls --- regtests/html/dddom.py | 32 +++++++++-- regtests/html/threepy.py | 120 ++++++++++++++++++++++++++++----------- 2 files changed, 112 insertions(+), 40 deletions(-) diff --git a/regtests/html/dddom.py b/regtests/html/dddom.py index 93fbc8f..152a210 100644 --- a/regtests/html/dddom.py +++ b/regtests/html/dddom.py @@ -199,7 +199,7 @@ def create_slider(value, onchange=None, width=200): div = document.createElement('div') ## a parent container is required div.appendChild( slider ) - $( slider ).PPSlider( width=300, onInput=onchange, value=value ) + $( slider ).PPSlider( width=width, onInput=onchange, value=value ) slider.onclick = lambda : slider.focus() @@ -226,6 +226,29 @@ def create_checkbox( checked, onchange=None ): if onchange: c.onchange = onchange return c +def create_number_input(value, step=1, onchange=None): + input = document.createElement('input') + input.setAttribute('type', 'number') + input.setAttribute('step', step) + input.value = value + input.style.width = 64 + input.style.height = 32 + input.onclick = lambda : this.focus() + if onchange: input.onchange = onchange + return input + +def create_float_input(value, step=0.01, onchange=None): + input = document.createElement('input') + input.setAttribute('type', 'number') + input.setAttribute('step', step) + input.value = value + input.style.width = 64 + input.style.height = 32 + input.onclick = lambda : this.focus() + if onchange: input.onchange = onchange + return input + + def create_dropdown_button( name, options ): div = document.createElement('div') div.setAttribute('class', 'btn-group') @@ -611,13 +634,10 @@ def expand(inter): m.castShadow = true; CLICKABLES.append( m ) - def spin(inter): + def clickfooter(inter): if self.collasped: self.expand() - else: - self.spin90() - self.object.position.x = -200 - m.onclick = spin.bind(self) + m.onclick = clickfooter.bind(self) geo = new THREE.BoxGeometry( 0.2, 0.1, 10 ); mat = new THREE.MeshPhongMaterial( {'color': 0xffff00 } ); diff --git a/regtests/html/threepy.py b/regtests/html/threepy.py index c10bce2..25e6960 100644 --- a/regtests/html/threepy.py +++ b/regtests/html/threepy.py @@ -49,9 +49,6 @@ def onclick(evt): - - - def _gen_material_ui(self, model): print(model.material) div = document.createElement('div') @@ -79,6 +76,18 @@ def change_blending(evt): model.material.blending = eval('THREE.'+opt) dd.onchange = change_blending + def change_wireframe(evt): model.material.wireframe = this.checked + div.appendChild(document.createTextNode(' wireframe:')) + checkbox = create_checkbox( model.material.wireframe, onchange=change_wireframe ) + div.appendChild( checkbox ) + + def change_wireframe_width(val): model.material.wireframeLinewidth = val * 10 + slider = create_slider( model.material.wireframeLinewidth*0.1, onchange=change_wireframe_width ) + div.appendChild( slider ) + + div.appendChild( document.createElement('br') ) + + def change_opacity(val): model.material.opacity = val slider = create_slider( model.material.opacity, onchange=change_opacity ) @@ -87,20 +96,17 @@ def change_opacity(val): div.appendChild( document.createElement('br') ) - def change_wireframe(evt): model.material.wireframe = this.checked - div.appendChild(document.createTextNode(' wireframe:')) - checkbox = create_checkbox( model.material.wireframe, onchange=change_wireframe ) - #checkbox.onchange = change_wireframe - div.appendChild( checkbox ) - div.appendChild( document.createElement('br') ) + well = document.createElement('div') + well.setAttribute('class', 'well') + div.appendChild( well ) ## MeshBasicMaterial.js - div.appendChild(document.createTextNode(' diffuse:')) + well.appendChild(document.createTextNode(' diffuse:')) input = document.createElement('input') input.setAttribute('type', 'color') input.style.width=64; input.style.height=32 - div.appendChild( input ) + well.appendChild( input ) def change_diffuse(evt): hex = int( '0x'+this.value[1:] ) model.material.color.setHex( hex ) @@ -111,11 +117,11 @@ def change_diffuse(evt): ## MeshPhongMaterial.js if hasattr(model.material, 'ambient'): - div.appendChild(document.createTextNode(' ambient:')) + well.appendChild(document.createTextNode(' ambient:')) input = document.createElement('input') input.setAttribute('type', 'color') input.style.width=64; input.style.height=32 - div.appendChild( input ) + well.appendChild( input ) def change_ambient(evt): hex = int( '0x'+this.value[1:] ) model.material.ambient.setHex( hex ) @@ -123,11 +129,11 @@ def change_ambient(evt): input.onchange = change_ambient if hasattr(model.material, 'emissive'): - div.appendChild(document.createTextNode(' emissive:')) + well.appendChild(document.createTextNode(' emissive:')) input = document.createElement('input') input.setAttribute('type', 'color') input.style.width=64; input.style.height=32 - div.appendChild( input ) + well.appendChild( input ) def change_emissive(evt): hex = int( '0x'+this.value[1:] ) model.material.emissive.setHex( hex ) @@ -135,9 +141,16 @@ def change_emissive(evt): input.onchange = change_emissive if hasattr(model.material, 'specular'): - div.appendChild( document.createElement('br') ) + #div.appendChild( document.createElement('br') ) div.appendChild(document.createTextNode(' specular:')) + + def change_shininess(val): + model.material.shininess = val * 100 + slider = create_slider( model.material.shininess*0.01, onchange=change_shininess ) + #div.appendChild( document.createTextNode(' shininess:') ) + div.appendChild( slider ) + input = document.createElement('input') input.setAttribute('type', 'color') input.style.width=64; input.style.height=32 @@ -148,11 +161,6 @@ def change_specular(evt): print(model.material.specular) input.onchange = change_specular - def change_shininess(val): - model.material.shininess = val * 100 - slider = create_slider( model.material.shininess*0.01, onchange=change_shininess ) - div.appendChild( document.createTextNode(' shininess:') ) - div.appendChild( slider ) return div @@ -161,9 +169,58 @@ def change_shininess(val): def _gen_ui_single(self, model): div = document.createElement('div') div.setAttribute('class', 'well') - h3 = document.createElement('h3') - h3.appendChild( document.createTextNode(model.name) ) - div.appendChild( h3 ) + #h3 = document.createElement('h3') + #h3.appendChild( document.createTextNode(model.name) ) + #div.appendChild( h3 ) + + div.appendChild( document.createTextNode(' position:') ) + + def set_pos_x(evt): model.position.x = this.value + input = create_float_input( model.position.x, onchange=set_pos_x) + div.appendChild( input ) + + def set_pos_y(evt): model.position.y = this.value + input = create_float_input( model.position.y, onchange=set_pos_y) + div.appendChild( input ) + + def set_pos_z(evt): model.position.z = this.value + input = create_float_input( model.position.z, onchange=set_pos_z) + div.appendChild( input ) + + div.appendChild( document.createElement('br') ) + + div.appendChild( document.createTextNode(' rotation:') ) + + def set_rot_x(evt): model.rotation.x = this.value + input = create_float_input( model.rotation.x, onchange=set_rot_x) + div.appendChild( input ) + + def set_rot_y(evt): model.rotation.y = this.value + input = create_float_input( model.rotation.y, onchange=set_rot_y) + div.appendChild( input ) + + def set_rot_z(evt): model.rotation.z = this.value + input = create_float_input( model.rotation.z, onchange=set_rot_z) + div.appendChild( input ) + + div.appendChild( document.createElement('br') ) + + div.appendChild( document.createTextNode(' scale:') ) + + def set_scale_x(evt): model.scale.x = this.value + input = create_float_input( model.scale.x, onchange=set_scale_x) + div.appendChild( input ) + + def set_scale_y(evt): model.scale.y = this.value + input = create_float_input( model.scale.y, onchange=set_scale_y) + div.appendChild( input ) + + def set_scale_z(evt): model.scale.z = this.value + input = create_float_input( model.scale.z, onchange=set_scale_z) + div.appendChild( input ) + + + if hasattr(model, 'material'): ## could be THREE.Mesh or THREE.SkinnedMesh ui = self._gen_material_ui(model) @@ -320,15 +377,6 @@ def __init__(self): self.scene3 = scene3 = new THREE.Scene(); - - geometry = new THREE.BoxGeometry( 800, 400, 3800 ); - material = new THREE.MeshPhongMaterial( color=0xc1c1c1, transparent=true, opacity=0.27 ); - mesh = new THREE.Mesh( geometry, material ); - mesh.position.z = -400 - mesh.position.y = -220 - scene.add( mesh ); - mesh.receiveShadow = true; - self.renderer = renderer = new THREE.WebGLRenderer(alpha=True); renderer.shadowMapEnabled = true renderer.shadowMapType = THREE.PCFSoftShadowMap @@ -363,10 +411,14 @@ def __init__(self): scene.add( light ); - self.pointlight = pointlight = new( THREE.PointLight(0xffffff, 2, 500) ) + self.pointlight1 = pointlight = new( THREE.PointLight(0xffffff, 2, 500) ) pointlight.position.set( 10, 100, 300 ) scene.add( pointlight ) + self.pointlight2 = pointlight = new( THREE.PointLight(0xffffff, 2, 500) ) + pointlight.position.set( -10, -100, 200 ) + scene.add( pointlight ) + renderer.sortObjects = false renderer.autoClear = false From 1123bb7bf693e132c8a598dcb9d76924fd0bd911 Mon Sep 17 00:00:00 2001 From: hartsantler Date: Wed, 16 Jul 2014 23:05:32 -0700 Subject: [PATCH 012/100] dddom.py: fixed NodeWebkit, and other browsers that are strict about `e.cloneNode(true)` --- regtests/html/dddom.py | 3 ++- regtests/html/threepy.py | 6 ++++-- regtests/run.py | 27 +++++++++++++++++---------- 3 files changed, 23 insertions(+), 13 deletions(-) diff --git a/regtests/html/dddom.py b/regtests/html/dddom.py index 152a210..9280220 100644 --- a/regtests/html/dddom.py +++ b/regtests/html/dddom.py @@ -685,7 +685,8 @@ def update(self): self.mask.scale.x = w*99 self.mask.scale.y = h*99 - self.shadow.element = self.element.cloneNode() ## this is just to display content + ## this is just to display content, cloneNode(true) ensures deep copy + self.shadow.element = self.element.cloneNode(true) ## sync scrollbars of any div with an id, ## note: this will not work with tab-content div's. diff --git a/regtests/html/threepy.py b/regtests/html/threepy.py index 25e6960..4ed9b48 100644 --- a/regtests/html/threepy.py +++ b/regtests/html/threepy.py @@ -354,12 +354,13 @@ def __init__(self): SCREEN_HEIGHT = window.innerHeight self.camera = camera = new THREE.PerspectiveCamera( 35, window.innerWidth / window.innerHeight, 1, 10000 ); - camera.position.set( 200, 150, 800 ); + camera.position.set( 200, 250, 800 ); self._selectman = SelectManager(self.camera) self.controls = controls = new THREE.TrackballControls( camera ); camera.smooth_target = controls.target.clone() + camera.smooth_target.y = 300 controls.rotateSpeed = 1.0; controls.zoomSpeed = 1.2; @@ -494,7 +495,8 @@ def animate(self): self.renderer3.render( self.scene3, self.camera ) def run(self): - self.animate() + #self.animate() + setTimeout(self.animate.bind(self), 1000) threepy = { 'Engine' : lambda : Engine(), diff --git a/regtests/run.py b/regtests/run.py index 127b182..aa33ea8 100755 --- a/regtests/run.py +++ b/regtests/run.py @@ -802,16 +802,23 @@ def run_html_test( filename, sum_errors ): html = '\n'.join(doc) open('/tmp/%s.html'%filename, 'wb').write( html.encode('utf-8') ) - ## chrome-extension that won't force you to close your browser windows when deving: `Allow-Control-Allow-Origin:*` - cmd = [ - 'google-chrome', - '--app=file:///tmp/%s.html'%filename, - '--allow-file-access-from-files', ## only takes affect if chrome is closed - '--allow-file-access', ## only takes affect if chrome is closed - '--disable-web-security' ## only takes affect if chrome is closed - ] - ## non-blocking, TODO check for chrome extension that allows output of console.log to stdout - subprocess.check_call(cmd) + if '--nodewebkit' in sys.argv: + ## nodewebkit can bypass all cross origin browser-side security + write("/tmp/package.json", '{"name":"test", "main":"%s.html"}' %filename) + run_command("%s /tmp" %nodewebkit, nodewebkit_workaround=True) + + else: + ## chrome-extension that won't force you to close your browser windows when deving: `Allow-Control-Allow-Origin:*` + ## this still fails with iframes that do not allow cross origin. + cmd = [ + 'google-chrome', + '--app=file:///tmp/%s.html'%filename, + '--allow-file-access-from-files', ## only takes affect if chrome is closed + '--allow-file-access', ## only takes affect if chrome is closed + '--disable-web-security' ## only takes affect if chrome is closed + ] + ## non-blocking, TODO check for chrome extension that allows output of console.log to stdout + subprocess.check_call(cmd) table_header = "%-12.12s %-28.28s" From 14005bc3d67750991b80ebc94060d3d3773043e4 Mon Sep 17 00:00:00 2001 From: hartsantler Date: Thu, 17 Jul 2014 03:31:23 -0700 Subject: [PATCH 013/100] updated threepy and dddom.py --- regtests/html/dddom.py | 3 ++- regtests/html/threepy.py | 36 +++++++++++++-------------- regtests/html/webgl_css3d_editor.html | 19 +++++++++++++- regtests/run.py | 14 ++++++++--- 4 files changed, 47 insertions(+), 25 deletions(-) diff --git a/regtests/html/dddom.py b/regtests/html/dddom.py index 9280220..0335b5e 100644 --- a/regtests/html/dddom.py +++ b/regtests/html/dddom.py @@ -355,7 +355,7 @@ def create_tab_menu(self): def create_iframe( self, url, element ): ## this currently only renders on the top layer transparent layer, - ## to make iframes visible the top layer needs to become semi-transparent of opaque. + ## to make iframes visible the top layer needs to become semi-transparent or opaque. ## `element` is the DOM element that will have its opacity adjusted on mouse enter/leave iframe = document.createElement('iframe') iframe.setAttribute('src', url) @@ -635,6 +635,7 @@ def expand(inter): CLICKABLES.append( m ) def clickfooter(inter): + self.active = True if self.collasped: self.expand() m.onclick = clickfooter.bind(self) diff --git a/regtests/html/threepy.py b/regtests/html/threepy.py index 4ed9b48..18de547 100644 --- a/regtests/html/threepy.py +++ b/regtests/html/threepy.py @@ -34,8 +34,7 @@ def ondrop(evt): evt.preventDefault() if evt.dataTransfer.files.length==0: url = evt.dataTransfer.getData("text/plain") - iframe = self.create_iframe( url, self.engine.renderer3.domElement ) - self.element.appendChild(iframe) + self.open_iframe(url) else: self.handle_drop_event(evt.dataTransfer.files) @@ -47,7 +46,9 @@ def onclick(evt): eval( ta.value ) b.onclick = onclick.bind(self) - + def open_iframe(self, url): + iframe = self.create_iframe( url, self.engine.renderer3.domElement ) + self.element.appendChild(iframe) def _gen_material_ui(self, model): print(model.material) @@ -247,6 +248,10 @@ def _gen_ui(self, o): def handle_drop_event(self, files): + self.engine.pointlight1.position.copy( self.position ) + self.engine.pointlight1.position.z += 40 + self.engine.gizmo.attach( self.right_bar ) + images = [] videos = [] for file in files: @@ -279,13 +284,13 @@ def onload(evt): elif file.path.endswith('.html'): iframe = element3D.create_iframe( file.path, renderer3.domElement ) - container.appendChild(iframe) + self.element.appendChild(iframe) elif file.path.endswith('.css'): print( 'TODO css' ) elif file.path.endswith('.js'): print( 'TODO js' ) - elif file.path.endswith('.jpg') or file.path.endswith('.png'): + elif file.path.endswith('.jpg') or file.path.endswith('.png') or file.path.endswith('.gif'): li = document.createElement('li') images.append(li) @@ -297,14 +302,15 @@ def onload(evt): elif file.path.endswith('.mp4'): li = document.createElement('li') - video = element3D.create_video( mp4=file.path ) + video = self.create_video( mp4=file.path ) li.appendChild( video ) videos.append( li ) + ## note, nodewebkit is missing libffmpegsumo, then it only plays ogv videos elif file.path.endswith('.ogv'): #li = document.createElement('li') - video = element3D.create_video( ogv=file.path ) - container.appendChild(video) + video = self.create_video( ogv=file.path ) + self.element.appendChild(video) #li.appendChild( video ) #videos.append( li ) @@ -319,23 +325,18 @@ def on_load(event): if images: print('loading images') ul = document.createElement('ul') - container.appendChild(ul) + self.element.appendChild(ul) for li in images: ul.appendChild(li) if videos: print('loading videos') ul = document.createElement('ul') - container.appendChild(ul) + self.element.appendChild(ul) for li in videos: ul.appendChild(li) -if False: - camera = scene = renderer = None - geometry = material = mesh = None - scene2 = renderer2 = renderer3 = None - controls = gizmo = composer = None - Elements = [] + class Engine: def Editor(self, **kw): @@ -343,9 +344,6 @@ def Editor(self, **kw): self.windows.append( e ) return e - #def create_editor(self, position=None): - # return Editor(self, position=position) - def __init__(self): self.windows = [] diff --git a/regtests/html/webgl_css3d_editor.html b/regtests/html/webgl_css3d_editor.html index bec0501..2154bf3 100644 --- a/regtests/html/webgl_css3d_editor.html +++ b/regtests/html/webgl_css3d_editor.html @@ -73,7 +73,24 @@ from threepy import * engine = threepy.Engine() -a = engine.Editor( position=[0,250,0] ) + +for i in range(10): + a = engine.Editor( position=[(random()*600)-100, 250*random(), (random()*400)+(i*250)-800] ) + if random() > 0.8: + a.rotation.y = Math.PI/2 + a.position.x = -300 + else: + a.rotation.y = random() * random() + +geometry = new THREE.BoxGeometry( 800, 400, 3800 ); +material = new THREE.MeshPhongMaterial( color=0xc1c1c1 ) +mesh = new THREE.Mesh( geometry, material ); +mesh.position.z = -400 +mesh.position.y = -280 +engine.scene.add( mesh ); +mesh.receiveShadow = true; + + engine.run() diff --git a/regtests/run.py b/regtests/run.py index aa33ea8..f122999 100755 --- a/regtests/run.py +++ b/regtests/run.py @@ -158,14 +158,19 @@ def run_old_pypy_test_on(filename): ## download https://github.com/rogerwang/node-webkit/releases/tag/nw-v0.9.2 ## and extract to your home directory. nodewebkit_runnable = False -nodewebkit = os.path.expanduser('~/node-webkit-v0.9.2-linux-x64/nw') + + +nodewebkit = os.path.expanduser('~/node-webkit-v0.10.0-rc1-linux-x64/nw') if os.path.isfile( nodewebkit ): nodewebkit_runnable = True else: - nodewebkit = os.path.expanduser('~/node-webkit-v0.9.1-linux-x64/nw') + nodewebkit = os.path.expanduser('~/node-webkit-v0.9.2-linux-x64/nw') if os.path.isfile( nodewebkit ): nodewebkit_runnable = True else: - nodewebkit = os.path.expanduser('~/node-webkit-v0.8.4-linux-x64/nw') + nodewebkit = os.path.expanduser('~/node-webkit-v0.9.1-linux-x64/nw') if os.path.isfile( nodewebkit ): nodewebkit_runnable = True + else: + nodewebkit = os.path.expanduser('~/node-webkit-v0.8.4-linux-x64/nw') + if os.path.isfile( nodewebkit ): nodewebkit_runnable = True if not show_details or '--no-nodewebkit' in sys.argv: nodewebkit_runnable = False @@ -804,7 +809,8 @@ def run_html_test( filename, sum_errors ): open('/tmp/%s.html'%filename, 'wb').write( html.encode('utf-8') ) if '--nodewebkit' in sys.argv: ## nodewebkit can bypass all cross origin browser-side security - write("/tmp/package.json", '{"name":"test", "main":"%s.html"}' %filename) + cfg = '{"name":"test", "main":"%s.html", "window":{"width":1200, "height":700}}' %filename + write("/tmp/package.json", cfg) run_command("%s /tmp" %nodewebkit, nodewebkit_workaround=True) else: From 81a521caaea02ff5cb76cbb033a11548de15498a Mon Sep 17 00:00:00 2001 From: hartsantler Date: Thu, 17 Jul 2014 23:05:54 -0700 Subject: [PATCH 014/100] three.js catmull clark subdivision example --- regtests/html/three_catmull_clark.html | 136 +++++++++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100644 regtests/html/three_catmull_clark.html diff --git a/regtests/html/three_catmull_clark.html b/regtests/html/three_catmull_clark.html new file mode 100644 index 0000000..f068b27 --- /dev/null +++ b/regtests/html/three_catmull_clark.html @@ -0,0 +1,136 @@ + + + + + + + + + + \ No newline at end of file From 1b26d4fe561958ac978df569cd88282892f8821f Mon Sep 17 00:00:00 2001 From: hartsantler Date: Fri, 18 Jul 2014 05:43:37 -0700 Subject: [PATCH 015/100] updated catmull clark example. --- regtests/html/three_catmull_clark.html | 106 +++++++++++++++++++------ 1 file changed, 80 insertions(+), 26 deletions(-) diff --git a/regtests/html/three_catmull_clark.html b/regtests/html/three_catmull_clark.html index f068b27..2d8223d 100644 --- a/regtests/html/three_catmull_clark.html +++ b/regtests/html/three_catmull_clark.html @@ -1,14 +1,23 @@ + From 7cfdfc9b18121b92b4ca67008ff176f806724757 Mon Sep 17 00:00:00 2001 From: hartsantler Date: Sat, 19 Jul 2014 16:36:25 -0700 Subject: [PATCH 016/100] updated catmull clark example. --- regtests/html/three_catmull_clark.html | 76 +++++++++++++++++--------- 1 file changed, 51 insertions(+), 25 deletions(-) diff --git a/regtests/html/three_catmull_clark.html b/regtests/html/three_catmull_clark.html index 2d8223d..3b5a5a4 100644 --- a/regtests/html/three_catmull_clark.html +++ b/regtests/html/three_catmull_clark.html @@ -4,6 +4,7 @@ ` --- README.md | 5 ++++- pythonjs/python_to_pythonjs.py | 25 ++++++++++++++++++++- pythonjs/pythonjs.py | 40 ++++++++++++++++++++++++++++++---- pythonjs/translator.py | 2 +- 4 files changed, 65 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 69992eb..ee62930 100644 --- a/README.md +++ b/README.md @@ -48,15 +48,18 @@ If you want to run the latest version of the translator, you will need to instal Python2.7 and git clone this repo. (the NodeJS package above is not required) Then, to translate your python script, directly run the `translator.py` script in the "pythonjs" directory. You can give it a list of python files to translate at once. It will output the translation to stdout. The default output type is JavaScript. +An html file can also be used as input, python code inside a script tag: `': + if script: + source = '\n'.join(script) + script = True + self._html_tail.append( '') + + elif isinstance( script, list ): + script.append( line ) + + elif script is True: + self._html_tail.append( line ) + + else: + writer.write( line ) source = typedpython.transform_source( source ) @@ -258,6 +277,10 @@ def __init__(self, source=None, module=None, module_path=None, dart=False, coffe else: self.visit(node) + if self._html_tail: + for line in self._html_tail: + writer.write(line) + def visit(self, node): """Visit a node.""" ## modified code of visit() method from Python 2.7 stdlib diff --git a/pythonjs/pythonjs.py b/pythonjs/pythonjs.py index 56eb8c9..6d73745 100755 --- a/pythonjs/pythonjs.py +++ b/pythonjs/pythonjs.py @@ -1101,9 +1101,34 @@ def generate_runtime(): ] return '\n'.join( lines ) -def main(script, requirejs=True, insert_runtime=True, webworker=False, function_expressions=False): +def main(source, requirejs=True, insert_runtime=True, webworker=False, function_expressions=False): + head = [] + tail = [] + script = False + if source.strip().startswith('') + script = list() + elif line.strip() == '': + if script: + source = '\n'.join(script) + script = True + tail.append( '') + + elif isinstance( script, list ): + script.append( line ) + + elif script is True: + tail.append( line ) + + else: + head.append( line ) + + try: - tree = ast.parse( script ) + tree = ast.parse( source ) except SyntaxError: import traceback err = traceback.format_exc() @@ -1116,7 +1141,7 @@ def main(script, requirejs=True, insert_runtime=True, webworker=False, function_ lineno = int(line.split()[-1]) - lines = script.splitlines() + lines = source.splitlines() if lineno > 10: for i in range(lineno-5, lineno+5): sys.stderr.write( 'line %s->'%i ) @@ -1131,7 +1156,14 @@ def main(script, requirejs=True, insert_runtime=True, webworker=False, function_ sys.exit(1) - return JSGenerator( requirejs=requirejs, insert_runtime=insert_runtime, webworker=webworker, function_expressions=function_expressions ).visit(tree) + gen = JSGenerator( requirejs=requirejs, insert_runtime=insert_runtime, webworker=webworker, function_expressions=function_expressions ) + output = gen.visit(tree) + if head: + head.append( output ) + head.extend( tail ) + output = '\n'.join( head ) + + return output def command(): diff --git a/pythonjs/translator.py b/pythonjs/translator.py index 7639639..bbeab65 100755 --- a/pythonjs/translator.py +++ b/pythonjs/translator.py @@ -65,7 +65,7 @@ def command(): scripts = [] if len(sys.argv) > 1: for arg in sys.argv[1:]: - if arg.endswith('.py'): + if arg.endswith('.py') or arg.endswith('.html'): scripts.append( arg ) if mpath is None: mpath = os.path.split(arg)[0] From 62dee2ded0c0314456ad17e63655c90dae7870d4 Mon Sep 17 00:00:00 2001 From: hartsantler Date: Sun, 20 Jul 2014 22:55:15 -0700 Subject: [PATCH 020/100] updated README --- README.md | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index ee62930..3c26968 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,17 @@ Introduction ------------ -PythonJS is a transpiler written in Python that converts Python into fast +PythonJS is a transpiler written in Python that converts a superset of Python into fast JavaScript. It can be run with regular Python, or fully self-hosted within -NodeJS using Empythoned. PythonJS has been designed with speed and easy -integration with existing JavaScript code in mind. +NodeJS using Empythoned. PythonJS extends the Python language with new keywords, syntax, +and optional static typing, to increase performance and allow seamless +integration with existing JavaScript libraries. -To convert your python scripts into javascript, you have two options: +We are not trying to shoehorn Python as defined by the BDFL into JavaScript, +our goal is to design something better than JavaScript so you can write larger +and more complex programs in a Python-like language. + + +To get started, you have two options: 1. install NodeJS, python-js package, and write a build script. 2. or install Python2 and use translator.py from this repo directly. From e46b9ab1667b92526aac5f89d9f9fd3f52569a69 Mon Sep 17 00:00:00 2001 From: hartsantler Date: Sun, 20 Jul 2014 23:24:27 -0700 Subject: [PATCH 021/100] allow new `->` syntax to auto bind method's this. --- README.md | 10 ++++++++++ pythonjs/typedpython.py | 11 +++++++++++ 2 files changed, 21 insertions(+) diff --git a/README.md b/README.md index 3c26968..8fed05d 100644 --- a/README.md +++ b/README.md @@ -99,6 +99,13 @@ def setup_my_jquery_class( $ ): $.fn.someclass = myclass_init ``` +6. `->` can be used to as a special attribute operator for passing methods that will automatically bind +the method's `this` calling context. This enables you to pass methods as callbacks to other objects, +and not have to write `a.some_method.bind(a)` +``` + b.set_callback( a->some_method ) +``` + Speed --------------- PythonJS gives you the option to optimize your program for speed with a new syntax for static typing, in some cases this results in code that is 20X faster. @@ -349,6 +356,7 @@ pythonjs.configure( Gotchas --------- 1. The calling context of `this` must be taken into account when using fast javascript mode, code that comes after: `pythonjs.configure(javascript=True)` or is inside a `with javascript:` block. When in javascript mode, passing a method as a callback, or setting it as an attribute on another object, requires you call `f.bind(self)` to ensure that `self` within the method points to the class instance. This is not required when using classes defined normal mode, because the `this` calling context is automatically managed. +Note: you can use the special `->` syntax in place of the attribute operator `.` to call `bind` automatically. ``` class A: @@ -365,10 +373,12 @@ with javascript: b = B() a.b_method1 = b.method a.b_method2 = b.method.bind(b) + a.b_method3 = b->method a.method() ## OK: prints a a.b_method1() ## FAILS: prints a, should have printed b a.b_method2() ## OK: prints b + a.b_method3() ## OK: prints b b.a_method = a.method b.a_method() ## OK: prints a diff --git a/pythonjs/typedpython.py b/pythonjs/typedpython.py index 8e1b80a..b9db14e 100644 --- a/pythonjs/typedpython.py +++ b/pythonjs/typedpython.py @@ -91,6 +91,12 @@ def transform_source( source, strip=False ): c += ')' * c.count(' new ') c = c.replace(' new ', ' new(') + if '->' in c: + a,b = c.split('->') + this_name = a.split()[-1].split('=')[-1].split(':')[-1].split(',')[-1] + method_name = b.split()[0].split('(')[0] + c = c.replace('->'+method_name, '.'+method_name+'.bind(%s)'%this_name) + ## jquery ## ## TODO ensure this is not inside quoted text if '$(' in c: @@ -117,6 +123,11 @@ def transform_source( source, strip=False ): if True: float* def Y(): pass + +A.callback = B->method +A.do_something( x,y,z, B->method ) +A.do_something( x,y,z, callback=B->method ) + ''' if __name__ == '__main__': From 31953c2e3f4eaa0ddb82ccf26dca49fb83675637 Mon Sep 17 00:00:00 2001 From: hartsantler Date: Mon, 21 Jul 2014 03:44:49 -0700 Subject: [PATCH 022/100] allow inline function `x.func( callback=def cb(): ...)` syntax --- pythonjs/typedpython.py | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/pythonjs/typedpython.py b/pythonjs/typedpython.py index b9db14e..4bacb26 100644 --- a/pythonjs/typedpython.py +++ b/pythonjs/typedpython.py @@ -23,6 +23,8 @@ def transform_source( source, strip=False ): output = [] + output_post = None + for line in source.splitlines(): a = [] for i,char in enumerate(line): @@ -91,12 +93,21 @@ def transform_source( source, strip=False ): c += ')' * c.count(' new ') c = c.replace(' new ', ' new(') + ## X.method.bind(X) shortcut `->` if '->' in c: a,b = c.split('->') this_name = a.split()[-1].split('=')[-1].split(':')[-1].split(',')[-1] method_name = b.split()[0].split('(')[0] c = c.replace('->'+method_name, '.'+method_name+'.bind(%s)'%this_name) + ## callback=def .. inline function ## + if '=def ' in c or '= def ' in c: + d = '=def ' + c, tail = c.split(d) + #name = c.split(d)[-1].split('(')[0] + c += '=lambda __INLINE_FUNCTION__: %s )' %tail.strip().split(':')[0] + output_post = 'def %s'%tail + ## jquery ## ## TODO ensure this is not inside quoted text if '$(' in c: @@ -110,8 +121,17 @@ def transform_source( source, strip=False ): c = c.replace('nonlocal ', 'global ') ## fake nonlocal with global output.append( c ) + if type(output_post) is str: + output.append(output_post) + output_post = True + elif output_post == True: + if output[-1].strip()==')': + output.pop() + output_post = None - return '\n'.join(output) + r = '\n'.join(output) + print(r) + return r test = ''' @@ -127,6 +147,9 @@ def transform_source( source, strip=False ): A.callback = B->method A.do_something( x,y,z, B->method ) A.do_something( x,y,z, callback=B->method ) +A.do_something( x,y,z, callback=def cb(x): + return x+y +) ''' From 9618b74ae73cfbd8032c29f444ac456cd2ea1061 Mon Sep 17 00:00:00 2001 From: hartsantler Date: Mon, 21 Jul 2014 06:18:43 -0700 Subject: [PATCH 023/100] regtest for inline def --- pythonjs/python_to_pythonjs.py | 9 ++++---- pythonjs/pythonjs.py | 39 +++++++++++++++++++++++++++------- pythonjs/typedpython.py | 8 ++++++- regtests/calling/inline_def.py | 11 ++++++++++ 4 files changed, 54 insertions(+), 13 deletions(-) create mode 100644 regtests/calling/inline_def.py diff --git a/pythonjs/python_to_pythonjs.py b/pythonjs/python_to_pythonjs.py index 811a513..b7d6abb 100755 --- a/pythonjs/python_to_pythonjs.py +++ b/pythonjs/python_to_pythonjs.py @@ -2540,10 +2540,11 @@ def visit_Call(self, node): def visit_Lambda(self, node): args = [self.visit(a) for a in node.args.args] - #if self._with_js: ## TODO is it better to return a normal lambda - # return """JS('(function (%s) {return %s})')""" %(','.join(args), self.visit(node.body)) - #else: - if hasattr(node, 'keep_as_lambda'): + + ##'__INLINE_FUNCTION__' from typedpython.py + + if hasattr(node, 'keep_as_lambda') or args and args[0]=='__INLINE_FUNCTION__': + ## TODO lambda keyword args self._in_lambda = True a = '(lambda %s: %s)' %(','.join(args), self.visit(node.body)) self._in_lambda = False diff --git a/pythonjs/pythonjs.py b/pythonjs/pythonjs.py index 6d73745..cfe10e0 100755 --- a/pythonjs/pythonjs.py +++ b/pythonjs/pythonjs.py @@ -19,6 +19,11 @@ #import code_writer import typedpython +class SwapNode( RuntimeError ): + def __init__(self, node): + self.node = node + RuntimeError.__init__(self) + class JSGenerator(NodeVisitor): #, inline_function.Inliner): def __init__(self, requirejs=True, insert_runtime=True, webworker=False, function_expressions=False): #writer = code_writer.Writer() @@ -31,6 +36,7 @@ def __init__(self, requirejs=True, insert_runtime=True, webworker=False, functio self._insert_runtime = insert_runtime self._webworker = webworker self._exports = set() + self._inline_lambda = False self.special_decorators = set(['__typedef__', '__glsl__', '__pyfunction__']) self._glsl = False @@ -178,7 +184,11 @@ def visit_ExceptHandler(self, node): def visit_Lambda(self, node): args = [self.visit(a) for a in node.args.args] - return '(function (%s) {return %s;})' %(','.join(args), self.visit(node.body)) + if args and args[0]=='__INLINE_FUNCTION__': + self._inline_lambda = True + return '' ## skip node, the next function contains the real def + else: + return '(function (%s) {return %s;})' %(','.join(args), self.visit(node.body)) @@ -475,15 +485,24 @@ def _visit_function(self, node): self.push() body = list() - for child in node.body: + next = None + for i,child in enumerate(node.body): if isinstance(child, Str): continue + elif next: + next = None + continue + + try: + v = self.visit(child) + except SwapNode as error: + error.node.__class__ = ast.FunctionDef + next = node.body[i+1] + assert isinstance(next, ast.FunctionDef) + error.node.__dict__ = next.__dict__ + v = self.visit(child) + - #if isinstance(child, GeneratorType): ## not tested - # for sub in child: - # body.append( self.indent()+self.visit(sub)) - #else: - v = self.visit(child) if v is None: msg = 'error in function: %s'%node.name msg += '\n%s' %child @@ -494,7 +513,9 @@ def _visit_function(self, node): buffer += '\n'.join(body) self.pull() buffer += '\n%s}\n' %self.indent() - if is_pyfunc: + if self._inline_lambda: + self._inline_lambda = False + elif is_pyfunc: buffer += ';%s.is_wrapper = true;' %node.name ## TODO change to .__pyfunc__ return buffer @@ -963,6 +984,8 @@ def visit_Dict(self, node): for i in range( len(node.keys) ): k = self.visit( node.keys[ i ] ) v = self.visit( node.values[i] ) + if self._inline_lambda: + raise SwapNode( node.values[i] ) ## caller catches this, changes the node to a function a.append( '%s:%s'%(k,v) ) b = ','.join( a ) return '{ %s }' %b diff --git a/pythonjs/typedpython.py b/pythonjs/typedpython.py index 4bacb26..67f23be 100644 --- a/pythonjs/typedpython.py +++ b/pythonjs/typedpython.py @@ -122,7 +122,13 @@ def transform_source( source, strip=False ): output.append( c ) if type(output_post) is str: - output.append(output_post) + indent = 0 + for u in output[-1]: + if u == ' ' or u == '\t': + indent += 1 + else: + break + output.append( ('\t'*indent)+output_post) output_post = True elif output_post == True: if output[-1].strip()==')': diff --git a/regtests/calling/inline_def.py b/regtests/calling/inline_def.py new file mode 100644 index 0000000..b1ef0fd --- /dev/null +++ b/regtests/calling/inline_def.py @@ -0,0 +1,11 @@ +"""inline def""" + +def test( callback=None ): + return callback + +def main(): + f = test( callback=def cb(x,y): + return x+y + ) + TestError( f(1,2) == 3 ) + From 832b29a5fd346d2db7b0af9e72e9140b2eb3d6cc Mon Sep 17 00:00:00 2001 From: hartsantler Date: Mon, 21 Jul 2014 14:04:07 -0700 Subject: [PATCH 024/100] fixed inline def in javascript mode. TODO fix for normal mode. --- README.md | 21 +++++++++++++++------ pythonjs/python_to_pythonjs.py | 2 +- pythonjs/pythonjs.py | 4 +++- pythonjs/typedpython.py | 6 +++++- regtests/calling/inline_def.py | 2 +- 5 files changed, 25 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 8fed05d..626fbfc 100644 --- a/README.md +++ b/README.md @@ -73,39 +73,48 @@ Extra Python Syntax PythonJS supports all the normal Python syntax you already know, and has been extended to support some extra JavaScript syntax. -1. it is ok to have `var ` before a variable name in an assignment. +. it is ok to have `var ` before a variable name in an assignment. ``` var x = 1 ``` -2. 'new' can be used to create a new JavaScript object +. 'new' can be used to create a new JavaScript object ``` a = new SomeObject() ``` -3. `$` can be used to call a function like jquery +. `$` can be used to call a function like jquery ``` $(selector).something( {'param1':1, 'param2':2} ) ``` -4. External Javascript functions that use an object as the last argument for optional named arguments, can be called with Python style keyword names instead. +. External Javascript functions that use an object as the last argument for optional named arguments, can be called with Python style keyword names instead. ``` $(selector).something( param1=1, param2=2 ) ``` -5. `$` can be used as a funtion parameter, and attributes can be get/set on `$`. +. `$` can be used as a funtion parameter, and attributes can be get/set on `$`. ``` def setup_my_jquery_class( $ ): $.fn.someclass = myclass_init ``` -6. `->` can be used to as a special attribute operator for passing methods that will automatically bind +. `->` can be used to as a special attribute operator for passing methods that will automatically bind the method's `this` calling context. This enables you to pass methods as callbacks to other objects, and not have to write `a.some_method.bind(a)` ``` b.set_callback( a->some_method ) ``` +. in a function call, as a keyword argument, define callbacks inline with def +``` +a.func( callback=def (x,y,z): + x += y + return x - z + +) +``` + Speed --------------- PythonJS gives you the option to optimize your program for speed with a new syntax for static typing, in some cases this results in code that is 20X faster. diff --git a/pythonjs/python_to_pythonjs.py b/pythonjs/python_to_pythonjs.py index b7d6abb..b87e9c2 100755 --- a/pythonjs/python_to_pythonjs.py +++ b/pythonjs/python_to_pythonjs.py @@ -2162,7 +2162,7 @@ def visit_Call(self, node): self._direct_operators.add( kw.value.s ) else: - raise SyntaxError( self.format_error(node) ) + raise SyntaxError( self.format_error('invalid keyword option') ) elif self._with_ll or name == 'inline' or self._with_glsl: F = self.visit(node.func) diff --git a/pythonjs/pythonjs.py b/pythonjs/pythonjs.py index cfe10e0..fbc23ad 100755 --- a/pythonjs/pythonjs.py +++ b/pythonjs/pythonjs.py @@ -498,8 +498,10 @@ def _visit_function(self, node): except SwapNode as error: error.node.__class__ = ast.FunctionDef next = node.body[i+1] - assert isinstance(next, ast.FunctionDef) + if not isinstance(next, ast.FunctionDef): + raise SyntaxError('inline def is only allowed in javascript mode') error.node.__dict__ = next.__dict__ + error.node.name = '' v = self.visit(child) diff --git a/pythonjs/typedpython.py b/pythonjs/typedpython.py index 67f23be..44453eb 100644 --- a/pythonjs/typedpython.py +++ b/pythonjs/typedpython.py @@ -102,6 +102,8 @@ def transform_source( source, strip=False ): ## callback=def .. inline function ## if '=def ' in c or '= def ' in c: + if 'def (' in c: + c = c.replace('def (', 'def __NAMELESS__(') d = '=def ' c, tail = c.split(d) #name = c.split(d)[-1].split('(')[0] @@ -136,7 +138,6 @@ def transform_source( source, strip=False ): output_post = None r = '\n'.join(output) - print(r) return r @@ -156,6 +157,9 @@ def transform_source( source, strip=False ): A.do_something( x,y,z, callback=def cb(x): return x+y ) +A.do_something( x,y,z, callback=def (x,y,z): + return x+y +) ''' diff --git a/regtests/calling/inline_def.py b/regtests/calling/inline_def.py index b1ef0fd..ad2f317 100644 --- a/regtests/calling/inline_def.py +++ b/regtests/calling/inline_def.py @@ -4,7 +4,7 @@ def test( callback=None ): return callback def main(): - f = test( callback=def cb(x,y): + f = test( callback=def (x,y): return x+y ) TestError( f(1,2) == 3 ) From e877fd4ce08d3103095153030c71968165bef870 Mon Sep 17 00:00:00 2001 From: hartsantler Date: Mon, 21 Jul 2014 23:33:39 -0700 Subject: [PATCH 025/100] adding support for RapydScript style inline function def --- pythonjs/typedpython.py | 62 +++++++++++++++++++++++++++++++++++------ 1 file changed, 53 insertions(+), 9 deletions(-) diff --git a/pythonjs/typedpython.py b/pythonjs/typedpython.py index 44453eb..2d79167 100644 --- a/pythonjs/typedpython.py +++ b/pythonjs/typedpython.py @@ -45,8 +45,8 @@ def transform_source( source, strip=False ): if a[-1]=='*': a.pop() a.append('POINTER') - a.append('=') - a.append( char ) + a.append('=\t\t\t\t') + #a.append( char ) else: a.append( char ) else: @@ -62,8 +62,8 @@ def transform_source( source, strip=False ): if cs.startswith('var '): c = c.replace('var ', '') - if '= def ' in c: - x, c = c.split('= def ') + if '=\t\t\t\tdef ' in c: + x, c = c.split('=\t\t\t\tdef ') indent = [] pre = [] for char in x: @@ -101,14 +101,35 @@ def transform_source( source, strip=False ): c = c.replace('->'+method_name, '.'+method_name+'.bind(%s)'%this_name) ## callback=def .. inline function ## - if '=def ' in c or '= def ' in c: + if '=def ' in c or '= def ' in c or ': def ' in c or ':def ' in c: + if '=def ' in c: + d = '=def ' + elif '= def ' in c: + d = '= def ' + elif ': def ' in c: + d = ': def ' + elif ':def ' in c: + d = ':def ' + if 'def (' in c: c = c.replace('def (', 'def __NAMELESS__(') - d = '=def ' c, tail = c.split(d) #name = c.split(d)[-1].split('(')[0] - c += '=lambda __INLINE_FUNCTION__: %s )' %tail.strip().split(':')[0] - output_post = 'def %s'%tail + if d.startswith('='): + if '(' in c: + c += '=lambda __INLINE_FUNCTION__: %s )' %tail.strip().split(':')[0] + else: + c += '=lambda __INLINE_FUNCTION__: %s' %tail.strip().split(':')[0] + output_post = 'def %s'%tail + else: + c += ':lambda __INLINE_FUNCTION__: %s,' %tail.strip().split(':')[0] + output.append( c ) + if output_post: + if output_post[-1][-1]==',': + output_post[-1] = output_post[-1][:-1] + else: output_post = list() + c = 'def %s'%tail + ## jquery ## ## TODO ensure this is not inside quoted text @@ -122,7 +143,11 @@ def transform_source( source, strip=False ): if c.strip().startswith('nonlocal '): ## Python3 syntax c = c.replace('nonlocal ', 'global ') ## fake nonlocal with global - output.append( c ) + if type(output_post) is list: + output_post.append( c ) + else: + output.append( c ) + if type(output_post) is str: indent = 0 for u in output[-1]: @@ -136,6 +161,11 @@ def transform_source( source, strip=False ): if output[-1].strip()==')': output.pop() output_post = None + elif type(output_post) is list: + if output_post[-1].strip().endswith('}'): + output.append( output_post.pop() ) + output.extend( output_post ) + output_post = None r = '\n'.join(output) return r @@ -160,6 +190,20 @@ def transform_source( source, strip=False ): A.do_something( x,y,z, callback=def (x,y,z): return x+y ) +a = { + 'cb1': def (x,y): + return x+y +} + +b = { + 'cb1': def (x,y): + return x+y, + 'cb2': def (x,y): + return x+y +} + +c=def (x,y): + return x+y ''' From d63890916d00b88ccbdf332260f4c94f2c9734d3 Mon Sep 17 00:00:00 2001 From: hartsantler Date: Tue, 22 Jul 2014 03:26:49 -0700 Subject: [PATCH 026/100] fixing inline def inside of dict --- pythonjs/pythonjs.py | 18 ++++++++++++++---- pythonjs/typedpython.py | 29 +++++++++++++++++++---------- regtests/dict/dict_inline_def.py | 10 ++++++++++ 3 files changed, 43 insertions(+), 14 deletions(-) create mode 100644 regtests/dict/dict_inline_def.py diff --git a/pythonjs/pythonjs.py b/pythonjs/pythonjs.py index fbc23ad..27e8f9e 100755 --- a/pythonjs/pythonjs.py +++ b/pythonjs/pythonjs.py @@ -140,7 +140,16 @@ def visit_Tuple(self, node): return '[%s]' % ', '.join(map(self.visit, node.elts)) def visit_List(self, node): - return '[%s]' % ', '.join(map(self.visit, node.elts)) + a = [] + for elt in node.elts: + b = self.visit(elt) + if b is None: + raise SyntaxError(elt) + a.append( b ) + #if self._inline_lambda == True: + # raise SwapNode( elt ) + return '[%s]' % ', '.join(a) + def visit_TryExcept(self, node): out = [] @@ -186,7 +195,8 @@ def visit_Lambda(self, node): args = [self.visit(a) for a in node.args.args] if args and args[0]=='__INLINE_FUNCTION__': self._inline_lambda = True - return '' ## skip node, the next function contains the real def + #return '' ## skip node, the next function contains the real def + raise SwapNode( node ) else: return '(function (%s) {return %s;})' %(','.join(args), self.visit(node.body)) @@ -986,8 +996,8 @@ def visit_Dict(self, node): for i in range( len(node.keys) ): k = self.visit( node.keys[ i ] ) v = self.visit( node.values[i] ) - if self._inline_lambda: - raise SwapNode( node.values[i] ) ## caller catches this, changes the node to a function + #if self._inline_lambda: + # raise SwapNode( node.values[i] ) ## caller catches this, changes the node to a function a.append( '%s:%s'%(k,v) ) b = ','.join( a ) return '{ %s }' %b diff --git a/pythonjs/typedpython.py b/pythonjs/typedpython.py index 2d79167..2542805 100644 --- a/pythonjs/typedpython.py +++ b/pythonjs/typedpython.py @@ -164,7 +164,16 @@ def transform_source( source, strip=False ): elif type(output_post) is list: if output_post[-1].strip().endswith('}'): output.append( output_post.pop() ) - output.extend( output_post ) + #output.extend( output_post ) + indent = 0 + for u in output[-1]: + if u == ' ' or u == '\t': + indent += 1 + else: + break + for ln in output_post: + output.append( ('\t'*indent)+ln ) + output_post = None r = '\n'.join(output) @@ -194,15 +203,15 @@ def transform_source( source, strip=False ): 'cb1': def (x,y): return x+y } - -b = { - 'cb1': def (x,y): - return x+y, - 'cb2': def (x,y): - return x+y -} - -c=def (x,y): +def xxx(): + b = { + 'cb1': def (x,y): + return x+y, + 'cb2': def (x,y): + return x+y + } + +c = def (x,y): return x+y ''' diff --git a/regtests/dict/dict_inline_def.py b/regtests/dict/dict_inline_def.py new file mode 100644 index 0000000..29b86f0 --- /dev/null +++ b/regtests/dict/dict_inline_def.py @@ -0,0 +1,10 @@ +"""dict inline def""" + + +def main(): + + d = { 'callback': def (x,y): + return x+y + } + TestError( d['callback'](1,2) == 3 ) + From ee3e16ebe15371be7d5a57967441198694a11d86 Mon Sep 17 00:00:00 2001 From: hartsantler Date: Tue, 22 Jul 2014 05:11:16 -0700 Subject: [PATCH 027/100] support multiple inline function def's inside a dict --- pythonjs/pythonjs.py | 61 ++++++++++++++++++++------------ regtests/dict/dict_inline_def.py | 7 ++++ 2 files changed, 46 insertions(+), 22 deletions(-) diff --git a/pythonjs/pythonjs.py b/pythonjs/pythonjs.py index 27e8f9e..425c31a 100755 --- a/pythonjs/pythonjs.py +++ b/pythonjs/pythonjs.py @@ -19,7 +19,7 @@ #import code_writer import typedpython -class SwapNode( RuntimeError ): +class SwapLambda( RuntimeError ): def __init__(self, node): self.node = node RuntimeError.__init__(self) @@ -143,11 +143,8 @@ def visit_List(self, node): a = [] for elt in node.elts: b = self.visit(elt) - if b is None: - raise SyntaxError(elt) + if b is None: raise SyntaxError(elt) a.append( b ) - #if self._inline_lambda == True: - # raise SwapNode( elt ) return '[%s]' % ', '.join(a) @@ -196,7 +193,7 @@ def visit_Lambda(self, node): if args and args[0]=='__INLINE_FUNCTION__': self._inline_lambda = True #return '' ## skip node, the next function contains the real def - raise SwapNode( node ) + raise SwapLambda( node ) else: return '(function (%s) {return %s;})' %(','.join(args), self.visit(node.body)) @@ -497,22 +494,21 @@ def _visit_function(self, node): body = list() next = None for i,child in enumerate(node.body): - if isinstance(child, Str): - continue - elif next: - next = None + if isinstance(child, Str) or hasattr(child, 'SKIP'): continue - try: - v = self.visit(child) - except SwapNode as error: - error.node.__class__ = ast.FunctionDef - next = node.body[i+1] - if not isinstance(next, ast.FunctionDef): - raise SyntaxError('inline def is only allowed in javascript mode') - error.node.__dict__ = next.__dict__ - error.node.name = '' - v = self.visit(child) + #try: + # v = self.visit(child) + #except SwapLambda as error: + # error.node.__class__ = ast.FunctionDef + # next = node.body[i+1] + # if not isinstance(next, ast.FunctionDef): + # raise SyntaxError('inline def is only allowed in javascript mode') + # error.node.__dict__ = next.__dict__ + # error.node.name = '' + # v = self.visit(child) + + v = self.try_and_catch_swap_lambda(child, node.body) if v is None: @@ -531,6 +527,29 @@ def _visit_function(self, node): buffer += ';%s.is_wrapper = true;' %node.name ## TODO change to .__pyfunc__ return buffer + def try_and_catch_swap_lambda(self, child, body): + try: + return self.visit(child) + except SwapLambda as e: + + next = None + for i in range( body.index(child), len(body) ): + n = body[ i ] + if isinstance(n, ast.FunctionDef): + if hasattr(n, 'SKIP'): + continue + else: + next = n + break + assert next + next.SKIP = True + e.node.__class__ = ast.FunctionDef + e.node.__dict__ = next.__dict__ + e.node.name = '' + return self.try_and_catch_swap_lambda( child, body ) + + + def _visit_subscript_ellipsis(self, node): name = self.visit(node.value) return '%s["$wrapped"]' %name @@ -996,8 +1015,6 @@ def visit_Dict(self, node): for i in range( len(node.keys) ): k = self.visit( node.keys[ i ] ) v = self.visit( node.values[i] ) - #if self._inline_lambda: - # raise SwapNode( node.values[i] ) ## caller catches this, changes the node to a function a.append( '%s:%s'%(k,v) ) b = ','.join( a ) return '{ %s }' %b diff --git a/regtests/dict/dict_inline_def.py b/regtests/dict/dict_inline_def.py index 29b86f0..e4ad9cb 100644 --- a/regtests/dict/dict_inline_def.py +++ b/regtests/dict/dict_inline_def.py @@ -8,3 +8,10 @@ def main(): } TestError( d['callback'](1,2) == 3 ) + a = { 'cb1': def (x,y): + return x+y, + 'cb2' : def (x): + return x*2 + } + TestError( a['cb1'](1,2) == 3 ) + TestError( a['cb2'](100) == 200 ) From 86da02ebc0befa5eff38376d0962e7e546373b06 Mon Sep 17 00:00:00 2001 From: hartsantler Date: Tue, 22 Jul 2014 06:26:13 -0700 Subject: [PATCH 028/100] support multiple inline functions as keyword args in function call. --- README.md | 22 +++++++++++---- pythonjs/typedpython.py | 50 ++++++++++++++++++++++++++-------- regtests/calling/inline_def.py | 13 +++++---- 3 files changed, 64 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index 626fbfc..adba600 100644 --- a/README.md +++ b/README.md @@ -106,15 +106,27 @@ and not have to write `a.some_method.bind(a)` b.set_callback( a->some_method ) ``` -. in a function call, as a keyword argument, define callbacks inline with def +. in a function call, inline functions can be given as keyword arguments ``` -a.func( callback=def (x,y,z): - x += y - return x - z - +a.func( + callback1=def (x,y,z): + x += y + return x - z, + callback2= def (x, y): + return x * y ) ``` +. inline functions can be used inside a dict literal +``` +a = { + 'cb1' : def (x): + return x, + 'cb2' : def (y): + return y +} +``` + Speed --------------- PythonJS gives you the option to optimize your program for speed with a new syntax for static typing, in some cases this results in code that is 20X faster. diff --git a/pythonjs/typedpython.py b/pythonjs/typedpython.py index 2542805..1356f9f 100644 --- a/pythonjs/typedpython.py +++ b/pythonjs/typedpython.py @@ -62,6 +62,13 @@ def transform_source( source, strip=False ): if cs.startswith('var '): c = c.replace('var ', '') + if '= function(' in c: + k = '= function(' + a,b = c.split(k) + output.append( '@func_expression(%s)' %a.strip()) + c = 'def __NAMELESS__(' + b + + if '=\t\t\t\tdef ' in c: x, c = c.split('=\t\t\t\tdef ') indent = [] @@ -114,13 +121,27 @@ def transform_source( source, strip=False ): if 'def (' in c: c = c.replace('def (', 'def __NAMELESS__(') c, tail = c.split(d) - #name = c.split(d)[-1].split('(')[0] + + #if d.startswith('='): + # if '(' in c: + # c += '=lambda __INLINE_FUNCTION__: %s )' %tail.strip().split(':')[0] + # else: + # c += '=lambda __INLINE_FUNCTION__: %s' %tail.strip().split(':')[0] + # output_post = 'def %s'%tail + if d.startswith('='): - if '(' in c: - c += '=lambda __INLINE_FUNCTION__: %s )' %tail.strip().split(':')[0] - else: - c += '=lambda __INLINE_FUNCTION__: %s' %tail.strip().split(':')[0] - output_post = 'def %s'%tail + c += '=lambda __INLINE_FUNCTION__: %s' %tail.strip().split(':')[0] + + if output_post: + if output_post[-1][-1]==',': + output_post[-1] = output_post[-1][:-1] + output[-1] += ',' + else: output_post = list() + + output.append( c ) + + c = 'def %s'%tail + else: c += ':lambda __INLINE_FUNCTION__: %s,' %tail.strip().split(':')[0] output.append( c ) @@ -148,7 +169,7 @@ def transform_source( source, strip=False ): else: output.append( c ) - if type(output_post) is str: + if type(output_post) is str: ## DEPRECATED indent = 0 for u in output[-1]: if u == ' ' or u == '\t': @@ -157,14 +178,14 @@ def transform_source( source, strip=False ): break output.append( ('\t'*indent)+output_post) output_post = True - elif output_post == True: + elif output_post == True: ## DEPRECATED if output[-1].strip()==')': output.pop() output_post = None + elif type(output_post) is list: - if output_post[-1].strip().endswith('}'): + if output_post[-1].strip().endswith( ('}',')') ): output.append( output_post.pop() ) - #output.extend( output_post ) indent = 0 for u in output[-1]: if u == ' ' or u == '\t': @@ -211,9 +232,16 @@ def xxx(): return x+y } -c = def (x,y): +X.func( cb1=def (): + return 1, + cb2=def (): + return 2 +) + +c = function(x,y): return x+y + ''' if __name__ == '__main__': diff --git a/regtests/calling/inline_def.py b/regtests/calling/inline_def.py index ad2f317..c9867fe 100644 --- a/regtests/calling/inline_def.py +++ b/regtests/calling/inline_def.py @@ -1,11 +1,14 @@ """inline def""" -def test( callback=None ): - return callback +def test( callback1=None, callback2=None ): + return {'cb1', callback1, 'cb2': callback2 } def main(): - f = test( callback=def (x,y): - return x+y + o = test( callback1=def (x,y): + return x+y, + callback2 = def (x): + return x*2 ) - TestError( f(1,2) == 3 ) + TestError( o['cb1'](1,2) == 3 ) + TestError( o['cb2'](100) == 200 ) From 3f087983b4d0ea8048f7bc72355f2b9c0a81b159 Mon Sep 17 00:00:00 2001 From: hartsantler Date: Tue, 22 Jul 2014 17:26:24 -0700 Subject: [PATCH 029/100] implemented exception expressions: PEP 463 --- README.md | 7 +++++++ pythonjs/typedpython.py | 8 ++++++++ 2 files changed, 15 insertions(+) diff --git a/README.md b/README.md index adba600..2e23f27 100644 --- a/README.md +++ b/README.md @@ -127,6 +127,13 @@ a = { } ``` +. exception expressions (PEP 463) +``` +a = {} +b = a['somekey'] except KeyError: 'my-default' +``` + + Speed --------------- PythonJS gives you the option to optimize your program for speed with a new syntax for static typing, in some cases this results in code that is 20X faster. diff --git a/pythonjs/typedpython.py b/pythonjs/typedpython.py index 1356f9f..e412265 100644 --- a/pythonjs/typedpython.py +++ b/pythonjs/typedpython.py @@ -68,6 +68,13 @@ def transform_source( source, strip=False ): output.append( '@func_expression(%s)' %a.strip()) c = 'def __NAMELESS__(' + b + if ' except ' in c: ## PEP 463 - exception expressions + s = c.split(' except ') + if len(s) == 2 and '=' in s[0]: + output.append('try: %s' %s[0]) + exception, default = s[1].split(':') + output.append('except %s: %s=%s' %( exception, s[0].split('=')[0], default) ) + c = '' if '=\t\t\t\tdef ' in c: x, c = c.split('=\t\t\t\tdef ') @@ -241,6 +248,7 @@ def xxx(): c = function(x,y): return x+y +d = a[ 'somekey' ] except KeyError: 'mydefault' ''' From 5015227f7ca65d6bde7f56275f37c94e294d83a2 Mon Sep 17 00:00:00 2001 From: hartsantler Date: Wed, 23 Jul 2014 01:43:05 -0700 Subject: [PATCH 030/100] Exception Expressions: fixed indented blocks. --- pythonjs/typedpython.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/pythonjs/typedpython.py b/pythonjs/typedpython.py index e412265..a245cf3 100644 --- a/pythonjs/typedpython.py +++ b/pythonjs/typedpython.py @@ -71,9 +71,17 @@ def transform_source( source, strip=False ): if ' except ' in c: ## PEP 463 - exception expressions s = c.split(' except ') if len(s) == 2 and '=' in s[0]: - output.append('try: %s' %s[0]) + indent = [] + for char in s[0]: + if char in __whitespace: + indent.append( char ) + else: + break + indent = ''.join(indent) + s0 = s[0].strip() + output.append('%stry: %s' %(indent, s0) ) exception, default = s[1].split(':') - output.append('except %s: %s=%s' %( exception, s[0].split('=')[0], default) ) + output.append('%sexcept %s: %s=%s' %(indent, exception, s0.split('=')[0], default) ) c = '' if '=\t\t\t\tdef ' in c: @@ -247,8 +255,8 @@ def xxx(): c = function(x,y): return x+y - -d = a[ 'somekey' ] except KeyError: 'mydefault' +if True: + d = a[ 'somekey' ] except KeyError: 'mydefault' ''' From 83900ef6c57d5a55289225bf325cad7ef9195330 Mon Sep 17 00:00:00 2001 From: hartsantler Date: Wed, 23 Jul 2014 04:07:41 -0700 Subject: [PATCH 031/100] removed ripplelib test --- regtests/requirejs/import_ripplelib.py | 37 -------------------------- 1 file changed, 37 deletions(-) delete mode 100644 regtests/requirejs/import_ripplelib.py diff --git a/regtests/requirejs/import_ripplelib.py b/regtests/requirejs/import_ripplelib.py deleted file mode 100644 index 30914c3..0000000 --- a/regtests/requirejs/import_ripplelib.py +++ /dev/null @@ -1,37 +0,0 @@ -'''test ripple library''' -# sudo npm install -g ripple-lib -# https://github.com/ripple/ripple-lib/blob/develop/docs/GUIDES.md - -import ripple-lib as ripple - -def main(): - R = new(ripple.Remote( - trusted=True, - local_signing=True, - local_fee=True, - fee_cushion=1.5, - servers = [ - {'host':'s1.ripple.com', 'port':443, 'secure':True} - ] - )) - def on_connect(): - print('connected!') - test2(R) - - R.connect( on_connect ) - -def test2(R): - req = R.request_server_info() - def on_server_info_ok(r): - print('info ok') - print(r) - def on_server_info_err(e): - print('info err') - print(e) - - req.on('success', on_server_info_ok) - req.on('error', on_server_info_err) - - req.request() - - print('ripple-lib test complete') From 7ab57cf6a7fe75ecac60f3639ed7ca275e618792 Mon Sep 17 00:00:00 2001 From: hartsantler Date: Wed, 23 Jul 2014 04:08:15 -0700 Subject: [PATCH 032/100] new command line option `--analyzer` for translator.py, trigger code analysis and debugging using dartanalyzer from the Dart SDK. --- README.md | 8 +- pythonjs/translator.py | 161 ++++++++++++++++++++++++----------------- 2 files changed, 103 insertions(+), 66 deletions(-) diff --git a/README.md b/README.md index 2e23f27..1c7b5b7 100644 --- a/README.md +++ b/README.md @@ -59,7 +59,7 @@ will be converted into JavaScript. Usage:: - translator.py [--dart|--coffee|--lua|--no-wrapper] file.py + translator.py [--help|--dart|--coffee|--lua|--no-wrapper|--analyzer] file.py Examples:: @@ -67,6 +67,12 @@ Examples:: ./translator.py myscript.py > myscript.js ./translator.py myapp.html > app.html +The option `--no-wrapper` will output the raw JavaScript, by default the output is wrapped as a requirejs module. + +The option `--analyzer` requires the Dart SDK is installed to your home directory: `~/dart-sdk`, +if this option is used then your script is also translated using the dart backend and fed to +`dartanalyzer` which will perform static analysis of your code. Dartanalyzer is able to catch many types of errors, like: missing functions, invalid names, calling a function with the wrong argument types. The quality of the analysis will depend on how much type information can be +inferred from your code, combined with the variables you have manually typed. If dartanalyzer detects an error in your code, translation will abort, and debugging information is printed. Extra Python Syntax ------------------- diff --git a/pythonjs/translator.py b/pythonjs/translator.py index bbeab65..46fd4b9 100755 --- a/pythonjs/translator.py +++ b/pythonjs/translator.py @@ -9,81 +9,112 @@ from pythonjs_to_luajs import main as pythonjs_to_luajs cmdhelp = """\ -usage: translator.py [--dart|--coffee|--lua] file.py - translator.py --visjs file.py\ +usage: translator.py [--dart|--coffee|--lua|--visjs|--no-wrapper|--analyze] file.py + +example: + translator.py --no-wrapper myscript.py > myscript.js """ + def main(script, module_path=None): - if '--visjs' in sys.argv: - import python_to_visjs - return python_to_visjs.main( script ) - else: - code = '' - if '--dart' in sys.argv: - a = python_to_pythonjs(script, dart=True, module_path=module_path) - code = pythonjs_to_dart( a ) - elif '--coffee' in sys.argv: - a = python_to_pythonjs(script, coffee=True, module_path=module_path) - code = pythonjs_to_coffee( a ) - elif '--lua' in sys.argv: - a = python_to_pythonjs(script, lua=True, module_path=module_path) - try: code = pythonjs_to_lua( a ) - except SyntaxError: - err = traceback.format_exc() - lineno = 0 - for line in err.splitlines(): - if "" in line: - lineno = int(line.split()[-1]) + if '--visjs' in sys.argv: + import python_to_visjs + return python_to_visjs.main( script ) + else: + code = '' + res = None + if '--dart' in sys.argv: + a = python_to_pythonjs(script, dart=True, module_path=module_path) + code = pythonjs_to_dart( a ) + elif '--coffee' in sys.argv: + a = python_to_pythonjs(script, coffee=True, module_path=module_path) + code = pythonjs_to_coffee( a ) + elif '--lua' in sys.argv: + a = python_to_pythonjs(script, lua=True, module_path=module_path) + try: code = pythonjs_to_lua( a ) + except SyntaxError: + err = traceback.format_exc() + lineno = 0 + for line in err.splitlines(): + if "" in line: + lineno = int(line.split()[-1]) + + b = a.splitlines()[ lineno ] + sys.stderr.write( '\n'.join([err,b]) ) + + elif '--luajs' in sys.argv: ## converts back to javascript + a = python_to_pythonjs(script, lua=True, module_path=module_path) + code = pythonjs_to_luajs( a ) + else: + a = python_to_pythonjs(script, module_path=module_path) + if isinstance(a, dict): + res = {} + for jsfile in a: + res[ jsfile ] = pythonjs_to_javascript( a[jsfile], webworker=jsfile != 'main' ) + return res + else: + ## requirejs module is on by default, this wraps the code in a `define` function + ## and returns `__module__` + ## if --no-wrapper is used, then the raw javascript is returned. + code = pythonjs_to_javascript( a, requirejs='--no-wrapper' not in sys.argv ) + + if '--analyze' in sys.argv: + dartanalyzer = os.path.expanduser('~/dart-sdk/bin/dartanalyzer') + #dart2js = os.path.expanduser('~/dart-sdk/bin/dart2js') + assert os.path.isfile( dartanalyzer ) - b = a.splitlines()[ lineno ] - sys.stderr.write( '\n'.join([err,b]) ) - - elif '--luajs' in sys.argv: ## converts back to javascript - a = python_to_pythonjs(script, lua=True, module_path=module_path) - code = pythonjs_to_luajs( a ) - else: - a = python_to_pythonjs(script, module_path=module_path) - if isinstance(a, dict): - res = {} - for jsfile in a: - res[ jsfile ] = pythonjs_to_javascript( a[jsfile], webworker=jsfile != 'main' ) - return res - else: - ## requirejs module is on by default, this wraps the code in a `define` function - ## and returns `__module__` - ## if --no-wrapper is used, then the raw javascript is returned. - code = pythonjs_to_javascript( a, requirejs='--no-wrapper' not in sys.argv ) + x = python_to_pythonjs(script, dart=True, module_path=module_path) + dartcode = pythonjs_to_dart( x ) + path = '/tmp/debug.dart' + open(path, 'wb').write( dartcode ) + import subprocess + try: + subprocess.check_output( [dartanalyzer, path] ) + except subprocess.CalledProcessError as err: + dartcodelines = dartcode.splitlines() + for line in err.output.splitlines(): + if line.startswith('[error]'): + a,b = line.split( path ) + a = a[:-1] + print( '\x1B[0;31m' + a + '\x1B[0m' ) + lineno = int( b.split('line ')[-1].split(',')[0] ) + print('line: %s' %lineno) + print( dartcodelines[lineno-1] ) + sys.exit(1) - return code + if res: ## dict return + return res + else: + return code def command(): - if '-h' in sys.argv or '--help' in sys.argv: - print(cmdhelp) - return + if '-h' in sys.argv or '--help' in sys.argv: + print(cmdhelp) + return - mpath = None - scripts = [] - if len(sys.argv) > 1: - for arg in sys.argv[1:]: - if arg.endswith('.py') or arg.endswith('.html'): - scripts.append( arg ) - if mpath is None: - mpath = os.path.split(arg)[0] + mpath = None + scripts = [] + if len(sys.argv) > 1: + for arg in sys.argv[1:]: + if arg.endswith('.py') or arg.endswith('.html'): + scripts.append( arg ) + if mpath is None: + mpath = os.path.split(arg)[0] - if len(scripts): - a = [] - for script in scripts: - a.append( open(script, 'rb').read() ) - data = '\n'.join( a ) - else: - data = sys.stdin.read() + if len(scripts): + a = [] + for script in scripts: + a.append( open(script, 'rb').read() ) + data = '\n'.join( a ) + else: + data = sys.stdin.read() - js = main(data, module_path=mpath) - if isinstance(js, dict): - print( json.dumps(js) ) - else: - print(js) + js = main(data, module_path=mpath) + if isinstance(js, dict): + print( json.dumps(js) ) + else: + print(js) if __name__ == '__main__': - command() + command() From 4d5b4a882889409036b9610eeeee7ef4b591eb3e Mon Sep 17 00:00:00 2001 From: hartsantler Date: Wed, 23 Jul 2014 07:07:01 -0700 Subject: [PATCH 033/100] new function expression syntax. --- README.md | 5 +++++ pythonjs/python_to_pythonjs.py | 8 ++++++++ pythonjs/pythonjs.py | 22 ++++++++++++++++------ pythonjs/typedpython.py | 2 +- regtests/calling/function_expression.py | 8 ++++++++ 5 files changed, 38 insertions(+), 7 deletions(-) create mode 100644 regtests/calling/function_expression.py diff --git a/README.md b/README.md index 1c7b5b7..ee42959 100644 --- a/README.md +++ b/README.md @@ -139,6 +139,11 @@ a = {} b = a['somekey'] except KeyError: 'my-default' ``` +. function expressions +``` +F = function(x): + return x +``` Speed --------------- diff --git a/pythonjs/python_to_pythonjs.py b/pythonjs/python_to_pythonjs.py index b87e9c2..619602d 100755 --- a/pythonjs/python_to_pythonjs.py +++ b/pythonjs/python_to_pythonjs.py @@ -2592,6 +2592,7 @@ def visit_FunctionDef(self, node): gpu_vectorize = False gpu_method = False local_typedefs = [] + func_expr = None ## deprecated? self._cached_property = None @@ -2605,6 +2606,10 @@ def visit_FunctionDef(self, node): if isinstance(decorator, Name) and decorator.id == 'gpu': gpu = True + elif isinstance(decorator, Call) and decorator.func.id == 'expression': + assert len(decorator.args)==1 + func_expr = self.visit(decorator.args[0]) + elif isinstance(decorator, Call) and decorator.func.id == 'typedef': c = decorator assert len(c.args) == 0 and len(c.keywords) @@ -2780,6 +2785,9 @@ def visit_FunctionDef(self, node): if args_typedefs: writer.write('@__typedef__(%s)' %','.join(args_typedefs)) + if func_expr: + writer.write('@expression(%s)' %func_expr) + if not self._with_dart and not self._with_lua and not self._with_js and not javascript and not self._with_glsl: writer.write('@__pyfunction__') diff --git a/pythonjs/pythonjs.py b/pythonjs/pythonjs.py index 425c31a..3910e7c 100755 --- a/pythonjs/pythonjs.py +++ b/pythonjs/pythonjs.py @@ -38,7 +38,7 @@ def __init__(self, requirejs=True, insert_runtime=True, webworker=False, functio self._exports = set() self._inline_lambda = False - self.special_decorators = set(['__typedef__', '__glsl__', '__pyfunction__']) + self.special_decorators = set(['__typedef__', '__glsl__', '__pyfunction__', 'expression']) self._glsl = False self._has_glsl = False self._typed_vars = dict() @@ -242,8 +242,15 @@ def _visit_function(self, node): gpu_vectorize = False gpu_method = False args_typedefs = {} + func_expr = False + for decor in node.decorator_list: - if isinstance(decor, ast.Name) and decor.id == '__pyfunction__': + if isinstance(decor, ast.Call) and isinstance(decor.func, ast.Name) and decor.func.id == 'expression': + assert len(decor.args)==1 + func_expr = True + node.name = self.visit(decor.args[0]) + + elif isinstance(decor, ast.Name) and decor.id == '__pyfunction__': is_pyfunc = True elif isinstance(decor, ast.Name) and decor.id == '__glsl__': glsl = True @@ -473,10 +480,13 @@ def _visit_function(self, node): elif len(self._function_stack) == 1: ## this style will not make function global to the eval context in NodeJS ## #buffer = self.indent() + 'function %s(%s) {\n' % (node.name, ', '.join(args)) - ## this is required for eval to be able to work in NodeJS, note there is no var keyword. - if self._func_expressions: - buffer = self.indent() + '%s = function(%s) {\n' % (node.name, ', '.join(args)) + ## note if there is no var keyword and this function is at the global level, + ## then it should be callable from eval in NodeJS - this is not correct. + ## infact, var should always be used with function expressions. + + if self._func_expressions or func_expr: + buffer = self.indent() + 'var %s = function(%s) {\n' % (node.name, ', '.join(args)) else: buffer = self.indent() + 'function %s(%s) {\n' % (node.name, ', '.join(args)) @@ -485,7 +495,7 @@ def _visit_function(self, node): else: - if self._func_expressions: + if self._func_expressions or func_expr: buffer = self.indent() + 'var %s = function(%s) {\n' % (node.name, ', '.join(args)) else: buffer = self.indent() + 'function %s(%s) {\n' % (node.name, ', '.join(args)) diff --git a/pythonjs/typedpython.py b/pythonjs/typedpython.py index a245cf3..b885edd 100644 --- a/pythonjs/typedpython.py +++ b/pythonjs/typedpython.py @@ -65,7 +65,7 @@ def transform_source( source, strip=False ): if '= function(' in c: k = '= function(' a,b = c.split(k) - output.append( '@func_expression(%s)' %a.strip()) + output.append( '@expression(%s)' %a.strip()) c = 'def __NAMELESS__(' + b if ' except ' in c: ## PEP 463 - exception expressions diff --git a/regtests/calling/function_expression.py b/regtests/calling/function_expression.py new file mode 100644 index 0000000..9c12bc7 --- /dev/null +++ b/regtests/calling/function_expression.py @@ -0,0 +1,8 @@ +"""func expr""" + +F = function( x,y ): + return x+y + +def main(): + TestError( F(1,2) == 3 ) + From ca4ca25920fe56e21b69d7ff88c971d6e1d4659b Mon Sep 17 00:00:00 2001 From: hartsantler Date: Wed, 23 Jul 2014 16:12:29 -0700 Subject: [PATCH 034/100] new regtest for tuple keys in dict --- regtests/dict/tuple_keys.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 regtests/dict/tuple_keys.py diff --git a/regtests/dict/tuple_keys.py b/regtests/dict/tuple_keys.py new file mode 100644 index 0000000..6767983 --- /dev/null +++ b/regtests/dict/tuple_keys.py @@ -0,0 +1,12 @@ +"""dict tuple key""" + + +def main(): + a = (1,2,3) + b = (1,2,3) + c = ( a, b, 'XXX' ) + + D = { a: 22, c:44 } + TestError( D[ a ] == 22) + TestError( D[ b ] == 22) + TestError( D[ c ] == 44) From cfd40f299176da955aa96582826f546bacd021c9 Mon Sep 17 00:00:00 2001 From: hartsantler Date: Wed, 23 Jul 2014 18:07:16 -0700 Subject: [PATCH 035/100] fixed using tuple as dict key in normal mode. --- pythonjs/pythonjs.js | 278 ++++++++++++++++++----------------- pythonjs/runtime/builtins.py | 18 ++- pythonjs/typedpython.py | 9 ++ 3 files changed, 163 insertions(+), 142 deletions(-) diff --git a/pythonjs/pythonjs.js b/pythonjs/pythonjs.js index de012ed..2a4317a 100644 --- a/pythonjs/pythonjs.js +++ b/pythonjs/pythonjs.js @@ -11,7 +11,7 @@ if (( typeof(window) ) != "undefined") { if (( typeof(importScripts) ) == "function") { __WEBWORKER__ = true; } -__create_array__ = function() { +var __create_array__ = function() { "Used to fix a bug/feature of Javascript where new Array(number)\n created a array with number of undefined elements which is not\n what we want"; var i,array; array = []; @@ -23,7 +23,7 @@ __create_array__ = function() { return array; } -__get__ = function(object, attribute, error_message) { +var __get__ = function(object, attribute, error_message) { "Retrieve an attribute, method, property, or wrapper function.\n\n method are actually functions which are converted to methods by\n prepending their arguments with the current object. Properties are\n not functions!\n\n DOM support:\n http://stackoverflow.com/questions/14202699/document-createelement-not-working\n https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/instanceof\n\n Direct JavaScript Calls:\n if an external javascript function is found, and it was not a wrapper that was generated here,\n check the function for a 'cached_wrapper' attribute, if none is found then generate a new\n wrapper, cache it on the function, and return the wrapper.\n "; if (( object ) === null) { if (error_message) { @@ -400,7 +400,7 @@ __get__ = function(object, attribute, error_message) { } } -_get_upstream_attribute = function(base, attr) { +var _get_upstream_attribute = function(base, attr) { if (( attr ) in base) { return base[attr]; } @@ -412,7 +412,7 @@ _get_upstream_attribute = function(base, attr) { } } -_get_upstream_property = function(base, attr) { +var _get_upstream_property = function(base, attr) { if (( attr ) in base.__properties__) { return base.__properties__[attr]; } @@ -424,7 +424,7 @@ _get_upstream_property = function(base, attr) { } } -__set__ = function(object, attribute, value) { +var __set__ = function(object, attribute, value) { "\n __setattr__ is always called when an attribute is set,\n unlike __getattr__ that only triggers when an attribute is not found,\n this asymmetry is in fact part of the Python spec.\n note there is no __setattribute__\n\n In normal Python a property setter is not called before __setattr__,\n this is bad language design because the user has been more explicit\n in having the property setter.\n\n In PythonJS, property setters are called instead of __setattr__.\n "; if (( "__class__" ) in object && ( object.__class__.__setters__.indexOf(attribute) ) != -1) { object[attribute] = value; @@ -437,7 +437,7 @@ __set__ = function(object, attribute, value) { } } -__getargs__ = function(func_name, signature, args, kwargs) { +var __getargs__ = function(func_name, signature, args, kwargs) { "Based on ``signature`` and ``args``, ``kwargs`` parameters retrieve\n the actual parameters.\n\n This will set default keyword arguments and retrieve positional arguments\n in kwargs if their called as such"; if (( args ) === null) { args = []; @@ -496,19 +496,19 @@ KeyError = function(msg) {this.message = msg || "";}; KeyError.prototype = Obj ValueError = function(msg) {this.message = msg || "";}; ValueError.prototype = Object.create(Error.prototype); ValueError.prototype.name = "ValueError"; AttributeError = function(msg) {this.message = msg || "";}; AttributeError.prototype = Object.create(Error.prototype);AttributeError.prototype.name = "AttributeError"; RuntimeError = function(msg) {this.message = msg || "";}; RuntimeError.prototype = Object.create(Error.prototype);RuntimeError.prototype.name = "RuntimeError"; -__gpu_object = function(cls, struct_name, data_name) { +var __gpu_object = function(cls, struct_name, data_name) { cls.prototype.__struct_name__ = struct_name; cls.prototype.__struct_data__ = data_name; } gpu = { "object":__gpu_object }; -glsljit_runtime = function(header) { +var glsljit_runtime = function(header) { return new GLSLJITRuntime(header); } -GLSLJITRuntime = function(header) { +var GLSLJITRuntime = function(header) { GLSLJITRuntime.__init__(this, header); this.__class__ = GLSLJITRuntime; this.__uid__ = ("" + _PythonJS_UID); @@ -918,14 +918,14 @@ GLSLJITRuntime.prototype.unpack_mat4 = function(arr) { GLSLJITRuntime.unpack_mat4 = function () { return GLSLJITRuntime.prototype.unpack_mat4.apply(arguments[0], Array.prototype.slice.call(arguments,1)) }; GLSLJITRuntime.prototype.__properties__ = { }; GLSLJITRuntime.prototype.__unbound_methods__ = { }; -__getattr__ = function(ob, a) { +var __getattr__ = function(ob, a) { if (ob.__getattr__) { return ob.__getattr__(a); } } ;__getattr__.is_wrapper = true; -__test_if_true__ = function(ob) { +var __test_if_true__ = function(ob) { if (( ob ) === true) { return true; @@ -962,7 +962,7 @@ __test_if_true__ = function(ob) { } } ;__test_if_true__.is_wrapper = true; -__replace_method = function(ob, a, b) { +var __replace_method = function(ob, a, b) { if (( typeof(ob) ) == "string") { return ob.split(a).join(b); @@ -971,7 +971,7 @@ __replace_method = function(ob, a, b) { } } ;__replace_method.is_wrapper = true; -__split_method = function(ob, delim) { +var __split_method = function(ob, delim) { if (( typeof(ob) ) == "string") { if (( delim ) === undefined) { @@ -1004,7 +1004,7 @@ if (( typeof(NodeList) ) == "function") { __dom_array_types__.push(ClientRectList); } } -__is_some_array = function(ob) { +var __is_some_array = function(ob) { if (( __dom_array_types__.length ) > 0) { var __iter14 = __dom_array_types__; @@ -1019,7 +1019,7 @@ __is_some_array = function(ob) { return false; } -__is_typed_array = function(ob) { +var __is_typed_array = function(ob) { if (__test_if_true__(ob instanceof Int8Array || ob instanceof Uint8Array)) { return true; @@ -1040,7 +1040,7 @@ __is_typed_array = function(ob) { } } -__js_typed_array = function(t, a) { +var __js_typed_array = function(t, a) { var arr; if (( t ) == "i") { arr = new Int32Array(a.length); @@ -1049,7 +1049,7 @@ __js_typed_array = function(t, a) { return arr; } -__contains__ = function(ob, a) { +var __contains__ = function(ob, a) { var t; t = typeof(ob); if (( t ) == "string") { @@ -1087,7 +1087,7 @@ __contains__ = function(ob, a) { } } -__add_op = function(a, b) { +var __add_op = function(a, b) { var c,t; t = typeof(a); if (__test_if_true__(( t ) == "string" || ( t ) == "number")) { @@ -1108,7 +1108,7 @@ __add_op = function(a, b) { } } -__mul_op = function(a, b) { +var __mul_op = function(a, b) { var c,arr,t; t = typeof(a); if (( t ) == "number") { @@ -1146,7 +1146,7 @@ __mul_op = function(a, b) { } } -__jsdict = function(items) { +var __jsdict = function(items) { var d,key; d = {}; var __iter16 = items; @@ -1162,7 +1162,7 @@ __jsdict = function(items) { return d; } -__jsdict_get = function(ob, key, default_value) { +var __jsdict_get = function(ob, key, default_value) { if (__test_if_true__(ob instanceof Object)) { if (__test_if_true__(key in ob)) { @@ -1178,7 +1178,7 @@ __jsdict_get = function(ob, key, default_value) { } } -__jsdict_set = function(ob, key, value) { +var __jsdict_set = function(ob, key, value) { if (__test_if_true__(ob instanceof Object)) { ob[key] = value; @@ -1187,7 +1187,7 @@ __jsdict_set = function(ob, key, value) { } } -__jsdict_keys = function(ob) { +var __jsdict_keys = function(ob) { if (__test_if_true__(ob instanceof Object)) { return Object.keys( ob ); @@ -1196,7 +1196,7 @@ __jsdict_keys = function(ob) { } } -__jsdict_values = function(ob) { +var __jsdict_values = function(ob) { var arr,value; if (__test_if_true__(ob instanceof Object)) { arr = []; @@ -1215,7 +1215,7 @@ __jsdict_values = function(ob) { } } -__jsdict_items = function(ob) { +var __jsdict_items = function(ob) { var arr,value; if (__test_if_true__(ob instanceof Object || ( ob.items ) === undefined)) { arr = []; @@ -1234,7 +1234,7 @@ __jsdict_items = function(ob) { } } -__jsdict_pop = function(ob, key, _kwargs_) { +var __jsdict_pop = function(ob, key, _kwargs_) { var v; if (!( _kwargs_ instanceof Object )) {; var _kwargs_ = {ob: arguments[0],key: arguments[1],_default: arguments[2]}; @@ -1269,7 +1269,7 @@ __jsdict_pop = function(ob, key, _kwargs_) { } } -dir = function(ob) { +var dir = function(ob) { if (__test_if_true__(ob instanceof Object)) { return Object.keys( ob ); @@ -1278,7 +1278,7 @@ dir = function(ob) { } } -__object_keys__ = function(ob) { +var __object_keys__ = function(ob) { var arr; "\n notes:\n . Object.keys(ob) will not work because we create PythonJS objects using `Object.create(null)`\n . this is different from Object.keys because it traverses the prototype chain.\n "; arr = []; @@ -1286,7 +1286,7 @@ __object_keys__ = function(ob) { return arr; } -__bind_property_descriptors__ = function(o, klass) { +var __bind_property_descriptors__ = function(o, klass) { var prop,desc; var __iter19 = klass.__properties__; if (! (__iter19 instanceof Array || typeof __iter19 == "string" || __is_typed_array(__iter19) || __is_some_array(__iter19) )) { __iter19 = __object_keys__(__iter19) } @@ -1310,7 +1310,7 @@ __bind_property_descriptors__ = function(o, klass) { } } -__generate_getter__ = function(klass, o, n) { +var __generate_getter__ = function(klass, o, n) { var __lambda__ = function() { @@ -1320,7 +1320,7 @@ __generate_getter__ = function(klass, o, n) { return __lambda__; } -__generate_setter__ = function(klass, o, n) { +var __generate_setter__ = function(klass, o, n) { var __lambda__ = function(v) { @@ -1330,7 +1330,7 @@ __generate_setter__ = function(klass, o, n) { return __lambda__; } -__sprintf = function(fmt, args) { +var __sprintf = function(fmt, args) { var chunks,item,arr; if (__test_if_true__(args instanceof Array)) { chunks = fmt.split("%s"); @@ -1363,7 +1363,7 @@ __sprintf = function(fmt, args) { } } -__create_class__ = function(class_name, parents, attrs, props) { +var __create_class__ = function(class_name, parents, attrs, props) { var f,klass,prop; "Create a PythonScript class"; klass = Object.create(null); @@ -1458,7 +1458,7 @@ __create_class__ = function(class_name, parents, attrs, props) { return klass; } -type = function(args, kwargs) { +var type = function(args, kwargs) { var __sig__,__args__; __sig__ = { kwargs:{"bases": null, "class_dict": null},args:["ob_or_class_name", "bases", "class_dict"] }; @@ -1480,7 +1480,7 @@ type = function(args, kwargs) { } } ;type.is_wrapper = true; -hasattr = function(args, kwargs) { +var hasattr = function(args, kwargs) { var __sig__,__args__; __sig__ = { kwargs:{},args:["ob", "attr"] }; @@ -1496,7 +1496,7 @@ hasattr = function(args, kwargs) { return Object.hasOwnProperty.call(ob, attr); } ;hasattr.is_wrapper = true; -getattr = function(args, kwargs) { +var getattr = function(args, kwargs) { var prop; var __sig__,__args__; __sig__ = { kwargs:{"property": false},args:["ob", "attr", "property"] }; @@ -1522,7 +1522,7 @@ getattr = function(args, kwargs) { } } ;getattr.is_wrapper = true; -setattr = function(args, kwargs) { +var setattr = function(args, kwargs) { var prop; var __sig__,__args__; __sig__ = { kwargs:{"property": false},args:["ob", "attr", "value", "property"] }; @@ -1549,7 +1549,7 @@ setattr = function(args, kwargs) { } } ;setattr.is_wrapper = true; -issubclass = function(args, kwargs) { +var issubclass = function(args, kwargs) { var i,bases; var __sig__,__args__; __sig__ = { kwargs:{},args:["C", "B"] }; @@ -1576,7 +1576,7 @@ issubclass = function(args, kwargs) { return false; } ;issubclass.is_wrapper = true; -isinstance = function(args, kwargs) { +var isinstance = function(args, kwargs) { var ob_class; var __sig__,__args__; __sig__ = { kwargs:{},args:["ob", "klass"] }; @@ -1608,7 +1608,7 @@ isinstance = function(args, kwargs) { } } ;isinstance.is_wrapper = true; -int = function(args, kwargs) { +var int = function(args, kwargs) { var __sig__,__args__; __sig__ = { kwargs:{},args:["a"] }; @@ -1627,14 +1627,14 @@ int = function(args, kwargs) { return a; } ;int.is_wrapper = true; -int16 = function(a) { +var int16 = function(a) { var arr; arr = new Int16Array(1); arr[0] = a; return arr; } -float = function(args, kwargs) { +var float = function(args, kwargs) { var b; var __sig__,__args__; __sig__ = { kwargs:{},args:["a"] }; @@ -1662,7 +1662,7 @@ float = function(args, kwargs) { return b; } ;float.is_wrapper = true; -round = function(args, kwargs) { +var round = function(args, kwargs) { var y,x,c,b; var __sig__,__args__; __sig__ = { kwargs:{},args:["a", "places"] }; @@ -1686,7 +1686,7 @@ round = function(args, kwargs) { } } ;round.is_wrapper = true; -str = function(args, kwargs) { +var str = function(args, kwargs) { var __sig__,__args__; __sig__ = { kwargs:{},args:["s"] }; @@ -1701,7 +1701,7 @@ str = function(args, kwargs) { return ("" + s); } ;str.is_wrapper = true; -_setup_str_prototype = function(args, kwargs) { +var _setup_str_prototype = function(args, kwargs) { "\n Extend JavaScript String.prototype with methods that implement the Python str API.\n The decorator @String.prototype.[name] assigns the function to the prototype,\n and ensures that the special 'this' variable will work.\n "; var func = function(a) { @@ -1906,7 +1906,7 @@ _setup_str_prototype = function(args, kwargs) { } ;_setup_str_prototype.is_wrapper = true; _setup_str_prototype(); -__sort_method = function(ob) { +var __sort_method = function(ob) { if (__test_if_true__(ob instanceof Array)) { var f = function(a, b) { @@ -1928,7 +1928,7 @@ __sort_method = function(ob) { } } -_setup_array_prototype = function(args, kwargs) { +var _setup_array_prototype = function(args, kwargs) { var func = function() { var i,item; @@ -2181,7 +2181,7 @@ _setup_array_prototype = function(args, kwargs) { } ;_setup_array_prototype.is_wrapper = true; _setup_array_prototype(); -_setup_nodelist_prototype = function(args, kwargs) { +var _setup_nodelist_prototype = function(args, kwargs) { var func = function(a) { @@ -2240,7 +2240,7 @@ _setup_nodelist_prototype = function(args, kwargs) { if (__test_if_true__(( __NODEJS__ ) == false && ( __WEBWORKER__ ) == false)) { _setup_nodelist_prototype(); } -bisect = function(args, kwargs) { +var bisect = function(args, kwargs) { var __sig__,__args__; __sig__ = { kwargs:{"low": null, "high": null},args:["a", "x", "low", "high"] }; @@ -2258,7 +2258,7 @@ bisect = function(args, kwargs) { return a.bisect(x, low, high); } ;bisect.is_wrapper = true; -range = function(args, kwargs) { +var range = function(args, kwargs) { var i,arr; var __sig__,__args__; __sig__ = { kwargs:{},args:["num", "stop", "step"] }; @@ -2290,7 +2290,7 @@ range = function(args, kwargs) { return arr; } ;range.is_wrapper = true; -xrange = function(args, kwargs) { +var xrange = function(args, kwargs) { var __sig__,__args__; __sig__ = { kwargs:{},args:["num", "stop", "step"] }; @@ -2307,7 +2307,7 @@ xrange = function(args, kwargs) { return range([num, stop, step], __NULL_OBJECT__); } ;xrange.is_wrapper = true; -sum = function(args, kwargs) { +var sum = function(args, kwargs) { var a; var __sig__,__args__; __sig__ = { kwargs:{},args:["arr"] }; @@ -2336,7 +2336,7 @@ __StopIteration_attrs = {}; __StopIteration_parents = []; __StopIteration_properties = {}; StopIteration = __create_class__("StopIteration", __StopIteration_parents, __StopIteration_attrs, __StopIteration_properties); -len = function(args, kwargs) { +var len = function(args, kwargs) { var __sig__,__args__; __sig__ = { kwargs:{},args:["ob"] }; @@ -2367,7 +2367,7 @@ len = function(args, kwargs) { } } ;len.is_wrapper = true; -next = function(args, kwargs) { +var next = function(args, kwargs) { var __sig__,__args__; __sig__ = { kwargs:{},args:["obj"] }; @@ -2382,7 +2382,7 @@ next = function(args, kwargs) { return __get__(__get__(obj, "next", "missing attribute `next` - line 1063: return obj.next()"), "__call__")(); } ;next.is_wrapper = true; -map = function(args, kwargs) { +var map = function(args, kwargs) { var arr,v; var __sig__,__args__; __sig__ = { kwargs:{},args:["func", "objs"] }; @@ -2408,7 +2408,7 @@ map = function(args, kwargs) { return arr; } ;map.is_wrapper = true; -filter = function(args, kwargs) { +var filter = function(args, kwargs) { var arr; var __sig__,__args__; __sig__ = { kwargs:{},args:["func", "objs"] }; @@ -2435,7 +2435,7 @@ filter = function(args, kwargs) { return arr; } ;filter.is_wrapper = true; -min = function(args, kwargs) { +var min = function(args, kwargs) { var a; var __sig__,__args__; __sig__ = { kwargs:{},args:["lst"] }; @@ -2465,7 +2465,7 @@ min = function(args, kwargs) { return a; } ;min.is_wrapper = true; -max = function(args, kwargs) { +var max = function(args, kwargs) { var a; var __sig__,__args__; __sig__ = { kwargs:{},args:["lst"] }; @@ -2495,7 +2495,7 @@ max = function(args, kwargs) { return a; } ;max.is_wrapper = true; -abs = function(args, kwargs) { +var abs = function(args, kwargs) { var __sig__,__args__; __sig__ = { kwargs:{},args:["num"] }; @@ -2510,7 +2510,7 @@ abs = function(args, kwargs) { return Math.abs(num); } ;abs.is_wrapper = true; -ord = function(args, kwargs) { +var ord = function(args, kwargs) { var __sig__,__args__; __sig__ = { kwargs:{},args:["char"] }; @@ -2525,7 +2525,7 @@ ord = function(args, kwargs) { return char.charCodeAt(0); } ;ord.is_wrapper = true; -chr = function(args, kwargs) { +var chr = function(args, kwargs) { var __sig__,__args__; __sig__ = { kwargs:{},args:["num"] }; @@ -2540,7 +2540,7 @@ chr = function(args, kwargs) { return String.fromCharCode(num); } ;chr.is_wrapper = true; -__ArrayIterator = function(arr, index) { +var __ArrayIterator = function(arr, index) { __ArrayIterator.__init__(this, arr, index); this.__class__ = __ArrayIterator; this.__uid__ = ("" + _PythonJS_UID); @@ -2572,7 +2572,7 @@ var Iterator,__Iterator_attrs,__Iterator_parents; __Iterator_attrs = {}; __Iterator_parents = []; __Iterator_properties = {}; -__Iterator___init__ = function(args, kwargs) { +var __Iterator___init__ = function(args, kwargs) { var __sig__,__args__; __sig__ = { kwargs:{},args:["self", "obj", "index"] }; @@ -2593,7 +2593,7 @@ __Iterator___init__ = function(args, kwargs) { } ;__Iterator___init__.is_wrapper = true; __Iterator_attrs.__init__ = __Iterator___init__; -__Iterator_next = function(args, kwargs) { +var __Iterator_next = function(args, kwargs) { var index; var __sig__,__args__; __sig__ = { kwargs:{},args:["self"] }; @@ -2612,7 +2612,7 @@ __Iterator_next = function(args, kwargs) { ;__Iterator_next.is_wrapper = true; __Iterator_attrs.next = __Iterator_next; Iterator = __create_class__("Iterator", __Iterator_parents, __Iterator_attrs, __Iterator_properties); -tuple = function(args, kwargs) { +var tuple = function(args, kwargs) { var __sig__,__args__; __sig__ = { kwargs:{},args:["a"] }; @@ -2641,7 +2641,7 @@ tuple = function(args, kwargs) { } } ;tuple.is_wrapper = true; -list = function(args, kwargs) { +var list = function(args, kwargs) { var __sig__,__args__; __sig__ = { kwargs:{},args:["a"] }; @@ -2674,7 +2674,7 @@ var dict,__dict_attrs,__dict_parents; __dict_attrs = {}; __dict_parents = []; __dict_properties = {}; -__dict___init__ = function(args, kwargs) { +var __dict___init__ = function(args, kwargs) { var ob,value; var __sig__,__args__; __sig__ = { kwargs:{"js_object": null, "pointer": null},args:["self", "js_object", "pointer"] }; @@ -2728,7 +2728,7 @@ __dict___init__ = function(args, kwargs) { } ;__dict___init__.is_wrapper = true; __dict_attrs.__init__ = __dict___init__; -__dict_jsify = function(args, kwargs) { +var __dict_jsify = function(args, kwargs) { var keys,value; var __sig__,__args__; __sig__ = { kwargs:{},args:["self"] }; @@ -2762,7 +2762,7 @@ __dict_jsify = function(args, kwargs) { } ;__dict_jsify.is_wrapper = true; __dict_attrs.jsify = __dict_jsify; -__dict_copy = function(args, kwargs) { +var __dict_copy = function(args, kwargs) { var __sig__,__args__; __sig__ = { kwargs:{},args:["self"] }; @@ -2778,7 +2778,7 @@ __dict_copy = function(args, kwargs) { } ;__dict_copy.is_wrapper = true; __dict_attrs.copy = __dict_copy; -__dict_clear = function(args, kwargs) { +var __dict_clear = function(args, kwargs) { var __sig__,__args__; __sig__ = { kwargs:{},args:["self"] }; @@ -2794,7 +2794,7 @@ __dict_clear = function(args, kwargs) { } ;__dict_clear.is_wrapper = true; __dict_attrs.clear = __dict_clear; -__dict_has_key = function(args, kwargs) { +var __dict_has_key = function(args, kwargs) { var __dict; var __sig__,__args__; __sig__ = { kwargs:{},args:["self", "key"] }; @@ -2819,7 +2819,7 @@ __dict_has_key = function(args, kwargs) { } ;__dict_has_key.is_wrapper = true; __dict_attrs.has_key = __dict_has_key; -__dict_update = function(args, kwargs) { +var __dict_update = function(args, kwargs) { var __sig__,__args__; __sig__ = { kwargs:{},args:["self", "other"] }; @@ -2843,7 +2843,7 @@ __dict_update = function(args, kwargs) { } ;__dict_update.is_wrapper = true; __dict_attrs.update = __dict_update; -__dict_items = function(args, kwargs) { +var __dict_items = function(args, kwargs) { var arr; var __sig__,__args__; __sig__ = { kwargs:{},args:["self"] }; @@ -2868,7 +2868,7 @@ __dict_items = function(args, kwargs) { } ;__dict_items.is_wrapper = true; __dict_attrs.items = __dict_items; -__dict_get = function(args, kwargs) { +var __dict_get = function(args, kwargs) { var __sig__,__args__; __sig__ = { kwargs:{"_default": null},args:["self", "key", "_default"] }; @@ -2891,7 +2891,7 @@ return _default; } ;__dict_get.is_wrapper = true; __dict_attrs.get = __dict_get; -__dict_set = function(args, kwargs) { +var __dict_set = function(args, kwargs) { var __sig__,__args__; __sig__ = { kwargs:{},args:["self", "key", "value"] }; @@ -2909,7 +2909,7 @@ __dict_set = function(args, kwargs) { } ;__dict_set.is_wrapper = true; __dict_attrs.set = __dict_set; -__dict___len__ = function(args, kwargs) { +var __dict___len__ = function(args, kwargs) { var __dict; var __sig__,__args__; __sig__ = { kwargs:{},args:["self"] }; @@ -2926,7 +2926,7 @@ __dict___len__ = function(args, kwargs) { } ;__dict___len__.is_wrapper = true; __dict_attrs.__len__ = __dict___len__; -__dict___getitem__ = function(args, kwargs) { +var __dict___getitem__ = function(args, kwargs) { var __dict; var __sig__,__args__; __sig__ = { kwargs:{},args:["self", "key"] }; @@ -2941,11 +2941,15 @@ __dict___getitem__ = function(args, kwargs) { var key = __args__['key']; "\n notes:\n . '4' and 4 are the same key\n . it is possible that the translator mistakes a javascript-object for a dict and inlines this function,\n that is why below we return the key in self if __dict is undefined.\n "; __dict = self["$wrapped"]; - if (__test_if_true__(typeof(key) === 'object' || typeof(key) === 'function')) { - if (__test_if_true__(key.__uid__ && key.__uid__ in __dict)) { - return __dict[key.__uid__]; + if (__test_if_true__(key instanceof Array)) { + return __dict[key]; + } else { + if (__test_if_true__(typeof(key) === 'object' || typeof(key) === 'function')) { + if (__test_if_true__(key.__uid__ && key.__uid__ in __dict)) { + return __dict[key.__uid__]; + } + throw new KeyError(key); } - throw new KeyError(key); } if (__test_if_true__(__dict && key in __dict)) { return __dict[key]; @@ -2954,7 +2958,7 @@ __dict___getitem__ = function(args, kwargs) { } ;__dict___getitem__.is_wrapper = true; __dict_attrs.__getitem__ = __dict___getitem__; -__dict___setitem__ = function(args, kwargs) { +var __dict___setitem__ = function(args, kwargs) { var __dict; var __sig__,__args__; __sig__ = { kwargs:{},args:["self", "key", "value"] }; @@ -2969,18 +2973,22 @@ __dict___setitem__ = function(args, kwargs) { var key = __args__['key']; var value = __args__['value']; __dict = self["$wrapped"]; - if (__test_if_true__(typeof(key) === 'object' || typeof(key) === 'function')) { - if (__test_if_true__(key.__uid__ === undefined)) { - key.__uid__ = '' + _PythonJS_UID++; - } - __dict[key.__uid__] = value; - } else { + if (__test_if_true__(key instanceof Array)) { __dict[key] = value; + } else { + if (__test_if_true__(typeof(key) === 'object' || typeof(key) === 'function')) { + if (__test_if_true__(key.__uid__ === undefined)) { + key.__uid__ = '' + _PythonJS_UID++; + } + __dict[key.__uid__] = value; + } else { + __dict[key] = value; + } } } ;__dict___setitem__.is_wrapper = true; __dict_attrs.__setitem__ = __dict___setitem__; -__dict_keys = function(args, kwargs) { +var __dict_keys = function(args, kwargs) { var __sig__,__args__; __sig__ = { kwargs:{},args:["self"] }; @@ -2996,7 +3004,7 @@ __dict_keys = function(args, kwargs) { } ;__dict_keys.is_wrapper = true; __dict_attrs.keys = __dict_keys; -__dict_pop = function(args, kwargs) { +var __dict_pop = function(args, kwargs) { var js_object,v; var __sig__,__args__; __sig__ = { kwargs:{"d": null},args:["self", "key", "d"] }; @@ -3021,7 +3029,7 @@ __dict_pop = function(args, kwargs) { } ;__dict_pop.is_wrapper = true; __dict_attrs.pop = __dict_pop; -__dict_values = function(args, kwargs) { +var __dict_values = function(args, kwargs) { var keys,out; var __sig__,__args__; __sig__ = { kwargs:{},args:["self"] }; @@ -3045,7 +3053,7 @@ __dict_values = function(args, kwargs) { } ;__dict_values.is_wrapper = true; __dict_attrs.values = __dict_values; -__dict___contains__ = function(args, kwargs) { +var __dict___contains__ = function(args, kwargs) { var __sig__,__args__; __sig__ = { kwargs:{},args:["self", "value"] }; @@ -3068,7 +3076,7 @@ return false; } ;__dict___contains__.is_wrapper = true; __dict_attrs.__contains__ = __dict___contains__; -__dict___iter__ = function(args, kwargs) { +var __dict___iter__ = function(args, kwargs) { var __sig__,__args__; __sig__ = { kwargs:{},args:["self"] }; @@ -3085,7 +3093,7 @@ __dict___iter__ = function(args, kwargs) { ;__dict___iter__.is_wrapper = true; __dict_attrs.__iter__ = __dict___iter__; dict = __create_class__("dict", __dict_parents, __dict_attrs, __dict_properties); -set = function(args, kwargs) { +var set = function(args, kwargs) { var keys,mask,s,hashtable,key,fallback; var __sig__,__args__; __sig__ = { kwargs:{},args:["a"] }; @@ -3160,7 +3168,7 @@ set = function(args, kwargs) { return s; } ;set.is_wrapper = true; -frozenset = function(args, kwargs) { +var frozenset = function(args, kwargs) { var __sig__,__args__; __sig__ = { kwargs:{},args:["a"] }; @@ -3183,7 +3191,7 @@ __array_typecodes = __jsdict([["c", 1], ["b", 1], ["B", 1], ["u", 2], ["h", 2], __array_attrs.typecodes = __array_typecodes; __array_typecode_names = __jsdict([["c", "Int8"], ["b", "Int8"], ["B", "Uint8"], ["u", "Uint16"], ["h", "Int16"], ["H", "Uint16"], ["i", "Int32"], ["I", "Uint32"], ["f", "Float32"], ["d", "Float64"], ["float32", "Float32"], ["float16", "Int16"], ["float8", "Int8"], ["int32", "Int32"], ["uint32", "Uint32"], ["int16", "Int16"], ["uint16", "Uint16"], ["int8", "Int8"], ["uint8", "Uint8"]]); __array_attrs.typecode_names = __array_typecode_names; -__array___init__ = function(args, kwargs) { +var __array___init__ = function(args, kwargs) { var size,buff; var __sig__,__args__; __sig__ = { kwargs:{"initializer": null, "little_endian": false},args:["self", "typecode", "initializer", "little_endian"] }; @@ -3199,7 +3207,7 @@ __array___init__ = function(args, kwargs) { var initializer = __args__['initializer']; var little_endian = __args__['little_endian']; self.typecode = typecode; - self.itemsize = __get__(__get__(self, "typecodes", "missing attribute `typecodes` - line 1376: self.itemsize = self.typecodes[ typecode ]"), "__getitem__", "line 1376: self.itemsize = self.typecodes[ typecode ]")([typecode], __NULL_OBJECT__); + self.itemsize = __get__(__get__(self, "typecodes", "missing attribute `typecodes` - line 1380: self.itemsize = self.typecodes[ typecode ]"), "__getitem__", "line 1380: self.itemsize = self.typecodes[ typecode ]")([typecode], __NULL_OBJECT__); self.little_endian = little_endian; if (__test_if_true__(initializer)) { self.length = len([initializer], __NULL_OBJECT__); @@ -3223,11 +3231,11 @@ __array___init__ = function(args, kwargs) { buff = new ArrayBuffer(size); self.dataview = new DataView(buff); self.buffer = buff; - __get__(__get__(self, "fromlist", "missing attribute `fromlist` - line 1397: self.fromlist( initializer )"), "__call__")([initializer], __NULL_OBJECT__); + __get__(__get__(self, "fromlist", "missing attribute `fromlist` - line 1401: self.fromlist( initializer )"), "__call__")([initializer], __NULL_OBJECT__); } ;__array___init__.is_wrapper = true; __array_attrs.__init__ = __array___init__; -__array___len__ = function(args, kwargs) { +var __array___len__ = function(args, kwargs) { var __sig__,__args__; __sig__ = { kwargs:{},args:["self"] }; @@ -3243,7 +3251,7 @@ __array___len__ = function(args, kwargs) { } ;__array___len__.is_wrapper = true; __array_attrs.__len__ = __array___len__; -__array___contains__ = function(args, kwargs) { +var __array___contains__ = function(args, kwargs) { var arr; var __sig__,__args__; __sig__ = { kwargs:{},args:["self", "value"] }; @@ -3256,7 +3264,7 @@ __array___contains__ = function(args, kwargs) { __args__ = __getargs__("__array___contains__", __sig__, args, kwargs); var self = __args__['self']; var value = __args__['value']; - arr = __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1403: arr = self.to_array()"), "__call__")(); + arr = __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1407: arr = self.to_array()"), "__call__")(); if (( arr.indexOf(value) ) == -1) { return false; } else { @@ -3265,7 +3273,7 @@ __array___contains__ = function(args, kwargs) { } ;__array___contains__.is_wrapper = true; __array_attrs.__contains__ = __array___contains__; -__array___getitem__ = function(args, kwargs) { +var __array___getitem__ = function(args, kwargs) { var func_name,dataview,value,step,func,offset; var __sig__,__args__; __sig__ = { kwargs:{},args:["self", "index"] }; @@ -3281,7 +3289,7 @@ __array___getitem__ = function(args, kwargs) { step = self.itemsize; offset = (step * index); dataview = self.dataview; - func_name = ("get" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1411: func_name = 'get'+self.typecode_names[ self.typecode ]"), "__getitem__", "line 1411: func_name = 'get'+self.typecode_names[ self.typecode ]")([self.typecode], __NULL_OBJECT__)); + func_name = ("get" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1415: func_name = 'get'+self.typecode_names[ self.typecode ]"), "__getitem__", "line 1415: func_name = 'get'+self.typecode_names[ self.typecode ]")([self.typecode], __NULL_OBJECT__)); func = dataview[func_name].bind(dataview); if (( offset ) < self.bytes) { value = func(offset); @@ -3299,7 +3307,7 @@ __array___getitem__ = function(args, kwargs) { } ;__array___getitem__.is_wrapper = true; __array_attrs.__getitem__ = __array___getitem__; -__array___setitem__ = function(args, kwargs) { +var __array___setitem__ = function(args, kwargs) { var func_name,dataview,step,func,offset; var __sig__,__args__; __sig__ = { kwargs:{},args:["self", "index", "value"] }; @@ -3319,7 +3327,7 @@ __array___setitem__ = function(args, kwargs) { } offset = (step * index); dataview = self.dataview; - func_name = ("set" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1427: func_name = 'set'+self.typecode_names[ self.typecode ]"), "__getitem__", "line 1427: func_name = 'set'+self.typecode_names[ self.typecode ]")([self.typecode], __NULL_OBJECT__)); + func_name = ("set" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1431: func_name = 'set'+self.typecode_names[ self.typecode ]"), "__getitem__", "line 1431: func_name = 'set'+self.typecode_names[ self.typecode ]")([self.typecode], __NULL_OBJECT__)); func = dataview[func_name].bind(dataview); if (( offset ) < self.bytes) { if (( self.typecode ) == "float8") { @@ -3336,7 +3344,7 @@ __array___setitem__ = function(args, kwargs) { } ;__array___setitem__.is_wrapper = true; __array_attrs.__setitem__ = __array___setitem__; -__array___iter__ = function(args, kwargs) { +var __array___iter__ = function(args, kwargs) { var __sig__,__args__; __sig__ = { kwargs:{},args:["self"] }; @@ -3352,7 +3360,7 @@ __array___iter__ = function(args, kwargs) { } ;__array___iter__.is_wrapper = true; __array_attrs.__iter__ = __array___iter__; -__array_get = function(args, kwargs) { +var __array_get = function(args, kwargs) { var __sig__,__args__; __sig__ = { kwargs:{},args:["self", "index"] }; @@ -3369,7 +3377,7 @@ __array_get = function(args, kwargs) { } ;__array_get.is_wrapper = true; __array_attrs.get = __array_get; -__array_fromlist = function(args, kwargs) { +var __array_fromlist = function(args, kwargs) { var typecode,i,func_name,dataview,length,item,step,func,offset,size; var __sig__,__args__; __sig__ = { kwargs:{},args:["self", "lst"] }; @@ -3387,13 +3395,13 @@ __array_fromlist = function(args, kwargs) { typecode = self.typecode; size = (length * step); dataview = self.dataview; - func_name = ("set" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1447: func_name = 'set'+self.typecode_names[ typecode ]"), "__getitem__", "line 1447: func_name = 'set'+self.typecode_names[ typecode ]")([typecode], __NULL_OBJECT__)); + func_name = ("set" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1451: func_name = 'set'+self.typecode_names[ typecode ]"), "__getitem__", "line 1451: func_name = 'set'+self.typecode_names[ typecode ]")([typecode], __NULL_OBJECT__)); func = dataview[func_name].bind(dataview); if (( size ) <= self.bytes) { i = 0; offset = 0; while (( i ) < length) { - item = ((lst instanceof Array) ? lst[i] : __get__(lst, "__getitem__", "line 1452: item = lst[i]")([i], __NULL_OBJECT__)); + item = ((lst instanceof Array) ? lst[i] : __get__(lst, "__getitem__", "line 1456: item = lst[i]")([i], __NULL_OBJECT__)); if (( typecode ) == "float8") { item *= self._norm_set; } else { @@ -3411,7 +3419,7 @@ __array_fromlist = function(args, kwargs) { } ;__array_fromlist.is_wrapper = true; __array_attrs.fromlist = __array_fromlist; -__array_resize = function(args, kwargs) { +var __array_resize = function(args, kwargs) { var source,new_buff,target,new_size,buff; var __sig__,__args__; __sig__ = { kwargs:{},args:["self", "length"] }; @@ -3437,7 +3445,7 @@ __array_resize = function(args, kwargs) { } ;__array_resize.is_wrapper = true; __array_attrs.resize = __array_resize; -__array_append = function(args, kwargs) { +var __array_append = function(args, kwargs) { var length; var __sig__,__args__; __sig__ = { kwargs:{},args:["self", "value"] }; @@ -3451,12 +3459,12 @@ __array_append = function(args, kwargs) { var self = __args__['self']; var value = __args__['value']; length = self.length; - __get__(__get__(self, "resize", "missing attribute `resize` - line 1475: self.resize( self.length + 1 )"), "__call__")([(self.length + 1)], __NULL_OBJECT__); + __get__(__get__(self, "resize", "missing attribute `resize` - line 1479: self.resize( self.length + 1 )"), "__call__")([(self.length + 1)], __NULL_OBJECT__); __get__(__get__(self, "__setitem__"), "__call__")([length, value], {}); } ;__array_append.is_wrapper = true; __array_attrs.append = __array_append; -__array_extend = function(args, kwargs) { +var __array_extend = function(args, kwargs) { var __sig__,__args__; __sig__ = { kwargs:{},args:["self", "lst"] }; @@ -3470,17 +3478,17 @@ __array_extend = function(args, kwargs) { var self = __args__['self']; var lst = __args__['lst']; var value,__iterator__54; - __iterator__54 = __get__(__get__(lst, "__iter__", "no iterator - line 1478: for value in lst:"), "__call__")([], __NULL_OBJECT__); + __iterator__54 = __get__(__get__(lst, "__iter__", "no iterator - line 1482: for value in lst:"), "__call__")([], __NULL_OBJECT__); var __next__54; __next__54 = __get__(__iterator__54, "next"); while (( __iterator__54.index ) < __iterator__54.length) { value = __next__54(); - __get__(__get__(self, "append", "missing attribute `append` - line 1479: self.append( value )"), "__call__")([value], __NULL_OBJECT__); + __get__(__get__(self, "append", "missing attribute `append` - line 1483: self.append( value )"), "__call__")([value], __NULL_OBJECT__); } } ;__array_extend.is_wrapper = true; __array_attrs.extend = __array_extend; -__array_to_array = function(args, kwargs) { +var __array_to_array = function(args, kwargs) { var i,item,arr; var __sig__,__args__; __sig__ = { kwargs:{},args:["self"] }; @@ -3503,7 +3511,7 @@ __array_to_array = function(args, kwargs) { } ;__array_to_array.is_wrapper = true; __array_attrs.to_array = __array_to_array; -__array_to_list = function(args, kwargs) { +var __array_to_list = function(args, kwargs) { var __sig__,__args__; __sig__ = { kwargs:{},args:["self"] }; @@ -3515,11 +3523,11 @@ __array_to_list = function(args, kwargs) { } __args__ = __getargs__("__array_to_list", __sig__, args, kwargs); var self = __args__['self']; - return __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1489: return self.to_array()"), "__call__")(); + return __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1493: return self.to_array()"), "__call__")(); } ;__array_to_list.is_wrapper = true; __array_attrs.to_list = __array_to_list; -__array_to_ascii = function(args, kwargs) { +var __array_to_ascii = function(args, kwargs) { var i,length,arr,string; var __sig__,__args__; __sig__ = { kwargs:{},args:["self"] }; @@ -3532,9 +3540,9 @@ __array_to_ascii = function(args, kwargs) { __args__ = __getargs__("__array_to_ascii", __sig__, args, kwargs); var self = __args__['self']; string = ""; - arr = __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1492: arr = self.to_array()"), "__call__")(); + arr = __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1496: arr = self.to_array()"), "__call__")(); i = 0; - length = __get__(arr, "length", "missing attribute `length` - line 1493: i = 0; length = arr.length"); + length = __get__(arr, "length", "missing attribute `length` - line 1497: i = 0; length = arr.length"); while (( i ) < length) { var num = arr[i]; var char = String.fromCharCode(num); @@ -3550,7 +3558,7 @@ var file,__file_attrs,__file_parents; __file_attrs = {}; __file_parents = []; __file_properties = {}; -__file___init__ = function(args, kwargs) { +var __file___init__ = function(args, kwargs) { var __sig__,__args__; __sig__ = { kwargs:{},args:["self", "path", "flags"] }; @@ -3581,7 +3589,7 @@ __file___init__ = function(args, kwargs) { } ;__file___init__.is_wrapper = true; __file_attrs.__init__ = __file___init__; -__file_read = function(args, kwargs) { +var __file_read = function(args, kwargs) { var _fs,path; var __sig__,__args__; __sig__ = { kwargs:{"binary": false},args:["self", "binary"] }; @@ -3604,7 +3612,7 @@ __file_read = function(args, kwargs) { } ;__file_read.is_wrapper = true; __file_attrs.read = __file_read; -__file_write = function(args, kwargs) { +var __file_write = function(args, kwargs) { var _fs,path; var __sig__,__args__; __sig__ = { kwargs:{"binary": false},args:["self", "data", "binary"] }; @@ -3628,7 +3636,7 @@ __file_write = function(args, kwargs) { } ;__file_write.is_wrapper = true; __file_attrs.write = __file_write; -__file_close = function(args, kwargs) { +var __file_close = function(args, kwargs) { var __sig__,__args__; __sig__ = { kwargs:{},args:["self"] }; @@ -3645,7 +3653,7 @@ __file_close = function(args, kwargs) { ;__file_close.is_wrapper = true; __file_attrs.close = __file_close; file = __create_class__("file", __file_parents, __file_attrs, __file_properties); -__open__ = function(args, kwargs) { +var __open__ = function(args, kwargs) { var __sig__,__args__; __sig__ = { kwargs:{"mode": null},args:["path", "mode"] }; @@ -3662,7 +3670,7 @@ __open__ = function(args, kwargs) { } ;__open__.is_wrapper = true; json = __jsdict([["loads", (function (s) {return JSON.parse(s);})], ["dumps", (function (o) {return JSON.stringify(o);})]]); -__get_other_workers_with_shared_arg = function(worker, ob) { +var __get_other_workers_with_shared_arg = function(worker, ob) { var a,other,args; a = []; var __iter38 = threading.workers; @@ -3688,7 +3696,7 @@ __get_other_workers_with_shared_arg = function(worker, ob) { } threading = __jsdict([["workers", []], ["_blocking_callback", null]]); -__start_new_thread = function(f, args) { +var __start_new_thread = function(f, args) { var jsargs,worker; worker = new Worker(f); worker.__uid__ = len(threading.workers); @@ -3758,7 +3766,7 @@ __start_new_thread = function(f, args) { return worker; } -__gen_worker_append = function(worker, ob, index) { +var __gen_worker_append = function(worker, ob, index) { var append = function(item) { @@ -3769,7 +3777,7 @@ __gen_worker_append = function(worker, ob, index) { Object.defineProperty(ob, "append", __jsdict([["enumerable", false], ["value", append], ["writeable", true], ["configurable", true]])); } -__webworker_wrap = function(ob, argindex) { +var __webworker_wrap = function(ob, argindex) { if (__test_if_true__(ob instanceof Array)) { var func = function(index, item) { @@ -3800,7 +3808,7 @@ __webworker_wrap = function(ob, argindex) { return ob; } -__rpc__ = function(url, func, args) { +var __rpc__ = function(url, func, args) { var req; req = new XMLHttpRequest(); req.open("POST", url, false); @@ -3809,7 +3817,7 @@ __rpc__ = function(url, func, args) { return JSON.parse(req.responseText); } -__rpc_iter__ = function(url, attr) { +var __rpc_iter__ = function(url, attr) { var req; req = new XMLHttpRequest(); req.open("POST", url, false); @@ -3818,7 +3826,7 @@ __rpc_iter__ = function(url, attr) { return JSON.parse(req.responseText); } -__rpc_set__ = function(url, attr, value) { +var __rpc_set__ = function(url, attr, value) { var req; req = new XMLHttpRequest(); req.open("POST", url, false); @@ -3826,7 +3834,7 @@ __rpc_set__ = function(url, attr, value) { req.send(JSON.stringify(__jsdict([["set", attr], ["value", value]]))); } -__rpc_get__ = function(url, attr) { +var __rpc_get__ = function(url, attr) { var req; req = new XMLHttpRequest(); req.open("POST", url, false); diff --git a/pythonjs/runtime/builtins.py b/pythonjs/runtime/builtins.py index 60a4980..68f356f 100644 --- a/pythonjs/runtime/builtins.py +++ b/pythonjs/runtime/builtins.py @@ -9,11 +9,11 @@ _PythonJS_UID = 0 -JS('IndexError = function(msg) {this.message = msg || "";}; IndexError.prototype = Object.create(Error.prototype); IndexError.prototype.name = "IndexError";') -JS('KeyError = function(msg) {this.message = msg || "";}; KeyError.prototype = Object.create(Error.prototype); KeyError.prototype.name = "KeyError";') -JS('ValueError = function(msg) {this.message = msg || "";}; ValueError.prototype = Object.create(Error.prototype); ValueError.prototype.name = "ValueError";') -JS('AttributeError = function(msg) {this.message = msg || "";}; AttributeError.prototype = Object.create(Error.prototype);AttributeError.prototype.name = "AttributeError";') -JS('RuntimeError = function(msg) {this.message = msg || "";}; RuntimeError.prototype = Object.create(Error.prototype);RuntimeError.prototype.name = "RuntimeError";') +inline('IndexError = function(msg) {this.message = msg || "";}; IndexError.prototype = Object.create(Error.prototype); IndexError.prototype.name = "IndexError";') +inline('KeyError = function(msg) {this.message = msg || "";}; KeyError.prototype = Object.create(Error.prototype); KeyError.prototype.name = "KeyError";') +inline('ValueError = function(msg) {this.message = msg || "";}; ValueError.prototype = Object.create(Error.prototype); ValueError.prototype.name = "ValueError";') +inline('AttributeError = function(msg) {this.message = msg || "";}; AttributeError.prototype = Object.create(Error.prototype);AttributeError.prototype.name = "AttributeError";') +inline('RuntimeError = function(msg) {this.message = msg || "";}; RuntimeError.prototype = Object.create(Error.prototype);RuntimeError.prototype.name = "RuntimeError";') with javascript: def __gpu_object(cls, struct_name, data_name): @@ -1451,7 +1451,9 @@ def __getitem__(self, key): that is why below we return the key in self if __dict is undefined. ''' __dict = self[...] - if JS("typeof(key) === 'object' || typeof(key) === 'function'"): + if instanceof(key, Array): + return inline('__dict[key]') + elif JS("typeof(key) === 'object' || typeof(key) === 'function'"): # Test undefined because it can be in the dict if JS("key.__uid__ && key.__uid__ in __dict"): return JS('__dict[key.__uid__]') @@ -1466,7 +1468,9 @@ def __getitem__(self, key): def __setitem__(self, key, value): __dict = self[...] - if JS("typeof(key) === 'object' || typeof(key) === 'function'"): + if instanceof(key, Array): ## using an Array as key converts it to a string + inline( '__dict[key] = value') + elif JS("typeof(key) === 'object' || typeof(key) === 'function'"): if JS("key.__uid__ === undefined"): # "" is needed so that integers can also be # used as keys diff --git a/pythonjs/typedpython.py b/pythonjs/typedpython.py index b885edd..a2d42df 100644 --- a/pythonjs/typedpython.py +++ b/pythonjs/typedpython.py @@ -51,14 +51,23 @@ def transform_source( source, strip=False ): a.append( char ) else: a.append( char ) + if not a: continue + + if a[-1]==';': a.pop() c = ''.join(a) cs = c.strip() + if cs.startswith('//'): continue + elif cs.startswith('inline('): + output.append(c) + continue + + if cs.startswith('var '): c = c.replace('var ', '') From c14718ae8cb5b03c194b93980f2012157ca68f09 Mon Sep 17 00:00:00 2001 From: hartsantler Date: Wed, 23 Jul 2014 20:53:36 -0700 Subject: [PATCH 036/100] tuple dict keys: fixed string vs numeric tuple elements in normal mode. --- README.md | 22 +++++++++++++++++++++- pythonjs/pythonjs.js | 32 +++++++++++++++++++------------- pythonjs/runtime/builtins.py | 9 ++++++++- regtests/dict/tuple_keys.py | 6 +++++- 4 files changed, 53 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index ee42959..d841b1c 100644 --- a/README.md +++ b/README.md @@ -440,4 +440,24 @@ d = "HI" * 2 ## FAILS 3. The syntax `from mymodule import *` allows you to import another python script from the same folder, but both mymodule and the parent will share the same namespace, mymodule can use global variables defined in the parent. - +4. Using tuples as keys in a dict in javascript mode breaks with strings that are numbers +``` +pythonjs.configure( javascript=True ) +a = (1,2,3) +b = ("1","2","3") +D = { a: 'hello', b: 'world' } +D[ a ] == 'hello' ## FAILS +D[ b ] == 'world' ## OK +``` +The example above works in the default Python mode, because when using a tuple as a key, its first item will be checked if it is a string, and if so then generate a key that is +different from a tuple of numeric elements. This logic assumes that all following keys +are also strings, so the following breaks even in the default Python mode, because all +the items in `b` are treated as strings and `a` contains the same values as strings. + +``` +a = ("1", "2", "3") +b = ("1", 2, 3) +D = {a:100, b:200} +D[ a ] == 100 ## FAILS - value is 200 +D[ b ] == 200 ## OK +``` \ No newline at end of file diff --git a/pythonjs/pythonjs.js b/pythonjs/pythonjs.js index 2a4317a..4ead326 100644 --- a/pythonjs/pythonjs.js +++ b/pythonjs/pythonjs.js @@ -2942,6 +2942,9 @@ var __dict___getitem__ = function(args, kwargs) { "\n notes:\n . '4' and 4 are the same key\n . it is possible that the translator mistakes a javascript-object for a dict and inlines this function,\n that is why below we return the key in self if __dict is undefined.\n "; __dict = self["$wrapped"]; if (__test_if_true__(key instanceof Array)) { + if (__test_if_true__(( __get__(key, "length", "missing attribute `length` - line 1221: if key.length > 0 and typeof( key[0] ) == 'string':") ) > 0 && ( typeof(((key instanceof Array) ? key[0] : __get__(key, "__getitem__", "line 1221: if key.length > 0 and typeof( key[0] ) == 'string':")([0], __NULL_OBJECT__))) ) == "string")) { + key = (("'" + __get__(__get__(key, "join", "missing attribute `join` - line 1222: key = \"'\" + key.join(\"'\") + \"'\""), "__call__")(["'"], __NULL_OBJECT__)) + "'"); + } return __dict[key]; } else { if (__test_if_true__(typeof(key) === 'object' || typeof(key) === 'function')) { @@ -2974,6 +2977,9 @@ var __dict___setitem__ = function(args, kwargs) { var value = __args__['value']; __dict = self["$wrapped"]; if (__test_if_true__(key instanceof Array)) { + if (__test_if_true__(( __get__(key, "length", "missing attribute `length` - line 1240: if key.length > 0 and typeof( key[0] ) == 'string':") ) > 0 && ( typeof(((key instanceof Array) ? key[0] : __get__(key, "__getitem__", "line 1240: if key.length > 0 and typeof( key[0] ) == 'string':")([0], __NULL_OBJECT__))) ) == "string")) { + key = (("'" + __get__(__get__(key, "join", "missing attribute `join` - line 1241: key = \"'\" + key.join(\"'\") + \"'\""), "__call__")(["'"], __NULL_OBJECT__)) + "'"); + } __dict[key] = value; } else { if (__test_if_true__(typeof(key) === 'object' || typeof(key) === 'function')) { @@ -3207,7 +3213,7 @@ var __array___init__ = function(args, kwargs) { var initializer = __args__['initializer']; var little_endian = __args__['little_endian']; self.typecode = typecode; - self.itemsize = __get__(__get__(self, "typecodes", "missing attribute `typecodes` - line 1380: self.itemsize = self.typecodes[ typecode ]"), "__getitem__", "line 1380: self.itemsize = self.typecodes[ typecode ]")([typecode], __NULL_OBJECT__); + self.itemsize = __get__(__get__(self, "typecodes", "missing attribute `typecodes` - line 1387: self.itemsize = self.typecodes[ typecode ]"), "__getitem__", "line 1387: self.itemsize = self.typecodes[ typecode ]")([typecode], __NULL_OBJECT__); self.little_endian = little_endian; if (__test_if_true__(initializer)) { self.length = len([initializer], __NULL_OBJECT__); @@ -3231,7 +3237,7 @@ var __array___init__ = function(args, kwargs) { buff = new ArrayBuffer(size); self.dataview = new DataView(buff); self.buffer = buff; - __get__(__get__(self, "fromlist", "missing attribute `fromlist` - line 1401: self.fromlist( initializer )"), "__call__")([initializer], __NULL_OBJECT__); + __get__(__get__(self, "fromlist", "missing attribute `fromlist` - line 1408: self.fromlist( initializer )"), "__call__")([initializer], __NULL_OBJECT__); } ;__array___init__.is_wrapper = true; __array_attrs.__init__ = __array___init__; @@ -3264,7 +3270,7 @@ var __array___contains__ = function(args, kwargs) { __args__ = __getargs__("__array___contains__", __sig__, args, kwargs); var self = __args__['self']; var value = __args__['value']; - arr = __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1407: arr = self.to_array()"), "__call__")(); + arr = __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1414: arr = self.to_array()"), "__call__")(); if (( arr.indexOf(value) ) == -1) { return false; } else { @@ -3289,7 +3295,7 @@ var __array___getitem__ = function(args, kwargs) { step = self.itemsize; offset = (step * index); dataview = self.dataview; - func_name = ("get" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1415: func_name = 'get'+self.typecode_names[ self.typecode ]"), "__getitem__", "line 1415: func_name = 'get'+self.typecode_names[ self.typecode ]")([self.typecode], __NULL_OBJECT__)); + func_name = ("get" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1422: func_name = 'get'+self.typecode_names[ self.typecode ]"), "__getitem__", "line 1422: func_name = 'get'+self.typecode_names[ self.typecode ]")([self.typecode], __NULL_OBJECT__)); func = dataview[func_name].bind(dataview); if (( offset ) < self.bytes) { value = func(offset); @@ -3327,7 +3333,7 @@ var __array___setitem__ = function(args, kwargs) { } offset = (step * index); dataview = self.dataview; - func_name = ("set" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1431: func_name = 'set'+self.typecode_names[ self.typecode ]"), "__getitem__", "line 1431: func_name = 'set'+self.typecode_names[ self.typecode ]")([self.typecode], __NULL_OBJECT__)); + func_name = ("set" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1438: func_name = 'set'+self.typecode_names[ self.typecode ]"), "__getitem__", "line 1438: func_name = 'set'+self.typecode_names[ self.typecode ]")([self.typecode], __NULL_OBJECT__)); func = dataview[func_name].bind(dataview); if (( offset ) < self.bytes) { if (( self.typecode ) == "float8") { @@ -3395,13 +3401,13 @@ var __array_fromlist = function(args, kwargs) { typecode = self.typecode; size = (length * step); dataview = self.dataview; - func_name = ("set" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1451: func_name = 'set'+self.typecode_names[ typecode ]"), "__getitem__", "line 1451: func_name = 'set'+self.typecode_names[ typecode ]")([typecode], __NULL_OBJECT__)); + func_name = ("set" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1458: func_name = 'set'+self.typecode_names[ typecode ]"), "__getitem__", "line 1458: func_name = 'set'+self.typecode_names[ typecode ]")([typecode], __NULL_OBJECT__)); func = dataview[func_name].bind(dataview); if (( size ) <= self.bytes) { i = 0; offset = 0; while (( i ) < length) { - item = ((lst instanceof Array) ? lst[i] : __get__(lst, "__getitem__", "line 1456: item = lst[i]")([i], __NULL_OBJECT__)); + item = ((lst instanceof Array) ? lst[i] : __get__(lst, "__getitem__", "line 1463: item = lst[i]")([i], __NULL_OBJECT__)); if (( typecode ) == "float8") { item *= self._norm_set; } else { @@ -3459,7 +3465,7 @@ var __array_append = function(args, kwargs) { var self = __args__['self']; var value = __args__['value']; length = self.length; - __get__(__get__(self, "resize", "missing attribute `resize` - line 1479: self.resize( self.length + 1 )"), "__call__")([(self.length + 1)], __NULL_OBJECT__); + __get__(__get__(self, "resize", "missing attribute `resize` - line 1486: self.resize( self.length + 1 )"), "__call__")([(self.length + 1)], __NULL_OBJECT__); __get__(__get__(self, "__setitem__"), "__call__")([length, value], {}); } ;__array_append.is_wrapper = true; @@ -3478,12 +3484,12 @@ var __array_extend = function(args, kwargs) { var self = __args__['self']; var lst = __args__['lst']; var value,__iterator__54; - __iterator__54 = __get__(__get__(lst, "__iter__", "no iterator - line 1482: for value in lst:"), "__call__")([], __NULL_OBJECT__); + __iterator__54 = __get__(__get__(lst, "__iter__", "no iterator - line 1489: for value in lst:"), "__call__")([], __NULL_OBJECT__); var __next__54; __next__54 = __get__(__iterator__54, "next"); while (( __iterator__54.index ) < __iterator__54.length) { value = __next__54(); - __get__(__get__(self, "append", "missing attribute `append` - line 1483: self.append( value )"), "__call__")([value], __NULL_OBJECT__); + __get__(__get__(self, "append", "missing attribute `append` - line 1490: self.append( value )"), "__call__")([value], __NULL_OBJECT__); } } ;__array_extend.is_wrapper = true; @@ -3523,7 +3529,7 @@ var __array_to_list = function(args, kwargs) { } __args__ = __getargs__("__array_to_list", __sig__, args, kwargs); var self = __args__['self']; - return __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1493: return self.to_array()"), "__call__")(); + return __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1500: return self.to_array()"), "__call__")(); } ;__array_to_list.is_wrapper = true; __array_attrs.to_list = __array_to_list; @@ -3540,9 +3546,9 @@ var __array_to_ascii = function(args, kwargs) { __args__ = __getargs__("__array_to_ascii", __sig__, args, kwargs); var self = __args__['self']; string = ""; - arr = __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1496: arr = self.to_array()"), "__call__")(); + arr = __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1503: arr = self.to_array()"), "__call__")(); i = 0; - length = __get__(arr, "length", "missing attribute `length` - line 1497: i = 0; length = arr.length"); + length = __get__(arr, "length", "missing attribute `length` - line 1504: i = 0; length = arr.length"); while (( i ) < length) { var num = arr[i]; var char = String.fromCharCode(num); diff --git a/pythonjs/runtime/builtins.py b/pythonjs/runtime/builtins.py index 68f356f..94b7175 100644 --- a/pythonjs/runtime/builtins.py +++ b/pythonjs/runtime/builtins.py @@ -1452,6 +1452,8 @@ def __getitem__(self, key): ''' __dict = self[...] if instanceof(key, Array): + if key.length > 0 and typeof( key[0] ) == 'string': + key = "'" + key.join("'") + "'" return inline('__dict[key]') elif JS("typeof(key) === 'object' || typeof(key) === 'function'"): # Test undefined because it can be in the dict @@ -1468,7 +1470,12 @@ def __getitem__(self, key): def __setitem__(self, key, value): __dict = self[...] - if instanceof(key, Array): ## using an Array as key converts it to a string + if instanceof(key, Array): + ## using an Array as key converts it to a string + ## check first item of array, if it is a string, the items must be quoted + ## so that numeric and string items are different. + if key.length > 0 and typeof( key[0] ) == 'string': + key = "'" + key.join("'") + "'" inline( '__dict[key] = value') elif JS("typeof(key) === 'object' || typeof(key) === 'function'"): if JS("key.__uid__ === undefined"): diff --git a/regtests/dict/tuple_keys.py b/regtests/dict/tuple_keys.py index 6767983..02a734a 100644 --- a/regtests/dict/tuple_keys.py +++ b/regtests/dict/tuple_keys.py @@ -2,11 +2,15 @@ def main(): + s = ("1", "2", "3") a = (1,2,3) b = (1,2,3) c = ( a, b, 'XXX' ) + d = ('1', 2, 3) - D = { a: 22, c:44 } + D = { d:100, s: 11, a: 22, c:44 } + TestError( D[ d ] == 100) ## this fails in both python and javascript mode + TestError( D[ s ] == 11) ## this fails in javascript mode TestError( D[ a ] == 22) TestError( D[ b ] == 22) TestError( D[ c ] == 44) From c1d8306fc5d61a65b2432c130ffa4f0e92b43f98 Mon Sep 17 00:00:00 2001 From: hartsantler Date: Wed, 23 Jul 2014 22:54:21 -0700 Subject: [PATCH 037/100] fixed tuple key in dict where tuple has mixed strings and numbers of the same value (JSON.stringify trick) --- pythonjs/pythonjs.js | 87 ++++++++++++++++++------------------ pythonjs/runtime/builtins.py | 22 +++++++-- 2 files changed, 62 insertions(+), 47 deletions(-) diff --git a/pythonjs/pythonjs.js b/pythonjs/pythonjs.js index 4ead326..c7c1c5e 100644 --- a/pythonjs/pythonjs.js +++ b/pythonjs/pythonjs.js @@ -918,6 +918,11 @@ GLSLJITRuntime.prototype.unpack_mat4 = function(arr) { GLSLJITRuntime.unpack_mat4 = function () { return GLSLJITRuntime.prototype.unpack_mat4.apply(arguments[0], Array.prototype.slice.call(arguments,1)) }; GLSLJITRuntime.prototype.__properties__ = { }; GLSLJITRuntime.prototype.__unbound_methods__ = { }; +var __tuple_key__ = function(arr) { + + return JSON.stringify(arr); +} +;__tuple_key__.is_wrapper = true; var __getattr__ = function(ob, a) { if (ob.__getattr__) { @@ -1567,8 +1572,8 @@ var issubclass = function(args, kwargs) { } bases = C.__bases__; i = 0; - while (( i ) < __get__(bases, "length", "missing attribute `length` - line 636: while i < bases.length:")) { - if (__test_if_true__(issubclass([((bases instanceof Array) ? bases[i] : __get__(bases, "__getitem__", "line 637: if issubclass( bases[i], B ):")([i], __NULL_OBJECT__)), B], __NULL_OBJECT__))) { + while (( i ) < __get__(bases, "length", "missing attribute `length` - line 648: while i < bases.length:")) { + if (__test_if_true__(issubclass([((bases instanceof Array) ? bases[i] : __get__(bases, "__getitem__", "line 649: if issubclass( bases[i], B ):")([i], __NULL_OBJECT__)), B], __NULL_OBJECT__))) { return true; } i += 1; @@ -2321,7 +2326,7 @@ var sum = function(args, kwargs) { var arr = __args__['arr']; a = 0; var b,__iterator__40; - __iterator__40 = __get__(__get__(arr, "__iter__", "no iterator - line 1045: for b in arr:"), "__call__")([], __NULL_OBJECT__); + __iterator__40 = __get__(__get__(arr, "__iter__", "no iterator - line 1057: for b in arr:"), "__call__")([], __NULL_OBJECT__); var __next__40; __next__40 = __get__(__iterator__40, "next"); while (( __iterator__40.index ) < __iterator__40.length) { @@ -2379,7 +2384,7 @@ var next = function(args, kwargs) { } __args__ = __getargs__("next", __sig__, args, kwargs); var obj = __args__['obj']; - return __get__(__get__(obj, "next", "missing attribute `next` - line 1063: return obj.next()"), "__call__")(); + return __get__(__get__(obj, "next", "missing attribute `next` - line 1075: return obj.next()"), "__call__")(); } ;next.is_wrapper = true; var map = function(args, kwargs) { @@ -2397,7 +2402,7 @@ var map = function(args, kwargs) { var objs = __args__['objs']; arr = []; var ob,__iterator__41; - __iterator__41 = __get__(__get__(objs, "__iter__", "no iterator - line 1066: for ob in objs:"), "__call__")([], __NULL_OBJECT__); + __iterator__41 = __get__(__get__(objs, "__iter__", "no iterator - line 1078: for ob in objs:"), "__call__")([], __NULL_OBJECT__); var __next__41; __next__41 = __get__(__iterator__41, "next"); while (( __iterator__41.index ) < __iterator__41.length) { @@ -2423,7 +2428,7 @@ var filter = function(args, kwargs) { var objs = __args__['objs']; arr = []; var ob,__iterator__42; - __iterator__42 = __get__(__get__(objs, "__iter__", "no iterator - line 1073: for ob in objs:"), "__call__")([], __NULL_OBJECT__); + __iterator__42 = __get__(__get__(objs, "__iter__", "no iterator - line 1085: for ob in objs:"), "__call__")([], __NULL_OBJECT__); var __next__42; __next__42 = __get__(__iterator__42, "next"); while (( __iterator__42.index ) < __iterator__42.length) { @@ -2449,7 +2454,7 @@ var min = function(args, kwargs) { var lst = __args__['lst']; a = null; var value,__iterator__43; - __iterator__43 = __get__(__get__(lst, "__iter__", "no iterator - line 1080: for value in lst:"), "__call__")([], __NULL_OBJECT__); + __iterator__43 = __get__(__get__(lst, "__iter__", "no iterator - line 1092: for value in lst:"), "__call__")([], __NULL_OBJECT__); var __next__43; __next__43 = __get__(__iterator__43, "next"); while (( __iterator__43.index ) < __iterator__43.length) { @@ -2479,7 +2484,7 @@ var max = function(args, kwargs) { var lst = __args__['lst']; a = null; var value,__iterator__44; - __iterator__44 = __get__(__get__(lst, "__iter__", "no iterator - line 1086: for value in lst:"), "__call__")([], __NULL_OBJECT__); + __iterator__44 = __get__(__get__(lst, "__iter__", "no iterator - line 1098: for value in lst:"), "__call__")([], __NULL_OBJECT__); var __next__44; __next__44 = __get__(__iterator__44, "next"); while (( __iterator__44.index ) < __iterator__44.length) { @@ -2589,7 +2594,7 @@ var __Iterator___init__ = function(args, kwargs) { self.obj = obj; self.index = index; self.length = len([obj], __NULL_OBJECT__); - self.obj_get = __get__(obj, "get", "missing attribute `get` - line 1114: self.obj_get = obj.get ## cache this for speed"); + self.obj_get = __get__(obj, "get", "missing attribute `get` - line 1126: self.obj_get = obj.get ## cache this for speed"); } ;__Iterator___init__.is_wrapper = true; __Iterator_attrs.__init__ = __Iterator___init__; @@ -2696,27 +2701,27 @@ var __dict___init__ = function(args, kwargs) { ob = js_object; if (__test_if_true__(ob instanceof Array)) { var o,__iterator__45; - __iterator__45 = __get__(__get__(ob, "__iter__", "no iterator - line 1157: for o in ob:"), "__call__")([], __NULL_OBJECT__); + __iterator__45 = __get__(__get__(ob, "__iter__", "no iterator - line 1169: for o in ob:"), "__call__")([], __NULL_OBJECT__); var __next__45; __next__45 = __get__(__iterator__45, "next"); while (( __iterator__45.index ) < __iterator__45.length) { o = __next__45(); if (__test_if_true__(o instanceof Array)) { - __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1159: self.__setitem__( o[0], o[1] )"), "__call__")([((o instanceof Array) ? o[0] : __get__(o, "__getitem__", "line 1159: self.__setitem__( o[0], o[1] )")([0], __NULL_OBJECT__)), ((o instanceof Array) ? o[1] : __get__(o, "__getitem__", "line 1159: self.__setitem__( o[0], o[1] )")([1], __NULL_OBJECT__))], __NULL_OBJECT__); + __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1171: self.__setitem__( o[0], o[1] )"), "__call__")([((o instanceof Array) ? o[0] : __get__(o, "__getitem__", "line 1171: self.__setitem__( o[0], o[1] )")([0], __NULL_OBJECT__)), ((o instanceof Array) ? o[1] : __get__(o, "__getitem__", "line 1171: self.__setitem__( o[0], o[1] )")([1], __NULL_OBJECT__))], __NULL_OBJECT__); } else { - __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1161: self.__setitem__( o['key'], o['value'] )"), "__call__")([((o instanceof Array) ? o["key"] : __get__(o, "__getitem__", "line 1161: self.__setitem__( o['key'], o['value'] )")(["key"], __NULL_OBJECT__)), ((o instanceof Array) ? o["value"] : __get__(o, "__getitem__", "line 1161: self.__setitem__( o['key'], o['value'] )")(["value"], __NULL_OBJECT__))], __NULL_OBJECT__); + __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1173: self.__setitem__( o['key'], o['value'] )"), "__call__")([((o instanceof Array) ? o["key"] : __get__(o, "__getitem__", "line 1173: self.__setitem__( o['key'], o['value'] )")(["key"], __NULL_OBJECT__)), ((o instanceof Array) ? o["value"] : __get__(o, "__getitem__", "line 1173: self.__setitem__( o['key'], o['value'] )")(["value"], __NULL_OBJECT__))], __NULL_OBJECT__); } } } else { if (__test_if_true__(isinstance([ob, dict], __NULL_OBJECT__))) { var key,__iterator__46; - __iterator__46 = __get__(__get__(__jsdict_keys(ob), "__iter__", "no iterator - line 1163: for key in ob.keys():"), "__call__")([], __NULL_OBJECT__); + __iterator__46 = __get__(__get__(__jsdict_keys(ob), "__iter__", "no iterator - line 1175: for key in ob.keys():"), "__call__")([], __NULL_OBJECT__); var __next__46; __next__46 = __get__(__iterator__46, "next"); while (( __iterator__46.index ) < __iterator__46.length) { key = __next__46(); - value = ((ob instanceof Array) ? ob[key] : __get__(ob, "__getitem__", "line 1164: value = ob[ key ]")([key], __NULL_OBJECT__)); - __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1165: self.__setitem__( key, value )"), "__call__")([key, value], __NULL_OBJECT__); + value = ((ob instanceof Array) ? ob[key] : __get__(ob, "__getitem__", "line 1176: value = ob[ key ]")([key], __NULL_OBJECT__)); + __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1177: self.__setitem__( key, value )"), "__call__")([key, value], __NULL_OBJECT__); } } else { console.log("ERROR init dict from:", js_object); @@ -2742,15 +2747,15 @@ var __dict_jsify = function(args, kwargs) { var self = __args__['self']; keys = __object_keys__([self["$wrapped"]], __NULL_OBJECT__); var key,__iterator__47; - __iterator__47 = __get__(__get__(keys, "__iter__", "no iterator - line 1172: for key in keys:"), "__call__")([], __NULL_OBJECT__); + __iterator__47 = __get__(__get__(keys, "__iter__", "no iterator - line 1184: for key in keys:"), "__call__")([], __NULL_OBJECT__); var __next__47; __next__47 = __get__(__iterator__47, "next"); while (( __iterator__47.index ) < __iterator__47.length) { key = __next__47(); - value = __get__(self["$wrapped"], "__getitem__", "line 1173: value = self[...][key]")([key], __NULL_OBJECT__); + value = __get__(self["$wrapped"], "__getitem__", "line 1185: value = self[...][key]")([key], __NULL_OBJECT__); if (( typeof(value) ) == "object") { if (__test_if_true__(hasattr([value, "jsify"], __NULL_OBJECT__))) { - __get__(__get__(self["$wrapped"], "__setitem__"), "__call__")([key, __get__(__get__(value, "jsify", "missing attribute `jsify` - line 1176: self[...][key] = value.jsify()"), "__call__")()], {}); + __get__(__get__(self["$wrapped"], "__setitem__"), "__call__")([key, __get__(__get__(value, "jsify", "missing attribute `jsify` - line 1188: self[...][key] = value.jsify()"), "__call__")()], {}); } } else { if (( typeof(value) ) == "function") { @@ -2809,7 +2814,7 @@ var __dict_has_key = function(args, kwargs) { var key = __args__['key']; __dict = self["$wrapped"]; if (__test_if_true__(typeof(key) === 'object' || typeof(key) === 'function')) { - key = __get__(key, "__uid__", "missing attribute `__uid__` - line 1189: key = key.__uid__"); + key = __get__(key, "__uid__", "missing attribute `__uid__` - line 1201: key = key.__uid__"); } if (__test_if_true__(key in __dict)) { return true; @@ -2833,12 +2838,12 @@ var __dict_update = function(args, kwargs) { var self = __args__['self']; var other = __args__['other']; var key,__iterator__48; - __iterator__48 = __get__(__get__(other, "__iter__", "no iterator - line 1195: for key in other:"), "__call__")([], __NULL_OBJECT__); + __iterator__48 = __get__(__get__(other, "__iter__", "no iterator - line 1207: for key in other:"), "__call__")([], __NULL_OBJECT__); var __next__48; __next__48 = __get__(__iterator__48, "next"); while (( __iterator__48.index ) < __iterator__48.length) { key = __next__48(); - __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1196: self.__setitem__( key, other[key] )"), "__call__")([key, ((other instanceof Array) ? other[key] : __get__(other, "__getitem__", "line 1196: self.__setitem__( key, other[key] )")([key], __NULL_OBJECT__))], __NULL_OBJECT__); + __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1208: self.__setitem__( key, other[key] )"), "__call__")([key, ((other instanceof Array) ? other[key] : __get__(other, "__getitem__", "line 1208: self.__setitem__( key, other[key] )")([key], __NULL_OBJECT__))], __NULL_OBJECT__); } } ;__dict_update.is_wrapper = true; @@ -2857,12 +2862,12 @@ var __dict_items = function(args, kwargs) { var self = __args__['self']; arr = []; var key,__iterator__49; - __iterator__49 = __get__(__get__(__jsdict_keys(self), "__iter__", "no iterator - line 1199: for key in self.keys():"), "__call__")([], __NULL_OBJECT__); + __iterator__49 = __get__(__get__(__jsdict_keys(self), "__iter__", "no iterator - line 1211: for key in self.keys():"), "__call__")([], __NULL_OBJECT__); var __next__49; __next__49 = __get__(__iterator__49, "next"); while (( __iterator__49.index ) < __iterator__49.length) { key = __next__49(); - __get__(__get__(arr, "append", "missing attribute `append` - line 1200: arr.append( [key, self[key]] )"), "__call__")([[key, __get__(self, "__getitem__")([key], __NULL_OBJECT__)]], __NULL_OBJECT__); + __get__(__get__(arr, "append", "missing attribute `append` - line 1212: arr.append( [key, self[key]] )"), "__call__")([[key, __get__(self, "__getitem__")([key], __NULL_OBJECT__)]], __NULL_OBJECT__); } return arr; } @@ -2905,7 +2910,7 @@ var __dict_set = function(args, kwargs) { var self = __args__['self']; var key = __args__['key']; var value = __args__['value']; - __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1208: self.__setitem__(key, value)"), "__call__")([key, value], __NULL_OBJECT__); + __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1220: self.__setitem__(key, value)"), "__call__")([key, value], __NULL_OBJECT__); } ;__dict_set.is_wrapper = true; __dict_attrs.set = __dict_set; @@ -2942,9 +2947,7 @@ var __dict___getitem__ = function(args, kwargs) { "\n notes:\n . '4' and 4 are the same key\n . it is possible that the translator mistakes a javascript-object for a dict and inlines this function,\n that is why below we return the key in self if __dict is undefined.\n "; __dict = self["$wrapped"]; if (__test_if_true__(key instanceof Array)) { - if (__test_if_true__(( __get__(key, "length", "missing attribute `length` - line 1221: if key.length > 0 and typeof( key[0] ) == 'string':") ) > 0 && ( typeof(((key instanceof Array) ? key[0] : __get__(key, "__getitem__", "line 1221: if key.length > 0 and typeof( key[0] ) == 'string':")([0], __NULL_OBJECT__))) ) == "string")) { - key = (("'" + __get__(__get__(key, "join", "missing attribute `join` - line 1222: key = \"'\" + key.join(\"'\") + \"'\""), "__call__")(["'"], __NULL_OBJECT__)) + "'"); - } + key = __get__(__get__(JSON, "stringify", "missing attribute `stringify` - line 1235: key = JSON.stringify( key )"), "__call__")([key], __NULL_OBJECT__); return __dict[key]; } else { if (__test_if_true__(typeof(key) === 'object' || typeof(key) === 'function')) { @@ -2977,9 +2980,7 @@ var __dict___setitem__ = function(args, kwargs) { var value = __args__['value']; __dict = self["$wrapped"]; if (__test_if_true__(key instanceof Array)) { - if (__test_if_true__(( __get__(key, "length", "missing attribute `length` - line 1240: if key.length > 0 and typeof( key[0] ) == 'string':") ) > 0 && ( typeof(((key instanceof Array) ? key[0] : __get__(key, "__getitem__", "line 1240: if key.length > 0 and typeof( key[0] ) == 'string':")([0], __NULL_OBJECT__))) ) == "string")) { - key = (("'" + __get__(__get__(key, "join", "missing attribute `join` - line 1241: key = \"'\" + key.join(\"'\") + \"'\""), "__call__")(["'"], __NULL_OBJECT__)) + "'"); - } + key = __get__(__get__(JSON, "stringify", "missing attribute `stringify` - line 1255: key = JSON.stringify( key )"), "__call__")([key], __NULL_OBJECT__); __dict[key] = value; } else { if (__test_if_true__(typeof(key) === 'object' || typeof(key) === 'function')) { @@ -3213,7 +3214,7 @@ var __array___init__ = function(args, kwargs) { var initializer = __args__['initializer']; var little_endian = __args__['little_endian']; self.typecode = typecode; - self.itemsize = __get__(__get__(self, "typecodes", "missing attribute `typecodes` - line 1387: self.itemsize = self.typecodes[ typecode ]"), "__getitem__", "line 1387: self.itemsize = self.typecodes[ typecode ]")([typecode], __NULL_OBJECT__); + self.itemsize = __get__(__get__(self, "typecodes", "missing attribute `typecodes` - line 1401: self.itemsize = self.typecodes[ typecode ]"), "__getitem__", "line 1401: self.itemsize = self.typecodes[ typecode ]")([typecode], __NULL_OBJECT__); self.little_endian = little_endian; if (__test_if_true__(initializer)) { self.length = len([initializer], __NULL_OBJECT__); @@ -3237,7 +3238,7 @@ var __array___init__ = function(args, kwargs) { buff = new ArrayBuffer(size); self.dataview = new DataView(buff); self.buffer = buff; - __get__(__get__(self, "fromlist", "missing attribute `fromlist` - line 1408: self.fromlist( initializer )"), "__call__")([initializer], __NULL_OBJECT__); + __get__(__get__(self, "fromlist", "missing attribute `fromlist` - line 1422: self.fromlist( initializer )"), "__call__")([initializer], __NULL_OBJECT__); } ;__array___init__.is_wrapper = true; __array_attrs.__init__ = __array___init__; @@ -3270,7 +3271,7 @@ var __array___contains__ = function(args, kwargs) { __args__ = __getargs__("__array___contains__", __sig__, args, kwargs); var self = __args__['self']; var value = __args__['value']; - arr = __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1414: arr = self.to_array()"), "__call__")(); + arr = __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1428: arr = self.to_array()"), "__call__")(); if (( arr.indexOf(value) ) == -1) { return false; } else { @@ -3295,7 +3296,7 @@ var __array___getitem__ = function(args, kwargs) { step = self.itemsize; offset = (step * index); dataview = self.dataview; - func_name = ("get" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1422: func_name = 'get'+self.typecode_names[ self.typecode ]"), "__getitem__", "line 1422: func_name = 'get'+self.typecode_names[ self.typecode ]")([self.typecode], __NULL_OBJECT__)); + func_name = ("get" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1436: func_name = 'get'+self.typecode_names[ self.typecode ]"), "__getitem__", "line 1436: func_name = 'get'+self.typecode_names[ self.typecode ]")([self.typecode], __NULL_OBJECT__)); func = dataview[func_name].bind(dataview); if (( offset ) < self.bytes) { value = func(offset); @@ -3333,7 +3334,7 @@ var __array___setitem__ = function(args, kwargs) { } offset = (step * index); dataview = self.dataview; - func_name = ("set" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1438: func_name = 'set'+self.typecode_names[ self.typecode ]"), "__getitem__", "line 1438: func_name = 'set'+self.typecode_names[ self.typecode ]")([self.typecode], __NULL_OBJECT__)); + func_name = ("set" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1452: func_name = 'set'+self.typecode_names[ self.typecode ]"), "__getitem__", "line 1452: func_name = 'set'+self.typecode_names[ self.typecode ]")([self.typecode], __NULL_OBJECT__)); func = dataview[func_name].bind(dataview); if (( offset ) < self.bytes) { if (( self.typecode ) == "float8") { @@ -3401,13 +3402,13 @@ var __array_fromlist = function(args, kwargs) { typecode = self.typecode; size = (length * step); dataview = self.dataview; - func_name = ("set" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1458: func_name = 'set'+self.typecode_names[ typecode ]"), "__getitem__", "line 1458: func_name = 'set'+self.typecode_names[ typecode ]")([typecode], __NULL_OBJECT__)); + func_name = ("set" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1472: func_name = 'set'+self.typecode_names[ typecode ]"), "__getitem__", "line 1472: func_name = 'set'+self.typecode_names[ typecode ]")([typecode], __NULL_OBJECT__)); func = dataview[func_name].bind(dataview); if (( size ) <= self.bytes) { i = 0; offset = 0; while (( i ) < length) { - item = ((lst instanceof Array) ? lst[i] : __get__(lst, "__getitem__", "line 1463: item = lst[i]")([i], __NULL_OBJECT__)); + item = ((lst instanceof Array) ? lst[i] : __get__(lst, "__getitem__", "line 1477: item = lst[i]")([i], __NULL_OBJECT__)); if (( typecode ) == "float8") { item *= self._norm_set; } else { @@ -3465,7 +3466,7 @@ var __array_append = function(args, kwargs) { var self = __args__['self']; var value = __args__['value']; length = self.length; - __get__(__get__(self, "resize", "missing attribute `resize` - line 1486: self.resize( self.length + 1 )"), "__call__")([(self.length + 1)], __NULL_OBJECT__); + __get__(__get__(self, "resize", "missing attribute `resize` - line 1500: self.resize( self.length + 1 )"), "__call__")([(self.length + 1)], __NULL_OBJECT__); __get__(__get__(self, "__setitem__"), "__call__")([length, value], {}); } ;__array_append.is_wrapper = true; @@ -3484,12 +3485,12 @@ var __array_extend = function(args, kwargs) { var self = __args__['self']; var lst = __args__['lst']; var value,__iterator__54; - __iterator__54 = __get__(__get__(lst, "__iter__", "no iterator - line 1489: for value in lst:"), "__call__")([], __NULL_OBJECT__); + __iterator__54 = __get__(__get__(lst, "__iter__", "no iterator - line 1503: for value in lst:"), "__call__")([], __NULL_OBJECT__); var __next__54; __next__54 = __get__(__iterator__54, "next"); while (( __iterator__54.index ) < __iterator__54.length) { value = __next__54(); - __get__(__get__(self, "append", "missing attribute `append` - line 1490: self.append( value )"), "__call__")([value], __NULL_OBJECT__); + __get__(__get__(self, "append", "missing attribute `append` - line 1504: self.append( value )"), "__call__")([value], __NULL_OBJECT__); } } ;__array_extend.is_wrapper = true; @@ -3529,7 +3530,7 @@ var __array_to_list = function(args, kwargs) { } __args__ = __getargs__("__array_to_list", __sig__, args, kwargs); var self = __args__['self']; - return __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1500: return self.to_array()"), "__call__")(); + return __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1514: return self.to_array()"), "__call__")(); } ;__array_to_list.is_wrapper = true; __array_attrs.to_list = __array_to_list; @@ -3546,9 +3547,9 @@ var __array_to_ascii = function(args, kwargs) { __args__ = __getargs__("__array_to_ascii", __sig__, args, kwargs); var self = __args__['self']; string = ""; - arr = __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1503: arr = self.to_array()"), "__call__")(); + arr = __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1517: arr = self.to_array()"), "__call__")(); i = 0; - length = __get__(arr, "length", "missing attribute `length` - line 1504: i = 0; length = arr.length"); + length = __get__(arr, "length", "missing attribute `length` - line 1518: i = 0; length = arr.length"); while (( i ) < length) { var num = arr[i]; var char = String.fromCharCode(num); diff --git a/pythonjs/runtime/builtins.py b/pythonjs/runtime/builtins.py index 94b7175..087fb51 100644 --- a/pythonjs/runtime/builtins.py +++ b/pythonjs/runtime/builtins.py @@ -319,6 +319,18 @@ def unpack_mat4(self, arr): return self.matrices with lowlevel: + def __tuple_key__(arr): + return JSON.stringify( arr ) ## this quotes strings, and should be fast + #r = [] + #i = 0 + #while i < arr.length: + # item = arr[i] + # t = typeof(item) + # if t=='string': + # r.append( "'"+item+"'") + # else: + # r.append( item ) + # i += 1 def __getattr__(ob, a ): if ob.__getattr__: @@ -1452,8 +1464,9 @@ def __getitem__(self, key): ''' __dict = self[...] if instanceof(key, Array): - if key.length > 0 and typeof( key[0] ) == 'string': - key = "'" + key.join("'") + "'" + #if key.length > 0 and typeof( key[0] ) == 'string': + # key = "'" + key.join("'") + "'" + key = JSON.stringify( key ) return inline('__dict[key]') elif JS("typeof(key) === 'object' || typeof(key) === 'function'"): # Test undefined because it can be in the dict @@ -1474,8 +1487,9 @@ def __setitem__(self, key, value): ## using an Array as key converts it to a string ## check first item of array, if it is a string, the items must be quoted ## so that numeric and string items are different. - if key.length > 0 and typeof( key[0] ) == 'string': - key = "'" + key.join("'") + "'" + #if key.length > 0 and typeof( key[0] ) == 'string': + # key = "'" + key.join("'") + "'" + key = JSON.stringify( key ) inline( '__dict[key] = value') elif JS("typeof(key) === 'object' || typeof(key) === 'function'"): if JS("key.__uid__ === undefined"): From 7b9341515838ff19e2e812f9dcafc27c166cd43e Mon Sep 17 00:00:00 2001 From: hartsantler Date: Wed, 23 Jul 2014 23:37:25 -0700 Subject: [PATCH 038/100] fixed tuple dict keys that mix numbers and strings in javascript mode. --- README.md | 20 ++----- pythonjs/python_to_pythonjs.py | 4 +- pythonjs/pythonjs.js | 95 +++++++++++++++++++--------------- pythonjs/runtime/builtins.py | 31 +++++------ 4 files changed, 73 insertions(+), 77 deletions(-) diff --git a/README.md b/README.md index d841b1c..e0fd80c 100644 --- a/README.md +++ b/README.md @@ -440,24 +440,12 @@ d = "HI" * 2 ## FAILS 3. The syntax `from mymodule import *` allows you to import another python script from the same folder, but both mymodule and the parent will share the same namespace, mymodule can use global variables defined in the parent. -4. Using tuples as keys in a dict in javascript mode breaks with strings that are numbers +4. Using tuples as keys in a dict is allowed, the tuple may contain other tuples, objects, and a mix of numbers or strings. +Note that tuples in PythonJS are actually JavaScript arrays, so if you modify the contents of the tuple, it would no +longer be the same key in a dict. ``` -pythonjs.configure( javascript=True ) a = (1,2,3) b = ("1","2","3") D = { a: 'hello', b: 'world' } -D[ a ] == 'hello' ## FAILS +D[ a ] == 'hello' ## OK D[ b ] == 'world' ## OK -``` -The example above works in the default Python mode, because when using a tuple as a key, its first item will be checked if it is a string, and if so then generate a key that is -different from a tuple of numeric elements. This logic assumes that all following keys -are also strings, so the following breaks even in the default Python mode, because all -the items in `b` are treated as strings and `a` contains the same values as strings. - -``` -a = ("1", "2", "3") -b = ("1", 2, 3) -D = {a:100, b:200} -D[ a ] == 100 ## FAILS - value is 200 -D[ b ] == 200 ## OK -``` \ No newline at end of file diff --git a/pythonjs/python_to_pythonjs.py b/pythonjs/python_to_pythonjs.py index 619602d..5ac5d3a 100755 --- a/pythonjs/python_to_pythonjs.py +++ b/pythonjs/python_to_pythonjs.py @@ -1633,7 +1633,9 @@ def visit_Subscript(self, node): else: ## ------------------ javascript mode ------------------------ s = self.visit(node.slice) - return '%s[ __ternary_operator__(%s.__uid__, %s) ]' %(name, s, s) + #return '%s[ __ternary_operator__(%s.__uid__, %s) ]' %(name, s, s) + check_array = '__ternary_operator__( instanceof(%s,Array), JSON.stringify(%s), %s )' %(s, s, s) + return '%s[ __ternary_operator__(%s.__uid__, %s) ]' %(name, s, check_array) elif isinstance(node.slice, ast.Slice): return '__get__(%s, "__getslice__")([%s], __NULL_OBJECT__)' % ( diff --git a/pythonjs/pythonjs.js b/pythonjs/pythonjs.js index c7c1c5e..f790a5d 100644 --- a/pythonjs/pythonjs.js +++ b/pythonjs/pythonjs.js @@ -1159,8 +1159,12 @@ var __jsdict = function(items) { for (var __idx16=0; __idx16 < __iter16.length; __idx16++) { var item = __iter16[ __idx16 ]; key = item[0]; - if (__test_if_true__(key.__uid__)) { - key = key.__uid__; + if (__test_if_true__(key instanceof Array)) { + key = JSON.stringify(key); + } else { + if (__test_if_true__(key.__uid__)) { + key = key.__uid__; + } } d[key] = item[1]; } @@ -1170,6 +1174,9 @@ var __jsdict = function(items) { var __jsdict_get = function(ob, key, default_value) { if (__test_if_true__(ob instanceof Object)) { + if (__test_if_true__(key instanceof Array)) { + key = JSON.stringify(key); + } if (__test_if_true__(key in ob)) { return ob[key]; } @@ -1186,6 +1193,9 @@ var __jsdict_get = function(ob, key, default_value) { var __jsdict_set = function(ob, key, value) { if (__test_if_true__(ob instanceof Object)) { + if (__test_if_true__(key instanceof Array)) { + key = JSON.stringify(key); + } ob[key] = value; } else { ob.set(key,value); @@ -1572,8 +1582,8 @@ var issubclass = function(args, kwargs) { } bases = C.__bases__; i = 0; - while (( i ) < __get__(bases, "length", "missing attribute `length` - line 648: while i < bases.length:")) { - if (__test_if_true__(issubclass([((bases instanceof Array) ? bases[i] : __get__(bases, "__getitem__", "line 649: if issubclass( bases[i], B ):")([i], __NULL_OBJECT__)), B], __NULL_OBJECT__))) { + while (( i ) < __get__(bases, "length", "missing attribute `length` - line 657: while i < bases.length:")) { + if (__test_if_true__(issubclass([((bases instanceof Array) ? bases[i] : __get__(bases, "__getitem__", "line 658: if issubclass( bases[i], B ):")([i], __NULL_OBJECT__)), B], __NULL_OBJECT__))) { return true; } i += 1; @@ -2326,7 +2336,7 @@ var sum = function(args, kwargs) { var arr = __args__['arr']; a = 0; var b,__iterator__40; - __iterator__40 = __get__(__get__(arr, "__iter__", "no iterator - line 1057: for b in arr:"), "__call__")([], __NULL_OBJECT__); + __iterator__40 = __get__(__get__(arr, "__iter__", "no iterator - line 1066: for b in arr:"), "__call__")([], __NULL_OBJECT__); var __next__40; __next__40 = __get__(__iterator__40, "next"); while (( __iterator__40.index ) < __iterator__40.length) { @@ -2384,7 +2394,7 @@ var next = function(args, kwargs) { } __args__ = __getargs__("next", __sig__, args, kwargs); var obj = __args__['obj']; - return __get__(__get__(obj, "next", "missing attribute `next` - line 1075: return obj.next()"), "__call__")(); + return __get__(__get__(obj, "next", "missing attribute `next` - line 1084: return obj.next()"), "__call__")(); } ;next.is_wrapper = true; var map = function(args, kwargs) { @@ -2402,7 +2412,7 @@ var map = function(args, kwargs) { var objs = __args__['objs']; arr = []; var ob,__iterator__41; - __iterator__41 = __get__(__get__(objs, "__iter__", "no iterator - line 1078: for ob in objs:"), "__call__")([], __NULL_OBJECT__); + __iterator__41 = __get__(__get__(objs, "__iter__", "no iterator - line 1087: for ob in objs:"), "__call__")([], __NULL_OBJECT__); var __next__41; __next__41 = __get__(__iterator__41, "next"); while (( __iterator__41.index ) < __iterator__41.length) { @@ -2428,7 +2438,7 @@ var filter = function(args, kwargs) { var objs = __args__['objs']; arr = []; var ob,__iterator__42; - __iterator__42 = __get__(__get__(objs, "__iter__", "no iterator - line 1085: for ob in objs:"), "__call__")([], __NULL_OBJECT__); + __iterator__42 = __get__(__get__(objs, "__iter__", "no iterator - line 1094: for ob in objs:"), "__call__")([], __NULL_OBJECT__); var __next__42; __next__42 = __get__(__iterator__42, "next"); while (( __iterator__42.index ) < __iterator__42.length) { @@ -2454,7 +2464,7 @@ var min = function(args, kwargs) { var lst = __args__['lst']; a = null; var value,__iterator__43; - __iterator__43 = __get__(__get__(lst, "__iter__", "no iterator - line 1092: for value in lst:"), "__call__")([], __NULL_OBJECT__); + __iterator__43 = __get__(__get__(lst, "__iter__", "no iterator - line 1101: for value in lst:"), "__call__")([], __NULL_OBJECT__); var __next__43; __next__43 = __get__(__iterator__43, "next"); while (( __iterator__43.index ) < __iterator__43.length) { @@ -2484,7 +2494,7 @@ var max = function(args, kwargs) { var lst = __args__['lst']; a = null; var value,__iterator__44; - __iterator__44 = __get__(__get__(lst, "__iter__", "no iterator - line 1098: for value in lst:"), "__call__")([], __NULL_OBJECT__); + __iterator__44 = __get__(__get__(lst, "__iter__", "no iterator - line 1107: for value in lst:"), "__call__")([], __NULL_OBJECT__); var __next__44; __next__44 = __get__(__iterator__44, "next"); while (( __iterator__44.index ) < __iterator__44.length) { @@ -2594,7 +2604,7 @@ var __Iterator___init__ = function(args, kwargs) { self.obj = obj; self.index = index; self.length = len([obj], __NULL_OBJECT__); - self.obj_get = __get__(obj, "get", "missing attribute `get` - line 1126: self.obj_get = obj.get ## cache this for speed"); + self.obj_get = __get__(obj, "get", "missing attribute `get` - line 1135: self.obj_get = obj.get ## cache this for speed"); } ;__Iterator___init__.is_wrapper = true; __Iterator_attrs.__init__ = __Iterator___init__; @@ -2701,27 +2711,27 @@ var __dict___init__ = function(args, kwargs) { ob = js_object; if (__test_if_true__(ob instanceof Array)) { var o,__iterator__45; - __iterator__45 = __get__(__get__(ob, "__iter__", "no iterator - line 1169: for o in ob:"), "__call__")([], __NULL_OBJECT__); + __iterator__45 = __get__(__get__(ob, "__iter__", "no iterator - line 1178: for o in ob:"), "__call__")([], __NULL_OBJECT__); var __next__45; __next__45 = __get__(__iterator__45, "next"); while (( __iterator__45.index ) < __iterator__45.length) { o = __next__45(); if (__test_if_true__(o instanceof Array)) { - __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1171: self.__setitem__( o[0], o[1] )"), "__call__")([((o instanceof Array) ? o[0] : __get__(o, "__getitem__", "line 1171: self.__setitem__( o[0], o[1] )")([0], __NULL_OBJECT__)), ((o instanceof Array) ? o[1] : __get__(o, "__getitem__", "line 1171: self.__setitem__( o[0], o[1] )")([1], __NULL_OBJECT__))], __NULL_OBJECT__); + __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1180: self.__setitem__( o[0], o[1] )"), "__call__")([((o instanceof Array) ? o[0] : __get__(o, "__getitem__", "line 1180: self.__setitem__( o[0], o[1] )")([0], __NULL_OBJECT__)), ((o instanceof Array) ? o[1] : __get__(o, "__getitem__", "line 1180: self.__setitem__( o[0], o[1] )")([1], __NULL_OBJECT__))], __NULL_OBJECT__); } else { - __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1173: self.__setitem__( o['key'], o['value'] )"), "__call__")([((o instanceof Array) ? o["key"] : __get__(o, "__getitem__", "line 1173: self.__setitem__( o['key'], o['value'] )")(["key"], __NULL_OBJECT__)), ((o instanceof Array) ? o["value"] : __get__(o, "__getitem__", "line 1173: self.__setitem__( o['key'], o['value'] )")(["value"], __NULL_OBJECT__))], __NULL_OBJECT__); + __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1182: self.__setitem__( o['key'], o['value'] )"), "__call__")([((o instanceof Array) ? o["key"] : __get__(o, "__getitem__", "line 1182: self.__setitem__( o['key'], o['value'] )")(["key"], __NULL_OBJECT__)), ((o instanceof Array) ? o["value"] : __get__(o, "__getitem__", "line 1182: self.__setitem__( o['key'], o['value'] )")(["value"], __NULL_OBJECT__))], __NULL_OBJECT__); } } } else { if (__test_if_true__(isinstance([ob, dict], __NULL_OBJECT__))) { var key,__iterator__46; - __iterator__46 = __get__(__get__(__jsdict_keys(ob), "__iter__", "no iterator - line 1175: for key in ob.keys():"), "__call__")([], __NULL_OBJECT__); + __iterator__46 = __get__(__get__(__jsdict_keys(ob), "__iter__", "no iterator - line 1184: for key in ob.keys():"), "__call__")([], __NULL_OBJECT__); var __next__46; __next__46 = __get__(__iterator__46, "next"); while (( __iterator__46.index ) < __iterator__46.length) { key = __next__46(); - value = ((ob instanceof Array) ? ob[key] : __get__(ob, "__getitem__", "line 1176: value = ob[ key ]")([key], __NULL_OBJECT__)); - __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1177: self.__setitem__( key, value )"), "__call__")([key, value], __NULL_OBJECT__); + value = ((ob instanceof Array) ? ob[key] : __get__(ob, "__getitem__", "line 1185: value = ob[ key ]")([key], __NULL_OBJECT__)); + __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1186: self.__setitem__( key, value )"), "__call__")([key, value], __NULL_OBJECT__); } } else { console.log("ERROR init dict from:", js_object); @@ -2747,15 +2757,15 @@ var __dict_jsify = function(args, kwargs) { var self = __args__['self']; keys = __object_keys__([self["$wrapped"]], __NULL_OBJECT__); var key,__iterator__47; - __iterator__47 = __get__(__get__(keys, "__iter__", "no iterator - line 1184: for key in keys:"), "__call__")([], __NULL_OBJECT__); + __iterator__47 = __get__(__get__(keys, "__iter__", "no iterator - line 1193: for key in keys:"), "__call__")([], __NULL_OBJECT__); var __next__47; __next__47 = __get__(__iterator__47, "next"); while (( __iterator__47.index ) < __iterator__47.length) { key = __next__47(); - value = __get__(self["$wrapped"], "__getitem__", "line 1185: value = self[...][key]")([key], __NULL_OBJECT__); + value = __get__(self["$wrapped"], "__getitem__", "line 1194: value = self[...][key]")([key], __NULL_OBJECT__); if (( typeof(value) ) == "object") { if (__test_if_true__(hasattr([value, "jsify"], __NULL_OBJECT__))) { - __get__(__get__(self["$wrapped"], "__setitem__"), "__call__")([key, __get__(__get__(value, "jsify", "missing attribute `jsify` - line 1188: self[...][key] = value.jsify()"), "__call__")()], {}); + __get__(__get__(self["$wrapped"], "__setitem__"), "__call__")([key, __get__(__get__(value, "jsify", "missing attribute `jsify` - line 1197: self[...][key] = value.jsify()"), "__call__")()], {}); } } else { if (( typeof(value) ) == "function") { @@ -2814,7 +2824,7 @@ var __dict_has_key = function(args, kwargs) { var key = __args__['key']; __dict = self["$wrapped"]; if (__test_if_true__(typeof(key) === 'object' || typeof(key) === 'function')) { - key = __get__(key, "__uid__", "missing attribute `__uid__` - line 1201: key = key.__uid__"); + key = __get__(key, "__uid__", "missing attribute `__uid__` - line 1210: key = key.__uid__"); } if (__test_if_true__(key in __dict)) { return true; @@ -2838,12 +2848,12 @@ var __dict_update = function(args, kwargs) { var self = __args__['self']; var other = __args__['other']; var key,__iterator__48; - __iterator__48 = __get__(__get__(other, "__iter__", "no iterator - line 1207: for key in other:"), "__call__")([], __NULL_OBJECT__); + __iterator__48 = __get__(__get__(other, "__iter__", "no iterator - line 1216: for key in other:"), "__call__")([], __NULL_OBJECT__); var __next__48; __next__48 = __get__(__iterator__48, "next"); while (( __iterator__48.index ) < __iterator__48.length) { key = __next__48(); - __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1208: self.__setitem__( key, other[key] )"), "__call__")([key, ((other instanceof Array) ? other[key] : __get__(other, "__getitem__", "line 1208: self.__setitem__( key, other[key] )")([key], __NULL_OBJECT__))], __NULL_OBJECT__); + __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1217: self.__setitem__( key, other[key] )"), "__call__")([key, ((other instanceof Array) ? other[key] : __get__(other, "__getitem__", "line 1217: self.__setitem__( key, other[key] )")([key], __NULL_OBJECT__))], __NULL_OBJECT__); } } ;__dict_update.is_wrapper = true; @@ -2862,12 +2872,12 @@ var __dict_items = function(args, kwargs) { var self = __args__['self']; arr = []; var key,__iterator__49; - __iterator__49 = __get__(__get__(__jsdict_keys(self), "__iter__", "no iterator - line 1211: for key in self.keys():"), "__call__")([], __NULL_OBJECT__); + __iterator__49 = __get__(__get__(__jsdict_keys(self), "__iter__", "no iterator - line 1220: for key in self.keys():"), "__call__")([], __NULL_OBJECT__); var __next__49; __next__49 = __get__(__iterator__49, "next"); while (( __iterator__49.index ) < __iterator__49.length) { key = __next__49(); - __get__(__get__(arr, "append", "missing attribute `append` - line 1212: arr.append( [key, self[key]] )"), "__call__")([[key, __get__(self, "__getitem__")([key], __NULL_OBJECT__)]], __NULL_OBJECT__); + __get__(__get__(arr, "append", "missing attribute `append` - line 1221: arr.append( [key, self[key]] )"), "__call__")([[key, __get__(self, "__getitem__")([key], __NULL_OBJECT__)]], __NULL_OBJECT__); } return arr; } @@ -2910,7 +2920,7 @@ var __dict_set = function(args, kwargs) { var self = __args__['self']; var key = __args__['key']; var value = __args__['value']; - __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1220: self.__setitem__(key, value)"), "__call__")([key, value], __NULL_OBJECT__); + __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1229: self.__setitem__(key, value)"), "__call__")([key, value], __NULL_OBJECT__); } ;__dict_set.is_wrapper = true; __dict_attrs.set = __dict_set; @@ -2944,11 +2954,10 @@ var __dict___getitem__ = function(args, kwargs) { __args__ = __getargs__("__dict___getitem__", __sig__, args, kwargs); var self = __args__['self']; var key = __args__['key']; - "\n notes:\n . '4' and 4 are the same key\n . it is possible that the translator mistakes a javascript-object for a dict and inlines this function,\n that is why below we return the key in self if __dict is undefined.\n "; + "\n note: `\"4\"` and `4` are the same key in javascript, is there a sane way to workaround this,\n that can remain compatible with external javascript?\n "; __dict = self["$wrapped"]; if (__test_if_true__(key instanceof Array)) { - key = __get__(__get__(JSON, "stringify", "missing attribute `stringify` - line 1235: key = JSON.stringify( key )"), "__call__")([key], __NULL_OBJECT__); - return __dict[key]; + key = __get__(__get__(JSON, "stringify", "missing attribute `stringify` - line 1240: key = JSON.stringify( key )"), "__call__")([key], __NULL_OBJECT__); } else { if (__test_if_true__(typeof(key) === 'object' || typeof(key) === 'function')) { if (__test_if_true__(key.__uid__ && key.__uid__ in __dict)) { @@ -2980,7 +2989,7 @@ var __dict___setitem__ = function(args, kwargs) { var value = __args__['value']; __dict = self["$wrapped"]; if (__test_if_true__(key instanceof Array)) { - key = __get__(__get__(JSON, "stringify", "missing attribute `stringify` - line 1255: key = JSON.stringify( key )"), "__call__")([key], __NULL_OBJECT__); + key = __get__(__get__(JSON, "stringify", "missing attribute `stringify` - line 1253: key = JSON.stringify( key )"), "__call__")([key], __NULL_OBJECT__); __dict[key] = value; } else { if (__test_if_true__(typeof(key) === 'object' || typeof(key) === 'function')) { @@ -3214,7 +3223,7 @@ var __array___init__ = function(args, kwargs) { var initializer = __args__['initializer']; var little_endian = __args__['little_endian']; self.typecode = typecode; - self.itemsize = __get__(__get__(self, "typecodes", "missing attribute `typecodes` - line 1401: self.itemsize = self.typecodes[ typecode ]"), "__getitem__", "line 1401: self.itemsize = self.typecodes[ typecode ]")([typecode], __NULL_OBJECT__); + self.itemsize = __get__(__get__(self, "typecodes", "missing attribute `typecodes` - line 1398: self.itemsize = self.typecodes[ typecode ]"), "__getitem__", "line 1398: self.itemsize = self.typecodes[ typecode ]")([typecode], __NULL_OBJECT__); self.little_endian = little_endian; if (__test_if_true__(initializer)) { self.length = len([initializer], __NULL_OBJECT__); @@ -3238,7 +3247,7 @@ var __array___init__ = function(args, kwargs) { buff = new ArrayBuffer(size); self.dataview = new DataView(buff); self.buffer = buff; - __get__(__get__(self, "fromlist", "missing attribute `fromlist` - line 1422: self.fromlist( initializer )"), "__call__")([initializer], __NULL_OBJECT__); + __get__(__get__(self, "fromlist", "missing attribute `fromlist` - line 1419: self.fromlist( initializer )"), "__call__")([initializer], __NULL_OBJECT__); } ;__array___init__.is_wrapper = true; __array_attrs.__init__ = __array___init__; @@ -3271,7 +3280,7 @@ var __array___contains__ = function(args, kwargs) { __args__ = __getargs__("__array___contains__", __sig__, args, kwargs); var self = __args__['self']; var value = __args__['value']; - arr = __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1428: arr = self.to_array()"), "__call__")(); + arr = __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1425: arr = self.to_array()"), "__call__")(); if (( arr.indexOf(value) ) == -1) { return false; } else { @@ -3296,7 +3305,7 @@ var __array___getitem__ = function(args, kwargs) { step = self.itemsize; offset = (step * index); dataview = self.dataview; - func_name = ("get" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1436: func_name = 'get'+self.typecode_names[ self.typecode ]"), "__getitem__", "line 1436: func_name = 'get'+self.typecode_names[ self.typecode ]")([self.typecode], __NULL_OBJECT__)); + func_name = ("get" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1433: func_name = 'get'+self.typecode_names[ self.typecode ]"), "__getitem__", "line 1433: func_name = 'get'+self.typecode_names[ self.typecode ]")([self.typecode], __NULL_OBJECT__)); func = dataview[func_name].bind(dataview); if (( offset ) < self.bytes) { value = func(offset); @@ -3334,7 +3343,7 @@ var __array___setitem__ = function(args, kwargs) { } offset = (step * index); dataview = self.dataview; - func_name = ("set" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1452: func_name = 'set'+self.typecode_names[ self.typecode ]"), "__getitem__", "line 1452: func_name = 'set'+self.typecode_names[ self.typecode ]")([self.typecode], __NULL_OBJECT__)); + func_name = ("set" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1449: func_name = 'set'+self.typecode_names[ self.typecode ]"), "__getitem__", "line 1449: func_name = 'set'+self.typecode_names[ self.typecode ]")([self.typecode], __NULL_OBJECT__)); func = dataview[func_name].bind(dataview); if (( offset ) < self.bytes) { if (( self.typecode ) == "float8") { @@ -3402,13 +3411,13 @@ var __array_fromlist = function(args, kwargs) { typecode = self.typecode; size = (length * step); dataview = self.dataview; - func_name = ("set" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1472: func_name = 'set'+self.typecode_names[ typecode ]"), "__getitem__", "line 1472: func_name = 'set'+self.typecode_names[ typecode ]")([typecode], __NULL_OBJECT__)); + func_name = ("set" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1469: func_name = 'set'+self.typecode_names[ typecode ]"), "__getitem__", "line 1469: func_name = 'set'+self.typecode_names[ typecode ]")([typecode], __NULL_OBJECT__)); func = dataview[func_name].bind(dataview); if (( size ) <= self.bytes) { i = 0; offset = 0; while (( i ) < length) { - item = ((lst instanceof Array) ? lst[i] : __get__(lst, "__getitem__", "line 1477: item = lst[i]")([i], __NULL_OBJECT__)); + item = ((lst instanceof Array) ? lst[i] : __get__(lst, "__getitem__", "line 1474: item = lst[i]")([i], __NULL_OBJECT__)); if (( typecode ) == "float8") { item *= self._norm_set; } else { @@ -3466,7 +3475,7 @@ var __array_append = function(args, kwargs) { var self = __args__['self']; var value = __args__['value']; length = self.length; - __get__(__get__(self, "resize", "missing attribute `resize` - line 1500: self.resize( self.length + 1 )"), "__call__")([(self.length + 1)], __NULL_OBJECT__); + __get__(__get__(self, "resize", "missing attribute `resize` - line 1497: self.resize( self.length + 1 )"), "__call__")([(self.length + 1)], __NULL_OBJECT__); __get__(__get__(self, "__setitem__"), "__call__")([length, value], {}); } ;__array_append.is_wrapper = true; @@ -3485,12 +3494,12 @@ var __array_extend = function(args, kwargs) { var self = __args__['self']; var lst = __args__['lst']; var value,__iterator__54; - __iterator__54 = __get__(__get__(lst, "__iter__", "no iterator - line 1503: for value in lst:"), "__call__")([], __NULL_OBJECT__); + __iterator__54 = __get__(__get__(lst, "__iter__", "no iterator - line 1500: for value in lst:"), "__call__")([], __NULL_OBJECT__); var __next__54; __next__54 = __get__(__iterator__54, "next"); while (( __iterator__54.index ) < __iterator__54.length) { value = __next__54(); - __get__(__get__(self, "append", "missing attribute `append` - line 1504: self.append( value )"), "__call__")([value], __NULL_OBJECT__); + __get__(__get__(self, "append", "missing attribute `append` - line 1501: self.append( value )"), "__call__")([value], __NULL_OBJECT__); } } ;__array_extend.is_wrapper = true; @@ -3530,7 +3539,7 @@ var __array_to_list = function(args, kwargs) { } __args__ = __getargs__("__array_to_list", __sig__, args, kwargs); var self = __args__['self']; - return __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1514: return self.to_array()"), "__call__")(); + return __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1511: return self.to_array()"), "__call__")(); } ;__array_to_list.is_wrapper = true; __array_attrs.to_list = __array_to_list; @@ -3547,9 +3556,9 @@ var __array_to_ascii = function(args, kwargs) { __args__ = __getargs__("__array_to_ascii", __sig__, args, kwargs); var self = __args__['self']; string = ""; - arr = __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1517: arr = self.to_array()"), "__call__")(); + arr = __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1514: arr = self.to_array()"), "__call__")(); i = 0; - length = __get__(arr, "length", "missing attribute `length` - line 1518: i = 0; length = arr.length"); + length = __get__(arr, "length", "missing attribute `length` - line 1515: i = 0; length = arr.length"); while (( i ) < length) { var num = arr[i]; var char = String.fromCharCode(num); diff --git a/pythonjs/runtime/builtins.py b/pythonjs/runtime/builtins.py index 087fb51..42cadc8 100644 --- a/pythonjs/runtime/builtins.py +++ b/pythonjs/runtime/builtins.py @@ -482,13 +482,17 @@ def __jsdict( items ): d = JS("{}") for item in items: key = item[0] - if key.__uid__: + if instanceof(key, Array): + key = JSON.stringify(key) + elif key.__uid__: key = key.__uid__ d[ key ] = item[1] return d def __jsdict_get(ob, key, default_value): if instanceof(ob, Object): + if instanceof(key, Array): + key = JSON.stringify(key) if JS("key in ob"): return ob[key] return default_value else: ## PythonJS object instance ## @@ -500,6 +504,8 @@ def __jsdict_get(ob, key, default_value): def __jsdict_set(ob, key, value): if instanceof(ob, Object): + if instanceof(key, Array): + key = JSON.stringify(key) ob[ key ] = value else: ## PythonJS object instance ## ## this works because instances from PythonJS are created using Object.create(null) ## @@ -507,6 +513,9 @@ def __jsdict_set(ob, key, value): def __jsdict_keys(ob): if instanceof(ob, Object): + ## in the case of tuple keys this would return stringified JSON instead of the original arrays, + ## TODO, should this loop over the keys and convert the json strings back to objects? + ## but then how would we know if a given string was json... special prefix character? return JS("Object.keys( ob )") else: ## PythonJS object instance ## ## this works because instances from PythonJS are created using Object.create(null) ## @@ -1457,25 +1466,18 @@ def __len__(self): def __getitem__(self, key): ''' - notes: - . '4' and 4 are the same key - . it is possible that the translator mistakes a javascript-object for a dict and inlines this function, - that is why below we return the key in self if __dict is undefined. + note: `"4"` and `4` are the same key in javascript, is there a sane way to workaround this, + that can remain compatible with external javascript? ''' __dict = self[...] if instanceof(key, Array): - #if key.length > 0 and typeof( key[0] ) == 'string': - # key = "'" + key.join("'") + "'" key = JSON.stringify( key ) - return inline('__dict[key]') elif JS("typeof(key) === 'object' || typeof(key) === 'function'"): # Test undefined because it can be in the dict if JS("key.__uid__ && key.__uid__ in __dict"): return JS('__dict[key.__uid__]') raise KeyError(key) - # Tested after in order to not convert functions to strings. - # The slow down is negligible if __dict and JS("key in __dict"): return JS('__dict[key]') @@ -1484,17 +1486,12 @@ def __getitem__(self, key): def __setitem__(self, key, value): __dict = self[...] if instanceof(key, Array): - ## using an Array as key converts it to a string - ## check first item of array, if it is a string, the items must be quoted - ## so that numeric and string items are different. - #if key.length > 0 and typeof( key[0] ) == 'string': - # key = "'" + key.join("'") + "'" + ## JSON.stringify will properly quote string elements ## key = JSON.stringify( key ) inline( '__dict[key] = value') elif JS("typeof(key) === 'object' || typeof(key) === 'function'"): if JS("key.__uid__ === undefined"): - # "" is needed so that integers can also be - # used as keys + # "" is needed so that integers can also be used as keys # JS(u"key.__uid__ = '' + _PythonJS_UID++") JS('__dict[key.__uid__] = value') else: From e315fa514dbd0d87172b2b91e5a5f007ab3e9043 Mon Sep 17 00:00:00 2001 From: hartsantler Date: Thu, 24 Jul 2014 04:11:37 -0700 Subject: [PATCH 039/100] fixed tuple key in dict with object instances in tuple. --- README.md | 2 + pythonjs/pythonjs.js | 108 +++++++++++++++++++++-------------- pythonjs/runtime/builtins.py | 79 +++++++++++++------------ regtests/dict/tuple_keys.py | 16 +++++- 4 files changed, 123 insertions(+), 82 deletions(-) diff --git a/README.md b/README.md index e0fd80c..01b7e73 100644 --- a/README.md +++ b/README.md @@ -449,3 +449,5 @@ b = ("1","2","3") D = { a: 'hello', b: 'world' } D[ a ] == 'hello' ## OK D[ b ] == 'world' ## OK + +5. AttributeError and KeyError are only raised in default python mode. \ No newline at end of file diff --git a/pythonjs/pythonjs.js b/pythonjs/pythonjs.js index f790a5d..255271e 100644 --- a/pythonjs/pythonjs.js +++ b/pythonjs/pythonjs.js @@ -918,11 +918,6 @@ GLSLJITRuntime.prototype.unpack_mat4 = function(arr) { GLSLJITRuntime.unpack_mat4 = function () { return GLSLJITRuntime.prototype.unpack_mat4.apply(arguments[0], Array.prototype.slice.call(arguments,1)) }; GLSLJITRuntime.prototype.__properties__ = { }; GLSLJITRuntime.prototype.__unbound_methods__ = { }; -var __tuple_key__ = function(arr) { - - return JSON.stringify(arr); -} -;__tuple_key__.is_wrapper = true; var __getattr__ = function(ob, a) { if (ob.__getattr__) { @@ -1582,8 +1577,8 @@ var issubclass = function(args, kwargs) { } bases = C.__bases__; i = 0; - while (( i ) < __get__(bases, "length", "missing attribute `length` - line 657: while i < bases.length:")) { - if (__test_if_true__(issubclass([((bases instanceof Array) ? bases[i] : __get__(bases, "__getitem__", "line 658: if issubclass( bases[i], B ):")([i], __NULL_OBJECT__)), B], __NULL_OBJECT__))) { + while (( i ) < __get__(bases, "length", "missing attribute `length` - line 645: while i < bases.length:")) { + if (__test_if_true__(issubclass([((bases instanceof Array) ? bases[i] : __get__(bases, "__getitem__", "line 646: if issubclass( bases[i], B ):")([i], __NULL_OBJECT__)), B], __NULL_OBJECT__))) { return true; } i += 1; @@ -2336,7 +2331,7 @@ var sum = function(args, kwargs) { var arr = __args__['arr']; a = 0; var b,__iterator__40; - __iterator__40 = __get__(__get__(arr, "__iter__", "no iterator - line 1066: for b in arr:"), "__call__")([], __NULL_OBJECT__); + __iterator__40 = __get__(__get__(arr, "__iter__", "no iterator - line 1054: for b in arr:"), "__call__")([], __NULL_OBJECT__); var __next__40; __next__40 = __get__(__iterator__40, "next"); while (( __iterator__40.index ) < __iterator__40.length) { @@ -2394,7 +2389,7 @@ var next = function(args, kwargs) { } __args__ = __getargs__("next", __sig__, args, kwargs); var obj = __args__['obj']; - return __get__(__get__(obj, "next", "missing attribute `next` - line 1084: return obj.next()"), "__call__")(); + return __get__(__get__(obj, "next", "missing attribute `next` - line 1072: return obj.next()"), "__call__")(); } ;next.is_wrapper = true; var map = function(args, kwargs) { @@ -2412,7 +2407,7 @@ var map = function(args, kwargs) { var objs = __args__['objs']; arr = []; var ob,__iterator__41; - __iterator__41 = __get__(__get__(objs, "__iter__", "no iterator - line 1087: for ob in objs:"), "__call__")([], __NULL_OBJECT__); + __iterator__41 = __get__(__get__(objs, "__iter__", "no iterator - line 1075: for ob in objs:"), "__call__")([], __NULL_OBJECT__); var __next__41; __next__41 = __get__(__iterator__41, "next"); while (( __iterator__41.index ) < __iterator__41.length) { @@ -2438,7 +2433,7 @@ var filter = function(args, kwargs) { var objs = __args__['objs']; arr = []; var ob,__iterator__42; - __iterator__42 = __get__(__get__(objs, "__iter__", "no iterator - line 1094: for ob in objs:"), "__call__")([], __NULL_OBJECT__); + __iterator__42 = __get__(__get__(objs, "__iter__", "no iterator - line 1082: for ob in objs:"), "__call__")([], __NULL_OBJECT__); var __next__42; __next__42 = __get__(__iterator__42, "next"); while (( __iterator__42.index ) < __iterator__42.length) { @@ -2464,7 +2459,7 @@ var min = function(args, kwargs) { var lst = __args__['lst']; a = null; var value,__iterator__43; - __iterator__43 = __get__(__get__(lst, "__iter__", "no iterator - line 1101: for value in lst:"), "__call__")([], __NULL_OBJECT__); + __iterator__43 = __get__(__get__(lst, "__iter__", "no iterator - line 1089: for value in lst:"), "__call__")([], __NULL_OBJECT__); var __next__43; __next__43 = __get__(__iterator__43, "next"); while (( __iterator__43.index ) < __iterator__43.length) { @@ -2494,7 +2489,7 @@ var max = function(args, kwargs) { var lst = __args__['lst']; a = null; var value,__iterator__44; - __iterator__44 = __get__(__get__(lst, "__iter__", "no iterator - line 1107: for value in lst:"), "__call__")([], __NULL_OBJECT__); + __iterator__44 = __get__(__get__(lst, "__iter__", "no iterator - line 1095: for value in lst:"), "__call__")([], __NULL_OBJECT__); var __next__44; __next__44 = __get__(__iterator__44, "next"); while (( __iterator__44.index ) < __iterator__44.length) { @@ -2604,7 +2599,7 @@ var __Iterator___init__ = function(args, kwargs) { self.obj = obj; self.index = index; self.length = len([obj], __NULL_OBJECT__); - self.obj_get = __get__(obj, "get", "missing attribute `get` - line 1135: self.obj_get = obj.get ## cache this for speed"); + self.obj_get = __get__(obj, "get", "missing attribute `get` - line 1123: self.obj_get = obj.get ## cache this for speed"); } ;__Iterator___init__.is_wrapper = true; __Iterator_attrs.__init__ = __Iterator___init__; @@ -2685,6 +2680,31 @@ var list = function(args, kwargs) { } } ;list.is_wrapper = true; +var __tuple_key__ = function(arr) { + var i,item,r,t; + r = []; + i = 0; + while (( i ) < arr.length) { + item = arr[i]; + t = typeof(item); + if (( t ) == "string") { + r.append((("'" + item) + "'")); + } else { + if (__test_if_true__(item instanceof Array)) { + r.append(__tuple_key__(item)); + } else { + if (( t ) == "object") { + r.append(item.__uid__); + } else { + r.append(item); + } + } + } + i += 1; + } + return r.join(","); +} + var dict,__dict_attrs,__dict_parents; __dict_attrs = {}; __dict_parents = []; @@ -2711,27 +2731,27 @@ var __dict___init__ = function(args, kwargs) { ob = js_object; if (__test_if_true__(ob instanceof Array)) { var o,__iterator__45; - __iterator__45 = __get__(__get__(ob, "__iter__", "no iterator - line 1178: for o in ob:"), "__call__")([], __NULL_OBJECT__); + __iterator__45 = __get__(__get__(ob, "__iter__", "no iterator - line 1183: for o in ob:"), "__call__")([], __NULL_OBJECT__); var __next__45; __next__45 = __get__(__iterator__45, "next"); while (( __iterator__45.index ) < __iterator__45.length) { o = __next__45(); if (__test_if_true__(o instanceof Array)) { - __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1180: self.__setitem__( o[0], o[1] )"), "__call__")([((o instanceof Array) ? o[0] : __get__(o, "__getitem__", "line 1180: self.__setitem__( o[0], o[1] )")([0], __NULL_OBJECT__)), ((o instanceof Array) ? o[1] : __get__(o, "__getitem__", "line 1180: self.__setitem__( o[0], o[1] )")([1], __NULL_OBJECT__))], __NULL_OBJECT__); + __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1185: self.__setitem__( o[0], o[1] )"), "__call__")([((o instanceof Array) ? o[0] : __get__(o, "__getitem__", "line 1185: self.__setitem__( o[0], o[1] )")([0], __NULL_OBJECT__)), ((o instanceof Array) ? o[1] : __get__(o, "__getitem__", "line 1185: self.__setitem__( o[0], o[1] )")([1], __NULL_OBJECT__))], __NULL_OBJECT__); } else { - __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1182: self.__setitem__( o['key'], o['value'] )"), "__call__")([((o instanceof Array) ? o["key"] : __get__(o, "__getitem__", "line 1182: self.__setitem__( o['key'], o['value'] )")(["key"], __NULL_OBJECT__)), ((o instanceof Array) ? o["value"] : __get__(o, "__getitem__", "line 1182: self.__setitem__( o['key'], o['value'] )")(["value"], __NULL_OBJECT__))], __NULL_OBJECT__); + __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1187: self.__setitem__( o['key'], o['value'] )"), "__call__")([((o instanceof Array) ? o["key"] : __get__(o, "__getitem__", "line 1187: self.__setitem__( o['key'], o['value'] )")(["key"], __NULL_OBJECT__)), ((o instanceof Array) ? o["value"] : __get__(o, "__getitem__", "line 1187: self.__setitem__( o['key'], o['value'] )")(["value"], __NULL_OBJECT__))], __NULL_OBJECT__); } } } else { if (__test_if_true__(isinstance([ob, dict], __NULL_OBJECT__))) { var key,__iterator__46; - __iterator__46 = __get__(__get__(__jsdict_keys(ob), "__iter__", "no iterator - line 1184: for key in ob.keys():"), "__call__")([], __NULL_OBJECT__); + __iterator__46 = __get__(__get__(__jsdict_keys(ob), "__iter__", "no iterator - line 1189: for key in ob.keys():"), "__call__")([], __NULL_OBJECT__); var __next__46; __next__46 = __get__(__iterator__46, "next"); while (( __iterator__46.index ) < __iterator__46.length) { key = __next__46(); - value = ((ob instanceof Array) ? ob[key] : __get__(ob, "__getitem__", "line 1185: value = ob[ key ]")([key], __NULL_OBJECT__)); - __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1186: self.__setitem__( key, value )"), "__call__")([key, value], __NULL_OBJECT__); + value = ((ob instanceof Array) ? ob[key] : __get__(ob, "__getitem__", "line 1190: value = ob[ key ]")([key], __NULL_OBJECT__)); + __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1191: self.__setitem__( key, value )"), "__call__")([key, value], __NULL_OBJECT__); } } else { console.log("ERROR init dict from:", js_object); @@ -2757,15 +2777,15 @@ var __dict_jsify = function(args, kwargs) { var self = __args__['self']; keys = __object_keys__([self["$wrapped"]], __NULL_OBJECT__); var key,__iterator__47; - __iterator__47 = __get__(__get__(keys, "__iter__", "no iterator - line 1193: for key in keys:"), "__call__")([], __NULL_OBJECT__); + __iterator__47 = __get__(__get__(keys, "__iter__", "no iterator - line 1198: for key in keys:"), "__call__")([], __NULL_OBJECT__); var __next__47; __next__47 = __get__(__iterator__47, "next"); while (( __iterator__47.index ) < __iterator__47.length) { key = __next__47(); - value = __get__(self["$wrapped"], "__getitem__", "line 1194: value = self[...][key]")([key], __NULL_OBJECT__); + value = __get__(self["$wrapped"], "__getitem__", "line 1199: value = self[...][key]")([key], __NULL_OBJECT__); if (( typeof(value) ) == "object") { if (__test_if_true__(hasattr([value, "jsify"], __NULL_OBJECT__))) { - __get__(__get__(self["$wrapped"], "__setitem__"), "__call__")([key, __get__(__get__(value, "jsify", "missing attribute `jsify` - line 1197: self[...][key] = value.jsify()"), "__call__")()], {}); + __get__(__get__(self["$wrapped"], "__setitem__"), "__call__")([key, __get__(__get__(value, "jsify", "missing attribute `jsify` - line 1202: self[...][key] = value.jsify()"), "__call__")()], {}); } } else { if (( typeof(value) ) == "function") { @@ -2824,7 +2844,7 @@ var __dict_has_key = function(args, kwargs) { var key = __args__['key']; __dict = self["$wrapped"]; if (__test_if_true__(typeof(key) === 'object' || typeof(key) === 'function')) { - key = __get__(key, "__uid__", "missing attribute `__uid__` - line 1210: key = key.__uid__"); + key = __get__(key, "__uid__", "missing attribute `__uid__` - line 1215: key = key.__uid__"); } if (__test_if_true__(key in __dict)) { return true; @@ -2848,12 +2868,12 @@ var __dict_update = function(args, kwargs) { var self = __args__['self']; var other = __args__['other']; var key,__iterator__48; - __iterator__48 = __get__(__get__(other, "__iter__", "no iterator - line 1216: for key in other:"), "__call__")([], __NULL_OBJECT__); + __iterator__48 = __get__(__get__(other, "__iter__", "no iterator - line 1221: for key in other:"), "__call__")([], __NULL_OBJECT__); var __next__48; __next__48 = __get__(__iterator__48, "next"); while (( __iterator__48.index ) < __iterator__48.length) { key = __next__48(); - __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1217: self.__setitem__( key, other[key] )"), "__call__")([key, ((other instanceof Array) ? other[key] : __get__(other, "__getitem__", "line 1217: self.__setitem__( key, other[key] )")([key], __NULL_OBJECT__))], __NULL_OBJECT__); + __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1222: self.__setitem__( key, other[key] )"), "__call__")([key, ((other instanceof Array) ? other[key] : __get__(other, "__getitem__", "line 1222: self.__setitem__( key, other[key] )")([key], __NULL_OBJECT__))], __NULL_OBJECT__); } } ;__dict_update.is_wrapper = true; @@ -2872,12 +2892,12 @@ var __dict_items = function(args, kwargs) { var self = __args__['self']; arr = []; var key,__iterator__49; - __iterator__49 = __get__(__get__(__jsdict_keys(self), "__iter__", "no iterator - line 1220: for key in self.keys():"), "__call__")([], __NULL_OBJECT__); + __iterator__49 = __get__(__get__(__jsdict_keys(self), "__iter__", "no iterator - line 1225: for key in self.keys():"), "__call__")([], __NULL_OBJECT__); var __next__49; __next__49 = __get__(__iterator__49, "next"); while (( __iterator__49.index ) < __iterator__49.length) { key = __next__49(); - __get__(__get__(arr, "append", "missing attribute `append` - line 1221: arr.append( [key, self[key]] )"), "__call__")([[key, __get__(self, "__getitem__")([key], __NULL_OBJECT__)]], __NULL_OBJECT__); + __get__(__get__(arr, "append", "missing attribute `append` - line 1226: arr.append( [key, self[key]] )"), "__call__")([[key, __get__(self, "__getitem__")([key], __NULL_OBJECT__)]], __NULL_OBJECT__); } return arr; } @@ -2920,7 +2940,7 @@ var __dict_set = function(args, kwargs) { var self = __args__['self']; var key = __args__['key']; var value = __args__['value']; - __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1229: self.__setitem__(key, value)"), "__call__")([key, value], __NULL_OBJECT__); + __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1234: self.__setitem__(key, value)"), "__call__")([key, value], __NULL_OBJECT__); } ;__dict_set.is_wrapper = true; __dict_attrs.set = __dict_set; @@ -2957,7 +2977,7 @@ var __dict___getitem__ = function(args, kwargs) { "\n note: `\"4\"` and `4` are the same key in javascript, is there a sane way to workaround this,\n that can remain compatible with external javascript?\n "; __dict = self["$wrapped"]; if (__test_if_true__(key instanceof Array)) { - key = __get__(__get__(JSON, "stringify", "missing attribute `stringify` - line 1240: key = JSON.stringify( key )"), "__call__")([key], __NULL_OBJECT__); + key = __tuple_key__(key); } else { if (__test_if_true__(typeof(key) === 'object' || typeof(key) === 'function')) { if (__test_if_true__(key.__uid__ && key.__uid__ in __dict)) { @@ -2989,7 +3009,7 @@ var __dict___setitem__ = function(args, kwargs) { var value = __args__['value']; __dict = self["$wrapped"]; if (__test_if_true__(key instanceof Array)) { - key = __get__(__get__(JSON, "stringify", "missing attribute `stringify` - line 1253: key = JSON.stringify( key )"), "__call__")([key], __NULL_OBJECT__); + key = __tuple_key__(key); __dict[key] = value; } else { if (__test_if_true__(typeof(key) === 'object' || typeof(key) === 'function')) { @@ -3223,7 +3243,7 @@ var __array___init__ = function(args, kwargs) { var initializer = __args__['initializer']; var little_endian = __args__['little_endian']; self.typecode = typecode; - self.itemsize = __get__(__get__(self, "typecodes", "missing attribute `typecodes` - line 1398: self.itemsize = self.typecodes[ typecode ]"), "__getitem__", "line 1398: self.itemsize = self.typecodes[ typecode ]")([typecode], __NULL_OBJECT__); + self.itemsize = __get__(__get__(self, "typecodes", "missing attribute `typecodes` - line 1406: self.itemsize = self.typecodes[ typecode ]"), "__getitem__", "line 1406: self.itemsize = self.typecodes[ typecode ]")([typecode], __NULL_OBJECT__); self.little_endian = little_endian; if (__test_if_true__(initializer)) { self.length = len([initializer], __NULL_OBJECT__); @@ -3247,7 +3267,7 @@ var __array___init__ = function(args, kwargs) { buff = new ArrayBuffer(size); self.dataview = new DataView(buff); self.buffer = buff; - __get__(__get__(self, "fromlist", "missing attribute `fromlist` - line 1419: self.fromlist( initializer )"), "__call__")([initializer], __NULL_OBJECT__); + __get__(__get__(self, "fromlist", "missing attribute `fromlist` - line 1427: self.fromlist( initializer )"), "__call__")([initializer], __NULL_OBJECT__); } ;__array___init__.is_wrapper = true; __array_attrs.__init__ = __array___init__; @@ -3280,7 +3300,7 @@ var __array___contains__ = function(args, kwargs) { __args__ = __getargs__("__array___contains__", __sig__, args, kwargs); var self = __args__['self']; var value = __args__['value']; - arr = __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1425: arr = self.to_array()"), "__call__")(); + arr = __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1433: arr = self.to_array()"), "__call__")(); if (( arr.indexOf(value) ) == -1) { return false; } else { @@ -3305,7 +3325,7 @@ var __array___getitem__ = function(args, kwargs) { step = self.itemsize; offset = (step * index); dataview = self.dataview; - func_name = ("get" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1433: func_name = 'get'+self.typecode_names[ self.typecode ]"), "__getitem__", "line 1433: func_name = 'get'+self.typecode_names[ self.typecode ]")([self.typecode], __NULL_OBJECT__)); + func_name = ("get" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1441: func_name = 'get'+self.typecode_names[ self.typecode ]"), "__getitem__", "line 1441: func_name = 'get'+self.typecode_names[ self.typecode ]")([self.typecode], __NULL_OBJECT__)); func = dataview[func_name].bind(dataview); if (( offset ) < self.bytes) { value = func(offset); @@ -3343,7 +3363,7 @@ var __array___setitem__ = function(args, kwargs) { } offset = (step * index); dataview = self.dataview; - func_name = ("set" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1449: func_name = 'set'+self.typecode_names[ self.typecode ]"), "__getitem__", "line 1449: func_name = 'set'+self.typecode_names[ self.typecode ]")([self.typecode], __NULL_OBJECT__)); + func_name = ("set" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1457: func_name = 'set'+self.typecode_names[ self.typecode ]"), "__getitem__", "line 1457: func_name = 'set'+self.typecode_names[ self.typecode ]")([self.typecode], __NULL_OBJECT__)); func = dataview[func_name].bind(dataview); if (( offset ) < self.bytes) { if (( self.typecode ) == "float8") { @@ -3411,13 +3431,13 @@ var __array_fromlist = function(args, kwargs) { typecode = self.typecode; size = (length * step); dataview = self.dataview; - func_name = ("set" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1469: func_name = 'set'+self.typecode_names[ typecode ]"), "__getitem__", "line 1469: func_name = 'set'+self.typecode_names[ typecode ]")([typecode], __NULL_OBJECT__)); + func_name = ("set" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1477: func_name = 'set'+self.typecode_names[ typecode ]"), "__getitem__", "line 1477: func_name = 'set'+self.typecode_names[ typecode ]")([typecode], __NULL_OBJECT__)); func = dataview[func_name].bind(dataview); if (( size ) <= self.bytes) { i = 0; offset = 0; while (( i ) < length) { - item = ((lst instanceof Array) ? lst[i] : __get__(lst, "__getitem__", "line 1474: item = lst[i]")([i], __NULL_OBJECT__)); + item = ((lst instanceof Array) ? lst[i] : __get__(lst, "__getitem__", "line 1482: item = lst[i]")([i], __NULL_OBJECT__)); if (( typecode ) == "float8") { item *= self._norm_set; } else { @@ -3475,7 +3495,7 @@ var __array_append = function(args, kwargs) { var self = __args__['self']; var value = __args__['value']; length = self.length; - __get__(__get__(self, "resize", "missing attribute `resize` - line 1497: self.resize( self.length + 1 )"), "__call__")([(self.length + 1)], __NULL_OBJECT__); + __get__(__get__(self, "resize", "missing attribute `resize` - line 1505: self.resize( self.length + 1 )"), "__call__")([(self.length + 1)], __NULL_OBJECT__); __get__(__get__(self, "__setitem__"), "__call__")([length, value], {}); } ;__array_append.is_wrapper = true; @@ -3494,12 +3514,12 @@ var __array_extend = function(args, kwargs) { var self = __args__['self']; var lst = __args__['lst']; var value,__iterator__54; - __iterator__54 = __get__(__get__(lst, "__iter__", "no iterator - line 1500: for value in lst:"), "__call__")([], __NULL_OBJECT__); + __iterator__54 = __get__(__get__(lst, "__iter__", "no iterator - line 1508: for value in lst:"), "__call__")([], __NULL_OBJECT__); var __next__54; __next__54 = __get__(__iterator__54, "next"); while (( __iterator__54.index ) < __iterator__54.length) { value = __next__54(); - __get__(__get__(self, "append", "missing attribute `append` - line 1501: self.append( value )"), "__call__")([value], __NULL_OBJECT__); + __get__(__get__(self, "append", "missing attribute `append` - line 1509: self.append( value )"), "__call__")([value], __NULL_OBJECT__); } } ;__array_extend.is_wrapper = true; @@ -3539,7 +3559,7 @@ var __array_to_list = function(args, kwargs) { } __args__ = __getargs__("__array_to_list", __sig__, args, kwargs); var self = __args__['self']; - return __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1511: return self.to_array()"), "__call__")(); + return __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1519: return self.to_array()"), "__call__")(); } ;__array_to_list.is_wrapper = true; __array_attrs.to_list = __array_to_list; @@ -3556,9 +3576,9 @@ var __array_to_ascii = function(args, kwargs) { __args__ = __getargs__("__array_to_ascii", __sig__, args, kwargs); var self = __args__['self']; string = ""; - arr = __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1514: arr = self.to_array()"), "__call__")(); + arr = __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1522: arr = self.to_array()"), "__call__")(); i = 0; - length = __get__(arr, "length", "missing attribute `length` - line 1515: i = 0; length = arr.length"); + length = __get__(arr, "length", "missing attribute `length` - line 1523: i = 0; length = arr.length"); while (( i ) < length) { var num = arr[i]; var char = String.fromCharCode(num); diff --git a/pythonjs/runtime/builtins.py b/pythonjs/runtime/builtins.py index 42cadc8..5b1e53e 100644 --- a/pythonjs/runtime/builtins.py +++ b/pythonjs/runtime/builtins.py @@ -319,18 +319,6 @@ def unpack_mat4(self, arr): return self.matrices with lowlevel: - def __tuple_key__(arr): - return JSON.stringify( arr ) ## this quotes strings, and should be fast - #r = [] - #i = 0 - #while i < arr.length: - # item = arr[i] - # t = typeof(item) - # if t=='string': - # r.append( "'"+item+"'") - # else: - # r.append( item ) - # i += 1 def __getattr__(ob, a ): if ob.__getattr__: @@ -1382,7 +1370,23 @@ def list(a): raise TypeError - +with javascript: + def __tuple_key__(arr): + r = [] + i = 0 + while i < arr.length: + item = arr[i] + t = typeof(item) + if t=='string': + r.append( "'"+item+"'") + elif instanceof(item, Array): + r.append( __tuple_key__(item) ) + elif t=='object': + r.append( item.__uid__ ) + else: + r.append( item ) + i += 1 + return r.join(',') class dict: # http://stackoverflow.com/questions/10892322/javascript-hashtable-use-object-key @@ -1469,33 +1473,36 @@ def __getitem__(self, key): note: `"4"` and `4` are the same key in javascript, is there a sane way to workaround this, that can remain compatible with external javascript? ''' - __dict = self[...] - if instanceof(key, Array): - key = JSON.stringify( key ) - elif JS("typeof(key) === 'object' || typeof(key) === 'function'"): - # Test undefined because it can be in the dict - if JS("key.__uid__ && key.__uid__ in __dict"): - return JS('__dict[key.__uid__]') - raise KeyError(key) + with javascript: + __dict = self[...] + if instanceof(key, Array): + #key = JSON.stringify( key ) ## fails on objects with circular references ## + key = __tuple_key__(key) + elif JS("typeof(key) === 'object' || typeof(key) === 'function'"): + # Test undefined because it can be in the dict + if JS("key.__uid__ && key.__uid__ in __dict"): + return JS('__dict[key.__uid__]') + raise KeyError(key) - if __dict and JS("key in __dict"): - return JS('__dict[key]') + if __dict and JS("key in __dict"): + return JS('__dict[key]') - raise KeyError(key) + raise KeyError(key) def __setitem__(self, key, value): - __dict = self[...] - if instanceof(key, Array): - ## JSON.stringify will properly quote string elements ## - key = JSON.stringify( key ) - inline( '__dict[key] = value') - elif JS("typeof(key) === 'object' || typeof(key) === 'function'"): - if JS("key.__uid__ === undefined"): - # "" is needed so that integers can also be used as keys # - JS(u"key.__uid__ = '' + _PythonJS_UID++") - JS('__dict[key.__uid__] = value') - else: - JS('__dict[key] = value') + with javascript: + __dict = self[...] + if instanceof(key, Array): + #key = JSON.stringify( key ) ## fails on objects with circular references ## + key = __tuple_key__(key) + inline( '__dict[key] = value') + elif JS("typeof(key) === 'object' || typeof(key) === 'function'"): + if JS("key.__uid__ === undefined"): + # "" is needed so that integers can also be used as keys # + JS(u"key.__uid__ = '' + _PythonJS_UID++") + JS('__dict[key.__uid__] = value') + else: + JS('__dict[key] = value') def keys(self): with javascript: diff --git a/regtests/dict/tuple_keys.py b/regtests/dict/tuple_keys.py index 02a734a..667a9c8 100644 --- a/regtests/dict/tuple_keys.py +++ b/regtests/dict/tuple_keys.py @@ -1,5 +1,9 @@ """dict tuple key""" +class A: pass +class B: + def __init__(self): + pass def main(): s = ("1", "2", "3") @@ -9,8 +13,16 @@ def main(): d = ('1', 2, 3) D = { d:100, s: 11, a: 22, c:44 } - TestError( D[ d ] == 100) ## this fails in both python and javascript mode - TestError( D[ s ] == 11) ## this fails in javascript mode + TestError( D[ d ] == 100) + TestError( D[ s ] == 11) TestError( D[ a ] == 22) TestError( D[ b ] == 22) TestError( D[ c ] == 44) + + aa = A() + bb = B() + ab = ( A(), B() ) + D2 = { aa: 'hello', bb: 'world', ab:'XXX' } + TestError( D2[aa]=='hello' ) + TestError( D2[bb]=='world' ) + TestError( D2[ab]=='XXX') From 3432a53ec93ae133ce18c6d8723e99ae86aa96ea Mon Sep 17 00:00:00 2001 From: hartsantler Date: Thu, 24 Jul 2014 21:03:36 -0700 Subject: [PATCH 040/100] KeyError is raised when value is `undefined` on a raw javascript object, and in javascript mode when inside a try/except KeyError block. --- pythonjs/python_to_pythonjs.py | 44 ++++++++++++++++++++++-------- pythonjs/pythonjs.js | 5 +++- pythonjs/runtime/pythonpythonjs.py | 9 +++++- regtests/exceptions/KeyError.py | 11 ++++++++ 4 files changed, 56 insertions(+), 13 deletions(-) create mode 100644 regtests/exceptions/KeyError.py diff --git a/pythonjs/python_to_pythonjs.py b/pythonjs/python_to_pythonjs.py index 5ac5d3a..9f02cdc 100755 --- a/pythonjs/python_to_pythonjs.py +++ b/pythonjs/python_to_pythonjs.py @@ -165,6 +165,8 @@ def __init__(self, source=None, module=None, module_path=None, dart=False, coffe self.setup_inliner( writer ) + self._in_catch_exception = False + self._line = None self._line_number = 0 self._stack = [] ## current path to the root @@ -194,8 +196,11 @@ def __init__(self, source=None, module=None, module_path=None, dart=False, coffe self._class_attributes = dict() self._catch_attributes = None self._typedef_vars = dict() + #self._names = set() ## not used? + ## inferred class instances, TODO regtests to confirm that this never breaks ## self._instances = dict() ## instance name : class name + self._decorator_properties = dict() self._decorator_class_props = dict() self._function_return_types = dict() @@ -1183,13 +1188,21 @@ def visit_If(self, node): writer.pull() def visit_TryExcept(self, node): + if len(node.handlers)==0: + raise SyntaxError(self.format_error('no except handlers')) + + ## by default in js-mode some expections will not be raised, + ## this allows those cases to throw proper errors. + if node.handlers[0].type: + self._in_catch_exception = self.visit(node.handlers[0].type) + else: + self._in_catch_exception = None + writer.write('try:') writer.push() map(self.visit, node.body) writer.pull() map(self.visit, node.handlers) - if len(node.handlers)==0: - raise SyntaxError(self.format_error('no except handlers')) def visit_Raise(self, node): #if self._with_js or self._with_dart: @@ -1625,17 +1638,26 @@ def visit_Subscript(self, node): return '%s[ %s ]' %(name, self.visit(node.slice)) - elif isinstance(node.slice, ast.Index) and isinstance(node.slice.value, ast.BinOp): - return '%s[ %s ]' %(name, self.visit(node.slice)) + else: ## ------------------ javascript mode ------------------------ + if self._in_catch_exception == 'KeyError': + value = self.visit(node.value) + slice = self.visit(node.slice) + return '__get__(%s, "__getitem__")([%s], __NULL_OBJECT__)' % (value, slice) + + elif isinstance(node.slice, ast.Index) and isinstance(node.slice.value, ast.BinOp): + ## TODO keep this optimization? in js mode `a[x+y]` is assumed to a direct key, + ## it would be safer to check if one of the operands is a number literal, + ## in that case it is safe to assume that this is a direct key. + return '%s[ %s ]' %(name, self.visit(node.slice)) - elif self._with_direct_keys: - return '%s[ %s ]' %(name, self.visit(node.slice)) + elif self._with_direct_keys: + return '%s[ %s ]' %(name, self.visit(node.slice)) - else: ## ------------------ javascript mode ------------------------ - s = self.visit(node.slice) - #return '%s[ __ternary_operator__(%s.__uid__, %s) ]' %(name, s, s) - check_array = '__ternary_operator__( instanceof(%s,Array), JSON.stringify(%s), %s )' %(s, s, s) - return '%s[ __ternary_operator__(%s.__uid__, %s) ]' %(name, s, check_array) + else: + s = self.visit(node.slice) + #return '%s[ __ternary_operator__(%s.__uid__, %s) ]' %(name, s, s) + check_array = '__ternary_operator__( instanceof(%s,Array), JSON.stringify(%s), %s )' %(s, s, s) + return '%s[ __ternary_operator__(%s.__uid__, %s) ]' %(name, s, check_array) elif isinstance(node.slice, ast.Slice): return '__get__(%s, "__getslice__")([%s], __NULL_OBJECT__)' % ( diff --git a/pythonjs/pythonjs.js b/pythonjs/pythonjs.js index 255271e..6cb112f 100644 --- a/pythonjs/pythonjs.js +++ b/pythonjs/pythonjs.js @@ -355,7 +355,10 @@ var __get__ = function(object, attribute, error_message) { } if (( attribute ) == "__getitem__") { var wrapper = function(args, kwargs) { - return object[args[0]]; + v = object[args[0]]; + if (( v ) === undefined) { + throw new KeyError(args[0]); + } } wrapper.is_wrapper = true; diff --git a/pythonjs/runtime/pythonpythonjs.py b/pythonjs/runtime/pythonpythonjs.py index 438bbad..70bbf09 100644 --- a/pythonjs/runtime/pythonpythonjs.py +++ b/pythonjs/runtime/pythonpythonjs.py @@ -333,7 +333,14 @@ def method(args,kwargs): ## getting/setting from a normal JavaScript Object ## if attribute == '__getitem__': - def wrapper(args,kwargs): return object[ args[0] ] + ## TODO, should object be checked if it really is an object here? + ## new rule: if value to return is `undefined` throw KeyError, + ## this could be a problem with some external js libraries but should be rare, + ## because most libraries will initalize keys to `null` + def wrapper(args,kwargs): + v = object[ args[0] ] + if v is undefined: + raise KeyError( args[0] ) wrapper.is_wrapper = True return wrapper elif attribute == '__setitem__': diff --git a/regtests/exceptions/KeyError.py b/regtests/exceptions/KeyError.py new file mode 100644 index 0000000..f48ec0d --- /dev/null +++ b/regtests/exceptions/KeyError.py @@ -0,0 +1,11 @@ +"""catch KeyError""" + +def main(): + D = {} + a = False + try: + a = D['XXX'] + except KeyError: + a = True + + TestError( a == True ) From 25096535297321fa200e5142bb389a9a7ea22766 Mon Sep 17 00:00:00 2001 From: hartsantler Date: Thu, 24 Jul 2014 23:40:23 -0700 Subject: [PATCH 041/100] fixed raise AttributeError in javascript mode. updated README. --- README.md | 14 +++++- pythonjs/python_to_pythonjs.py | 11 ++--- pythonjs/pythonjs.js | 84 +++++++++++++++++++--------------- pythonjs/runtime/builtins.py | 8 ++++ 4 files changed, 73 insertions(+), 44 deletions(-) diff --git a/README.md b/README.md index 01b7e73..8b5411d 100644 --- a/README.md +++ b/README.md @@ -450,4 +450,16 @@ D = { a: 'hello', b: 'world' } D[ a ] == 'hello' ## OK D[ b ] == 'world' ## OK -5. AttributeError and KeyError are only raised in default python mode. \ No newline at end of file +5. AttributeError and KeyError are only raised in javascript mode when inside a block that catches those errors. +In the default python mode these errors will always be thrown, and halt the program. +``` +pythonjs.configure(javascript=True) +a = {} + +# this will not throw any error +b = a['xxx'] + +# this will throw KeyError, and when caught `b` is set to "my-default" +b = a['xxx'] except KeyError: 'my-default' + +``` \ No newline at end of file diff --git a/pythonjs/python_to_pythonjs.py b/pythonjs/python_to_pythonjs.py index 9f02cdc..5e61c8c 100755 --- a/pythonjs/python_to_pythonjs.py +++ b/pythonjs/python_to_pythonjs.py @@ -1579,13 +1579,12 @@ def visit_Attribute(self, node): return '%s.%s' %(node_value, node.attr) elif self._with_dart or self._with_ll: return '%s.%s' %(node_value, node.attr) + elif self._with_js: - return '%s.%s' %(node_value, node.attr) - ## TODO pythonjs.configure to allow this - #if self._in_assign_target or not isinstance(node.attr, str): - # return '%s.%s' %(node_value, node.attr) - #else: - # return '__ternary_operator__(%s.%s is not undefined, %s.%s, __getattr__(%s, "%s"))' %(node_value, node.attr, node_value, node.attr, node_value, node.attr) + if self._in_catch_exception == 'AttributeError': + return '__getfast__(%s, "%s")' % (node_value, node.attr) + else: + return '%s.%s' %(node_value, node.attr) elif self._with_lua and self._in_assign_target: ## this is required because lua has no support for inplace assignment ops like "+=" return '%s.%s' %(node_value, node.attr) diff --git a/pythonjs/pythonjs.js b/pythonjs/pythonjs.js index 6cb112f..81d222f 100644 --- a/pythonjs/pythonjs.js +++ b/pythonjs/pythonjs.js @@ -499,6 +499,16 @@ KeyError = function(msg) {this.message = msg || "";}; KeyError.prototype = Obj ValueError = function(msg) {this.message = msg || "";}; ValueError.prototype = Object.create(Error.prototype); ValueError.prototype.name = "ValueError"; AttributeError = function(msg) {this.message = msg || "";}; AttributeError.prototype = Object.create(Error.prototype);AttributeError.prototype.name = "AttributeError"; RuntimeError = function(msg) {this.message = msg || "";}; RuntimeError.prototype = Object.create(Error.prototype);RuntimeError.prototype.name = "RuntimeError"; +var __getfast__ = function(ob, attr) { + var v; + v = ob[attr]; + if (( v ) === undefined) { + throw new AttributeError(attr); + } else { + return v; + } +} +;__getfast__.is_wrapper = true; var __gpu_object = function(cls, struct_name, data_name) { cls.prototype.__struct_name__ = struct_name; @@ -1580,8 +1590,8 @@ var issubclass = function(args, kwargs) { } bases = C.__bases__; i = 0; - while (( i ) < __get__(bases, "length", "missing attribute `length` - line 645: while i < bases.length:")) { - if (__test_if_true__(issubclass([((bases instanceof Array) ? bases[i] : __get__(bases, "__getitem__", "line 646: if issubclass( bases[i], B ):")([i], __NULL_OBJECT__)), B], __NULL_OBJECT__))) { + while (( i ) < __get__(bases, "length", "missing attribute `length` - line 652: while i < bases.length:")) { + if (__test_if_true__(issubclass([((bases instanceof Array) ? bases[i] : __get__(bases, "__getitem__", "line 653: if issubclass( bases[i], B ):")([i], __NULL_OBJECT__)), B], __NULL_OBJECT__))) { return true; } i += 1; @@ -2334,7 +2344,7 @@ var sum = function(args, kwargs) { var arr = __args__['arr']; a = 0; var b,__iterator__40; - __iterator__40 = __get__(__get__(arr, "__iter__", "no iterator - line 1054: for b in arr:"), "__call__")([], __NULL_OBJECT__); + __iterator__40 = __get__(__get__(arr, "__iter__", "no iterator - line 1061: for b in arr:"), "__call__")([], __NULL_OBJECT__); var __next__40; __next__40 = __get__(__iterator__40, "next"); while (( __iterator__40.index ) < __iterator__40.length) { @@ -2392,7 +2402,7 @@ var next = function(args, kwargs) { } __args__ = __getargs__("next", __sig__, args, kwargs); var obj = __args__['obj']; - return __get__(__get__(obj, "next", "missing attribute `next` - line 1072: return obj.next()"), "__call__")(); + return __get__(__get__(obj, "next", "missing attribute `next` - line 1079: return obj.next()"), "__call__")(); } ;next.is_wrapper = true; var map = function(args, kwargs) { @@ -2410,7 +2420,7 @@ var map = function(args, kwargs) { var objs = __args__['objs']; arr = []; var ob,__iterator__41; - __iterator__41 = __get__(__get__(objs, "__iter__", "no iterator - line 1075: for ob in objs:"), "__call__")([], __NULL_OBJECT__); + __iterator__41 = __get__(__get__(objs, "__iter__", "no iterator - line 1082: for ob in objs:"), "__call__")([], __NULL_OBJECT__); var __next__41; __next__41 = __get__(__iterator__41, "next"); while (( __iterator__41.index ) < __iterator__41.length) { @@ -2436,7 +2446,7 @@ var filter = function(args, kwargs) { var objs = __args__['objs']; arr = []; var ob,__iterator__42; - __iterator__42 = __get__(__get__(objs, "__iter__", "no iterator - line 1082: for ob in objs:"), "__call__")([], __NULL_OBJECT__); + __iterator__42 = __get__(__get__(objs, "__iter__", "no iterator - line 1089: for ob in objs:"), "__call__")([], __NULL_OBJECT__); var __next__42; __next__42 = __get__(__iterator__42, "next"); while (( __iterator__42.index ) < __iterator__42.length) { @@ -2462,7 +2472,7 @@ var min = function(args, kwargs) { var lst = __args__['lst']; a = null; var value,__iterator__43; - __iterator__43 = __get__(__get__(lst, "__iter__", "no iterator - line 1089: for value in lst:"), "__call__")([], __NULL_OBJECT__); + __iterator__43 = __get__(__get__(lst, "__iter__", "no iterator - line 1096: for value in lst:"), "__call__")([], __NULL_OBJECT__); var __next__43; __next__43 = __get__(__iterator__43, "next"); while (( __iterator__43.index ) < __iterator__43.length) { @@ -2492,7 +2502,7 @@ var max = function(args, kwargs) { var lst = __args__['lst']; a = null; var value,__iterator__44; - __iterator__44 = __get__(__get__(lst, "__iter__", "no iterator - line 1095: for value in lst:"), "__call__")([], __NULL_OBJECT__); + __iterator__44 = __get__(__get__(lst, "__iter__", "no iterator - line 1102: for value in lst:"), "__call__")([], __NULL_OBJECT__); var __next__44; __next__44 = __get__(__iterator__44, "next"); while (( __iterator__44.index ) < __iterator__44.length) { @@ -2602,7 +2612,7 @@ var __Iterator___init__ = function(args, kwargs) { self.obj = obj; self.index = index; self.length = len([obj], __NULL_OBJECT__); - self.obj_get = __get__(obj, "get", "missing attribute `get` - line 1123: self.obj_get = obj.get ## cache this for speed"); + self.obj_get = __get__(obj, "get", "missing attribute `get` - line 1130: self.obj_get = obj.get ## cache this for speed"); } ;__Iterator___init__.is_wrapper = true; __Iterator_attrs.__init__ = __Iterator___init__; @@ -2734,27 +2744,27 @@ var __dict___init__ = function(args, kwargs) { ob = js_object; if (__test_if_true__(ob instanceof Array)) { var o,__iterator__45; - __iterator__45 = __get__(__get__(ob, "__iter__", "no iterator - line 1183: for o in ob:"), "__call__")([], __NULL_OBJECT__); + __iterator__45 = __get__(__get__(ob, "__iter__", "no iterator - line 1190: for o in ob:"), "__call__")([], __NULL_OBJECT__); var __next__45; __next__45 = __get__(__iterator__45, "next"); while (( __iterator__45.index ) < __iterator__45.length) { o = __next__45(); if (__test_if_true__(o instanceof Array)) { - __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1185: self.__setitem__( o[0], o[1] )"), "__call__")([((o instanceof Array) ? o[0] : __get__(o, "__getitem__", "line 1185: self.__setitem__( o[0], o[1] )")([0], __NULL_OBJECT__)), ((o instanceof Array) ? o[1] : __get__(o, "__getitem__", "line 1185: self.__setitem__( o[0], o[1] )")([1], __NULL_OBJECT__))], __NULL_OBJECT__); + __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1192: self.__setitem__( o[0], o[1] )"), "__call__")([((o instanceof Array) ? o[0] : __get__(o, "__getitem__", "line 1192: self.__setitem__( o[0], o[1] )")([0], __NULL_OBJECT__)), ((o instanceof Array) ? o[1] : __get__(o, "__getitem__", "line 1192: self.__setitem__( o[0], o[1] )")([1], __NULL_OBJECT__))], __NULL_OBJECT__); } else { - __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1187: self.__setitem__( o['key'], o['value'] )"), "__call__")([((o instanceof Array) ? o["key"] : __get__(o, "__getitem__", "line 1187: self.__setitem__( o['key'], o['value'] )")(["key"], __NULL_OBJECT__)), ((o instanceof Array) ? o["value"] : __get__(o, "__getitem__", "line 1187: self.__setitem__( o['key'], o['value'] )")(["value"], __NULL_OBJECT__))], __NULL_OBJECT__); + __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1194: self.__setitem__( o['key'], o['value'] )"), "__call__")([((o instanceof Array) ? o["key"] : __get__(o, "__getitem__", "line 1194: self.__setitem__( o['key'], o['value'] )")(["key"], __NULL_OBJECT__)), ((o instanceof Array) ? o["value"] : __get__(o, "__getitem__", "line 1194: self.__setitem__( o['key'], o['value'] )")(["value"], __NULL_OBJECT__))], __NULL_OBJECT__); } } } else { if (__test_if_true__(isinstance([ob, dict], __NULL_OBJECT__))) { var key,__iterator__46; - __iterator__46 = __get__(__get__(__jsdict_keys(ob), "__iter__", "no iterator - line 1189: for key in ob.keys():"), "__call__")([], __NULL_OBJECT__); + __iterator__46 = __get__(__get__(__jsdict_keys(ob), "__iter__", "no iterator - line 1196: for key in ob.keys():"), "__call__")([], __NULL_OBJECT__); var __next__46; __next__46 = __get__(__iterator__46, "next"); while (( __iterator__46.index ) < __iterator__46.length) { key = __next__46(); - value = ((ob instanceof Array) ? ob[key] : __get__(ob, "__getitem__", "line 1190: value = ob[ key ]")([key], __NULL_OBJECT__)); - __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1191: self.__setitem__( key, value )"), "__call__")([key, value], __NULL_OBJECT__); + value = ((ob instanceof Array) ? ob[key] : __get__(ob, "__getitem__", "line 1197: value = ob[ key ]")([key], __NULL_OBJECT__)); + __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1198: self.__setitem__( key, value )"), "__call__")([key, value], __NULL_OBJECT__); } } else { console.log("ERROR init dict from:", js_object); @@ -2780,15 +2790,15 @@ var __dict_jsify = function(args, kwargs) { var self = __args__['self']; keys = __object_keys__([self["$wrapped"]], __NULL_OBJECT__); var key,__iterator__47; - __iterator__47 = __get__(__get__(keys, "__iter__", "no iterator - line 1198: for key in keys:"), "__call__")([], __NULL_OBJECT__); + __iterator__47 = __get__(__get__(keys, "__iter__", "no iterator - line 1205: for key in keys:"), "__call__")([], __NULL_OBJECT__); var __next__47; __next__47 = __get__(__iterator__47, "next"); while (( __iterator__47.index ) < __iterator__47.length) { key = __next__47(); - value = __get__(self["$wrapped"], "__getitem__", "line 1199: value = self[...][key]")([key], __NULL_OBJECT__); + value = __get__(self["$wrapped"], "__getitem__", "line 1206: value = self[...][key]")([key], __NULL_OBJECT__); if (( typeof(value) ) == "object") { if (__test_if_true__(hasattr([value, "jsify"], __NULL_OBJECT__))) { - __get__(__get__(self["$wrapped"], "__setitem__"), "__call__")([key, __get__(__get__(value, "jsify", "missing attribute `jsify` - line 1202: self[...][key] = value.jsify()"), "__call__")()], {}); + __get__(__get__(self["$wrapped"], "__setitem__"), "__call__")([key, __get__(__get__(value, "jsify", "missing attribute `jsify` - line 1209: self[...][key] = value.jsify()"), "__call__")()], {}); } } else { if (( typeof(value) ) == "function") { @@ -2847,7 +2857,7 @@ var __dict_has_key = function(args, kwargs) { var key = __args__['key']; __dict = self["$wrapped"]; if (__test_if_true__(typeof(key) === 'object' || typeof(key) === 'function')) { - key = __get__(key, "__uid__", "missing attribute `__uid__` - line 1215: key = key.__uid__"); + key = __get__(key, "__uid__", "missing attribute `__uid__` - line 1222: key = key.__uid__"); } if (__test_if_true__(key in __dict)) { return true; @@ -2871,12 +2881,12 @@ var __dict_update = function(args, kwargs) { var self = __args__['self']; var other = __args__['other']; var key,__iterator__48; - __iterator__48 = __get__(__get__(other, "__iter__", "no iterator - line 1221: for key in other:"), "__call__")([], __NULL_OBJECT__); + __iterator__48 = __get__(__get__(other, "__iter__", "no iterator - line 1228: for key in other:"), "__call__")([], __NULL_OBJECT__); var __next__48; __next__48 = __get__(__iterator__48, "next"); while (( __iterator__48.index ) < __iterator__48.length) { key = __next__48(); - __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1222: self.__setitem__( key, other[key] )"), "__call__")([key, ((other instanceof Array) ? other[key] : __get__(other, "__getitem__", "line 1222: self.__setitem__( key, other[key] )")([key], __NULL_OBJECT__))], __NULL_OBJECT__); + __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1229: self.__setitem__( key, other[key] )"), "__call__")([key, ((other instanceof Array) ? other[key] : __get__(other, "__getitem__", "line 1229: self.__setitem__( key, other[key] )")([key], __NULL_OBJECT__))], __NULL_OBJECT__); } } ;__dict_update.is_wrapper = true; @@ -2895,12 +2905,12 @@ var __dict_items = function(args, kwargs) { var self = __args__['self']; arr = []; var key,__iterator__49; - __iterator__49 = __get__(__get__(__jsdict_keys(self), "__iter__", "no iterator - line 1225: for key in self.keys():"), "__call__")([], __NULL_OBJECT__); + __iterator__49 = __get__(__get__(__jsdict_keys(self), "__iter__", "no iterator - line 1232: for key in self.keys():"), "__call__")([], __NULL_OBJECT__); var __next__49; __next__49 = __get__(__iterator__49, "next"); while (( __iterator__49.index ) < __iterator__49.length) { key = __next__49(); - __get__(__get__(arr, "append", "missing attribute `append` - line 1226: arr.append( [key, self[key]] )"), "__call__")([[key, __get__(self, "__getitem__")([key], __NULL_OBJECT__)]], __NULL_OBJECT__); + __get__(__get__(arr, "append", "missing attribute `append` - line 1233: arr.append( [key, self[key]] )"), "__call__")([[key, __get__(self, "__getitem__")([key], __NULL_OBJECT__)]], __NULL_OBJECT__); } return arr; } @@ -2943,7 +2953,7 @@ var __dict_set = function(args, kwargs) { var self = __args__['self']; var key = __args__['key']; var value = __args__['value']; - __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1234: self.__setitem__(key, value)"), "__call__")([key, value], __NULL_OBJECT__); + __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1241: self.__setitem__(key, value)"), "__call__")([key, value], __NULL_OBJECT__); } ;__dict_set.is_wrapper = true; __dict_attrs.set = __dict_set; @@ -3246,7 +3256,7 @@ var __array___init__ = function(args, kwargs) { var initializer = __args__['initializer']; var little_endian = __args__['little_endian']; self.typecode = typecode; - self.itemsize = __get__(__get__(self, "typecodes", "missing attribute `typecodes` - line 1406: self.itemsize = self.typecodes[ typecode ]"), "__getitem__", "line 1406: self.itemsize = self.typecodes[ typecode ]")([typecode], __NULL_OBJECT__); + self.itemsize = __get__(__get__(self, "typecodes", "missing attribute `typecodes` - line 1413: self.itemsize = self.typecodes[ typecode ]"), "__getitem__", "line 1413: self.itemsize = self.typecodes[ typecode ]")([typecode], __NULL_OBJECT__); self.little_endian = little_endian; if (__test_if_true__(initializer)) { self.length = len([initializer], __NULL_OBJECT__); @@ -3270,7 +3280,7 @@ var __array___init__ = function(args, kwargs) { buff = new ArrayBuffer(size); self.dataview = new DataView(buff); self.buffer = buff; - __get__(__get__(self, "fromlist", "missing attribute `fromlist` - line 1427: self.fromlist( initializer )"), "__call__")([initializer], __NULL_OBJECT__); + __get__(__get__(self, "fromlist", "missing attribute `fromlist` - line 1434: self.fromlist( initializer )"), "__call__")([initializer], __NULL_OBJECT__); } ;__array___init__.is_wrapper = true; __array_attrs.__init__ = __array___init__; @@ -3303,7 +3313,7 @@ var __array___contains__ = function(args, kwargs) { __args__ = __getargs__("__array___contains__", __sig__, args, kwargs); var self = __args__['self']; var value = __args__['value']; - arr = __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1433: arr = self.to_array()"), "__call__")(); + arr = __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1440: arr = self.to_array()"), "__call__")(); if (( arr.indexOf(value) ) == -1) { return false; } else { @@ -3328,7 +3338,7 @@ var __array___getitem__ = function(args, kwargs) { step = self.itemsize; offset = (step * index); dataview = self.dataview; - func_name = ("get" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1441: func_name = 'get'+self.typecode_names[ self.typecode ]"), "__getitem__", "line 1441: func_name = 'get'+self.typecode_names[ self.typecode ]")([self.typecode], __NULL_OBJECT__)); + func_name = ("get" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1448: func_name = 'get'+self.typecode_names[ self.typecode ]"), "__getitem__", "line 1448: func_name = 'get'+self.typecode_names[ self.typecode ]")([self.typecode], __NULL_OBJECT__)); func = dataview[func_name].bind(dataview); if (( offset ) < self.bytes) { value = func(offset); @@ -3366,7 +3376,7 @@ var __array___setitem__ = function(args, kwargs) { } offset = (step * index); dataview = self.dataview; - func_name = ("set" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1457: func_name = 'set'+self.typecode_names[ self.typecode ]"), "__getitem__", "line 1457: func_name = 'set'+self.typecode_names[ self.typecode ]")([self.typecode], __NULL_OBJECT__)); + func_name = ("set" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1464: func_name = 'set'+self.typecode_names[ self.typecode ]"), "__getitem__", "line 1464: func_name = 'set'+self.typecode_names[ self.typecode ]")([self.typecode], __NULL_OBJECT__)); func = dataview[func_name].bind(dataview); if (( offset ) < self.bytes) { if (( self.typecode ) == "float8") { @@ -3434,13 +3444,13 @@ var __array_fromlist = function(args, kwargs) { typecode = self.typecode; size = (length * step); dataview = self.dataview; - func_name = ("set" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1477: func_name = 'set'+self.typecode_names[ typecode ]"), "__getitem__", "line 1477: func_name = 'set'+self.typecode_names[ typecode ]")([typecode], __NULL_OBJECT__)); + func_name = ("set" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1484: func_name = 'set'+self.typecode_names[ typecode ]"), "__getitem__", "line 1484: func_name = 'set'+self.typecode_names[ typecode ]")([typecode], __NULL_OBJECT__)); func = dataview[func_name].bind(dataview); if (( size ) <= self.bytes) { i = 0; offset = 0; while (( i ) < length) { - item = ((lst instanceof Array) ? lst[i] : __get__(lst, "__getitem__", "line 1482: item = lst[i]")([i], __NULL_OBJECT__)); + item = ((lst instanceof Array) ? lst[i] : __get__(lst, "__getitem__", "line 1489: item = lst[i]")([i], __NULL_OBJECT__)); if (( typecode ) == "float8") { item *= self._norm_set; } else { @@ -3498,7 +3508,7 @@ var __array_append = function(args, kwargs) { var self = __args__['self']; var value = __args__['value']; length = self.length; - __get__(__get__(self, "resize", "missing attribute `resize` - line 1505: self.resize( self.length + 1 )"), "__call__")([(self.length + 1)], __NULL_OBJECT__); + __get__(__get__(self, "resize", "missing attribute `resize` - line 1512: self.resize( self.length + 1 )"), "__call__")([(self.length + 1)], __NULL_OBJECT__); __get__(__get__(self, "__setitem__"), "__call__")([length, value], {}); } ;__array_append.is_wrapper = true; @@ -3517,12 +3527,12 @@ var __array_extend = function(args, kwargs) { var self = __args__['self']; var lst = __args__['lst']; var value,__iterator__54; - __iterator__54 = __get__(__get__(lst, "__iter__", "no iterator - line 1508: for value in lst:"), "__call__")([], __NULL_OBJECT__); + __iterator__54 = __get__(__get__(lst, "__iter__", "no iterator - line 1515: for value in lst:"), "__call__")([], __NULL_OBJECT__); var __next__54; __next__54 = __get__(__iterator__54, "next"); while (( __iterator__54.index ) < __iterator__54.length) { value = __next__54(); - __get__(__get__(self, "append", "missing attribute `append` - line 1509: self.append( value )"), "__call__")([value], __NULL_OBJECT__); + __get__(__get__(self, "append", "missing attribute `append` - line 1516: self.append( value )"), "__call__")([value], __NULL_OBJECT__); } } ;__array_extend.is_wrapper = true; @@ -3562,7 +3572,7 @@ var __array_to_list = function(args, kwargs) { } __args__ = __getargs__("__array_to_list", __sig__, args, kwargs); var self = __args__['self']; - return __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1519: return self.to_array()"), "__call__")(); + return __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1526: return self.to_array()"), "__call__")(); } ;__array_to_list.is_wrapper = true; __array_attrs.to_list = __array_to_list; @@ -3579,9 +3589,9 @@ var __array_to_ascii = function(args, kwargs) { __args__ = __getargs__("__array_to_ascii", __sig__, args, kwargs); var self = __args__['self']; string = ""; - arr = __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1522: arr = self.to_array()"), "__call__")(); + arr = __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1529: arr = self.to_array()"), "__call__")(); i = 0; - length = __get__(arr, "length", "missing attribute `length` - line 1523: i = 0; length = arr.length"); + length = __get__(arr, "length", "missing attribute `length` - line 1530: i = 0; length = arr.length"); while (( i ) < length) { var num = arr[i]; var char = String.fromCharCode(num); diff --git a/pythonjs/runtime/builtins.py b/pythonjs/runtime/builtins.py index 5b1e53e..f574586 100644 --- a/pythonjs/runtime/builtins.py +++ b/pythonjs/runtime/builtins.py @@ -15,6 +15,14 @@ inline('AttributeError = function(msg) {this.message = msg || "";}; AttributeError.prototype = Object.create(Error.prototype);AttributeError.prototype.name = "AttributeError";') inline('RuntimeError = function(msg) {this.message = msg || "";}; RuntimeError.prototype = Object.create(Error.prototype);RuntimeError.prototype.name = "RuntimeError";') +with lowlevel: + def __getfast__(ob, attr): + v = ob[ attr ] + if v is undefined: + raise AttributeError(attr) + else: + return v + with javascript: def __gpu_object(cls, struct_name, data_name): cls.prototype.__struct_name__ = struct_name From d7c3753f90d73542cb76666aa1f720ac5426fdc3 Mon Sep 17 00:00:00 2001 From: hartsantler Date: Thu, 24 Jul 2014 23:51:39 -0700 Subject: [PATCH 042/100] updated README --- README.md | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 8b5411d..97736c5 100644 --- a/README.md +++ b/README.md @@ -455,11 +455,6 @@ In the default python mode these errors will always be thrown, and halt the prog ``` pythonjs.configure(javascript=True) a = {} - -# this will not throw any error -b = a['xxx'] - -# this will throw KeyError, and when caught `b` is set to "my-default" +b = a['xxx'] # this will not throw any error b = a['xxx'] except KeyError: 'my-default' - -``` \ No newline at end of file +``` From fe3fd33f9c561b0589f569bd0f492f5025542cde Mon Sep 17 00:00:00 2001 From: hartsantler Date: Thu, 24 Jul 2014 23:53:49 -0700 Subject: [PATCH 043/100] fixed README --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 97736c5..77d04b3 100644 --- a/README.md +++ b/README.md @@ -449,12 +449,15 @@ b = ("1","2","3") D = { a: 'hello', b: 'world' } D[ a ] == 'hello' ## OK D[ b ] == 'world' ## OK +``` 5. AttributeError and KeyError are only raised in javascript mode when inside a block that catches those errors. In the default python mode these errors will always be thrown, and halt the program. ``` pythonjs.configure(javascript=True) a = {} -b = a['xxx'] # this will not throw any error +# this will not throw any error +b = a['xxx'] +# this works as expected, "b" will be set to "my-default" b = a['xxx'] except KeyError: 'my-default' ``` From 8f812c5eec0a4618043954ca897e258505437266 Mon Sep 17 00:00:00 2001 From: hartsantler Date: Sat, 26 Jul 2014 16:56:19 -0700 Subject: [PATCH 044/100] fixed dict. --- README.md | 7 ++ pythonjs/python_to_pythonjs.py | 6 +- pythonjs/pythonjs.js | 138 ++++++++++++++++----------------- pythonjs/runtime/builtins.py | 11 +-- 4 files changed, 86 insertions(+), 76 deletions(-) diff --git a/README.md b/README.md index 77d04b3..defe55b 100644 --- a/README.md +++ b/README.md @@ -394,6 +394,13 @@ pythonjs.configure( Gotchas --------- +0. in a dictionary number keys will be converted to strings. +In the example below the key `100` and `"100"` are the same key. +``` +a = {"100": 'X'} +a[ 100 ] = 'Y' +``` + 1. The calling context of `this` must be taken into account when using fast javascript mode, code that comes after: `pythonjs.configure(javascript=True)` or is inside a `with javascript:` block. When in javascript mode, passing a method as a callback, or setting it as an attribute on another object, requires you call `f.bind(self)` to ensure that `self` within the method points to the class instance. This is not required when using classes defined normal mode, because the `this` calling context is automatically managed. Note: you can use the special `->` syntax in place of the attribute operator `.` to call `bind` automatically. diff --git a/pythonjs/python_to_pythonjs.py b/pythonjs/python_to_pythonjs.py index 5e61c8c..198d9c7 100755 --- a/pythonjs/python_to_pythonjs.py +++ b/pythonjs/python_to_pythonjs.py @@ -2373,7 +2373,11 @@ def visit_Call(self, node): a = ( self.visit(node.func),self.visit(node.func), self.visit(node.starargs), ','.join(kwargs) ) return '%s.apply(%s, [].extend(%s).append({%s}) )' %a else: - return '%s({%s})' %( self.visit(node.func), ','.join(kwargs) ) + func_name = self.visit(node.func) + if func_name == 'dict': + return '{%s}' %','.join(kwargs) + else: + return '%s({%s})' %( func_name, ','.join(kwargs) ) else: if node.starargs: diff --git a/pythonjs/pythonjs.js b/pythonjs/pythonjs.js index 81d222f..9cd417e 100644 --- a/pythonjs/pythonjs.js +++ b/pythonjs/pythonjs.js @@ -2743,28 +2743,26 @@ var __dict___init__ = function(args, kwargs) { if (__test_if_true__(js_object)) { ob = js_object; if (__test_if_true__(ob instanceof Array)) { - var o,__iterator__45; - __iterator__45 = __get__(__get__(ob, "__iter__", "no iterator - line 1190: for o in ob:"), "__call__")([], __NULL_OBJECT__); - var __next__45; - __next__45 = __get__(__iterator__45, "next"); - while (( __iterator__45.index ) < __iterator__45.length) { - o = __next__45(); - if (__test_if_true__(o instanceof Array)) { - __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1192: self.__setitem__( o[0], o[1] )"), "__call__")([((o instanceof Array) ? o[0] : __get__(o, "__getitem__", "line 1192: self.__setitem__( o[0], o[1] )")([0], __NULL_OBJECT__)), ((o instanceof Array) ? o[1] : __get__(o, "__getitem__", "line 1192: self.__setitem__( o[0], o[1] )")([1], __NULL_OBJECT__))], __NULL_OBJECT__); + var __iter34 = ob; + if (! (__iter34 instanceof Array || typeof __iter34 == "string" || __is_typed_array(__iter34) || __is_some_array(__iter34) )) { __iter34 = __object_keys__(__iter34) } + for (var __idx34=0; __idx34 < __iter34.length; __idx34++) { + var o = __iter34[ __idx34 ]; + if (o instanceof Array) { + self.__setitem__(o[0], o[1]); } else { - __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1194: self.__setitem__( o['key'], o['value'] )"), "__call__")([((o instanceof Array) ? o["key"] : __get__(o, "__getitem__", "line 1194: self.__setitem__( o['key'], o['value'] )")(["key"], __NULL_OBJECT__)), ((o instanceof Array) ? o["value"] : __get__(o, "__getitem__", "line 1194: self.__setitem__( o['key'], o['value'] )")(["value"], __NULL_OBJECT__))], __NULL_OBJECT__); + self.__setitem__(o["key"], o["value"]); } } } else { if (__test_if_true__(isinstance([ob, dict], __NULL_OBJECT__))) { var key,__iterator__46; - __iterator__46 = __get__(__get__(__jsdict_keys(ob), "__iter__", "no iterator - line 1196: for key in ob.keys():"), "__call__")([], __NULL_OBJECT__); + __iterator__46 = __get__(__get__(__jsdict_keys(ob), "__iter__", "no iterator - line 1197: for key in ob.keys():"), "__call__")([], __NULL_OBJECT__); var __next__46; __next__46 = __get__(__iterator__46, "next"); while (( __iterator__46.index ) < __iterator__46.length) { key = __next__46(); - value = ((ob instanceof Array) ? ob[key] : __get__(ob, "__getitem__", "line 1197: value = ob[ key ]")([key], __NULL_OBJECT__)); - __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1198: self.__setitem__( key, value )"), "__call__")([key, value], __NULL_OBJECT__); + value = ((ob instanceof Array) ? ob[key] : __get__(ob, "__getitem__", "line 1198: value = ob[ key ]")([key], __NULL_OBJECT__)); + __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1199: self.__setitem__( key, value )"), "__call__")([key, value], __NULL_OBJECT__); } } else { console.log("ERROR init dict from:", js_object); @@ -2790,15 +2788,15 @@ var __dict_jsify = function(args, kwargs) { var self = __args__['self']; keys = __object_keys__([self["$wrapped"]], __NULL_OBJECT__); var key,__iterator__47; - __iterator__47 = __get__(__get__(keys, "__iter__", "no iterator - line 1205: for key in keys:"), "__call__")([], __NULL_OBJECT__); + __iterator__47 = __get__(__get__(keys, "__iter__", "no iterator - line 1206: for key in keys:"), "__call__")([], __NULL_OBJECT__); var __next__47; __next__47 = __get__(__iterator__47, "next"); while (( __iterator__47.index ) < __iterator__47.length) { key = __next__47(); - value = __get__(self["$wrapped"], "__getitem__", "line 1206: value = self[...][key]")([key], __NULL_OBJECT__); + value = __get__(self["$wrapped"], "__getitem__", "line 1207: value = self[...][key]")([key], __NULL_OBJECT__); if (( typeof(value) ) == "object") { if (__test_if_true__(hasattr([value, "jsify"], __NULL_OBJECT__))) { - __get__(__get__(self["$wrapped"], "__setitem__"), "__call__")([key, __get__(__get__(value, "jsify", "missing attribute `jsify` - line 1209: self[...][key] = value.jsify()"), "__call__")()], {}); + __get__(__get__(self["$wrapped"], "__setitem__"), "__call__")([key, __get__(__get__(value, "jsify", "missing attribute `jsify` - line 1210: self[...][key] = value.jsify()"), "__call__")()], {}); } } else { if (( typeof(value) ) == "function") { @@ -2857,7 +2855,7 @@ var __dict_has_key = function(args, kwargs) { var key = __args__['key']; __dict = self["$wrapped"]; if (__test_if_true__(typeof(key) === 'object' || typeof(key) === 'function')) { - key = __get__(key, "__uid__", "missing attribute `__uid__` - line 1222: key = key.__uid__"); + key = __get__(key, "__uid__", "missing attribute `__uid__` - line 1223: key = key.__uid__"); } if (__test_if_true__(key in __dict)) { return true; @@ -2881,12 +2879,12 @@ var __dict_update = function(args, kwargs) { var self = __args__['self']; var other = __args__['other']; var key,__iterator__48; - __iterator__48 = __get__(__get__(other, "__iter__", "no iterator - line 1228: for key in other:"), "__call__")([], __NULL_OBJECT__); + __iterator__48 = __get__(__get__(other, "__iter__", "no iterator - line 1229: for key in other:"), "__call__")([], __NULL_OBJECT__); var __next__48; __next__48 = __get__(__iterator__48, "next"); while (( __iterator__48.index ) < __iterator__48.length) { key = __next__48(); - __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1229: self.__setitem__( key, other[key] )"), "__call__")([key, ((other instanceof Array) ? other[key] : __get__(other, "__getitem__", "line 1229: self.__setitem__( key, other[key] )")([key], __NULL_OBJECT__))], __NULL_OBJECT__); + __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1230: self.__setitem__( key, other[key] )"), "__call__")([key, ((other instanceof Array) ? other[key] : __get__(other, "__getitem__", "line 1230: self.__setitem__( key, other[key] )")([key], __NULL_OBJECT__))], __NULL_OBJECT__); } } ;__dict_update.is_wrapper = true; @@ -2905,12 +2903,12 @@ var __dict_items = function(args, kwargs) { var self = __args__['self']; arr = []; var key,__iterator__49; - __iterator__49 = __get__(__get__(__jsdict_keys(self), "__iter__", "no iterator - line 1232: for key in self.keys():"), "__call__")([], __NULL_OBJECT__); + __iterator__49 = __get__(__get__(__jsdict_keys(self), "__iter__", "no iterator - line 1233: for key in self.keys():"), "__call__")([], __NULL_OBJECT__); var __next__49; __next__49 = __get__(__iterator__49, "next"); while (( __iterator__49.index ) < __iterator__49.length) { key = __next__49(); - __get__(__get__(arr, "append", "missing attribute `append` - line 1233: arr.append( [key, self[key]] )"), "__call__")([[key, __get__(self, "__getitem__")([key], __NULL_OBJECT__)]], __NULL_OBJECT__); + __get__(__get__(arr, "append", "missing attribute `append` - line 1234: arr.append( [key, self[key]] )"), "__call__")([[key, __get__(self, "__getitem__")([key], __NULL_OBJECT__)]], __NULL_OBJECT__); } return arr; } @@ -2953,7 +2951,7 @@ var __dict_set = function(args, kwargs) { var self = __args__['self']; var key = __args__['key']; var value = __args__['value']; - __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1241: self.__setitem__(key, value)"), "__call__")([key, value], __NULL_OBJECT__); + __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1242: self.__setitem__(key, value)"), "__call__")([key, value], __NULL_OBJECT__); } ;__dict_set.is_wrapper = true; __dict_attrs.set = __dict_set; @@ -3092,10 +3090,10 @@ var __dict_values = function(args, kwargs) { var self = __args__['self']; keys = Object.keys(self["$wrapped"]); out = []; - var __iter34 = keys; - if (! (__iter34 instanceof Array || typeof __iter34 == "string" || __is_typed_array(__iter34) || __is_some_array(__iter34) )) { __iter34 = __object_keys__(__iter34) } - for (var __idx34=0; __idx34 < __iter34.length; __idx34++) { - var key = __iter34[ __idx34 ]; + var __iter35 = keys; + if (! (__iter35 instanceof Array || typeof __iter35 == "string" || __is_typed_array(__iter35) || __is_some_array(__iter35) )) { __iter35 = __object_keys__(__iter35) } + for (var __idx35=0; __idx35 < __iter35.length; __idx35++) { + var key = __iter35[ __idx35 ]; out.push(self["$wrapped"][key]); } return out; @@ -3179,10 +3177,10 @@ var set = function(args, kwargs) { } fallback = false; if (__test_if_true__(hashtable)) { - var __iter35 = a; - if (! (__iter35 instanceof Array || typeof __iter35 == "string" || __is_typed_array(__iter35) || __is_some_array(__iter35) )) { __iter35 = __object_keys__(__iter35) } - for (var __idx35=0; __idx35 < __iter35.length; __idx35++) { - var b = __iter35[ __idx35 ]; + var __iter36 = a; + if (! (__iter36 instanceof Array || typeof __iter36 == "string" || __is_typed_array(__iter36) || __is_some_array(__iter36) )) { __iter36 = __object_keys__(__iter36) } + for (var __idx36=0; __idx36 < __iter36.length; __idx36++) { + var b = __iter36[ __idx36 ]; if (__test_if_true__(( typeof(b) ) == "number" && ( b ) === ( (b | 0) ))) { key = (b & mask); hashtable[key] = b; @@ -3197,20 +3195,20 @@ var set = function(args, kwargs) { } s = []; if (__test_if_true__(fallback)) { - var __iter36 = a; - if (! (__iter36 instanceof Array || typeof __iter36 == "string" || __is_typed_array(__iter36) || __is_some_array(__iter36) )) { __iter36 = __object_keys__(__iter36) } - for (var __idx36=0; __idx36 < __iter36.length; __idx36++) { - var item = __iter36[ __idx36 ]; + var __iter37 = a; + if (! (__iter37 instanceof Array || typeof __iter37 == "string" || __is_typed_array(__iter37) || __is_some_array(__iter37) )) { __iter37 = __object_keys__(__iter37) } + for (var __idx37=0; __idx37 < __iter37.length; __idx37++) { + var item = __iter37[ __idx37 ]; if (( s.indexOf(item) ) == -1) { s.push(item); } } } else { __sort_method(keys); - var __iter37 = keys; - if (! (__iter37 instanceof Array || typeof __iter37 == "string" || __is_typed_array(__iter37) || __is_some_array(__iter37) )) { __iter37 = __object_keys__(__iter37) } - for (var __idx37=0; __idx37 < __iter37.length; __idx37++) { - var key = __iter37[ __idx37 ]; + var __iter38 = keys; + if (! (__iter38 instanceof Array || typeof __iter38 == "string" || __is_typed_array(__iter38) || __is_some_array(__iter38) )) { __iter38 = __object_keys__(__iter38) } + for (var __idx38=0; __idx38 < __iter38.length; __idx38++) { + var key = __iter38[ __idx38 ]; s.push(hashtable[key]); } } @@ -3256,7 +3254,7 @@ var __array___init__ = function(args, kwargs) { var initializer = __args__['initializer']; var little_endian = __args__['little_endian']; self.typecode = typecode; - self.itemsize = __get__(__get__(self, "typecodes", "missing attribute `typecodes` - line 1413: self.itemsize = self.typecodes[ typecode ]"), "__getitem__", "line 1413: self.itemsize = self.typecodes[ typecode ]")([typecode], __NULL_OBJECT__); + self.itemsize = __get__(__get__(self, "typecodes", "missing attribute `typecodes` - line 1414: self.itemsize = self.typecodes[ typecode ]"), "__getitem__", "line 1414: self.itemsize = self.typecodes[ typecode ]")([typecode], __NULL_OBJECT__); self.little_endian = little_endian; if (__test_if_true__(initializer)) { self.length = len([initializer], __NULL_OBJECT__); @@ -3280,7 +3278,7 @@ var __array___init__ = function(args, kwargs) { buff = new ArrayBuffer(size); self.dataview = new DataView(buff); self.buffer = buff; - __get__(__get__(self, "fromlist", "missing attribute `fromlist` - line 1434: self.fromlist( initializer )"), "__call__")([initializer], __NULL_OBJECT__); + __get__(__get__(self, "fromlist", "missing attribute `fromlist` - line 1435: self.fromlist( initializer )"), "__call__")([initializer], __NULL_OBJECT__); } ;__array___init__.is_wrapper = true; __array_attrs.__init__ = __array___init__; @@ -3313,7 +3311,7 @@ var __array___contains__ = function(args, kwargs) { __args__ = __getargs__("__array___contains__", __sig__, args, kwargs); var self = __args__['self']; var value = __args__['value']; - arr = __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1440: arr = self.to_array()"), "__call__")(); + arr = __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1441: arr = self.to_array()"), "__call__")(); if (( arr.indexOf(value) ) == -1) { return false; } else { @@ -3338,7 +3336,7 @@ var __array___getitem__ = function(args, kwargs) { step = self.itemsize; offset = (step * index); dataview = self.dataview; - func_name = ("get" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1448: func_name = 'get'+self.typecode_names[ self.typecode ]"), "__getitem__", "line 1448: func_name = 'get'+self.typecode_names[ self.typecode ]")([self.typecode], __NULL_OBJECT__)); + func_name = ("get" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1449: func_name = 'get'+self.typecode_names[ self.typecode ]"), "__getitem__", "line 1449: func_name = 'get'+self.typecode_names[ self.typecode ]")([self.typecode], __NULL_OBJECT__)); func = dataview[func_name].bind(dataview); if (( offset ) < self.bytes) { value = func(offset); @@ -3376,7 +3374,7 @@ var __array___setitem__ = function(args, kwargs) { } offset = (step * index); dataview = self.dataview; - func_name = ("set" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1464: func_name = 'set'+self.typecode_names[ self.typecode ]"), "__getitem__", "line 1464: func_name = 'set'+self.typecode_names[ self.typecode ]")([self.typecode], __NULL_OBJECT__)); + func_name = ("set" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1465: func_name = 'set'+self.typecode_names[ self.typecode ]"), "__getitem__", "line 1465: func_name = 'set'+self.typecode_names[ self.typecode ]")([self.typecode], __NULL_OBJECT__)); func = dataview[func_name].bind(dataview); if (( offset ) < self.bytes) { if (( self.typecode ) == "float8") { @@ -3444,13 +3442,13 @@ var __array_fromlist = function(args, kwargs) { typecode = self.typecode; size = (length * step); dataview = self.dataview; - func_name = ("set" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1484: func_name = 'set'+self.typecode_names[ typecode ]"), "__getitem__", "line 1484: func_name = 'set'+self.typecode_names[ typecode ]")([typecode], __NULL_OBJECT__)); + func_name = ("set" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1485: func_name = 'set'+self.typecode_names[ typecode ]"), "__getitem__", "line 1485: func_name = 'set'+self.typecode_names[ typecode ]")([typecode], __NULL_OBJECT__)); func = dataview[func_name].bind(dataview); if (( size ) <= self.bytes) { i = 0; offset = 0; while (( i ) < length) { - item = ((lst instanceof Array) ? lst[i] : __get__(lst, "__getitem__", "line 1489: item = lst[i]")([i], __NULL_OBJECT__)); + item = ((lst instanceof Array) ? lst[i] : __get__(lst, "__getitem__", "line 1490: item = lst[i]")([i], __NULL_OBJECT__)); if (( typecode ) == "float8") { item *= self._norm_set; } else { @@ -3508,7 +3506,7 @@ var __array_append = function(args, kwargs) { var self = __args__['self']; var value = __args__['value']; length = self.length; - __get__(__get__(self, "resize", "missing attribute `resize` - line 1512: self.resize( self.length + 1 )"), "__call__")([(self.length + 1)], __NULL_OBJECT__); + __get__(__get__(self, "resize", "missing attribute `resize` - line 1513: self.resize( self.length + 1 )"), "__call__")([(self.length + 1)], __NULL_OBJECT__); __get__(__get__(self, "__setitem__"), "__call__")([length, value], {}); } ;__array_append.is_wrapper = true; @@ -3527,12 +3525,12 @@ var __array_extend = function(args, kwargs) { var self = __args__['self']; var lst = __args__['lst']; var value,__iterator__54; - __iterator__54 = __get__(__get__(lst, "__iter__", "no iterator - line 1515: for value in lst:"), "__call__")([], __NULL_OBJECT__); + __iterator__54 = __get__(__get__(lst, "__iter__", "no iterator - line 1516: for value in lst:"), "__call__")([], __NULL_OBJECT__); var __next__54; __next__54 = __get__(__iterator__54, "next"); while (( __iterator__54.index ) < __iterator__54.length) { value = __next__54(); - __get__(__get__(self, "append", "missing attribute `append` - line 1516: self.append( value )"), "__call__")([value], __NULL_OBJECT__); + __get__(__get__(self, "append", "missing attribute `append` - line 1517: self.append( value )"), "__call__")([value], __NULL_OBJECT__); } } ;__array_extend.is_wrapper = true; @@ -3572,7 +3570,7 @@ var __array_to_list = function(args, kwargs) { } __args__ = __getargs__("__array_to_list", __sig__, args, kwargs); var self = __args__['self']; - return __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1526: return self.to_array()"), "__call__")(); + return __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1527: return self.to_array()"), "__call__")(); } ;__array_to_list.is_wrapper = true; __array_attrs.to_list = __array_to_list; @@ -3589,9 +3587,9 @@ var __array_to_ascii = function(args, kwargs) { __args__ = __getargs__("__array_to_ascii", __sig__, args, kwargs); var self = __args__['self']; string = ""; - arr = __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1529: arr = self.to_array()"), "__call__")(); + arr = __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1530: arr = self.to_array()"), "__call__")(); i = 0; - length = __get__(arr, "length", "missing attribute `length` - line 1530: i = 0; length = arr.length"); + length = __get__(arr, "length", "missing attribute `length` - line 1531: i = 0; length = arr.length"); while (( i ) < length) { var num = arr[i]; var char = String.fromCharCode(num); @@ -3722,17 +3720,17 @@ json = __jsdict([["loads", (function (s) {return JSON.parse(s);})], ["dumps", (f var __get_other_workers_with_shared_arg = function(worker, ob) { var a,other,args; a = []; - var __iter38 = threading.workers; - if (! (__iter38 instanceof Array || typeof __iter38 == "string" || __is_typed_array(__iter38) || __is_some_array(__iter38) )) { __iter38 = __object_keys__(__iter38) } - for (var __idx38=0; __idx38 < __iter38.length; __idx38++) { - var b = __iter38[ __idx38 ]; + var __iter39 = threading.workers; + if (! (__iter39 instanceof Array || typeof __iter39 == "string" || __is_typed_array(__iter39) || __is_some_array(__iter39) )) { __iter39 = __object_keys__(__iter39) } + for (var __idx39=0; __idx39 < __iter39.length; __idx39++) { + var b = __iter39[ __idx39 ]; other = b["worker"]; args = b["args"]; if (( other ) !== worker) { - var __iter39 = args; - if (! (__iter39 instanceof Array || typeof __iter39 == "string" || __is_typed_array(__iter39) || __is_some_array(__iter39) )) { __iter39 = __object_keys__(__iter39) } - for (var __idx39=0; __idx39 < __iter39.length; __idx39++) { - var arg = __iter39[ __idx39 ]; + var __iter40 = args; + if (! (__iter40 instanceof Array || typeof __iter40 == "string" || __is_typed_array(__iter40) || __is_some_array(__iter40) )) { __iter40 = __object_keys__(__iter40) } + for (var __idx40=0; __idx40 < __iter40.length; __idx40++) { + var arg = __iter40[ __idx40 ]; if (( arg ) === ob) { if (! (__contains__(a, other))) { a.append(other); @@ -3764,10 +3762,10 @@ var __start_new_thread = function(f, args) { if (( event.data.type ) == "append") { a = args[event.data.argindex]; a.push(event.data.value); - var __iter40 = __get_other_workers_with_shared_arg(worker, a); - if (! (__iter40 instanceof Array || typeof __iter40 == "string" || __is_typed_array(__iter40) || __is_some_array(__iter40) )) { __iter40 = __object_keys__(__iter40) } - for (var __idx40=0; __idx40 < __iter40.length; __idx40++) { - var other = __iter40[ __idx40 ]; + var __iter41 = __get_other_workers_with_shared_arg(worker, a); + if (! (__iter41 instanceof Array || typeof __iter41 == "string" || __is_typed_array(__iter41) || __is_some_array(__iter41) )) { __iter41 = __object_keys__(__iter41) } + for (var __idx41=0; __idx41 < __iter41.length; __idx41++) { + var other = __iter41[ __idx41 ]; other.postMessage(__jsdict([["type", "append"], ["argindex", event.data.argindex], ["value", event.data.value]])); } } else { @@ -3779,10 +3777,10 @@ var __start_new_thread = function(f, args) { } else { a[event.data.index] = value; } - var __iter41 = __get_other_workers_with_shared_arg(worker, a); - if (! (__iter41 instanceof Array || typeof __iter41 == "string" || __is_typed_array(__iter41) || __is_some_array(__iter41) )) { __iter41 = __object_keys__(__iter41) } - for (var __idx41=0; __idx41 < __iter41.length; __idx41++) { - var other = __iter41[ __idx41 ]; + var __iter42 = __get_other_workers_with_shared_arg(worker, a); + if (! (__iter42 instanceof Array || typeof __iter42 == "string" || __is_typed_array(__iter42) || __is_some_array(__iter42) )) { __iter42 = __object_keys__(__iter42) } + for (var __idx42=0; __idx42 < __iter42.length; __idx42++) { + var other = __iter42[ __idx42 ]; other.postMessage(__jsdict([["type", "__setitem__"], ["argindex", event.data.argindex], ["key", event.data.index], ["value", event.data.value]])); } } else { @@ -3797,10 +3795,10 @@ var __start_new_thread = function(f, args) { jsargs = []; var i; i = 0; - var __iter42 = args; - if (! (__iter42 instanceof Array || typeof __iter42 == "string" || __is_typed_array(__iter42) || __is_some_array(__iter42) )) { __iter42 = __object_keys__(__iter42) } - for (var __idx42=0; __idx42 < __iter42.length; __idx42++) { - var arg = __iter42[ __idx42 ]; + var __iter43 = args; + if (! (__iter43 instanceof Array || typeof __iter43 == "string" || __is_typed_array(__iter43) || __is_some_array(__iter43) )) { __iter43 = __object_keys__(__iter43) } + for (var __idx43=0; __idx43 < __iter43.length; __idx43++) { + var arg = __iter43[ __idx43 ]; if (__test_if_true__(arg.jsify)) { jsargs.append(arg.jsify()); } else { diff --git a/pythonjs/runtime/builtins.py b/pythonjs/runtime/builtins.py index f574586..f04ff4b 100644 --- a/pythonjs/runtime/builtins.py +++ b/pythonjs/runtime/builtins.py @@ -1410,11 +1410,12 @@ def __init__(self, js_object=None, pointer=None): elif js_object: ob = js_object if instanceof(ob, Array): - for o in ob: - if instanceof(o, Array): - self.__setitem__( o[0], o[1] ) - else: - self.__setitem__( o['key'], o['value'] ) + with lowlevel: + for o in ob: + if instanceof(o, Array): + self.__setitem__( o[0], o[1] ) + else: + self.__setitem__( o['key'], o['value'] ) elif isinstance(ob, dict): for key in ob.keys(): value = ob[ key ] From 7381f36f7205d3ad633164a1a9f39709df1e7f44 Mon Sep 17 00:00:00 2001 From: hartsantler Date: Sun, 27 Jul 2014 15:53:33 -0700 Subject: [PATCH 045/100] starting on Go backend. --- pythonjs/python_to_pythonjs.py | 10 ++-- pythonjs/pythonjs_to_go.py | 96 ++++++++++++++++++++++++++++++++++ pythonjs/translator.py | 8 ++- pythonjs/typedpython.py | 2 +- regtests/lang/inline.py | 5 ++ regtests/run.py | 29 +++++++++- 6 files changed, 142 insertions(+), 8 deletions(-) create mode 100644 pythonjs/pythonjs_to_go.py create mode 100644 regtests/lang/inline.py diff --git a/pythonjs/python_to_pythonjs.py b/pythonjs/python_to_pythonjs.py index 198d9c7..72daabc 100755 --- a/pythonjs/python_to_pythonjs.py +++ b/pythonjs/python_to_pythonjs.py @@ -132,12 +132,13 @@ def format_error(self, node): msg += '%s%s line:%s col:%s\n' % (' '*(l+1)*2, n.__class__.__name__, n.lineno, n.col_offset) return msg - def __init__(self, source=None, module=None, module_path=None, dart=False, coffee=False, lua=False): + def __init__(self, source=None, module=None, module_path=None, dart=False, coffee=False, lua=False, go=False): super(PythonToPythonJS, self).__init__() self._module_path = module_path ## used for user `from xxx import *` to load .py files in the same directory. self._with_lua = lua self._with_coffee = coffee self._with_dart = dart + self._with_go = go self._html_tail = []; script = False if source.strip().startswith(' 1: + for arg in sys.argv[1:]: + if arg.endswith('.py'): + scripts.append( arg ) + + if len(scripts): + a = [] + for script in scripts: + a.append( open(script, 'rb').read() ) + data = '\n'.join( a ) + else: + data = sys.stdin.read() + + out = main( data ) + print( out ) + + +if __name__ == '__main__': + command() diff --git a/pythonjs/translator.py b/pythonjs/translator.py index 46fd4b9..0d12938 100755 --- a/pythonjs/translator.py +++ b/pythonjs/translator.py @@ -7,9 +7,10 @@ from pythonjs_to_coffee import main as pythonjs_to_coffee from pythonjs_to_lua import main as pythonjs_to_lua from pythonjs_to_luajs import main as pythonjs_to_luajs +from pythonjs_to_go import main as pythonjs_to_go cmdhelp = """\ -usage: translator.py [--dart|--coffee|--lua|--visjs|--no-wrapper|--analyze] file.py +usage: translator.py [--dart|--coffee|--lua|--go|--visjs|--no-wrapper|--analyze] file.py example: translator.py --no-wrapper myscript.py > myscript.js @@ -23,7 +24,10 @@ def main(script, module_path=None): else: code = '' res = None - if '--dart' in sys.argv: + if '--go' in sys.argv: + a = python_to_pythonjs(script, go=True, module_path=module_path) + code = pythonjs_to_go( a ) + elif '--dart' in sys.argv: a = python_to_pythonjs(script, dart=True, module_path=module_path) code = pythonjs_to_dart( a ) elif '--coffee' in sys.argv: diff --git a/pythonjs/typedpython.py b/pythonjs/typedpython.py index a2d42df..00c01a5 100644 --- a/pythonjs/typedpython.py +++ b/pythonjs/typedpython.py @@ -63,7 +63,7 @@ def transform_source( source, strip=False ): if cs.startswith('//'): continue - elif cs.startswith('inline('): + elif cs.startswith('inline(') or cs.startswith('JS('): output.append(c) continue diff --git a/regtests/lang/inline.py b/regtests/lang/inline.py new file mode 100644 index 0000000..7a8e3e4 --- /dev/null +++ b/regtests/lang/inline.py @@ -0,0 +1,5 @@ +"""inline""" + +def main(): + JS("now = new Date()") + inline("now = new Date()") diff --git a/regtests/run.py b/regtests/run.py index f122999..fc6e013 100755 --- a/regtests/run.py +++ b/regtests/run.py @@ -189,6 +189,8 @@ def run_old_pypy_test_on(filename): lua2js = os.path.abspath( '../external/lua.js/lua2js' ) luajs_runnable = os.path.isfile( lua2js ) and '--lua2js' in sys.argv +go_runnable = runnable( 'go version') + assert rhino_runnable or node_runnable if show_details: @@ -458,7 +460,7 @@ def run_python3_test_on(filename): -def translate_js(filename, javascript=False, dart=False, coffee=False, lua=False, luajs=False, multioutput=False, requirejs=True): +def translate_js(filename, javascript=False, dart=False, coffee=False, lua=False, luajs=False, go=False, multioutput=False, requirejs=True): global tmpname tmpname = os.path.join( tempfile.gettempdir(), @@ -490,6 +492,9 @@ def translate_js(filename, javascript=False, dart=False, coffee=False, lua=False ] content = '\n'.join( source ) + elif go: + content = patch_python(filename, backend='GO') + else: content = patch_python(filename) @@ -514,6 +519,8 @@ def translate_js(filename, javascript=False, dart=False, coffee=False, lua=False cmd.append( '--lua') elif luajs: cmd.append( '--luajs') + elif go: + cmd.append( '--go' ) if not requirejs: cmd.append( '--no-wrapper' ) @@ -763,6 +770,17 @@ def run_luajs_node(content): return run_command("node %s.js" % tmpname) +def run_pythonjs_go_test(dummy_filename): + """PythonJS (Go backend)""" + return run_if_no_error(run_go) + +def run_go(content): + """compile and run go program""" + #builtins = read(os.path.join("../external/lua.js", "lua.js")) + write("%s.go" % tmpname, content) + return run_command("go build %s.go" % tmpname) + + def run_html_test( filename, sum_errors ): lines = open(filename, 'rb').read().decode('utf-8').splitlines() filename = os.path.split(filename)[-1] @@ -926,6 +944,11 @@ def display(function): js = translate_js(filename, lua=True) display(run_pythonjs_lua_test_on_luajit) + if go_runnable: + js = translate_js(filename, go=True) + display(run_pythonjs_go_test) + + print() return sum_errors @@ -976,6 +999,10 @@ def run(): if luajit_runnable: headers.append("Lua\nJIT") + if go_runnable: + headers.append("Go\n-") + + print(table_header % ("", "Regtest run on") + ''.join(table_cell % i.split('\n')[0] for i in headers) From 45e101dcd58a21823b07661ac7adfd25eb534487 Mon Sep 17 00:00:00 2001 From: hartsantler Date: Tue, 29 Jul 2014 17:23:48 -0700 Subject: [PATCH 046/100] fixed tuple keys `a[i]=b[i]` in javascript mode. --- pythonjs/python_to_pythonjs.py | 9 ++- pythonjs/pythonjs.js | 134 ++++++++++++++++++--------------- pythonjs/runtime/builtins.py | 23 ++++-- regtests/dict/tuple_keys.py | 6 ++ 4 files changed, 100 insertions(+), 72 deletions(-) diff --git a/pythonjs/python_to_pythonjs.py b/pythonjs/python_to_pythonjs.py index 72daabc..52b7133 100755 --- a/pythonjs/python_to_pythonjs.py +++ b/pythonjs/python_to_pythonjs.py @@ -1797,7 +1797,8 @@ def _visit_assign_helper(self, node, target): elif self._with_direct_keys: code = '%s[ %s ] = %s' % (self.visit(target.value), s, self.visit(node.value)) else: - code = '%s[ __ternary_operator__(%s.__uid__, %s) ] = %s' % (self.visit(target.value), s, s, self.visit(node.value)) + check_array = '__ternary_operator__( instanceof(%s,Array), JSON.stringify(%s), %s )' %(s, s, s) + code = '%s[ __ternary_operator__(%s.__uid__, %s) ] = %s' %(self.visit(target.value), s, check_array, self.visit(node.value)) elif name in self._func_typedefs and self._func_typedefs[name] == 'list': code = '%s[%s] = %s'%(name, self.visit(target.slice.value), self.visit(node.value)) @@ -2893,7 +2894,11 @@ def visit_FunctionDef(self, node): writer.write( 'def %s( %s ):' % (node.name, ','.join(args)) ) else: - writer.write('def %s(args, kwargs):' % node.name) + if len(node.args.defaults) or node.args.kwarg or len(node.args.args) or node.args.vararg: + writer.write('def %s(args, kwargs):' % node.name) + else: + writer.write('def %s():' % node.name) + writer.push() ## write local typedefs and var scope ## diff --git a/pythonjs/pythonjs.js b/pythonjs/pythonjs.js index 9cd417e..d5b7378 100644 --- a/pythonjs/pythonjs.js +++ b/pythonjs/pythonjs.js @@ -1724,7 +1724,7 @@ var str = function(args, kwargs) { return ("" + s); } ;str.is_wrapper = true; -var _setup_str_prototype = function(args, kwargs) { +var _setup_str_prototype = function() { "\n Extend JavaScript String.prototype with methods that implement the Python str API.\n The decorator @String.prototype.[name] assigns the function to the prototype,\n and ensures that the special 'this' variable will work.\n "; var func = function(a) { @@ -1951,7 +1951,7 @@ var __sort_method = function(ob) { } } -var _setup_array_prototype = function(args, kwargs) { +var _setup_array_prototype = function() { var func = function() { var i,item; @@ -2204,7 +2204,7 @@ var _setup_array_prototype = function(args, kwargs) { } ;_setup_array_prototype.is_wrapper = true; _setup_array_prototype(); -var _setup_nodelist_prototype = function(args, kwargs) { +var _setup_nodelist_prototype = function() { var func = function(a) { @@ -2743,14 +2743,16 @@ var __dict___init__ = function(args, kwargs) { if (__test_if_true__(js_object)) { ob = js_object; if (__test_if_true__(ob instanceof Array)) { - var __iter34 = ob; - if (! (__iter34 instanceof Array || typeof __iter34 == "string" || __is_typed_array(__iter34) || __is_some_array(__iter34) )) { __iter34 = __object_keys__(__iter34) } - for (var __idx34=0; __idx34 < __iter34.length; __idx34++) { - var o = __iter34[ __idx34 ]; - if (o instanceof Array) { - self.__setitem__(o[0], o[1]); + var o,__iterator__45; + __iterator__45 = __get__(__get__(ob, "__iter__", "no iterator - line 1191: for o in ob:"), "__call__")([], __NULL_OBJECT__); + var __next__45; + __next__45 = __get__(__iterator__45, "next"); + while (( __iterator__45.index ) < __iterator__45.length) { + o = __next__45(); + if (__test_if_true__(o instanceof Array)) { + __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1193: self.__setitem__( o[0], o[1] )"), "__call__")([((o instanceof Array) ? o[0] : __get__(o, "__getitem__", "line 1193: self.__setitem__( o[0], o[1] )")([0], __NULL_OBJECT__)), ((o instanceof Array) ? o[1] : __get__(o, "__getitem__", "line 1193: self.__setitem__( o[0], o[1] )")([1], __NULL_OBJECT__))], __NULL_OBJECT__); } else { - self.__setitem__(o["key"], o["value"]); + __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1195: self.__setitem__( o['key'], o['value'] )"), "__call__")([((o instanceof Array) ? o["key"] : __get__(o, "__getitem__", "line 1195: self.__setitem__( o['key'], o['value'] )")(["key"], __NULL_OBJECT__)), ((o instanceof Array) ? o["value"] : __get__(o, "__getitem__", "line 1195: self.__setitem__( o['key'], o['value'] )")(["value"], __NULL_OBJECT__))], __NULL_OBJECT__); } } } else { @@ -2973,7 +2975,7 @@ var __dict___len__ = function(args, kwargs) { ;__dict___len__.is_wrapper = true; __dict_attrs.__len__ = __dict___len__; var __dict___getitem__ = function(args, kwargs) { - var __dict; + var __dict,msg,err; var __sig__,__args__; __sig__ = { kwargs:{},args:["self", "key"] }; if (args instanceof Array && ( Object.prototype.toString.call(kwargs) ) == "[object Object]" && ( arguments.length ) == 2) { @@ -2987,20 +2989,28 @@ var __dict___getitem__ = function(args, kwargs) { var key = __args__['key']; "\n note: `\"4\"` and `4` are the same key in javascript, is there a sane way to workaround this,\n that can remain compatible with external javascript?\n "; __dict = self["$wrapped"]; + err = false; if (__test_if_true__(key instanceof Array)) { key = __tuple_key__(key); } else { if (__test_if_true__(typeof(key) === 'object' || typeof(key) === 'function')) { if (__test_if_true__(key.__uid__ && key.__uid__ in __dict)) { return __dict[key.__uid__]; + } else { + err = true; } - throw new KeyError(key); } } if (__test_if_true__(__dict && key in __dict)) { return __dict[key]; + } else { + err = true; + } + if (__test_if_true__(err)) { + msg = __sprintf("missing key: %s", key); + msg += __sprintf("\n - dict keys: %s", Object.keys(__dict)); + throw new KeyError(msg); } - throw new KeyError(key); } ;__dict___getitem__.is_wrapper = true; __dict_attrs.__getitem__ = __dict___getitem__; @@ -3090,10 +3100,10 @@ var __dict_values = function(args, kwargs) { var self = __args__['self']; keys = Object.keys(self["$wrapped"]); out = []; - var __iter35 = keys; - if (! (__iter35 instanceof Array || typeof __iter35 == "string" || __is_typed_array(__iter35) || __is_some_array(__iter35) )) { __iter35 = __object_keys__(__iter35) } - for (var __idx35=0; __idx35 < __iter35.length; __idx35++) { - var key = __iter35[ __idx35 ]; + var __iter34 = keys; + if (! (__iter34 instanceof Array || typeof __iter34 == "string" || __is_typed_array(__iter34) || __is_some_array(__iter34) )) { __iter34 = __object_keys__(__iter34) } + for (var __idx34=0; __idx34 < __iter34.length; __idx34++) { + var key = __iter34[ __idx34 ]; out.push(self["$wrapped"][key]); } return out; @@ -3177,10 +3187,10 @@ var set = function(args, kwargs) { } fallback = false; if (__test_if_true__(hashtable)) { - var __iter36 = a; - if (! (__iter36 instanceof Array || typeof __iter36 == "string" || __is_typed_array(__iter36) || __is_some_array(__iter36) )) { __iter36 = __object_keys__(__iter36) } - for (var __idx36=0; __idx36 < __iter36.length; __idx36++) { - var b = __iter36[ __idx36 ]; + var __iter35 = a; + if (! (__iter35 instanceof Array || typeof __iter35 == "string" || __is_typed_array(__iter35) || __is_some_array(__iter35) )) { __iter35 = __object_keys__(__iter35) } + for (var __idx35=0; __idx35 < __iter35.length; __idx35++) { + var b = __iter35[ __idx35 ]; if (__test_if_true__(( typeof(b) ) == "number" && ( b ) === ( (b | 0) ))) { key = (b & mask); hashtable[key] = b; @@ -3195,20 +3205,20 @@ var set = function(args, kwargs) { } s = []; if (__test_if_true__(fallback)) { - var __iter37 = a; - if (! (__iter37 instanceof Array || typeof __iter37 == "string" || __is_typed_array(__iter37) || __is_some_array(__iter37) )) { __iter37 = __object_keys__(__iter37) } - for (var __idx37=0; __idx37 < __iter37.length; __idx37++) { - var item = __iter37[ __idx37 ]; + var __iter36 = a; + if (! (__iter36 instanceof Array || typeof __iter36 == "string" || __is_typed_array(__iter36) || __is_some_array(__iter36) )) { __iter36 = __object_keys__(__iter36) } + for (var __idx36=0; __idx36 < __iter36.length; __idx36++) { + var item = __iter36[ __idx36 ]; if (( s.indexOf(item) ) == -1) { s.push(item); } } } else { __sort_method(keys); - var __iter38 = keys; - if (! (__iter38 instanceof Array || typeof __iter38 == "string" || __is_typed_array(__iter38) || __is_some_array(__iter38) )) { __iter38 = __object_keys__(__iter38) } - for (var __idx38=0; __idx38 < __iter38.length; __idx38++) { - var key = __iter38[ __idx38 ]; + var __iter37 = keys; + if (! (__iter37 instanceof Array || typeof __iter37 == "string" || __is_typed_array(__iter37) || __is_some_array(__iter37) )) { __iter37 = __object_keys__(__iter37) } + for (var __idx37=0; __idx37 < __iter37.length; __idx37++) { + var key = __iter37[ __idx37 ]; s.push(hashtable[key]); } } @@ -3254,7 +3264,7 @@ var __array___init__ = function(args, kwargs) { var initializer = __args__['initializer']; var little_endian = __args__['little_endian']; self.typecode = typecode; - self.itemsize = __get__(__get__(self, "typecodes", "missing attribute `typecodes` - line 1414: self.itemsize = self.typecodes[ typecode ]"), "__getitem__", "line 1414: self.itemsize = self.typecodes[ typecode ]")([typecode], __NULL_OBJECT__); + self.itemsize = __get__(__get__(self, "typecodes", "missing attribute `typecodes` - line 1421: self.itemsize = self.typecodes[ typecode ]"), "__getitem__", "line 1421: self.itemsize = self.typecodes[ typecode ]")([typecode], __NULL_OBJECT__); self.little_endian = little_endian; if (__test_if_true__(initializer)) { self.length = len([initializer], __NULL_OBJECT__); @@ -3278,7 +3288,7 @@ var __array___init__ = function(args, kwargs) { buff = new ArrayBuffer(size); self.dataview = new DataView(buff); self.buffer = buff; - __get__(__get__(self, "fromlist", "missing attribute `fromlist` - line 1435: self.fromlist( initializer )"), "__call__")([initializer], __NULL_OBJECT__); + __get__(__get__(self, "fromlist", "missing attribute `fromlist` - line 1442: self.fromlist( initializer )"), "__call__")([initializer], __NULL_OBJECT__); } ;__array___init__.is_wrapper = true; __array_attrs.__init__ = __array___init__; @@ -3311,7 +3321,7 @@ var __array___contains__ = function(args, kwargs) { __args__ = __getargs__("__array___contains__", __sig__, args, kwargs); var self = __args__['self']; var value = __args__['value']; - arr = __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1441: arr = self.to_array()"), "__call__")(); + arr = __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1448: arr = self.to_array()"), "__call__")(); if (( arr.indexOf(value) ) == -1) { return false; } else { @@ -3336,7 +3346,7 @@ var __array___getitem__ = function(args, kwargs) { step = self.itemsize; offset = (step * index); dataview = self.dataview; - func_name = ("get" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1449: func_name = 'get'+self.typecode_names[ self.typecode ]"), "__getitem__", "line 1449: func_name = 'get'+self.typecode_names[ self.typecode ]")([self.typecode], __NULL_OBJECT__)); + func_name = ("get" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1456: func_name = 'get'+self.typecode_names[ self.typecode ]"), "__getitem__", "line 1456: func_name = 'get'+self.typecode_names[ self.typecode ]")([self.typecode], __NULL_OBJECT__)); func = dataview[func_name].bind(dataview); if (( offset ) < self.bytes) { value = func(offset); @@ -3374,7 +3384,7 @@ var __array___setitem__ = function(args, kwargs) { } offset = (step * index); dataview = self.dataview; - func_name = ("set" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1465: func_name = 'set'+self.typecode_names[ self.typecode ]"), "__getitem__", "line 1465: func_name = 'set'+self.typecode_names[ self.typecode ]")([self.typecode], __NULL_OBJECT__)); + func_name = ("set" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1472: func_name = 'set'+self.typecode_names[ self.typecode ]"), "__getitem__", "line 1472: func_name = 'set'+self.typecode_names[ self.typecode ]")([self.typecode], __NULL_OBJECT__)); func = dataview[func_name].bind(dataview); if (( offset ) < self.bytes) { if (( self.typecode ) == "float8") { @@ -3442,13 +3452,13 @@ var __array_fromlist = function(args, kwargs) { typecode = self.typecode; size = (length * step); dataview = self.dataview; - func_name = ("set" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1485: func_name = 'set'+self.typecode_names[ typecode ]"), "__getitem__", "line 1485: func_name = 'set'+self.typecode_names[ typecode ]")([typecode], __NULL_OBJECT__)); + func_name = ("set" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1492: func_name = 'set'+self.typecode_names[ typecode ]"), "__getitem__", "line 1492: func_name = 'set'+self.typecode_names[ typecode ]")([typecode], __NULL_OBJECT__)); func = dataview[func_name].bind(dataview); if (( size ) <= self.bytes) { i = 0; offset = 0; while (( i ) < length) { - item = ((lst instanceof Array) ? lst[i] : __get__(lst, "__getitem__", "line 1490: item = lst[i]")([i], __NULL_OBJECT__)); + item = ((lst instanceof Array) ? lst[i] : __get__(lst, "__getitem__", "line 1497: item = lst[i]")([i], __NULL_OBJECT__)); if (( typecode ) == "float8") { item *= self._norm_set; } else { @@ -3506,7 +3516,7 @@ var __array_append = function(args, kwargs) { var self = __args__['self']; var value = __args__['value']; length = self.length; - __get__(__get__(self, "resize", "missing attribute `resize` - line 1513: self.resize( self.length + 1 )"), "__call__")([(self.length + 1)], __NULL_OBJECT__); + __get__(__get__(self, "resize", "missing attribute `resize` - line 1520: self.resize( self.length + 1 )"), "__call__")([(self.length + 1)], __NULL_OBJECT__); __get__(__get__(self, "__setitem__"), "__call__")([length, value], {}); } ;__array_append.is_wrapper = true; @@ -3525,12 +3535,12 @@ var __array_extend = function(args, kwargs) { var self = __args__['self']; var lst = __args__['lst']; var value,__iterator__54; - __iterator__54 = __get__(__get__(lst, "__iter__", "no iterator - line 1516: for value in lst:"), "__call__")([], __NULL_OBJECT__); + __iterator__54 = __get__(__get__(lst, "__iter__", "no iterator - line 1523: for value in lst:"), "__call__")([], __NULL_OBJECT__); var __next__54; __next__54 = __get__(__iterator__54, "next"); while (( __iterator__54.index ) < __iterator__54.length) { value = __next__54(); - __get__(__get__(self, "append", "missing attribute `append` - line 1517: self.append( value )"), "__call__")([value], __NULL_OBJECT__); + __get__(__get__(self, "append", "missing attribute `append` - line 1524: self.append( value )"), "__call__")([value], __NULL_OBJECT__); } } ;__array_extend.is_wrapper = true; @@ -3570,7 +3580,7 @@ var __array_to_list = function(args, kwargs) { } __args__ = __getargs__("__array_to_list", __sig__, args, kwargs); var self = __args__['self']; - return __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1527: return self.to_array()"), "__call__")(); + return __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1534: return self.to_array()"), "__call__")(); } ;__array_to_list.is_wrapper = true; __array_attrs.to_list = __array_to_list; @@ -3587,9 +3597,9 @@ var __array_to_ascii = function(args, kwargs) { __args__ = __getargs__("__array_to_ascii", __sig__, args, kwargs); var self = __args__['self']; string = ""; - arr = __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1530: arr = self.to_array()"), "__call__")(); + arr = __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1537: arr = self.to_array()"), "__call__")(); i = 0; - length = __get__(arr, "length", "missing attribute `length` - line 1531: i = 0; length = arr.length"); + length = __get__(arr, "length", "missing attribute `length` - line 1538: i = 0; length = arr.length"); while (( i ) < length) { var num = arr[i]; var char = String.fromCharCode(num); @@ -3720,17 +3730,17 @@ json = __jsdict([["loads", (function (s) {return JSON.parse(s);})], ["dumps", (f var __get_other_workers_with_shared_arg = function(worker, ob) { var a,other,args; a = []; - var __iter39 = threading.workers; - if (! (__iter39 instanceof Array || typeof __iter39 == "string" || __is_typed_array(__iter39) || __is_some_array(__iter39) )) { __iter39 = __object_keys__(__iter39) } - for (var __idx39=0; __idx39 < __iter39.length; __idx39++) { - var b = __iter39[ __idx39 ]; + var __iter38 = threading.workers; + if (! (__iter38 instanceof Array || typeof __iter38 == "string" || __is_typed_array(__iter38) || __is_some_array(__iter38) )) { __iter38 = __object_keys__(__iter38) } + for (var __idx38=0; __idx38 < __iter38.length; __idx38++) { + var b = __iter38[ __idx38 ]; other = b["worker"]; args = b["args"]; if (( other ) !== worker) { - var __iter40 = args; - if (! (__iter40 instanceof Array || typeof __iter40 == "string" || __is_typed_array(__iter40) || __is_some_array(__iter40) )) { __iter40 = __object_keys__(__iter40) } - for (var __idx40=0; __idx40 < __iter40.length; __idx40++) { - var arg = __iter40[ __idx40 ]; + var __iter39 = args; + if (! (__iter39 instanceof Array || typeof __iter39 == "string" || __is_typed_array(__iter39) || __is_some_array(__iter39) )) { __iter39 = __object_keys__(__iter39) } + for (var __idx39=0; __idx39 < __iter39.length; __idx39++) { + var arg = __iter39[ __idx39 ]; if (( arg ) === ob) { if (! (__contains__(a, other))) { a.append(other); @@ -3762,10 +3772,10 @@ var __start_new_thread = function(f, args) { if (( event.data.type ) == "append") { a = args[event.data.argindex]; a.push(event.data.value); - var __iter41 = __get_other_workers_with_shared_arg(worker, a); - if (! (__iter41 instanceof Array || typeof __iter41 == "string" || __is_typed_array(__iter41) || __is_some_array(__iter41) )) { __iter41 = __object_keys__(__iter41) } - for (var __idx41=0; __idx41 < __iter41.length; __idx41++) { - var other = __iter41[ __idx41 ]; + var __iter40 = __get_other_workers_with_shared_arg(worker, a); + if (! (__iter40 instanceof Array || typeof __iter40 == "string" || __is_typed_array(__iter40) || __is_some_array(__iter40) )) { __iter40 = __object_keys__(__iter40) } + for (var __idx40=0; __idx40 < __iter40.length; __idx40++) { + var other = __iter40[ __idx40 ]; other.postMessage(__jsdict([["type", "append"], ["argindex", event.data.argindex], ["value", event.data.value]])); } } else { @@ -3777,10 +3787,10 @@ var __start_new_thread = function(f, args) { } else { a[event.data.index] = value; } - var __iter42 = __get_other_workers_with_shared_arg(worker, a); - if (! (__iter42 instanceof Array || typeof __iter42 == "string" || __is_typed_array(__iter42) || __is_some_array(__iter42) )) { __iter42 = __object_keys__(__iter42) } - for (var __idx42=0; __idx42 < __iter42.length; __idx42++) { - var other = __iter42[ __idx42 ]; + var __iter41 = __get_other_workers_with_shared_arg(worker, a); + if (! (__iter41 instanceof Array || typeof __iter41 == "string" || __is_typed_array(__iter41) || __is_some_array(__iter41) )) { __iter41 = __object_keys__(__iter41) } + for (var __idx41=0; __idx41 < __iter41.length; __idx41++) { + var other = __iter41[ __idx41 ]; other.postMessage(__jsdict([["type", "__setitem__"], ["argindex", event.data.argindex], ["key", event.data.index], ["value", event.data.value]])); } } else { @@ -3795,10 +3805,10 @@ var __start_new_thread = function(f, args) { jsargs = []; var i; i = 0; - var __iter43 = args; - if (! (__iter43 instanceof Array || typeof __iter43 == "string" || __is_typed_array(__iter43) || __is_some_array(__iter43) )) { __iter43 = __object_keys__(__iter43) } - for (var __idx43=0; __idx43 < __iter43.length; __idx43++) { - var arg = __iter43[ __idx43 ]; + var __iter42 = args; + if (! (__iter42 instanceof Array || typeof __iter42 == "string" || __is_typed_array(__iter42) || __is_some_array(__iter42) )) { __iter42 = __object_keys__(__iter42) } + for (var __idx42=0; __idx42 < __iter42.length; __idx42++) { + var arg = __iter42[ __idx42 ]; if (__test_if_true__(arg.jsify)) { jsargs.append(arg.jsify()); } else { diff --git a/pythonjs/runtime/builtins.py b/pythonjs/runtime/builtins.py index f04ff4b..63c0567 100644 --- a/pythonjs/runtime/builtins.py +++ b/pythonjs/runtime/builtins.py @@ -1410,12 +1410,12 @@ def __init__(self, js_object=None, pointer=None): elif js_object: ob = js_object if instanceof(ob, Array): - with lowlevel: - for o in ob: - if instanceof(o, Array): - self.__setitem__( o[0], o[1] ) - else: - self.__setitem__( o['key'], o['value'] ) + #with lowlevel: + for o in ob: + if instanceof(o, Array): + self.__setitem__( o[0], o[1] ) + else: + self.__setitem__( o['key'], o['value'] ) elif isinstance(ob, dict): for key in ob.keys(): value = ob[ key ] @@ -1484,6 +1484,7 @@ def __getitem__(self, key): ''' with javascript: __dict = self[...] + err = False if instanceof(key, Array): #key = JSON.stringify( key ) ## fails on objects with circular references ## key = __tuple_key__(key) @@ -1491,12 +1492,18 @@ def __getitem__(self, key): # Test undefined because it can be in the dict if JS("key.__uid__ && key.__uid__ in __dict"): return JS('__dict[key.__uid__]') - raise KeyError(key) + else: + err = True if __dict and JS("key in __dict"): return JS('__dict[key]') + else: + err = True - raise KeyError(key) + if err: + msg = "missing key: %s" %key + msg += "\n - dict keys: %s" %inline('Object.keys(__dict)') + raise KeyError(msg) def __setitem__(self, key, value): with javascript: diff --git a/regtests/dict/tuple_keys.py b/regtests/dict/tuple_keys.py index 667a9c8..7d3dea0 100644 --- a/regtests/dict/tuple_keys.py +++ b/regtests/dict/tuple_keys.py @@ -26,3 +26,9 @@ def main(): TestError( D2[aa]=='hello' ) TestError( D2[bb]=='world' ) TestError( D2[ab]=='XXX') + + r = { s:1, a:aa } + r2 = {} + for x in [ s, a ]: + r2[ x ] = r[ x ] + TestError( r[s] is r2[s] ) \ No newline at end of file From 8d1680d644947ca1bfaf4788d158d80c843dc8c3 Mon Sep 17 00:00:00 2001 From: hartsantler Date: Wed, 30 Jul 2014 07:26:33 -0700 Subject: [PATCH 047/100] fixed string keys in normal mode. --- pythonjs/pythonjs.js | 80 +++++++++++++++++++++--------------- pythonjs/runtime/builtins.py | 29 +++++++++---- 2 files changed, 67 insertions(+), 42 deletions(-) diff --git a/pythonjs/pythonjs.js b/pythonjs/pythonjs.js index d5b7378..19a4a8f 100644 --- a/pythonjs/pythonjs.js +++ b/pythonjs/pythonjs.js @@ -2707,6 +2707,9 @@ var __tuple_key__ = function(arr) { r.append(__tuple_key__(item)); } else { if (( t ) == "object") { + if (( item.__uid__ ) === undefined) { + throw new KeyError(item); + } r.append(item.__uid__); } else { r.append(item); @@ -2723,7 +2726,7 @@ __dict_attrs = {}; __dict_parents = []; __dict_properties = {}; var __dict___init__ = function(args, kwargs) { - var ob,value; + var k,ob,value,v; var __sig__,__args__; __sig__ = { kwargs:{"js_object": null, "pointer": null},args:["self", "js_object", "pointer"] }; if (args instanceof Array && ( Object.prototype.toString.call(kwargs) ) == "[object Object]" && ( arguments.length ) == 2) { @@ -2744,27 +2747,30 @@ var __dict___init__ = function(args, kwargs) { ob = js_object; if (__test_if_true__(ob instanceof Array)) { var o,__iterator__45; - __iterator__45 = __get__(__get__(ob, "__iter__", "no iterator - line 1191: for o in ob:"), "__call__")([], __NULL_OBJECT__); + __iterator__45 = __get__(__get__(ob, "__iter__", "no iterator - line 1192: for o in ob:"), "__call__")([], __NULL_OBJECT__); var __next__45; __next__45 = __get__(__iterator__45, "next"); while (( __iterator__45.index ) < __iterator__45.length) { o = __next__45(); - if (__test_if_true__(o instanceof Array)) { - __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1193: self.__setitem__( o[0], o[1] )"), "__call__")([((o instanceof Array) ? o[0] : __get__(o, "__getitem__", "line 1193: self.__setitem__( o[0], o[1] )")([0], __NULL_OBJECT__)), ((o instanceof Array) ? o[1] : __get__(o, "__getitem__", "line 1193: self.__setitem__( o[0], o[1] )")([1], __NULL_OBJECT__))], __NULL_OBJECT__); + if (o instanceof Array) { + k = o[0]; + v = o[1]; } else { - __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1195: self.__setitem__( o['key'], o['value'] )"), "__call__")([((o instanceof Array) ? o["key"] : __get__(o, "__getitem__", "line 1195: self.__setitem__( o['key'], o['value'] )")(["key"], __NULL_OBJECT__)), ((o instanceof Array) ? o["value"] : __get__(o, "__getitem__", "line 1195: self.__setitem__( o['key'], o['value'] )")(["value"], __NULL_OBJECT__))], __NULL_OBJECT__); + k = o["key"]; + v = o["value"]; } + __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1198: self.__setitem__( k,v )"), "__call__")([k, v], __NULL_OBJECT__); } } else { if (__test_if_true__(isinstance([ob, dict], __NULL_OBJECT__))) { var key,__iterator__46; - __iterator__46 = __get__(__get__(__jsdict_keys(ob), "__iter__", "no iterator - line 1197: for key in ob.keys():"), "__call__")([], __NULL_OBJECT__); + __iterator__46 = __get__(__get__(__jsdict_keys(ob), "__iter__", "no iterator - line 1200: for key in ob.keys():"), "__call__")([], __NULL_OBJECT__); var __next__46; __next__46 = __get__(__iterator__46, "next"); while (( __iterator__46.index ) < __iterator__46.length) { key = __next__46(); - value = ((ob instanceof Array) ? ob[key] : __get__(ob, "__getitem__", "line 1198: value = ob[ key ]")([key], __NULL_OBJECT__)); - __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1199: self.__setitem__( key, value )"), "__call__")([key, value], __NULL_OBJECT__); + value = ((ob instanceof Array) ? ob[key] : __get__(ob, "__getitem__", "line 1201: value = ob[ key ]")([key], __NULL_OBJECT__)); + __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1202: self.__setitem__( key, value )"), "__call__")([key, value], __NULL_OBJECT__); } } else { console.log("ERROR init dict from:", js_object); @@ -2790,15 +2796,15 @@ var __dict_jsify = function(args, kwargs) { var self = __args__['self']; keys = __object_keys__([self["$wrapped"]], __NULL_OBJECT__); var key,__iterator__47; - __iterator__47 = __get__(__get__(keys, "__iter__", "no iterator - line 1206: for key in keys:"), "__call__")([], __NULL_OBJECT__); + __iterator__47 = __get__(__get__(keys, "__iter__", "no iterator - line 1209: for key in keys:"), "__call__")([], __NULL_OBJECT__); var __next__47; __next__47 = __get__(__iterator__47, "next"); while (( __iterator__47.index ) < __iterator__47.length) { key = __next__47(); - value = __get__(self["$wrapped"], "__getitem__", "line 1207: value = self[...][key]")([key], __NULL_OBJECT__); + value = __get__(self["$wrapped"], "__getitem__", "line 1210: value = self[...][key]")([key], __NULL_OBJECT__); if (( typeof(value) ) == "object") { if (__test_if_true__(hasattr([value, "jsify"], __NULL_OBJECT__))) { - __get__(__get__(self["$wrapped"], "__setitem__"), "__call__")([key, __get__(__get__(value, "jsify", "missing attribute `jsify` - line 1210: self[...][key] = value.jsify()"), "__call__")()], {}); + __get__(__get__(self["$wrapped"], "__setitem__"), "__call__")([key, __get__(__get__(value, "jsify", "missing attribute `jsify` - line 1213: self[...][key] = value.jsify()"), "__call__")()], {}); } } else { if (( typeof(value) ) == "function") { @@ -2857,7 +2863,7 @@ var __dict_has_key = function(args, kwargs) { var key = __args__['key']; __dict = self["$wrapped"]; if (__test_if_true__(typeof(key) === 'object' || typeof(key) === 'function')) { - key = __get__(key, "__uid__", "missing attribute `__uid__` - line 1223: key = key.__uid__"); + key = __get__(key, "__uid__", "missing attribute `__uid__` - line 1226: key = key.__uid__"); } if (__test_if_true__(key in __dict)) { return true; @@ -2881,12 +2887,12 @@ var __dict_update = function(args, kwargs) { var self = __args__['self']; var other = __args__['other']; var key,__iterator__48; - __iterator__48 = __get__(__get__(other, "__iter__", "no iterator - line 1229: for key in other:"), "__call__")([], __NULL_OBJECT__); + __iterator__48 = __get__(__get__(other, "__iter__", "no iterator - line 1232: for key in other:"), "__call__")([], __NULL_OBJECT__); var __next__48; __next__48 = __get__(__iterator__48, "next"); while (( __iterator__48.index ) < __iterator__48.length) { key = __next__48(); - __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1230: self.__setitem__( key, other[key] )"), "__call__")([key, ((other instanceof Array) ? other[key] : __get__(other, "__getitem__", "line 1230: self.__setitem__( key, other[key] )")([key], __NULL_OBJECT__))], __NULL_OBJECT__); + __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1233: self.__setitem__( key, other[key] )"), "__call__")([key, ((other instanceof Array) ? other[key] : __get__(other, "__getitem__", "line 1233: self.__setitem__( key, other[key] )")([key], __NULL_OBJECT__))], __NULL_OBJECT__); } } ;__dict_update.is_wrapper = true; @@ -2905,12 +2911,12 @@ var __dict_items = function(args, kwargs) { var self = __args__['self']; arr = []; var key,__iterator__49; - __iterator__49 = __get__(__get__(__jsdict_keys(self), "__iter__", "no iterator - line 1233: for key in self.keys():"), "__call__")([], __NULL_OBJECT__); + __iterator__49 = __get__(__get__(__jsdict_keys(self), "__iter__", "no iterator - line 1236: for key in self.keys():"), "__call__")([], __NULL_OBJECT__); var __next__49; __next__49 = __get__(__iterator__49, "next"); while (( __iterator__49.index ) < __iterator__49.length) { key = __next__49(); - __get__(__get__(arr, "append", "missing attribute `append` - line 1234: arr.append( [key, self[key]] )"), "__call__")([[key, __get__(self, "__getitem__")([key], __NULL_OBJECT__)]], __NULL_OBJECT__); + __get__(__get__(arr, "append", "missing attribute `append` - line 1237: arr.append( [key, self[key]] )"), "__call__")([[key, __get__(self, "__getitem__")([key], __NULL_OBJECT__)]], __NULL_OBJECT__); } return arr; } @@ -2953,7 +2959,7 @@ var __dict_set = function(args, kwargs) { var self = __args__['self']; var key = __args__['key']; var value = __args__['value']; - __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1242: self.__setitem__(key, value)"), "__call__")([key, value], __NULL_OBJECT__); + __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1245: self.__setitem__(key, value)"), "__call__")([key, value], __NULL_OBJECT__); } ;__dict_set.is_wrapper = true; __dict_attrs.set = __dict_set; @@ -3007,9 +3013,8 @@ var __dict___getitem__ = function(args, kwargs) { err = true; } if (__test_if_true__(err)) { - msg = __sprintf("missing key: %s", key); - msg += __sprintf("\n - dict keys: %s", Object.keys(__dict)); - throw new KeyError(msg); + msg = __sprintf("missing key: %s -\n", key); + throw new KeyError(__jsdict_keys(__dict)); } } ;__dict___getitem__.is_wrapper = true; @@ -3028,9 +3033,18 @@ var __dict___setitem__ = function(args, kwargs) { var self = __args__['self']; var key = __args__['key']; var value = __args__['value']; + if (( key ) === undefined) { + throw new KeyError("undefined is invalid key type"); + } + if (( key ) === null) { + throw new KeyError("null is invalid key type"); + } __dict = self["$wrapped"]; if (__test_if_true__(key instanceof Array)) { key = __tuple_key__(key); + if (( key ) === undefined) { + throw new KeyError("undefined is invalid key type (tuple)"); + } __dict[key] = value; } else { if (__test_if_true__(typeof(key) === 'object' || typeof(key) === 'function')) { @@ -3264,7 +3278,7 @@ var __array___init__ = function(args, kwargs) { var initializer = __args__['initializer']; var little_endian = __args__['little_endian']; self.typecode = typecode; - self.itemsize = __get__(__get__(self, "typecodes", "missing attribute `typecodes` - line 1421: self.itemsize = self.typecodes[ typecode ]"), "__getitem__", "line 1421: self.itemsize = self.typecodes[ typecode ]")([typecode], __NULL_OBJECT__); + self.itemsize = __get__(__get__(self, "typecodes", "missing attribute `typecodes` - line 1429: self.itemsize = self.typecodes[ typecode ]"), "__getitem__", "line 1429: self.itemsize = self.typecodes[ typecode ]")([typecode], __NULL_OBJECT__); self.little_endian = little_endian; if (__test_if_true__(initializer)) { self.length = len([initializer], __NULL_OBJECT__); @@ -3288,7 +3302,7 @@ var __array___init__ = function(args, kwargs) { buff = new ArrayBuffer(size); self.dataview = new DataView(buff); self.buffer = buff; - __get__(__get__(self, "fromlist", "missing attribute `fromlist` - line 1442: self.fromlist( initializer )"), "__call__")([initializer], __NULL_OBJECT__); + __get__(__get__(self, "fromlist", "missing attribute `fromlist` - line 1450: self.fromlist( initializer )"), "__call__")([initializer], __NULL_OBJECT__); } ;__array___init__.is_wrapper = true; __array_attrs.__init__ = __array___init__; @@ -3321,7 +3335,7 @@ var __array___contains__ = function(args, kwargs) { __args__ = __getargs__("__array___contains__", __sig__, args, kwargs); var self = __args__['self']; var value = __args__['value']; - arr = __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1448: arr = self.to_array()"), "__call__")(); + arr = __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1456: arr = self.to_array()"), "__call__")(); if (( arr.indexOf(value) ) == -1) { return false; } else { @@ -3346,7 +3360,7 @@ var __array___getitem__ = function(args, kwargs) { step = self.itemsize; offset = (step * index); dataview = self.dataview; - func_name = ("get" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1456: func_name = 'get'+self.typecode_names[ self.typecode ]"), "__getitem__", "line 1456: func_name = 'get'+self.typecode_names[ self.typecode ]")([self.typecode], __NULL_OBJECT__)); + func_name = ("get" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1464: func_name = 'get'+self.typecode_names[ self.typecode ]"), "__getitem__", "line 1464: func_name = 'get'+self.typecode_names[ self.typecode ]")([self.typecode], __NULL_OBJECT__)); func = dataview[func_name].bind(dataview); if (( offset ) < self.bytes) { value = func(offset); @@ -3384,7 +3398,7 @@ var __array___setitem__ = function(args, kwargs) { } offset = (step * index); dataview = self.dataview; - func_name = ("set" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1472: func_name = 'set'+self.typecode_names[ self.typecode ]"), "__getitem__", "line 1472: func_name = 'set'+self.typecode_names[ self.typecode ]")([self.typecode], __NULL_OBJECT__)); + func_name = ("set" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1480: func_name = 'set'+self.typecode_names[ self.typecode ]"), "__getitem__", "line 1480: func_name = 'set'+self.typecode_names[ self.typecode ]")([self.typecode], __NULL_OBJECT__)); func = dataview[func_name].bind(dataview); if (( offset ) < self.bytes) { if (( self.typecode ) == "float8") { @@ -3452,13 +3466,13 @@ var __array_fromlist = function(args, kwargs) { typecode = self.typecode; size = (length * step); dataview = self.dataview; - func_name = ("set" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1492: func_name = 'set'+self.typecode_names[ typecode ]"), "__getitem__", "line 1492: func_name = 'set'+self.typecode_names[ typecode ]")([typecode], __NULL_OBJECT__)); + func_name = ("set" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1500: func_name = 'set'+self.typecode_names[ typecode ]"), "__getitem__", "line 1500: func_name = 'set'+self.typecode_names[ typecode ]")([typecode], __NULL_OBJECT__)); func = dataview[func_name].bind(dataview); if (( size ) <= self.bytes) { i = 0; offset = 0; while (( i ) < length) { - item = ((lst instanceof Array) ? lst[i] : __get__(lst, "__getitem__", "line 1497: item = lst[i]")([i], __NULL_OBJECT__)); + item = ((lst instanceof Array) ? lst[i] : __get__(lst, "__getitem__", "line 1505: item = lst[i]")([i], __NULL_OBJECT__)); if (( typecode ) == "float8") { item *= self._norm_set; } else { @@ -3516,7 +3530,7 @@ var __array_append = function(args, kwargs) { var self = __args__['self']; var value = __args__['value']; length = self.length; - __get__(__get__(self, "resize", "missing attribute `resize` - line 1520: self.resize( self.length + 1 )"), "__call__")([(self.length + 1)], __NULL_OBJECT__); + __get__(__get__(self, "resize", "missing attribute `resize` - line 1528: self.resize( self.length + 1 )"), "__call__")([(self.length + 1)], __NULL_OBJECT__); __get__(__get__(self, "__setitem__"), "__call__")([length, value], {}); } ;__array_append.is_wrapper = true; @@ -3535,12 +3549,12 @@ var __array_extend = function(args, kwargs) { var self = __args__['self']; var lst = __args__['lst']; var value,__iterator__54; - __iterator__54 = __get__(__get__(lst, "__iter__", "no iterator - line 1523: for value in lst:"), "__call__")([], __NULL_OBJECT__); + __iterator__54 = __get__(__get__(lst, "__iter__", "no iterator - line 1531: for value in lst:"), "__call__")([], __NULL_OBJECT__); var __next__54; __next__54 = __get__(__iterator__54, "next"); while (( __iterator__54.index ) < __iterator__54.length) { value = __next__54(); - __get__(__get__(self, "append", "missing attribute `append` - line 1524: self.append( value )"), "__call__")([value], __NULL_OBJECT__); + __get__(__get__(self, "append", "missing attribute `append` - line 1532: self.append( value )"), "__call__")([value], __NULL_OBJECT__); } } ;__array_extend.is_wrapper = true; @@ -3580,7 +3594,7 @@ var __array_to_list = function(args, kwargs) { } __args__ = __getargs__("__array_to_list", __sig__, args, kwargs); var self = __args__['self']; - return __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1534: return self.to_array()"), "__call__")(); + return __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1542: return self.to_array()"), "__call__")(); } ;__array_to_list.is_wrapper = true; __array_attrs.to_list = __array_to_list; @@ -3597,9 +3611,9 @@ var __array_to_ascii = function(args, kwargs) { __args__ = __getargs__("__array_to_ascii", __sig__, args, kwargs); var self = __args__['self']; string = ""; - arr = __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1537: arr = self.to_array()"), "__call__")(); + arr = __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1545: arr = self.to_array()"), "__call__")(); i = 0; - length = __get__(arr, "length", "missing attribute `length` - line 1538: i = 0; length = arr.length"); + length = __get__(arr, "length", "missing attribute `length` - line 1546: i = 0; length = arr.length"); while (( i ) < length) { var num = arr[i]; var char = String.fromCharCode(num); diff --git a/pythonjs/runtime/builtins.py b/pythonjs/runtime/builtins.py index 63c0567..dd8db3a 100644 --- a/pythonjs/runtime/builtins.py +++ b/pythonjs/runtime/builtins.py @@ -1390,6 +1390,8 @@ def __tuple_key__(arr): elif instanceof(item, Array): r.append( __tuple_key__(item) ) elif t=='object': + if item.__uid__ is undefined: + raise KeyError(item) r.append( item.__uid__ ) else: r.append( item ) @@ -1410,12 +1412,15 @@ def __init__(self, js_object=None, pointer=None): elif js_object: ob = js_object if instanceof(ob, Array): - #with lowlevel: for o in ob: - if instanceof(o, Array): - self.__setitem__( o[0], o[1] ) - else: - self.__setitem__( o['key'], o['value'] ) + with lowlevel: + if instanceof(o, Array): + k= o[0]; v= o[1] + else: + k= o['key']; v= o['value'] + + self.__setitem__( k,v ) + elif isinstance(ob, dict): for key in ob.keys(): value = ob[ key ] @@ -1501,16 +1506,22 @@ def __getitem__(self, key): err = True if err: - msg = "missing key: %s" %key - msg += "\n - dict keys: %s" %inline('Object.keys(__dict)') - raise KeyError(msg) + msg = "missing key: %s -\n" %key + raise KeyError(__dict.keys()) def __setitem__(self, key, value): with javascript: + if key is undefined: + raise KeyError('undefined is invalid key type') + if key is null: + raise KeyError('null is invalid key type') + __dict = self[...] if instanceof(key, Array): #key = JSON.stringify( key ) ## fails on objects with circular references ## key = __tuple_key__(key) + if key is undefined: + raise KeyError('undefined is invalid key type (tuple)') inline( '__dict[key] = value') elif JS("typeof(key) === 'object' || typeof(key) === 'function'"): if JS("key.__uid__ === undefined"): @@ -1521,7 +1532,7 @@ def __setitem__(self, key, value): JS('__dict[key] = value') def keys(self): - with javascript: + with lowlevel: return Object.keys( self[...] ) def pop(self, key, d=None): From ac85478965bcfe26a36aa3867016f21981bc06c6 Mon Sep 17 00:00:00 2001 From: hartsantler Date: Wed, 30 Jul 2014 20:58:49 -0700 Subject: [PATCH 048/100] regtest for builtin `round` --- regtests/lang/builtins.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/regtests/lang/builtins.py b/regtests/lang/builtins.py index df562bb..29ba91a 100644 --- a/regtests/lang/builtins.py +++ b/regtests/lang/builtins.py @@ -10,4 +10,8 @@ def main(): n = float('NaN') TestError( isNaN(n)==True ) + r = round( 1.1234, 2) + #print(r) + TestError( str(r) == '1.12' ) + From 5c00d750eed6f93fe802d002824b714bf87da529 Mon Sep 17 00:00:00 2001 From: hartsantler Date: Wed, 30 Jul 2014 21:06:01 -0700 Subject: [PATCH 049/100] updated builtins regtest --- regtests/lang/builtins.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/regtests/lang/builtins.py b/regtests/lang/builtins.py index 29ba91a..7d2c9f3 100644 --- a/regtests/lang/builtins.py +++ b/regtests/lang/builtins.py @@ -14,4 +14,9 @@ def main(): #print(r) TestError( str(r) == '1.12' ) + r = round( 100.001, 2) + TestError( r == 100 ) + + i = int( 100.1 ) + TestError( i == 100 ) From 2a03ea83c301a84526fd3a5398766f19d64a245e Mon Sep 17 00:00:00 2001 From: hartsantler Date: Thu, 31 Jul 2014 16:59:41 -0700 Subject: [PATCH 050/100] fixed builtin round --- pythonjs/pythonjs.js | 69 +++++++++++++++++++----------------- pythonjs/pythonjs.py | 14 +++++++- pythonjs/runtime/builtins.py | 16 +++++---- regtests/lang/builtins.py | 6 ++++ 4 files changed, 65 insertions(+), 40 deletions(-) diff --git a/pythonjs/pythonjs.js b/pythonjs/pythonjs.js index 19a4a8f..50c0664 100644 --- a/pythonjs/pythonjs.js +++ b/pythonjs/pythonjs.js @@ -1686,9 +1686,9 @@ var float = function(args, kwargs) { } ;float.is_wrapper = true; var round = function(args, kwargs) { - var y,x,c,b; + var p,b; var __sig__,__args__; - __sig__ = { kwargs:{},args:["a", "places"] }; + __sig__ = { kwargs:{"places": 0},args:["a", "places"] }; if (args instanceof Array && ( Object.prototype.toString.call(kwargs) ) == "[object Object]" && ( arguments.length ) == 2) { /*pass*/ } else { @@ -1702,10 +1702,8 @@ var round = function(args, kwargs) { if (( b.indexOf(".") ) == -1) { return a; } else { - c = b.split("."); - x = c[0]; - y = c[1].substring(0, places); - return parseFloat(((x + ".") + y)); + p = Math.pow(10, places); + return (Math.round((a * p)) / p); } } ;round.is_wrapper = true; @@ -2759,18 +2757,25 @@ var __dict___init__ = function(args, kwargs) { k = o["key"]; v = o["value"]; } - __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1198: self.__setitem__( k,v )"), "__call__")([k, v], __NULL_OBJECT__); + try { +__get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1199: self.__setitem__( k,v )"), "__call__")([k, v], __NULL_OBJECT__); + } catch(__exception__) { +if (__exception__ == KeyError || __exception__ instanceof KeyError) { +throw new KeyError("error in dict init, bad key"); +} + +} } } else { if (__test_if_true__(isinstance([ob, dict], __NULL_OBJECT__))) { var key,__iterator__46; - __iterator__46 = __get__(__get__(__jsdict_keys(ob), "__iter__", "no iterator - line 1200: for key in ob.keys():"), "__call__")([], __NULL_OBJECT__); + __iterator__46 = __get__(__get__(__jsdict_keys(ob), "__iter__", "no iterator - line 1203: for key in ob.keys():"), "__call__")([], __NULL_OBJECT__); var __next__46; __next__46 = __get__(__iterator__46, "next"); while (( __iterator__46.index ) < __iterator__46.length) { key = __next__46(); - value = ((ob instanceof Array) ? ob[key] : __get__(ob, "__getitem__", "line 1201: value = ob[ key ]")([key], __NULL_OBJECT__)); - __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1202: self.__setitem__( key, value )"), "__call__")([key, value], __NULL_OBJECT__); + value = ((ob instanceof Array) ? ob[key] : __get__(ob, "__getitem__", "line 1204: value = ob[ key ]")([key], __NULL_OBJECT__)); + __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1205: self.__setitem__( key, value )"), "__call__")([key, value], __NULL_OBJECT__); } } else { console.log("ERROR init dict from:", js_object); @@ -2796,15 +2801,15 @@ var __dict_jsify = function(args, kwargs) { var self = __args__['self']; keys = __object_keys__([self["$wrapped"]], __NULL_OBJECT__); var key,__iterator__47; - __iterator__47 = __get__(__get__(keys, "__iter__", "no iterator - line 1209: for key in keys:"), "__call__")([], __NULL_OBJECT__); + __iterator__47 = __get__(__get__(keys, "__iter__", "no iterator - line 1212: for key in keys:"), "__call__")([], __NULL_OBJECT__); var __next__47; __next__47 = __get__(__iterator__47, "next"); while (( __iterator__47.index ) < __iterator__47.length) { key = __next__47(); - value = __get__(self["$wrapped"], "__getitem__", "line 1210: value = self[...][key]")([key], __NULL_OBJECT__); + value = __get__(self["$wrapped"], "__getitem__", "line 1213: value = self[...][key]")([key], __NULL_OBJECT__); if (( typeof(value) ) == "object") { if (__test_if_true__(hasattr([value, "jsify"], __NULL_OBJECT__))) { - __get__(__get__(self["$wrapped"], "__setitem__"), "__call__")([key, __get__(__get__(value, "jsify", "missing attribute `jsify` - line 1213: self[...][key] = value.jsify()"), "__call__")()], {}); + __get__(__get__(self["$wrapped"], "__setitem__"), "__call__")([key, __get__(__get__(value, "jsify", "missing attribute `jsify` - line 1216: self[...][key] = value.jsify()"), "__call__")()], {}); } } else { if (( typeof(value) ) == "function") { @@ -2863,7 +2868,7 @@ var __dict_has_key = function(args, kwargs) { var key = __args__['key']; __dict = self["$wrapped"]; if (__test_if_true__(typeof(key) === 'object' || typeof(key) === 'function')) { - key = __get__(key, "__uid__", "missing attribute `__uid__` - line 1226: key = key.__uid__"); + key = __get__(key, "__uid__", "missing attribute `__uid__` - line 1229: key = key.__uid__"); } if (__test_if_true__(key in __dict)) { return true; @@ -2887,12 +2892,12 @@ var __dict_update = function(args, kwargs) { var self = __args__['self']; var other = __args__['other']; var key,__iterator__48; - __iterator__48 = __get__(__get__(other, "__iter__", "no iterator - line 1232: for key in other:"), "__call__")([], __NULL_OBJECT__); + __iterator__48 = __get__(__get__(other, "__iter__", "no iterator - line 1235: for key in other:"), "__call__")([], __NULL_OBJECT__); var __next__48; __next__48 = __get__(__iterator__48, "next"); while (( __iterator__48.index ) < __iterator__48.length) { key = __next__48(); - __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1233: self.__setitem__( key, other[key] )"), "__call__")([key, ((other instanceof Array) ? other[key] : __get__(other, "__getitem__", "line 1233: self.__setitem__( key, other[key] )")([key], __NULL_OBJECT__))], __NULL_OBJECT__); + __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1236: self.__setitem__( key, other[key] )"), "__call__")([key, ((other instanceof Array) ? other[key] : __get__(other, "__getitem__", "line 1236: self.__setitem__( key, other[key] )")([key], __NULL_OBJECT__))], __NULL_OBJECT__); } } ;__dict_update.is_wrapper = true; @@ -2911,12 +2916,12 @@ var __dict_items = function(args, kwargs) { var self = __args__['self']; arr = []; var key,__iterator__49; - __iterator__49 = __get__(__get__(__jsdict_keys(self), "__iter__", "no iterator - line 1236: for key in self.keys():"), "__call__")([], __NULL_OBJECT__); + __iterator__49 = __get__(__get__(__jsdict_keys(self), "__iter__", "no iterator - line 1239: for key in self.keys():"), "__call__")([], __NULL_OBJECT__); var __next__49; __next__49 = __get__(__iterator__49, "next"); while (( __iterator__49.index ) < __iterator__49.length) { key = __next__49(); - __get__(__get__(arr, "append", "missing attribute `append` - line 1237: arr.append( [key, self[key]] )"), "__call__")([[key, __get__(self, "__getitem__")([key], __NULL_OBJECT__)]], __NULL_OBJECT__); + __get__(__get__(arr, "append", "missing attribute `append` - line 1240: arr.append( [key, self[key]] )"), "__call__")([[key, __get__(self, "__getitem__")([key], __NULL_OBJECT__)]], __NULL_OBJECT__); } return arr; } @@ -2959,7 +2964,7 @@ var __dict_set = function(args, kwargs) { var self = __args__['self']; var key = __args__['key']; var value = __args__['value']; - __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1245: self.__setitem__(key, value)"), "__call__")([key, value], __NULL_OBJECT__); + __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1248: self.__setitem__(key, value)"), "__call__")([key, value], __NULL_OBJECT__); } ;__dict_set.is_wrapper = true; __dict_attrs.set = __dict_set; @@ -3278,7 +3283,7 @@ var __array___init__ = function(args, kwargs) { var initializer = __args__['initializer']; var little_endian = __args__['little_endian']; self.typecode = typecode; - self.itemsize = __get__(__get__(self, "typecodes", "missing attribute `typecodes` - line 1429: self.itemsize = self.typecodes[ typecode ]"), "__getitem__", "line 1429: self.itemsize = self.typecodes[ typecode ]")([typecode], __NULL_OBJECT__); + self.itemsize = __get__(__get__(self, "typecodes", "missing attribute `typecodes` - line 1432: self.itemsize = self.typecodes[ typecode ]"), "__getitem__", "line 1432: self.itemsize = self.typecodes[ typecode ]")([typecode], __NULL_OBJECT__); self.little_endian = little_endian; if (__test_if_true__(initializer)) { self.length = len([initializer], __NULL_OBJECT__); @@ -3302,7 +3307,7 @@ var __array___init__ = function(args, kwargs) { buff = new ArrayBuffer(size); self.dataview = new DataView(buff); self.buffer = buff; - __get__(__get__(self, "fromlist", "missing attribute `fromlist` - line 1450: self.fromlist( initializer )"), "__call__")([initializer], __NULL_OBJECT__); + __get__(__get__(self, "fromlist", "missing attribute `fromlist` - line 1453: self.fromlist( initializer )"), "__call__")([initializer], __NULL_OBJECT__); } ;__array___init__.is_wrapper = true; __array_attrs.__init__ = __array___init__; @@ -3335,7 +3340,7 @@ var __array___contains__ = function(args, kwargs) { __args__ = __getargs__("__array___contains__", __sig__, args, kwargs); var self = __args__['self']; var value = __args__['value']; - arr = __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1456: arr = self.to_array()"), "__call__")(); + arr = __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1459: arr = self.to_array()"), "__call__")(); if (( arr.indexOf(value) ) == -1) { return false; } else { @@ -3360,7 +3365,7 @@ var __array___getitem__ = function(args, kwargs) { step = self.itemsize; offset = (step * index); dataview = self.dataview; - func_name = ("get" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1464: func_name = 'get'+self.typecode_names[ self.typecode ]"), "__getitem__", "line 1464: func_name = 'get'+self.typecode_names[ self.typecode ]")([self.typecode], __NULL_OBJECT__)); + func_name = ("get" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1467: func_name = 'get'+self.typecode_names[ self.typecode ]"), "__getitem__", "line 1467: func_name = 'get'+self.typecode_names[ self.typecode ]")([self.typecode], __NULL_OBJECT__)); func = dataview[func_name].bind(dataview); if (( offset ) < self.bytes) { value = func(offset); @@ -3398,7 +3403,7 @@ var __array___setitem__ = function(args, kwargs) { } offset = (step * index); dataview = self.dataview; - func_name = ("set" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1480: func_name = 'set'+self.typecode_names[ self.typecode ]"), "__getitem__", "line 1480: func_name = 'set'+self.typecode_names[ self.typecode ]")([self.typecode], __NULL_OBJECT__)); + func_name = ("set" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1483: func_name = 'set'+self.typecode_names[ self.typecode ]"), "__getitem__", "line 1483: func_name = 'set'+self.typecode_names[ self.typecode ]")([self.typecode], __NULL_OBJECT__)); func = dataview[func_name].bind(dataview); if (( offset ) < self.bytes) { if (( self.typecode ) == "float8") { @@ -3466,13 +3471,13 @@ var __array_fromlist = function(args, kwargs) { typecode = self.typecode; size = (length * step); dataview = self.dataview; - func_name = ("set" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1500: func_name = 'set'+self.typecode_names[ typecode ]"), "__getitem__", "line 1500: func_name = 'set'+self.typecode_names[ typecode ]")([typecode], __NULL_OBJECT__)); + func_name = ("set" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1503: func_name = 'set'+self.typecode_names[ typecode ]"), "__getitem__", "line 1503: func_name = 'set'+self.typecode_names[ typecode ]")([typecode], __NULL_OBJECT__)); func = dataview[func_name].bind(dataview); if (( size ) <= self.bytes) { i = 0; offset = 0; while (( i ) < length) { - item = ((lst instanceof Array) ? lst[i] : __get__(lst, "__getitem__", "line 1505: item = lst[i]")([i], __NULL_OBJECT__)); + item = ((lst instanceof Array) ? lst[i] : __get__(lst, "__getitem__", "line 1508: item = lst[i]")([i], __NULL_OBJECT__)); if (( typecode ) == "float8") { item *= self._norm_set; } else { @@ -3530,7 +3535,7 @@ var __array_append = function(args, kwargs) { var self = __args__['self']; var value = __args__['value']; length = self.length; - __get__(__get__(self, "resize", "missing attribute `resize` - line 1528: self.resize( self.length + 1 )"), "__call__")([(self.length + 1)], __NULL_OBJECT__); + __get__(__get__(self, "resize", "missing attribute `resize` - line 1531: self.resize( self.length + 1 )"), "__call__")([(self.length + 1)], __NULL_OBJECT__); __get__(__get__(self, "__setitem__"), "__call__")([length, value], {}); } ;__array_append.is_wrapper = true; @@ -3549,12 +3554,12 @@ var __array_extend = function(args, kwargs) { var self = __args__['self']; var lst = __args__['lst']; var value,__iterator__54; - __iterator__54 = __get__(__get__(lst, "__iter__", "no iterator - line 1531: for value in lst:"), "__call__")([], __NULL_OBJECT__); + __iterator__54 = __get__(__get__(lst, "__iter__", "no iterator - line 1534: for value in lst:"), "__call__")([], __NULL_OBJECT__); var __next__54; __next__54 = __get__(__iterator__54, "next"); while (( __iterator__54.index ) < __iterator__54.length) { value = __next__54(); - __get__(__get__(self, "append", "missing attribute `append` - line 1532: self.append( value )"), "__call__")([value], __NULL_OBJECT__); + __get__(__get__(self, "append", "missing attribute `append` - line 1535: self.append( value )"), "__call__")([value], __NULL_OBJECT__); } } ;__array_extend.is_wrapper = true; @@ -3594,7 +3599,7 @@ var __array_to_list = function(args, kwargs) { } __args__ = __getargs__("__array_to_list", __sig__, args, kwargs); var self = __args__['self']; - return __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1542: return self.to_array()"), "__call__")(); + return __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1545: return self.to_array()"), "__call__")(); } ;__array_to_list.is_wrapper = true; __array_attrs.to_list = __array_to_list; @@ -3611,9 +3616,9 @@ var __array_to_ascii = function(args, kwargs) { __args__ = __getargs__("__array_to_ascii", __sig__, args, kwargs); var self = __args__['self']; string = ""; - arr = __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1545: arr = self.to_array()"), "__call__")(); + arr = __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1548: arr = self.to_array()"), "__call__")(); i = 0; - length = __get__(arr, "length", "missing attribute `length` - line 1546: i = 0; length = arr.length"); + length = __get__(arr, "length", "missing attribute `length` - line 1549: i = 0; length = arr.length"); while (( i ) < length) { var num = arr[i]; var char = String.fromCharCode(num); diff --git a/pythonjs/pythonjs.py b/pythonjs/pythonjs.py index 3910e7c..fc61459 100755 --- a/pythonjs/pythonjs.py +++ b/pythonjs/pythonjs.py @@ -338,9 +338,14 @@ def _visit_function(self, node): raise RuntimeError(chunks) sub = [] for ci,chk in enumerate(chunks): + #if not chk.startswith('@'): ## special inline javascript. + # chk = '```'+chk+'```' + #chk = chk.replace('$', '```') + if not ci%2: if '@' in chk: raise SyntaxError(chunks) + if ci==0: if chk: sub.append('"%s"'%chk) @@ -363,6 +368,7 @@ def _visit_function(self, node): lines.append( 'glsljit.push(%s);' %''.join(sub)) else: + sub = sub.replace('$', '```') lines.append( 'glsljit.push("%s");' %(self.indent()+sub) ) @@ -400,9 +406,11 @@ def _visit_function(self, node): lines.append(' var __webclgl = new WebCLGL()') lines.append(' var header = glsljit.compile_header()') lines.append(' var shader = glsljit.compile_main()') - lines.append(' console.log(header)') + + #lines.append(' console.log(header)') lines.append(' console.log("-----------")') lines.append(' console.log(shader)') + ## create the webCLGL kernel, compiles GLSL source lines.append(' var __kernel = __webclgl.createKernel( shader, header );') @@ -1072,6 +1080,8 @@ def visit_For(self, node): '`@var %s = %s[0];`' %(target, iter) ## capture first item with target name so that for loops can get the length of member arrays ] + ##TODO## lines.append('$') ## optimizes webclgl parser + lines.append('for (int _iter=0; _iter < `__length__`; _iter++) {' ) ## declare struct variable ## @@ -1082,6 +1092,8 @@ def visit_For(self, node): lines.append( '`@glsljit.push("if (_iter==" +__j+ ") { %s=%s_" +__j+ ";}");`' %(target, iter)) lines.append( '`@}`') + ##TODO## lines.append('$') ## optimizes webclgl parser + elif isinstance(node.iter, ast.Call): ## `for i in range(n):` iter = self.visit(node.iter.args[0]) diff --git a/pythonjs/runtime/builtins.py b/pythonjs/runtime/builtins.py index dd8db3a..767f274 100644 --- a/pythonjs/runtime/builtins.py +++ b/pythonjs/runtime/builtins.py @@ -812,17 +812,16 @@ def float(a): raise ValueError('can not convert to float: '+a) return b -def round(a, places): +def round(a, places=0): with javascript: b = '' + a if b.indexOf('.') == -1: return a else: - c = b.split('.') - x = c[0] - y = c[1].substring(0, places) - return parseFloat( x+'.'+y ) - + ## this could return NaN with large numbers and large places, + ## TODO check for NaN and instead fallback to `a.toFixed(places)` + p = Math.pow(10, places) + return Math.round(a * p) / p def str(s): return ''+s @@ -1419,7 +1418,10 @@ def __init__(self, js_object=None, pointer=None): else: k= o['key']; v= o['value'] - self.__setitem__( k,v ) + try: + self.__setitem__( k,v ) + except KeyError: + raise KeyError('error in dict init, bad key') elif isinstance(ob, dict): for key in ob.keys(): diff --git a/regtests/lang/builtins.py b/regtests/lang/builtins.py index 7d2c9f3..61cbd2a 100644 --- a/regtests/lang/builtins.py +++ b/regtests/lang/builtins.py @@ -20,3 +20,9 @@ def main(): i = int( 100.1 ) TestError( i == 100 ) + r = round( 5.49 ) + TestError( r == 5 ) + + r = round( 5.49, 1 ) + TestError( r == 5.5 ) + From a4f9f527fd64fb47f1c56cb5aa1223c8016c59f6 Mon Sep 17 00:00:00 2001 From: hartsantler Date: Thu, 31 Jul 2014 17:56:23 -0700 Subject: [PATCH 051/100] Golang backend: hello world. --- pythonjs/pythonjs_to_go.py | 22 +++++++++++++++++++--- regtests/exceptions/AttributeError.py | 13 +++++++++++++ regtests/go/print.py | 4 ++++ regtests/run.py | 27 ++++++++++++++++++--------- 4 files changed, 54 insertions(+), 12 deletions(-) create mode 100644 regtests/exceptions/AttributeError.py create mode 100644 regtests/go/print.py diff --git a/pythonjs/pythonjs_to_go.py b/pythonjs/pythonjs_to_go.py index 6b3c46e..060c7a4 100644 --- a/pythonjs/pythonjs_to_go.py +++ b/pythonjs/pythonjs_to_go.py @@ -15,6 +15,11 @@ def __init__(self, requirejs=False, insert_runtime=False): #self._classes = dict() #self._class_props = dict() + def visit_Print(self, node): + r = [ 'fmt.Print(%s);' %self.visit(e) for e in node.values] + return ''.join(r) + + def visit_Module(self, node): header = [ 'package main', @@ -63,9 +68,20 @@ def _visit_call_helper_var(self, node): out = [] for v in args: - out.append( self.indent() + 'var ' + v) - - return '\n'.join(out) + out.append( self.indent() + 'var ' + v + ' int') + + #return '\n'.join(out) + return '' + + def visit_Assign(self, node): + target = node.targets[0] + if isinstance(target, ast.Tuple): + raise NotImplementedError('target tuple assignment should have been transformed to flat assignment by python_to_pythonjs.py') + else: + target = self.visit(target) + value = self.visit(node.value) + code = 'var %s = %s;' % (target, value) + return code def main(script): diff --git a/regtests/exceptions/AttributeError.py b/regtests/exceptions/AttributeError.py new file mode 100644 index 0000000..bb302ae --- /dev/null +++ b/regtests/exceptions/AttributeError.py @@ -0,0 +1,13 @@ +"""catch AttributeError""" + +class A: pass + +def main(): + a = A() + b = False + try: + b = a.xxx + except AttributeError: + b = True + + TestError( b == True ) diff --git a/regtests/go/print.py b/regtests/go/print.py new file mode 100644 index 0000000..363f081 --- /dev/null +++ b/regtests/go/print.py @@ -0,0 +1,4 @@ +"""hello world""" + +def main(): + print "hi" diff --git a/regtests/run.py b/regtests/run.py index fc6e013..e826ab2 100755 --- a/regtests/run.py +++ b/regtests/run.py @@ -142,9 +142,13 @@ def run_old_pypy_test_on(filename): old_pypy_runnable = True old_pypy_exe = os.path.expanduser('~/pypy-1.9/bin/pypy') -webclgl = None -if os.path.isfile( os.path.expanduser('~/webclgl/WebCLGL_2.0.Min.class.js') ): - webclgl = open( os.path.expanduser('~/webclgl/WebCLGL_2.0.Min.class.js'), 'rb').read().decode('utf-8') +webclgl = [] +if os.path.isdir( os.path.expanduser('~/webclgl') ): + #webclgl.append( open( os.path.expanduser('~/webclgl/WebCLGL_2.0.Min.class.js'), 'rb').read().decode('utf-8') ) + webclgl.append( open( os.path.expanduser('~/webclgl/WebCLGLUtils.class.js'), 'rb').read().decode('utf-8') ) + webclgl.append( open( os.path.expanduser('~/webclgl/WebCLGLBuffer.class.js'), 'rb').read().decode('utf-8') ) + webclgl.append( open( os.path.expanduser('~/webclgl/WebCLGLKernel.class.js'), 'rb').read().decode('utf-8') ) + webclgl.append( open( os.path.expanduser('~/webclgl/WebCLGL.class.js'), 'rb').read().decode('utf-8') ) ## rhino is not run by default because it simply freezes up on maximum callstack errors rhino_runnable = '--rhino' in sys.argv and runnable("rhino -e 'quit()'") @@ -432,10 +436,11 @@ def patch_python(filename, dart=False, python='PYTHONJS', backend=None): # out.append( line ) # code = '\n'.join( out ) a = [ - _patch_header, 'PYTHON="%s"'%python, 'BACKEND="%s"'%backend, ] + if backend != 'GO': + a.append(_patch_header) if python != 'PYTHONJS': code = typedpython.transform_source( code, strip=True ) @@ -693,9 +698,10 @@ def run_js_nodewebkit(content): html = [''] if webclgl: - html.append('') + for data in webclgl: + html.append('') html.append('') + if script is True: + self._html_tail.extend( o ) + else: + for y in o: + writer.write(y) + + else: + writer.write(line) + elif line.strip() == '': - if script: + if type(script) is list and len(script): source = '\n'.join(script) - script = True - self._html_tail.append( '') + script = True + self._html_tail.append( '') + else: + writer.write( line ) elif isinstance( script, list ): script.append( line ) @@ -174,7 +201,7 @@ def __init__(self, source=None, module=None, module_path=None, dart=False, coffe self._direct_operators = set() ## optimize "+" and "*" operator self._with_ll = False ## lowlevel - self._with_js = False + self._with_js = True self._in_lambda = False self._in_while_test = False self._use_threading = False @@ -272,8 +299,14 @@ def __init__(self, source=None, module=None, module_path=None, dart=False, coffe self._source = source.splitlines() + if '--debug' in sys.argv: + try: + tree = ast.parse( source ) + except: + raise SyntaxError(source) + else: + tree = ast.parse( source ) - tree = parse( source ) ## ast.parse self._generator_function_nodes = collect_generator_functions( tree ) for node in tree.body: diff --git a/pythonjs/pythonjs.py b/pythonjs/pythonjs.py index d9db207..41a234f 100755 --- a/pythonjs/pythonjs.py +++ b/pythonjs/pythonjs.py @@ -1265,6 +1265,7 @@ def main(source, requirejs=True, insert_runtime=True, webworker=False, function_ head = [] tail = [] script = False + osource = source if source.strip().startswith('') script = list() elif line.strip() == '': - if script: + if type(script) is list: source = '\n'.join(script) - script = True - tail.append( '') + script = True + tail.append( '') + elif script is True: + tail.append( '') + else: + head.append( '') elif isinstance( script, list ): script.append( line ) @@ -1315,6 +1320,10 @@ def main(source, requirejs=True, insert_runtime=True, webworker=False, function_ sys.stderr.write( lines[lineno] ) sys.stderr.write( '\n' ) + if '--debug' in sys.argv: + sys.stderr.write( osource ) + sys.stderr.write( '\n' ) + sys.exit(1) gen = JSGenerator( requirejs=requirejs, insert_runtime=insert_runtime, webworker=webworker, function_expressions=function_expressions ) diff --git a/pythonjs/translator.py b/pythonjs/translator.py index 0d12938..b133f66 100755 --- a/pythonjs/translator.py +++ b/pythonjs/translator.py @@ -51,6 +51,7 @@ def main(script, module_path=None): code = pythonjs_to_luajs( a ) else: a = python_to_pythonjs(script, module_path=module_path) + if isinstance(a, dict): res = {} for jsfile in a: From 1dc78a8c9b59b12f053ea3e25fafc8128e113457 Mon Sep 17 00:00:00 2001 From: hartsantler Date: Sat, 30 Aug 2014 08:21:08 -0700 Subject: [PATCH 085/100] improved `new` syntax keyword. --- pythonjs/pythonjs.py | 5 ++++- pythonjs/typedpython.py | 5 +++-- regtests/html/date.html | 18 ++++++++++++++++++ 3 files changed, 25 insertions(+), 3 deletions(-) create mode 100644 regtests/html/date.html diff --git a/pythonjs/pythonjs.py b/pythonjs/pythonjs.py index 41a234f..b56c759 100755 --- a/pythonjs/pythonjs.py +++ b/pythonjs/pythonjs.py @@ -950,7 +950,10 @@ def visit_BinOp(self, node): op = self.visit(node.op) right = self.visit(node.right) - if op == '<<': + if op == '>>' and left == '__new__': + return ' new %s' %right + + elif op == '<<': if left in ('__go__receive__', '__go__send__'): return '<- %s' %right elif isinstance(node.left, ast.Call) and isinstance(node.left.func, ast.Name) and node.left.func.id in ('__go__array__', '__go__arrayfixed__', '__go__map__'): diff --git a/pythonjs/typedpython.py b/pythonjs/typedpython.py index d4d813c..5f9ff3e 100644 --- a/pythonjs/typedpython.py +++ b/pythonjs/typedpython.py @@ -155,8 +155,9 @@ def transform_source( source, strip=False ): elif c.startswith('import ') and '-' in c: c = c.replace('-', '__DASH__') elif ' new ' in c: - c += ')' * c.count(' new ') - c = c.replace(' new ', ' new(') + #c += ')' * c.count(' new ') + #c = c.replace(' new ', ' new(') + c = c.replace(' new ', ' __new__>>') diff --git a/regtests/html/date.html b/regtests/html/date.html new file mode 100644 index 0000000..97b3f50 --- /dev/null +++ b/regtests/html/date.html @@ -0,0 +1,18 @@ + + + + + + + + + + \ No newline at end of file From db92530aec387684ae811f0c48fa7db3eb1ecf21 Mon Sep 17 00:00:00 2001 From: hartsantler Date: Sat, 30 Aug 2014 09:40:53 -0700 Subject: [PATCH 086/100] fixed `JS(" new XXX")` --- pythonjs/pythonjs.py | 4 +++- regtests/lang/new.py | 8 ++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 regtests/lang/new.py diff --git a/pythonjs/pythonjs.py b/pythonjs/pythonjs.py index b56c759..8dd2704 100755 --- a/pythonjs/pythonjs.py +++ b/pythonjs/pythonjs.py @@ -919,7 +919,9 @@ def _inline_code_helper(self, s): ## TODO, should newline be changed here? s = s.replace('\n', '\\n').replace('\0', '\\0') ## AttributeError: 'BinOp' object has no attribute 's' - this is caused by bad quotes if s.strip().startswith('#'): s = '/*%s*/'%s - if '"' in s or "'" in s: ## can not trust direct-replace hacks + if '__new__>>' in s: ## fixes inline `JS("new XXX")` + s = s.replace('__new__>>', ' new ') + elif '"' in s or "'" in s: ## can not trust direct-replace hacks pass else: if ' or ' in s: diff --git a/regtests/lang/new.py b/regtests/lang/new.py new file mode 100644 index 0000000..b65296b --- /dev/null +++ b/regtests/lang/new.py @@ -0,0 +1,8 @@ +''' +js new keyword +''' + +def main(): + #a = new Date() ## this also works + a = JS(' new Date()') + TestError( a.getFullYear()==2014 ) From 628d2a8e664d34822b71fb6a0785767c5f9a9b1d Mon Sep 17 00:00:00 2001 From: hartsantler Date: Mon, 1 Sep 2014 07:21:49 -0700 Subject: [PATCH 087/100] fixed ` new XXX` tab space before new. --- pythonjs/typedpython.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pythonjs/typedpython.py b/pythonjs/typedpython.py index 5f9ff3e..c2ebf3e 100644 --- a/pythonjs/typedpython.py +++ b/pythonjs/typedpython.py @@ -154,11 +154,11 @@ def transform_source( source, strip=False ): output.append( indent + '@returns(%s)' %rtype) elif c.startswith('import ') and '-' in c: c = c.replace('-', '__DASH__') - elif ' new ' in c: - #c += ')' * c.count(' new ') - #c = c.replace(' new ', ' new(') - c = c.replace(' new ', ' __new__>>') + if ' new ' in c: + c = c.replace(' new ', ' __new__>>') + if '\tnew ' in c: + c = c.replace('\tnew ', ' __new__>>') ## golang From c7a77447d4a95edef50bd4ee064c93e7c14f8d78 Mon Sep 17 00:00:00 2001 From: hartsantler Date: Wed, 3 Sep 2014 02:18:45 -0700 Subject: [PATCH 088/100] new backend Gopherjs --- pythonjs/translator.py | 13 +++++++++++++ regtests/run.py | 19 +++++++++++++++++-- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/pythonjs/translator.py b/pythonjs/translator.py index b133f66..0b772f9 100755 --- a/pythonjs/translator.py +++ b/pythonjs/translator.py @@ -27,6 +27,19 @@ def main(script, module_path=None): if '--go' in sys.argv: a = python_to_pythonjs(script, go=True, module_path=module_path) code = pythonjs_to_go( a ) + elif '--gopherjs' in sys.argv: + a = python_to_pythonjs(script, go=True, module_path=module_path) + code = pythonjs_to_go( a ) + + exe = os.path.expanduser('~/go/bin/gopherjs') + if not os.path.isfile(exe): + raise RuntimeError('gopherjs not installed to ~/go/bin/gopherjs') + import subprocess + path = '/tmp/gopherjs-input.go' + open(path, 'wb').write(code) + subprocess.check_call([exe, 'build', path], cwd='/tmp') + code = open('/tmp/gopherjs-input.js', 'rb').read() + elif '--dart' in sys.argv: a = python_to_pythonjs(script, dart=True, module_path=module_path) code = pythonjs_to_dart( a ) diff --git a/regtests/run.py b/regtests/run.py index 9a8702a..cf5ff34 100755 --- a/regtests/run.py +++ b/regtests/run.py @@ -194,6 +194,7 @@ def run_old_pypy_test_on(filename): luajs_runnable = os.path.isfile( lua2js ) and '--lua2js' in sys.argv go_runnable = runnable( 'go version') +gopherjs_runnable = runnable( 'gopherjs') assert rhino_runnable or node_runnable @@ -474,7 +475,7 @@ def run_python3_test_on(filename): -def translate_js(filename, javascript=False, dart=False, coffee=False, lua=False, luajs=False, go=False, multioutput=False, requirejs=True): +def translate_js(filename, javascript=False, dart=False, coffee=False, lua=False, luajs=False, go=False, gopherjs=False, multioutput=False, requirejs=True): global tmpname tmpname = os.path.join( tempfile.gettempdir(), @@ -506,7 +507,7 @@ def translate_js(filename, javascript=False, dart=False, coffee=False, lua=False ] content = '\n'.join( source ) - elif go: + elif go or gopherjs: content = patch_python(filename, backend='GO') else: @@ -535,6 +536,8 @@ def translate_js(filename, javascript=False, dart=False, coffee=False, lua=False cmd.append( '--luajs') elif go: cmd.append( '--go' ) + elif gopherjs: + cmd.append( '--gopherjs' ) if not requirejs: cmd.append( '--no-wrapper' ) @@ -799,6 +802,15 @@ def run_go(content): return run_command( '/tmp/regtest-go' ) +def run_pythonjs_gopherjs_test(dummy_filename): + """PythonJS (Gopherjs)""" + return run_if_no_error(run_gopherjs_node) + +def run_gopherjs_node(content): + """Run Gopherjs using Node""" + write("%s.js" % tmpname, content) + return run_command("node %s.js" % tmpname) + def run_html_test( filename, sum_errors ): lines = open(filename, 'rb').read().decode('utf-8').splitlines() filename = os.path.split(filename)[-1] @@ -967,6 +979,9 @@ def display(function): js = translate_js(filename, go=True) display(run_pythonjs_go_test) + if gopherjs_runnable: + js = translate_js(filename, gopherjs=True) + display(run_pythonjs_gopherjs_test) print() return sum_errors From 276b5f79b64b38de676c01384bd4460ba822f829 Mon Sep 17 00:00:00 2001 From: hartsantler Date: Wed, 3 Sep 2014 09:18:07 -0700 Subject: [PATCH 089/100] Go backend: fixed chan test, and sending data over a channel. --- pythonjs/python_to_pythonjs.py | 1 + pythonjs/pythonjs_to_go.py | 21 ++++++++++++++++----- pythonjs/typedpython.py | 9 +++++---- regtests/go/chan.py | 15 +++++++-------- 4 files changed, 29 insertions(+), 17 deletions(-) diff --git a/pythonjs/python_to_pythonjs.py b/pythonjs/python_to_pythonjs.py index 4bbba7a..d3fa084 100755 --- a/pythonjs/python_to_pythonjs.py +++ b/pythonjs/python_to_pythonjs.py @@ -2780,6 +2780,7 @@ def visit_FunctionDef(self, node): local_typedefs.append( '%s=%s' %(kw.arg, kwval)) if decorator.func.id=='typedef_chan': typedef_chans.append( kw.arg ) + writer.write('@__typedef_chan__(%s=%s)' %(kw.arg, kwval)) else: writer.write('@__typedef__(%s=%s)' %(kw.arg, kwval)) diff --git a/pythonjs/pythonjs_to_go.py b/pythonjs/pythonjs_to_go.py index 9eecbe4..4bccfe4 100644 --- a/pythonjs/pythonjs_to_go.py +++ b/pythonjs/pythonjs_to_go.py @@ -217,20 +217,26 @@ def _visit_call_helper_go(self, node): return 'go %s' %self.visit(node.args[0]) elif name == '__gomake__': return 'make(%s)' %self.visit(node.args[0]) + elif name == '__go_make_chan__': + return 'make(chan %s)' %self.visit(node.args[0]) else: - return SyntaxError('invalid special go call') + raise SyntaxError('invalid special go call') def _visit_function(self, node): if self._function_stack[0] is node: self._vars = set() args_typedefs = {} + chan_args_typedefs = {} return_type = None for decor in node.decorator_list: if isinstance(decor, ast.Call) and isinstance(decor.func, ast.Name) and decor.func.id == '__typedef__': for key in decor.keywords: #args_typedefs[ key.arg ] = key.value.id args_typedefs[ key.arg ] = self.visit(key.value) + elif isinstance(decor, ast.Call) and isinstance(decor.func, ast.Name) and decor.func.id == '__typedef_chan__': + for key in decor.keywords: + chan_args_typedefs[ key.arg ] = self.visit(key.value) elif isinstance(decor, ast.Call) and isinstance(decor.func, ast.Name) and decor.func.id == 'returns': if decor.keywords: raise SyntaxError('invalid go return type') @@ -248,7 +254,7 @@ def _visit_function(self, node): for i, arg in enumerate(node.args.args): arg_name = arg.id - if arg_name not in args_typedefs: + if arg_name not in args_typedefs.keys()+chan_args_typedefs.keys(): if arg_name=='self': assert i==0 is_method = True @@ -258,8 +264,13 @@ def _visit_function(self, node): err += '\n missing typedef: %s' %arg.id raise SyntaxError(err) - arg_type = args_typedefs[arg_name] - a = '%s %s' %(arg_name, arg_type) + if arg_name in args_typedefs: + arg_type = args_typedefs[arg_name] + a = '%s %s' %(arg_name, arg_type) + else: + arg_type = chan_args_typedefs[arg_name] + a = '%s chan %s' %(arg_name, arg_type) + dindex = i - offset if a.startswith('__variable_args__'): ## TODO support go `...` varargs @@ -347,7 +358,7 @@ def visit_Assign(self, node): elif isinstance(node.value, ast.BinOp) and self.visit(node.value.op)=='<<' and isinstance(node.value.left, ast.Name) and node.value.left.id=='__go__send__': target = self.visit(target) value = self.visit(node.value.right) - return 'var %s <- %s;' % (target, value) + return '%s <- %s;' % (target, value) elif not self._function_stack: target = self.visit(target) diff --git a/pythonjs/typedpython.py b/pythonjs/typedpython.py index c2ebf3e..7f31496 100644 --- a/pythonjs/typedpython.py +++ b/pythonjs/typedpython.py @@ -23,7 +23,7 @@ GO_SPECIAL_CALLS = { 'go' : '__go__', - 'go.channel' : '__gomake__', + 'go.channel' : '__go_make_chan__', } def transform_source( source, strip=False ): @@ -267,8 +267,9 @@ def transform_source( source, strip=False ): y, kw = y.split('=') arg, typedef = y.split(':') chan = False - if len(arg.split()) == 2: - chan, arg = arg.split() + if len(typedef.strip().split()) == 2: + chan = True + typedef = typedef.strip().split()[-1] if '*' in arg: arg_name = arg.split('*')[-1] else: @@ -385,7 +386,7 @@ def xxx(): def call_method( cb:func(int)(int) ) ->int: return cb(3) -def wrapper(a:int, chan c:int): +def wrapper(a:int, c:chan int): result = longCalculation(a) c <- result diff --git a/regtests/go/chan.py b/regtests/go/chan.py index 1ddbcf1..fdf6e02 100644 --- a/regtests/go/chan.py +++ b/regtests/go/chan.py @@ -1,17 +1,16 @@ -"""a <- """ +"""send int over channel""" + +def wrapper(a:int, c: chan int): + result = 100 + c <- result def main(): c = go.channel(int) - - def wrapper(a:int, chan c:int): - result = 100 - c <- result - go( - wrapper(17, c) - ) + go( wrapper(17, c) ) # Do other work in the current goroutine until the channel has a result. x = <-c print(x) + TestError(x==100) From c1a088b9cd45b1a37b1945290fec9326188ef11c Mon Sep 17 00:00:00 2001 From: hartsantler Date: Wed, 3 Sep 2014 13:40:18 -0700 Subject: [PATCH 090/100] Go backend: fixed select on channel --- pythonjs/python_to_pythonjs.py | 2 +- pythonjs/pythonjs_to_go.py | 61 ++++++++++++++++++++++++++++++++-- regtests/go/select.py | 44 +++++++++++++++++++----- 3 files changed, 95 insertions(+), 12 deletions(-) diff --git a/pythonjs/python_to_pythonjs.py b/pythonjs/python_to_pythonjs.py index d3fa084..802ec1a 100755 --- a/pythonjs/python_to_pythonjs.py +++ b/pythonjs/python_to_pythonjs.py @@ -2107,7 +2107,7 @@ def _visit_assign_helper(self, node, target): writer.write("%s = __ternary_operator__(instanceof(%s,Array), %s[%s], %s)" % (self.visit(target), r, r,i, fallback )) def visit_Print(self, node): - writer.write('print %s' % ', '.join(map(self.visit, node.values))) + writer.write('print(%s)' % ', '.join(map(self.visit, node.values))) def visit_Str(self, node): s = node.s.replace('\\','\\\\').replace('\n', '\\n').replace('\r', '\\r').replace('\0', '\\0') diff --git a/pythonjs/pythonjs_to_go.py b/pythonjs/pythonjs_to_go.py index 4bccfe4..73e4864 100644 --- a/pythonjs/pythonjs_to_go.py +++ b/pythonjs/pythonjs_to_go.py @@ -18,6 +18,7 @@ def __init__(self, requirejs=False, insert_runtime=False): self._class_props = dict() self._vars = set() + self._known_vars = set() self._kwargs_type_ = dict() def visit_ClassDef(self, node): @@ -89,7 +90,13 @@ def visit_Slice(self, node): def visit_Print(self, node): - r = [ 'fmt.Println(%s);' %self.visit(e) for e in node.values] + r = [] + for e in node.values: + s = self.visit(e) + if isinstance(e, ast.List): + r.append('fmt.Println(%s);' %s[1:-1]) + else: + r.append('fmt.Println(%s);' %s) return ''.join(r) def visit_Expr(self, node): @@ -225,6 +232,7 @@ def _visit_call_helper_go(self, node): def _visit_function(self, node): if self._function_stack[0] is node: self._vars = set() + self._known_vars = set() args_typedefs = {} chan_args_typedefs = {} @@ -350,6 +358,47 @@ def _visit_call_helper_var(self, node): #return '\n'.join(out) return '' + def visit_With(self, node): + r = [] + is_switch = False + if isinstance( node.context_expr, ast.Name ) and node.context_expr.id == '__default__': + r.append('default:') + elif isinstance( node.context_expr, ast.Name ) and node.context_expr.id == '__select__': + r.append('select {') + is_switch = True + elif isinstance( node.context_expr, ast.Call ): + if not isinstance(node.context_expr.func, ast.Name): + raise SyntaxError( self.visit(node.context_expr)) + + if len(node.context_expr.args): + a = self.visit(node.context_expr.args[0]) + else: + assert len(node.context_expr.keywords) + ## need to catch if this is a new variable ## + name = node.context_expr.keywords[0].arg + if name not in self._known_vars: + a = '%s := %s' %(name, self.visit(node.context_expr.keywords[0].value)) + else: + a = '%s = %s' %(name, self.visit(node.context_expr.keywords[0].value)) + + if node.context_expr.func.id == '__case__': + r.append('case %s:' %a) + elif node.context_expr.func.id == '__switch__': + r.append('switch (%s) {' %self.visit(node.context_expr.args[0])) + is_switch = True + else: + raise SyntaxError( 'invalid use of with') + + + for b in node.body: + a = self.visit(b) + if a: r.append(a) + + if is_switch: + r.append('}') + + return '\n'.join(r) + def visit_Assign(self, node): target = node.targets[0] if isinstance(target, ast.Tuple): @@ -369,15 +418,22 @@ def visit_Assign(self, node): target = self.visit(target) value = self.visit(node.value) self._vars.remove( target ) + self._known_vars.add( target ) return '%s := %s;' % (target, value) else: target = self.visit(target) value = self.visit(node.value) + + #if '<-' in value: + # raise RuntimeError(target+value) + return '%s = %s;' % (target, value) def visit_While(self, node): - body = [ 'for %s {' %self.visit(node.test)] + cond = self.visit(node.test) + if cond == 'true' or cond == '1': cond = '' + body = [ 'for %s {' %cond] self.push() for line in list( map(self.visit, node.body) ): body.append( self.indent()+line ) @@ -393,6 +449,7 @@ def _inline_code_helper(self, s): def main(script, insert_runtime=True): + if insert_runtime: dirname = os.path.dirname(os.path.abspath(__file__)) dirname = os.path.join(dirname, 'runtime') diff --git a/regtests/go/select.py b/regtests/go/select.py index f0cb7f0..6bcb8fe 100644 --- a/regtests/go/select.py +++ b/regtests/go/select.py @@ -1,17 +1,43 @@ """go select""" +def send_data( A:chan int, B:chan int, X:int, Y:int): + while True: + print('sending data..') + A <- X + B <- Y + +def select_loop(A:chan int, B:chan int, W:chan int) -> int: + print('starting select loop') + y = 0 + while True: + print('select loop:',y) + select: + case x = <- A: + y += x + W <- y + case x = <- B: + y += x + W <- y + print('end select loop', y) + return y + def main(): a = go.channel(int) b = go.channel(int) + w = go.channel(int) - a <- 1 - b <- 2 - y = 0 + go( + select_loop(a,b, w) + ) + + + go( + send_data(a,b, 5, 10) + ) - select: - case x = <- a: - y += x - case x = <- b: - y += x + z = 0 + while z < 100: + z = <- w + print('main loop', z) - print(y) + print('end test') \ No newline at end of file From 284180b42f104a024b127b97e7b4e3f48230b831 Mon Sep 17 00:00:00 2001 From: hartsantler Date: Thu, 4 Sep 2014 10:44:25 -0700 Subject: [PATCH 091/100] function expressions are now the default function type (hoisted functions are not default anymore) this breaks some of the regtests that were prototypes for auto async transform using functions like `sleep`. --- pythonjs/pythonjs.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pythonjs/pythonjs.py b/pythonjs/pythonjs.py index 8dd2704..8eb22bd 100755 --- a/pythonjs/pythonjs.py +++ b/pythonjs/pythonjs.py @@ -25,7 +25,7 @@ def __init__(self, node): RuntimeError.__init__(self) class JSGenerator(NodeVisitor): #, inline_function.Inliner): - def __init__(self, requirejs=True, insert_runtime=True, webworker=False, function_expressions=False): + def __init__(self, requirejs=True, insert_runtime=True, webworker=False, function_expressions=True): #writer = code_writer.Writer() #self.setup_inliner( writer ) self._func_expressions = function_expressions @@ -1266,7 +1266,7 @@ def generate_runtime(): ] return '\n'.join( lines ) -def main(source, requirejs=True, insert_runtime=True, webworker=False, function_expressions=False): +def main(source, requirejs=True, insert_runtime=True, webworker=False, function_expressions=True): head = [] tail = [] script = False From de044f4785c9806c92c04708e6d6f54853db147c Mon Sep 17 00:00:00 2001 From: hartsantler Date: Fri, 5 Sep 2014 08:55:02 -0700 Subject: [PATCH 092/100] fixed array slice `a[:0]` --- pythonjs/pythonjs.js | 108 +++++++++++++++++------------------ pythonjs/runtime/builtins.py | 19 ++++-- 2 files changed, 69 insertions(+), 58 deletions(-) diff --git a/pythonjs/pythonjs.js b/pythonjs/pythonjs.js index 8feb509..fa6a00b 100644 --- a/pythonjs/pythonjs.js +++ b/pythonjs/pythonjs.js @@ -484,15 +484,6 @@ var __getargs__ = function(func_name, signature, args, kwargs) { return out; } -try { -/*pass*/ -} catch(__exception__) { -console.trace(); -console.error(__exception__, __exception__.message); -console.error("line 4: pythonjs.configure( runtime_exceptions=False )"); -throw new RuntimeError("line 4: pythonjs.configure( runtime_exceptions=False )"); - -} _PythonJS_UID = 0; IndexError = function(msg) {this.message = msg || "";}; IndexError.prototype = Object.create(Error.prototype); IndexError.prototype.name = "IndexError"; KeyError = function(msg) {this.message = msg || "";}; KeyError.prototype = Object.create(Error.prototype); KeyError.prototype.name = "KeyError"; @@ -507,7 +498,8 @@ var __getfast__ = function(ob, attr) { } else { return v; } -};__getfast__.is_wrapper = true; +} + var __wrap_function__ = function(f) { f.is_wrapper = true; @@ -1459,7 +1451,7 @@ var __create_class__ = function(class_name, parents, attrs, props) { } else { wrapper = __get__(object, name); if (__test_if_true__(! (wrapper.is_wrapper))) { - console.log("RUNTIME ERROR: failed to get wrapper for:", name); + console.log(["RUNTIME ERROR: failed to get wrapper for:", name]); } } } @@ -1496,7 +1488,7 @@ var type = function(args, kwargs) { var ob_or_class_name = __args__['ob_or_class_name']; var bases = __args__['bases']; var class_dict = __args__['class_dict']; - "\n type(object) -> the object's type\n type(name, bases, dict) -> a new(type ## broken? - TODO test)\n "; + "\n type(object) -> the object's type\n type(name, bases, dict) -> a __new__>>type ## broken? - TODO test\n "; if (__test_if_true__((( bases ) === null && ( class_dict ) === null))) { return ob_or_class_name.__class__; } else { @@ -1537,7 +1529,7 @@ var getattr = function(args, kwargs) { if (__test_if_true__((prop && prop["get"]))) { return prop["get"]([ob], __jsdict([])); } else { - console.log("ERROR: getattr property error", prop); + console.log(["ERROR: getattr property error", prop]); } } else { return __get__(ob, attr); @@ -1563,7 +1555,7 @@ var setattr = function(args, kwargs) { if (__test_if_true__((prop && prop["set"]))) { prop["set"]([ob, value], __jsdict([])); } else { - console.log("ERROR: setattr property error", prop); + console.log(["ERROR: setattr property error", prop]); } } else { __set__(ob, attr, value); @@ -2007,7 +1999,9 @@ var _setup_array_prototype = function() { var i,arr,n; arr = []; start = (start | 0); - stop = (stop | this.length); + if (( stop ) === undefined) { + stop = this.length; + } if (( start ) < 0) { start = (this.length + start); } @@ -2327,7 +2321,7 @@ var sum = function(args, kwargs) { var arr = __args__['arr']; a = 0; var b,__iterator__40; - __iterator__40 = __get__(__get__(arr, "__iter__", "no iterator - line 1064: for b in arr:"), "__call__")([], __NULL_OBJECT__); + __iterator__40 = __get__(__get__(arr, "__iter__", "no iterator - line 1065: for b in arr:"), "__call__")([], __NULL_OBJECT__); var __next__40; __next__40 = __get__(__iterator__40, "next"); while (( __iterator__40.index ) < __iterator__40.length) { @@ -2383,7 +2377,7 @@ var next = function(args, kwargs) { } __args__ = __getargs__("next", __sig__, args, kwargs); var obj = __args__['obj']; - return __get__(__get__(obj, "next", "missing attribute `next` - line 1082: return obj.next()"), "__call__")(); + return __get__(__get__(obj, "next", "missing attribute `next` - line 1083: return obj.next()"), "__call__")(); };next.is_wrapper = true; var map = function(args, kwargs) { var arr,v; @@ -2400,7 +2394,7 @@ var map = function(args, kwargs) { var objs = __args__['objs']; arr = []; var ob,__iterator__41; - __iterator__41 = __get__(__get__(objs, "__iter__", "no iterator - line 1085: for ob in objs:"), "__call__")([], __NULL_OBJECT__); + __iterator__41 = __get__(__get__(objs, "__iter__", "no iterator - line 1086: for ob in objs:"), "__call__")([], __NULL_OBJECT__); var __next__41; __next__41 = __get__(__iterator__41, "next"); while (( __iterator__41.index ) < __iterator__41.length) { @@ -2425,7 +2419,7 @@ var filter = function(args, kwargs) { var objs = __args__['objs']; arr = []; var ob,__iterator__42; - __iterator__42 = __get__(__get__(objs, "__iter__", "no iterator - line 1092: for ob in objs:"), "__call__")([], __NULL_OBJECT__); + __iterator__42 = __get__(__get__(objs, "__iter__", "no iterator - line 1093: for ob in objs:"), "__call__")([], __NULL_OBJECT__); var __next__42; __next__42 = __get__(__iterator__42, "next"); while (( __iterator__42.index ) < __iterator__42.length) { @@ -2450,7 +2444,7 @@ var min = function(args, kwargs) { var lst = __args__['lst']; a = null; var value,__iterator__43; - __iterator__43 = __get__(__get__(lst, "__iter__", "no iterator - line 1099: for value in lst:"), "__call__")([], __NULL_OBJECT__); + __iterator__43 = __get__(__get__(lst, "__iter__", "no iterator - line 1100: for value in lst:"), "__call__")([], __NULL_OBJECT__); var __next__43; __next__43 = __get__(__iterator__43, "next"); while (( __iterator__43.index ) < __iterator__43.length) { @@ -2479,7 +2473,7 @@ var max = function(args, kwargs) { var lst = __args__['lst']; a = null; var value,__iterator__44; - __iterator__44 = __get__(__get__(lst, "__iter__", "no iterator - line 1105: for value in lst:"), "__call__")([], __NULL_OBJECT__); + __iterator__44 = __get__(__get__(lst, "__iter__", "no iterator - line 1106: for value in lst:"), "__call__")([], __NULL_OBJECT__); var __next__44; __next__44 = __get__(__iterator__44, "next"); while (( __iterator__44.index ) < __iterator__44.length) { @@ -2585,7 +2579,7 @@ var __Iterator___init__ = function(args, kwargs) { self.obj = obj; self.index = index; self.length = len([obj], __NULL_OBJECT__); - self.obj_get = __get__(obj, "get", "missing attribute `get` - line 1133: self.obj_get = obj.get ## cache this for speed"); + self.obj_get = __get__(obj, "get", "missing attribute `get` - line 1134: self.obj_get = obj.get ## cache this for speed"); };__Iterator___init__.is_wrapper = true; __Iterator_attrs.__init__ = __Iterator___init__; var __Iterator_next = function(args, kwargs) { @@ -2716,7 +2710,7 @@ var __dict___init__ = function(args, kwargs) { ob = js_object; if (__test_if_true__(ob instanceof Array)) { var o,__iterator__45; - __iterator__45 = __get__(__get__(ob, "__iter__", "no iterator - line 1195: for o in ob:"), "__call__")([], __NULL_OBJECT__); + __iterator__45 = __get__(__get__(ob, "__iter__", "no iterator - line 1196: for o in ob:"), "__call__")([], __NULL_OBJECT__); var __next__45; __next__45 = __get__(__iterator__45, "next"); while (( __iterator__45.index ) < __iterator__45.length) { @@ -2729,7 +2723,7 @@ var __dict___init__ = function(args, kwargs) { v = o["value"]; } try { -__get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1202: self.__setitem__( k,v )"), "__call__")([k, v], __NULL_OBJECT__); +__get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1203: self.__setitem__( k,v )"), "__call__")([k, v], __NULL_OBJECT__); } catch(__exception__) { if (__exception__ == KeyError || __exception__ instanceof KeyError) { throw new KeyError("error in dict init, bad key"); @@ -2740,16 +2734,16 @@ throw new KeyError("error in dict init, bad key"); } else { if (__test_if_true__(isinstance([ob, dict], __NULL_OBJECT__))) { var key,__iterator__46; - __iterator__46 = __get__(__get__(__jsdict_keys(ob), "__iter__", "no iterator - line 1206: for key in ob.keys():"), "__call__")([], __NULL_OBJECT__); + __iterator__46 = __get__(__get__(__jsdict_keys(ob), "__iter__", "no iterator - line 1207: for key in ob.keys():"), "__call__")([], __NULL_OBJECT__); var __next__46; __next__46 = __get__(__iterator__46, "next"); while (( __iterator__46.index ) < __iterator__46.length) { key = __next__46(); - value = ((ob instanceof Array) ? ob[key] : __get__(ob, "__getitem__", "line 1207: value = ob[ key ]")([key], __NULL_OBJECT__)); - __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1208: self.__setitem__( key, value )"), "__call__")([key, value], __NULL_OBJECT__); + value = ((ob instanceof Array) ? ob[key] : __get__(ob, "__getitem__", "line 1208: value = ob[ key ]")([key], __NULL_OBJECT__)); + __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1209: self.__setitem__( key, value )"), "__call__")([key, value], __NULL_OBJECT__); } } else { - console.log("ERROR init dict from:", js_object); + console.log(["ERROR init dict from:", js_object]); throw new TypeError; } } @@ -2771,15 +2765,15 @@ var __dict_jsify = function(args, kwargs) { var self = __args__['self']; keys = __object_keys__([self["$wrapped"]], __NULL_OBJECT__); var key,__iterator__47; - __iterator__47 = __get__(__get__(keys, "__iter__", "no iterator - line 1215: for key in keys:"), "__call__")([], __NULL_OBJECT__); + __iterator__47 = __get__(__get__(keys, "__iter__", "no iterator - line 1216: for key in keys:"), "__call__")([], __NULL_OBJECT__); var __next__47; __next__47 = __get__(__iterator__47, "next"); while (( __iterator__47.index ) < __iterator__47.length) { key = __next__47(); - value = __get__(self["$wrapped"], "__getitem__", "line 1216: value = self[...][key]")([key], __NULL_OBJECT__); + value = __get__(self["$wrapped"], "__getitem__", "line 1217: value = self[...][key]")([key], __NULL_OBJECT__); if ((typeof(value) instanceof Array ? JSON.stringify(typeof(value))==JSON.stringify("object") : typeof(value)==="object")) { if (__test_if_true__(hasattr([value, "jsify"], __NULL_OBJECT__))) { - __get__(__get__(self["$wrapped"], "__setitem__"), "__call__")([key, __get__(__get__(value, "jsify", "missing attribute `jsify` - line 1219: self[...][key] = value.jsify()"), "__call__")()], {}); + __get__(__get__(self["$wrapped"], "__setitem__"), "__call__")([key, __get__(__get__(value, "jsify", "missing attribute `jsify` - line 1220: self[...][key] = value.jsify()"), "__call__")()], {}); } } else { if ((typeof(value) instanceof Array ? JSON.stringify(typeof(value))==JSON.stringify("function") : typeof(value)==="function")) { @@ -2835,7 +2829,7 @@ var __dict_has_key = function(args, kwargs) { var key = __args__['key']; __dict = self["$wrapped"]; if (__test_if_true__(typeof(key) === 'object' || typeof(key) === 'function')) { - key = __get__(key, "__uid__", "missing attribute `__uid__` - line 1232: key = key.__uid__"); + key = __get__(key, "__uid__", "missing attribute `__uid__` - line 1233: key = key.__uid__"); } if (__test_if_true__(key in __dict)) { return true; @@ -2858,12 +2852,12 @@ var __dict_update = function(args, kwargs) { var self = __args__['self']; var other = __args__['other']; var key,__iterator__48; - __iterator__48 = __get__(__get__(other, "__iter__", "no iterator - line 1238: for key in other:"), "__call__")([], __NULL_OBJECT__); + __iterator__48 = __get__(__get__(other, "__iter__", "no iterator - line 1239: for key in other:"), "__call__")([], __NULL_OBJECT__); var __next__48; __next__48 = __get__(__iterator__48, "next"); while (( __iterator__48.index ) < __iterator__48.length) { key = __next__48(); - __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1239: self.__setitem__( key, other[key] )"), "__call__")([key, ((other instanceof Array) ? other[key] : __get__(other, "__getitem__", "line 1239: self.__setitem__( key, other[key] )")([key], __NULL_OBJECT__))], __NULL_OBJECT__); + __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1240: self.__setitem__( key, other[key] )"), "__call__")([key, ((other instanceof Array) ? other[key] : __get__(other, "__getitem__", "line 1240: self.__setitem__( key, other[key] )")([key], __NULL_OBJECT__))], __NULL_OBJECT__); } };__dict_update.is_wrapper = true; __dict_attrs.update = __dict_update; @@ -2881,12 +2875,12 @@ var __dict_items = function(args, kwargs) { var self = __args__['self']; arr = []; var key,__iterator__49; - __iterator__49 = __get__(__get__(__jsdict_keys(self), "__iter__", "no iterator - line 1242: for key in self.keys():"), "__call__")([], __NULL_OBJECT__); + __iterator__49 = __get__(__get__(__jsdict_keys(self), "__iter__", "no iterator - line 1243: for key in self.keys():"), "__call__")([], __NULL_OBJECT__); var __next__49; __next__49 = __get__(__iterator__49, "next"); while (( __iterator__49.index ) < __iterator__49.length) { key = __next__49(); - __get__(__get__(arr, "append", "missing attribute `append` - line 1243: arr.append( [key, self[key]] )"), "__call__")([[key, __get__(self, "__getitem__")([key], __NULL_OBJECT__)]], __NULL_OBJECT__); + __get__(__get__(arr, "append", "missing attribute `append` - line 1244: arr.append( [key, self[key]] )"), "__call__")([[key, __get__(self, "__getitem__")([key], __NULL_OBJECT__)]], __NULL_OBJECT__); } return arr; };__dict_items.is_wrapper = true; @@ -2927,7 +2921,7 @@ var __dict_set = function(args, kwargs) { var self = __args__['self']; var key = __args__['key']; var value = __args__['value']; - __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1251: self.__setitem__(key, value)"), "__call__")([key, value], __NULL_OBJECT__); + __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1252: self.__setitem__(key, value)"), "__call__")([key, value], __NULL_OBJECT__); };__dict_set.is_wrapper = true; __dict_attrs.set = __dict_set; var __dict___len__ = function(args, kwargs) { @@ -3135,7 +3129,7 @@ var set = function(args, kwargs) { } __args__ = __getargs__("set", __sig__, args, kwargs); var a = __args__['a']; - "\n This returns an array that is a minimal implementation of set.\n Often sets are used simply to remove duplicate entries from a list, \n and then it get converted back to a list, it is safe to use fastset for this.\n The array prototype is overloaded with basic set functions:\n difference\n intersection\n issubset\n Note: sets in Python are not subscriptable, but can be iterated over.\n Python docs say that set are unordered, some programs may rely on this disorder\n for randomness, for sets of integers we emulate the unorder only uppon initalization \n of the set, by masking the value by bits-1. Python implements sets starting with an \n array of length 8, and mask of 7, if set length grows to 6 (3/4th), then it allocates \n a new(array of length 32 and mask of 31. This is only emulated for arrays of )\n integers up to an array length of 1536.\n "; + "\n This returns an array that is a minimal implementation of set.\n Often sets are used simply to remove duplicate entries from a list, \n and then it get converted back to a list, it is safe to use fastset for this.\n The array prototype is overloaded with basic set functions:\n difference\n intersection\n issubset\n Note: sets in Python are not subscriptable, but can be iterated over.\n Python docs say that set are unordered, some programs may rely on this disorder\n for randomness, for sets of integers we emulate the unorder only uppon initalization \n of the set, by masking the value by bits-1. Python implements sets starting with an \n array of length 8, and mask of 7, if set length grows to 6 (3/4th), then it allocates \n a __new__>>array of length 32 and mask of 31. This is only emulated for arrays of \n integers up to an array length of 1536.\n "; hashtable = null; if (( a.length ) <= 1536) { hashtable = __jsdict([]); @@ -3235,7 +3229,7 @@ var __array___init__ = function(args, kwargs) { var initializer = __args__['initializer']; var little_endian = __args__['little_endian']; self.typecode = typecode; - self.itemsize = __get__(__get__(self, "typecodes", "missing attribute `typecodes` - line 1435: self.itemsize = self.typecodes[ typecode ]"), "__getitem__", "line 1435: self.itemsize = self.typecodes[ typecode ]")([typecode], __NULL_OBJECT__); + self.itemsize = __get__(__get__(self, "typecodes", "missing attribute `typecodes` - line 1436: self.itemsize = self.typecodes[ typecode ]"), "__getitem__", "line 1436: self.itemsize = self.typecodes[ typecode ]")([typecode], __NULL_OBJECT__); self.little_endian = little_endian; if (__test_if_true__(initializer)) { self.length = len([initializer], __NULL_OBJECT__); @@ -3259,7 +3253,7 @@ var __array___init__ = function(args, kwargs) { buff = new ArrayBuffer(size); self.dataview = new DataView(buff); self.buffer = buff; - __get__(__get__(self, "fromlist", "missing attribute `fromlist` - line 1456: self.fromlist( initializer )"), "__call__")([initializer], __NULL_OBJECT__); + __get__(__get__(self, "fromlist", "missing attribute `fromlist` - line 1457: self.fromlist( initializer )"), "__call__")([initializer], __NULL_OBJECT__); };__array___init__.is_wrapper = true; __array_attrs.__init__ = __array___init__; var __array___len__ = function(args, kwargs) { @@ -3290,7 +3284,7 @@ var __array___contains__ = function(args, kwargs) { __args__ = __getargs__("__array___contains__", __sig__, args, kwargs); var self = __args__['self']; var value = __args__['value']; - arr = __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1462: arr = self.to_array()"), "__call__")(); + arr = __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1463: arr = self.to_array()"), "__call__")(); if ((arr.indexOf(value) instanceof Array ? JSON.stringify(arr.indexOf(value))==JSON.stringify(-1) : arr.indexOf(value)===-1)) { return false; } else { @@ -3314,7 +3308,7 @@ var __array___getitem__ = function(args, kwargs) { step = self.itemsize; offset = (step * index); dataview = self.dataview; - func_name = ("get" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1470: func_name = 'get'+self.typecode_names[ self.typecode ]"), "__getitem__", "line 1470: func_name = 'get'+self.typecode_names[ self.typecode ]")([self.typecode], __NULL_OBJECT__)); + func_name = ("get" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1471: func_name = 'get'+self.typecode_names[ self.typecode ]"), "__getitem__", "line 1471: func_name = 'get'+self.typecode_names[ self.typecode ]")([self.typecode], __NULL_OBJECT__)); func = dataview[func_name].bind(dataview); if (( offset ) < self.bytes) { value = func(offset); @@ -3351,7 +3345,7 @@ var __array___setitem__ = function(args, kwargs) { } offset = (step * index); dataview = self.dataview; - func_name = ("set" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1486: func_name = 'set'+self.typecode_names[ self.typecode ]"), "__getitem__", "line 1486: func_name = 'set'+self.typecode_names[ self.typecode ]")([self.typecode], __NULL_OBJECT__)); + func_name = ("set" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1487: func_name = 'set'+self.typecode_names[ self.typecode ]"), "__getitem__", "line 1487: func_name = 'set'+self.typecode_names[ self.typecode ]")([self.typecode], __NULL_OBJECT__)); func = dataview[func_name].bind(dataview); if (( offset ) < self.bytes) { if ((self.typecode instanceof Array ? JSON.stringify(self.typecode)==JSON.stringify("float8") : self.typecode==="float8")) { @@ -3416,13 +3410,13 @@ var __array_fromlist = function(args, kwargs) { typecode = self.typecode; size = (length * step); dataview = self.dataview; - func_name = ("set" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1506: func_name = 'set'+self.typecode_names[ typecode ]"), "__getitem__", "line 1506: func_name = 'set'+self.typecode_names[ typecode ]")([typecode], __NULL_OBJECT__)); + func_name = ("set" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1507: func_name = 'set'+self.typecode_names[ typecode ]"), "__getitem__", "line 1507: func_name = 'set'+self.typecode_names[ typecode ]")([typecode], __NULL_OBJECT__)); func = dataview[func_name].bind(dataview); if (( size ) <= self.bytes) { i = 0; offset = 0; while (( i ) < length) { - item = ((lst instanceof Array) ? lst[i] : __get__(lst, "__getitem__", "line 1511: item = lst[i]")([i], __NULL_OBJECT__)); + item = ((lst instanceof Array) ? lst[i] : __get__(lst, "__getitem__", "line 1512: item = lst[i]")([i], __NULL_OBJECT__)); if ((typecode instanceof Array ? JSON.stringify(typecode)==JSON.stringify("float8") : typecode==="float8")) { item *= self._norm_set; } else { @@ -3478,7 +3472,7 @@ var __array_append = function(args, kwargs) { var self = __args__['self']; var value = __args__['value']; length = self.length; - __get__(__get__(self, "resize", "missing attribute `resize` - line 1534: self.resize( self.length + 1 )"), "__call__")([(self.length + 1)], __NULL_OBJECT__); + __get__(__get__(self, "resize", "missing attribute `resize` - line 1535: self.resize( self.length + 1 )"), "__call__")([(self.length + 1)], __NULL_OBJECT__); __get__(__get__(self, "__setitem__"), "__call__")([length, value], {}); };__array_append.is_wrapper = true; __array_attrs.append = __array_append; @@ -3496,12 +3490,12 @@ var __array_extend = function(args, kwargs) { var self = __args__['self']; var lst = __args__['lst']; var value,__iterator__54; - __iterator__54 = __get__(__get__(lst, "__iter__", "no iterator - line 1537: for value in lst:"), "__call__")([], __NULL_OBJECT__); + __iterator__54 = __get__(__get__(lst, "__iter__", "no iterator - line 1538: for value in lst:"), "__call__")([], __NULL_OBJECT__); var __next__54; __next__54 = __get__(__iterator__54, "next"); while (( __iterator__54.index ) < __iterator__54.length) { value = __next__54(); - __get__(__get__(self, "append", "missing attribute `append` - line 1538: self.append( value )"), "__call__")([value], __NULL_OBJECT__); + __get__(__get__(self, "append", "missing attribute `append` - line 1539: self.append( value )"), "__call__")([value], __NULL_OBJECT__); } };__array_extend.is_wrapper = true; __array_attrs.extend = __array_extend; @@ -3539,7 +3533,7 @@ var __array_to_list = function(args, kwargs) { } __args__ = __getargs__("__array_to_list", __sig__, args, kwargs); var self = __args__['self']; - return __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1548: return self.to_array()"), "__call__")(); + return __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1549: return self.to_array()"), "__call__")(); };__array_to_list.is_wrapper = true; __array_attrs.to_list = __array_to_list; var __array_to_ascii = function(args, kwargs) { @@ -3555,9 +3549,9 @@ var __array_to_ascii = function(args, kwargs) { __args__ = __getargs__("__array_to_ascii", __sig__, args, kwargs); var self = __args__['self']; string = ""; - arr = __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1551: arr = self.to_array()"), "__call__")(); + arr = __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1552: arr = self.to_array()"), "__call__")(); i = 0; - length = __get__(arr, "length", "missing attribute `length` - line 1552: i = 0; length = arr.length"); + length = __get__(arr, "length", "missing attribute `length` - line 1553: i = 0; length = arr.length"); while (( i ) < length) { var num = arr[i]; var char = String.fromCharCode(num); @@ -3618,14 +3612,14 @@ var __file_read = function(args, kwargs) { _fs = __get__(require, "__call__")(["fs"], __NULL_OBJECT__); path = self.path; if (__test_if_true__((binary || self.binary))) { - return _fs.readFileSync(path); + return _fs.readFileSync(path, { encoding:null }); } else { return _fs.readFileSync(path, __jsdict([["encoding", "utf8"]])); } };__file_read.is_wrapper = true; __file_attrs.read = __file_read; var __file_write = function(args, kwargs) { - var _fs,path; + var path,buff,_fs; var __sig__,__args__; __sig__ = { kwargs:{"binary": false},args:["self", "data", "binary"] }; if ((args instanceof Array && (Object.prototype.toString.call(kwargs) instanceof Array ? JSON.stringify(Object.prototype.toString.call(kwargs))==JSON.stringify("[object Object]") : Object.prototype.toString.call(kwargs)==="[object Object]") && (arguments.length instanceof Array ? JSON.stringify(arguments.length)==JSON.stringify(2) : arguments.length===2))) { @@ -3641,7 +3635,13 @@ var __file_write = function(args, kwargs) { _fs = __get__(require, "__call__")(["fs"], __NULL_OBJECT__); path = self.path; if (__test_if_true__((binary || self.binary))) { - _fs.writeFileSync(path, data); + binary = (binary || self.binary); + if ((binary instanceof Array ? JSON.stringify(binary)==JSON.stringify("base64") : binary==="base64")) { + buff = new Buffer(data, "base64"); + _fs.writeFileSync(path, buff, __jsdict([["encoding", null]])); + } else { + _fs.writeFileSync(path, data, __jsdict([["encoding", null]])); + } } else { _fs.writeFileSync(path, data, __jsdict([["encoding", "utf8"]])); } diff --git a/pythonjs/runtime/builtins.py b/pythonjs/runtime/builtins.py index d493cdd..7047472 100644 --- a/pythonjs/runtime/builtins.py +++ b/pythonjs/runtime/builtins.py @@ -1030,10 +1030,11 @@ def func(): @Array.prototype.__getslice__ def func(start, stop, step): - arr = [] #new(Array(this.length)) + arr = [] start = start | 0 - stop = stop | this.length + if stop is undefined: + stop = this.length if start < 0: start = this.length + start @@ -1878,7 +1879,7 @@ def read(self, binary=False): path = self.path with javascript: if binary or self.binary: - return _fs.readFileSync( path ) + return _fs.readFileSync( path, encoding=None ) else: return _fs.readFileSync( path, {'encoding':'utf8'} ) @@ -1887,8 +1888,18 @@ def write(self, data, binary=False): path = self.path with javascript: if binary or self.binary: - _fs.writeFileSync( path, data ) + binary = binary or self.binary + if binary == 'base64': ## TODO: fixme, something bad in this if test + #print('write base64 data') + buff = new Buffer(data, 'base64') + _fs.writeFileSync( path, buff, {'encoding':None}) + + else: + #print('write binary data') + #print(binary) + _fs.writeFileSync( path, data, {'encoding':None}) else: + #print('write utf8 data') _fs.writeFileSync( path, data, {'encoding':'utf8'} ) def close(self): From 027a3a878269499f5f6bc21a20a66ced497a14ae Mon Sep 17 00:00:00 2001 From: hartsantler Date: Sun, 7 Sep 2014 02:50:28 -0700 Subject: [PATCH 093/100] Go backend: subclasses, methods can over-ride the parents, but not extend. --- pythonjs/pythonjs_to_go.py | 42 +++++++++++++++++++++++++++++++++-- regtests/class/mi.py | 8 +++---- regtests/class/mi_override.py | 32 ++++++++++++++++++++++++++ 3 files changed, 76 insertions(+), 6 deletions(-) create mode 100644 regtests/class/mi_override.py diff --git a/pythonjs/pythonjs_to_go.py b/pythonjs/pythonjs_to_go.py index 73e4864..c418d84 100644 --- a/pythonjs/pythonjs_to_go.py +++ b/pythonjs/pythonjs_to_go.py @@ -32,6 +32,27 @@ def visit_ClassDef(self, node): self._classes[ node.name ] = node self._class_props[ node.name ] = props + + + for base in node.bases: + n = self.visit(base) + if n == 'object': + continue + node._parents.add( n ) + + bases.add( n ) + if n in self._class_props: + props.update( self._class_props[n] ) + base_classes.add( self._classes[n] ) + #else: ## special case - subclassing a builtin like `list` + # continue + + for p in self._classes[ n ]._parents: + bases.add( p ) + props.update( self._class_props[p] ) + base_classes.add( self._classes[p] ) + + for decor in node.decorator_list: ## class decorators if isinstance(decor, ast.Call): assert decor.func.id=='__struct__' @@ -47,10 +68,11 @@ def visit_ClassDef(self, node): init = None - + method_names = set() for b in node.body: - out.append( self.visit(b) ) assert isinstance(b, ast.FunctionDef) + method_names.add( b.name ) + out.append( self.visit(b) ) if b.name == '__init__': init = b @@ -66,6 +88,21 @@ def visit_ClassDef(self, node): out.append( 'func __new__%s() *%s { return &%s{} }' %(node.name, node.name, node.name)) + if base_classes: + for bnode in base_classes: + for b in bnode.body: + if isinstance(b, ast.FunctionDef): + if b.name == '__init__': continue + if b.name in method_names: continue + out.append( self.visit(b) ) + #args = [self.visit(a) for a in b.args.args][1:] + #args = ','.join(args) + #if args: + # out.append(self.indent()+ '%s(%s) { return %s.__%s(this,%s); }'%(b.name, args, bnode.name, b.name, args) ) + #else: + # out.append(self.indent()+ '%s() { return %s.__%s(this); }'%(b.name, bnode.name, b.name) ) + + self._class_stack.pop() return '\n'.join(out) @@ -443,6 +480,7 @@ def visit_While(self, node): def _inline_code_helper(self, s): return s + #return 'js.Global.Call("eval", "%s")' %s ## TODO inline JS() diff --git a/regtests/class/mi.py b/regtests/class/mi.py index 0b96290..5c1a591 100644 --- a/regtests/class/mi.py +++ b/regtests/class/mi.py @@ -2,21 +2,21 @@ multiple inheritance ''' class A: - def foo(self): + def foo(self) -> int: return 1 class B: - def bar(self): + def bar(self) -> int: return 2 class C( A, B ): - def call_foo_bar(self): + def call_foo_bar(self) -> int: a = self.foo() a += self.bar() return a ## extend foo ## - def foo(self): + def foo(self) -> int: a = A.foo(self) a += 100 return a diff --git a/regtests/class/mi_override.py b/regtests/class/mi_override.py new file mode 100644 index 0000000..d36fb6f --- /dev/null +++ b/regtests/class/mi_override.py @@ -0,0 +1,32 @@ +''' +multiple inheritance +''' +class A: + def foo(self) -> int: + return 1 + +class B: + def bar(self) -> int: + return 2 + +class C( A, B ): + def call_foo_bar(self) -> int: + a = self.foo() + a += self.bar() + return a + + ## override foo ## + def foo(self) -> int: + return 100 + +def main(): + a = A() + TestError( a.foo()==1 ) + b = B() + TestError( b.bar()==2 ) + + c = C() + TestError( c.foo()==100 ) + TestError( c.bar()==2 ) + + TestError( c.call_foo_bar()==102 ) From 4f39bd5b2e55b5170c0e0702dba75db601fd7f1e Mon Sep 17 00:00:00 2001 From: hartsantler Date: Sun, 7 Sep 2014 11:10:15 -0700 Subject: [PATCH 094/100] documentation for the Go backend --- README.md | 11 +++- doc/go_syntax.md | 157 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 166 insertions(+), 2 deletions(-) create mode 100644 doc/go_syntax.md diff --git a/README.md b/README.md index aaed747..db3e43f 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,18 @@ Introduction ------------ PythonJS is a transpiler written in Python that converts a python like language into fast -JavaScript. With a few exceptions, the PythonJS language is a superset of Python that is extended to support new syntax inspired by JavaScript and Go. +JavaScript. It also includes experimental backends that translate to: Dart, Lua, CoffeeScript, and Go. [Syntax Documentation](https://github.com/PythonJS/PythonJS/blob/master/doc/syntax.md) +Go backend +---------- +The Go backend uses a fully typed subset of Python, mixed with extra syntax inspired by Golang to output Go programs that can be compiled to native executeables, or translated to JavaScript using GopherJS. + +[Syntax Documentation](https://github.com/PythonJS/PythonJS/blob/master/doc/go_syntax.md) + + Getting Started =============== PythonJS can be run with regular Python, or fully self-hosted within @@ -59,7 +66,7 @@ will be converted into JavaScript. Usage:: - translator.py [--help|--dart|--coffee|--lua|--no-wrapper|--analyzer] file.py + translator.py [--help|--go|--dart|--coffee|--lua|--no-wrapper|--analyzer] file.py Examples:: diff --git a/doc/go_syntax.md b/doc/go_syntax.md new file mode 100644 index 0000000..698fbc3 --- /dev/null +++ b/doc/go_syntax.md @@ -0,0 +1,157 @@ +PythonJS Go Syntax +=============== + +PythonJS supports a fully typed subset of Python with extra syntax to support the Golang backend. + + +select +------- +Below `A` and `B` are typed as `chan int`. Data is read from a channel with `<-`. +``` + def select_loop(A:chan int, B:chan int): + print('starting select loop') + y = 0 + while True: + select: + case x = <- A: + y += x + case x = <- B: + y += x + +``` + +maps +------- +Go maps store key value pairs. The key type is given first enclosed in brackets, the value type is given after. +The example below shows a map with string keys and integer values + +``` + a = map[string]int{ + 'x': 1, + 'y': 2, + 'z': 3, + } +``` + +map iteration +------------- +The key value pairs can be looped over with a for loop. +``` + def main(): + a = map[string]int{'x':100, 'y':200} + b = '' + c = 0 + for key,value in a: + b += key + c += value +``` + +arrays +------ +Go typed arrays are defined with an optional size followed by the type, and values passed as arguments to the constructor. +Items in an array can be iterated over with a normal `for x in a` loop. Arrays also support index value pair loops using `enumerate` + +``` + a = []int(1,2,3) + b = [2]int(100,200) + +``` + +classes +------- +A Python class is translated into a Go struct with methods. Below a dict is used to type all the attribute variables that `self` will use. +``` + class A: + { + x:int, + y:int, + z:int, + } + def __init__(self, x:int, y:int, z:int=1): + self.x = x + self.y = y + self.z = z + + +``` + +subclasses +---------- +Subclasses can mix multiple classes, and override methods from the parent class. + +``` + class A: + def foo(self) -> int: + return 1 + + class B: + def bar(self) -> int: + return 2 + + class C( A, B ): + def call_foo_bar(self) -> int: + a = self.foo() + a += self.bar() + return a + + ## override foo ## + def foo(self) -> int: + return 100 + + def main(): + a = A() + b = B() + + c = C() + + ## below is all true ## + b.bar()==2 + c.bar()==2 + c.foo()==100 + c.call_foo_bar()==102 + +``` + +callbacks +--------- +Functions and methods can be passed as callbacks to other functions. The function argument type must contain the keyword `func` followed by the type signature of the callback (argument types) and (return type). Below the method is typed as `func(int)(int)` + +``` +class A: + { + x:int, + y:int, + z:int, + } + def __init__(self, x:int, y:int, z:int=1): + self.x = x + self.y = y + self.z = z + + def mymethod(self, m:int) -> int: + return self.x * m + + def call_method( cb:func(int)(int), mx:int ) ->int: + return cb(mx) + + def main(): + a = A( 100, 200, z=9999 ) + c = call_method( a.mymethod, 4 ) + print( c ) + +``` + +goroutines +---------- +The function `go` can be called to spawn a new function call as a goroutine +``` + go( myfunc(x,y,z) ) + +``` + +channels +-------- +To make a new Go channel call `go.channel(type)`, this is the same as in Go calling `make(chan type)`. +``` + c = go.channel(int) +``` From 1bc0b9dea97e557b731559ef475ac49b21024cf5 Mon Sep 17 00:00:00 2001 From: hartsantler Date: Sun, 7 Sep 2014 11:34:15 -0700 Subject: [PATCH 095/100] Go backend: fixed subclasses without __init__. --- pythonjs/pythonjs_to_go.py | 42 +++++++++++++++++++++++-------------- regtests/go/subclass.py | 43 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+), 16 deletions(-) create mode 100644 regtests/go/subclass.py diff --git a/pythonjs/pythonjs_to_go.py b/pythonjs/pythonjs_to_go.py index c418d84..8eb00b7 100644 --- a/pythonjs/pythonjs_to_go.py +++ b/pythonjs/pythonjs_to_go.py @@ -24,6 +24,7 @@ def __init__(self, requirejs=False, insert_runtime=False): def visit_ClassDef(self, node): self._class_stack.append( node ) node._parents = set() + node._struct_def = dict() out = [] sdef = dict() props = set() @@ -61,7 +62,13 @@ def visit_ClassDef(self, node): props.add( kw.arg ) sdef[ kw.arg ] = kw.value.id + node._struct_def.update( sdef ) out.append( 'type %s struct {' %node.name) + if base_classes: + for bnode in base_classes: + ## Go only needs the name of the parent struct and all its items are inserted automatically ## + out.append('%s' %bnode.name) + for name in sdef: out.append('%s %s' %(name, sdef[name])) out.append('}') @@ -76,7 +83,25 @@ def visit_ClassDef(self, node): if b.name == '__init__': init = b - if init: + + parent_init = None + if base_classes: + for bnode in base_classes: + for b in bnode.body: + if isinstance(b, ast.FunctionDef): + if b.name in method_names: + continue + if b.name == '__init__': + parent_init = {'class':bnode, 'init':b} + #continue + out.append( self.visit(b) ) + + if init or parent_init: + if parent_init: + classname = parent_init['class'].name + init = parent_init['init'] + else: + classname = node.name out.append( 'func __new__%s( %s ) *%s {' %(node.name, init._args_signature, node.name)) out.append( ' ob := %s{}' %node.name ) @@ -88,21 +113,6 @@ def visit_ClassDef(self, node): out.append( 'func __new__%s() *%s { return &%s{} }' %(node.name, node.name, node.name)) - if base_classes: - for bnode in base_classes: - for b in bnode.body: - if isinstance(b, ast.FunctionDef): - if b.name == '__init__': continue - if b.name in method_names: continue - out.append( self.visit(b) ) - #args = [self.visit(a) for a in b.args.args][1:] - #args = ','.join(args) - #if args: - # out.append(self.indent()+ '%s(%s) { return %s.__%s(this,%s); }'%(b.name, args, bnode.name, b.name, args) ) - #else: - # out.append(self.indent()+ '%s() { return %s.__%s(this); }'%(b.name, bnode.name, b.name) ) - - self._class_stack.pop() return '\n'.join(out) diff --git a/regtests/go/subclass.py b/regtests/go/subclass.py new file mode 100644 index 0000000..69e87b9 --- /dev/null +++ b/regtests/go/subclass.py @@ -0,0 +1,43 @@ +''' +simple class +''' +class A: + { + x:int, + y:int, + z:int, + } + def __init__(self, x:int, y:int, z:int=1): + self.x = x + self.y = y + self.z = z + + def mymethod(self, m:int) -> int: + return self.x * m + +class B(A): + { + w:string + } + + def method2(self, v:string) ->string: + self.w = v + return self.w + +def call_method( cb:func(int)(int), mx:int ) ->int: + return cb(mx) + +def main(): + a = A( 100, 200, z=9999 ) + print( a.x ) + print( a.y ) + print( a.z ) + + b = a.mymethod(3) + print( b ) + + c = call_method( a.mymethod, 4 ) + print( c ) + + x = B(1,2,z=3) + print( x.method2('hello world') ) \ No newline at end of file From 09c5f685e33a142ed831eedb998436d2fb0c6af9 Mon Sep 17 00:00:00 2001 From: hartsantler Date: Sun, 7 Sep 2014 15:23:38 -0700 Subject: [PATCH 096/100] Go backend: list comprehensions `[]int( x for x in range(n) )` --- doc/go_syntax.md | 7 +++++++ pythonjs/python_to_pythonjs.py | 27 +++++++++++++++++++++++++-- pythonjs/pythonjs_to_go.py | 4 +++- pythonjs/typedpython.py | 3 +++ regtests/go/list_comprehension.py | 11 +++++++++++ 5 files changed, 49 insertions(+), 3 deletions(-) create mode 100644 regtests/go/list_comprehension.py diff --git a/doc/go_syntax.md b/doc/go_syntax.md index 698fbc3..598778a 100644 --- a/doc/go_syntax.md +++ b/doc/go_syntax.md @@ -155,3 +155,10 @@ To make a new Go channel call `go.channel(type)`, this is the same as in Go call ``` c = go.channel(int) ``` + +list comprehensions +------------------- + +``` + a = []int(x for x in range(3)) +``` \ No newline at end of file diff --git a/pythonjs/python_to_pythonjs.py b/pythonjs/python_to_pythonjs.py index 802ec1a..11f5c4d 100755 --- a/pythonjs/python_to_pythonjs.py +++ b/pythonjs/python_to_pythonjs.py @@ -604,7 +604,11 @@ def visit_ListComp(self, node): a = ['get%s'%i for i in range(length)] writer.write('var( %s )' %','.join(a) ) - writer.write('%s = JSArray()'%cname) + if self._with_go: + assert node.go_listcomp_type + writer.write('%s = __go__array__(%s)' %(cname, node.go_listcomp_type)) + else: + writer.write('%s = JSArray()'%cname) generators = list( node.generators ) generators.reverse() @@ -661,6 +665,8 @@ def _gen_comp(self, generators, node): writer.write('%s.add( %s )' %(cname,self.visit(node.elt)) ) elif self._with_lua: writer.write('table.insert(%s, %s )' %(cname,self.visit(node.elt)) ) + elif self._with_go: + writer.write('%s = append(%s, %s )' %(cname, cname,self.visit(node.elt)) ) else: writer.write('%s.push( %s )' %(cname,self.visit(node.elt)) ) writer.pull() @@ -670,6 +676,8 @@ def _gen_comp(self, generators, node): writer.write('%s.add( %s )' %(cname,self.visit(node.elt)) ) elif self._with_lua: writer.write('table.insert(%s, %s )' %(cname,self.visit(node.elt)) ) + elif self._with_go: + writer.write('%s = append(%s, %s )' %(cname, cname,self.visit(node.elt)) ) else: writer.write('%s.push( %s )' %(cname,self.visit(node.elt)) ) if self._with_lua: @@ -1365,10 +1373,25 @@ def visit_Return(self, node): def visit_BinOp(self, node): left = self.visit(node.left) op = self.visit(node.op) + + is_go_listcomp = False + if self._with_go: + if op == '<<': + if isinstance(node.left, ast.Call) and isinstance(node.left.func, ast.Name) and node.left.func.id=='__go__array__': + if isinstance(node.right, ast.GeneratorExp): + is_go_listcomp = True + node.right.go_listcomp_type = node.left.args[0].id + + right = self.visit(node.right) - if self._with_glsl or self._with_go: + if self._with_glsl: return '(%s %s %s)' % (left, op, right) + elif self._with_go: + if is_go_listcomp: + return right + else: + return '(%s %s %s)' % (left, op, right) elif op == '|': if isinstance(node.right, Str): diff --git a/pythonjs/pythonjs_to_go.py b/pythonjs/pythonjs_to_go.py index 8eb00b7..2c02e63 100644 --- a/pythonjs/pythonjs_to_go.py +++ b/pythonjs/pythonjs_to_go.py @@ -273,8 +273,10 @@ def _visit_call_helper_go(self, node): return 'make(%s)' %self.visit(node.args[0]) elif name == '__go_make_chan__': return 'make(chan %s)' %self.visit(node.args[0]) + elif name == '__go__array__': + return '[]%s{}' %self.visit(node.args[0]) else: - raise SyntaxError('invalid special go call') + raise SyntaxError(name) def _visit_function(self, node): if self._function_stack[0] is node: diff --git a/pythonjs/typedpython.py b/pythonjs/typedpython.py index 7f31496..ecc1b86 100644 --- a/pythonjs/typedpython.py +++ b/pythonjs/typedpython.py @@ -24,6 +24,7 @@ GO_SPECIAL_CALLS = { 'go' : '__go__', 'go.channel' : '__go_make_chan__', + 'go.array' : '__go__array__' } def transform_source( source, strip=False ): @@ -427,6 +428,8 @@ def f(a:int=100, b:int=100) ->int: def f(*args:int, **kwargs:int) ->int: return a+b +a = []int(x for x in range(3)) + ''' if __name__ == '__main__': diff --git a/regtests/go/list_comprehension.py b/regtests/go/list_comprehension.py new file mode 100644 index 0000000..75c7f7a --- /dev/null +++ b/regtests/go/list_comprehension.py @@ -0,0 +1,11 @@ +''' +go list comprehensions +''' + +def main(): + a = []int(x for x in range(3)) + + TestError( len(a)==3 ) + TestError( a[0]==0 ) + TestError( a[1]==1 ) + TestError( a[2]==2 ) From 3b12597f32b13d0875858a497ec1edcb8141b955 Mon Sep 17 00:00:00 2001 From: hartsantler Date: Mon, 8 Sep 2014 19:17:53 -0700 Subject: [PATCH 097/100] fixed `yield` generator functions. --- pythonjs/python_to_pythonjs.py | 35 ++++++---------------------------- 1 file changed, 6 insertions(+), 29 deletions(-) diff --git a/pythonjs/python_to_pythonjs.py b/pythonjs/python_to_pythonjs.py index 11f5c4d..a507fc1 100755 --- a/pythonjs/python_to_pythonjs.py +++ b/pythonjs/python_to_pythonjs.py @@ -3874,38 +3874,15 @@ class GeneratorFunctionTransformer( PythonToPythonJS ): ''' def __init__(self, node, compiler=None): - self._with_ll = False - self._with_js = False - self._with_dart = False - self._with_coffee = False - self._with_lua = False - self._with_rpc = None - self._with_rpc_name = None - self._with_inline = False - self._in_while_test = False - self._in_lambda = False + assert '_stack' in dir(compiler) + #self.__dict___ = compiler.__dict__ ## share all state + for name in dir(compiler): + if name not in dir(self): + setattr(self, name, (getattr(compiler, name))) - if compiler._with_dart: ## TODO - self._with_dart = True - elif compiler._with_coffee: - self._with_coffee = True - elif compiler._with_lua: - self._with_lua = True - else: - self._with_js = True - - self._typedef_vars = compiler._typedef_vars - self._direct_operators = compiler._direct_operators - self._builtin_functions = compiler._builtin_functions - self._js_classes = compiler._js_classes - self._global_functions = compiler._global_functions - self._addop_ids = compiler._addop_ids - self._cache_for_body_calls = False - self._source = compiler._source - self._instances = dict() self._head_yield = False self.visit( node ) - compiler._addop_ids = self._addop_ids + compiler._addop_ids = self._addop_ids ## note: need to keep id index insync def visit_Yield(self, node): if self._in_head: From d9f143f8d2d37ba05a83dba57cfd7f8720367ad4 Mon Sep 17 00:00:00 2001 From: hartsantler Date: Wed, 10 Sep 2014 17:42:14 -0700 Subject: [PATCH 098/100] go backend: multidimensional array `[][]` --- pythonjs/python_to_pythonjs.py | 4 +++- pythonjs/pythonjs_to_go.py | 4 ++-- pythonjs/typedpython.py | 24 ++++++++++++++++++++---- 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/pythonjs/python_to_pythonjs.py b/pythonjs/python_to_pythonjs.py index a507fc1..6d89ae4 100755 --- a/pythonjs/python_to_pythonjs.py +++ b/pythonjs/python_to_pythonjs.py @@ -424,7 +424,9 @@ def visit_Import(self, node): tornado = ['tornado', 'tornado.web', 'tornado.ioloop'] for alias in node.names: - if alias.name in tornado: + if self._with_go: + writer.write('import %s' %alias.name) + elif alias.name in tornado: pass ## pythonjs/fakelibs/tornado.py elif alias.name == 'tempfile': pass ## pythonjs/fakelibs/tempfile.py diff --git a/pythonjs/pythonjs_to_go.py b/pythonjs/pythonjs_to_go.py index 2c02e63..56c5fcf 100644 --- a/pythonjs/pythonjs_to_go.py +++ b/pythonjs/pythonjs_to_go.py @@ -150,9 +150,9 @@ def visit_Expr(self, node): return self.visit(node.value) def visit_Import(self, node): - r = [alias.name for alias in node.names] + r = [alias.name.replace('__SLASH__', '/') for alias in node.names] if r: - return 'import "%s"' %';'.join(r) + return 'import("%s")' %';'.join(r) else: return '' diff --git a/pythonjs/typedpython.py b/pythonjs/typedpython.py index ecc1b86..9c06d9b 100644 --- a/pythonjs/typedpython.py +++ b/pythonjs/typedpython.py @@ -44,7 +44,7 @@ def transform_source( source, strip=False ): if nextchar.strip(): break j += 1 - if a and char==']' and j==i+1 and nextchar!=None and nextchar in 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ': + if a and char==']' and j==i+1 and nextchar!=None and nextchar in '[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ': assert '[' in a gotype = [] b = a.pop() @@ -54,7 +54,10 @@ def transform_source( source, strip=False ): gotype.reverse() gotype = ''.join(gotype) if not gotype: - a.append('__go__array__(') + if nextchar=='[': + a.append('__go__array__<<') + else: + a.append('__go__array__(') elif gotype.isdigit(): a.append('__go__arrayfixed__(%s,' %gotype) else: @@ -69,6 +72,10 @@ def transform_source( source, strip=False ): elif hit_go_typedef and char=='{': a.append(')<<{') hit_go_typedef = False + elif hit_go_typedef and char==',': + a.append('),') + hit_go_typedef = False + elif a and char in __whitespace: b = ''.join(a) @@ -153,8 +160,15 @@ def transform_source( source, strip=False ): break indent = ''.join(indent) output.append( indent + '@returns(%s)' %rtype) - elif c.startswith('import ') and '-' in c: - c = c.replace('-', '__DASH__') + + if c.startswith('import '): + if '-' in c: + c = c.replace('-', '__DASH__') + if '/' in c: + c = c.replace('/', '__SLASH__') + if '"' in c: + c = c.replace('"', '') + if ' new ' in c: c = c.replace(' new ', ' __new__>>') @@ -430,6 +444,8 @@ def f(*args:int, **kwargs:int) ->int: a = []int(x for x in range(3)) +y = go.make([]float64, 1000) + ''' if __name__ == '__main__': From 2dd323501d3751a7c7ae632d5d9e60782788f447 Mon Sep 17 00:00:00 2001 From: hartsantler Date: Thu, 11 Sep 2014 02:56:27 -0700 Subject: [PATCH 099/100] go backend: support go.make --- pythonjs/python_to_pythonjs.py | 4 ++-- pythonjs/pythonjs.py | 3 +++ pythonjs/pythonjs_to_go.py | 26 ++++++++++++++++++-------- pythonjs/typedpython.py | 14 ++++++++------ 4 files changed, 31 insertions(+), 16 deletions(-) diff --git a/pythonjs/python_to_pythonjs.py b/pythonjs/python_to_pythonjs.py index 6d89ae4..4bf5339 100755 --- a/pythonjs/python_to_pythonjs.py +++ b/pythonjs/python_to_pythonjs.py @@ -299,10 +299,10 @@ def __init__(self, source=None, module=None, module_path=None, dart=False, coffe self._source = source.splitlines() - if '--debug' in sys.argv: + if '--debug--' in sys.argv: try: tree = ast.parse( source ) - except: + except SyntaxError: raise SyntaxError(source) else: tree = ast.parse( source ) diff --git a/pythonjs/pythonjs.py b/pythonjs/pythonjs.py index 8eb22bd..159f25c 100755 --- a/pythonjs/pythonjs.py +++ b/pythonjs/pythonjs.py @@ -962,6 +962,7 @@ def visit_BinOp(self, node): if node.left.func.id == '__go__map__': key_type = self.visit(node.left.args[0]) value_type = self.visit(node.left.args[1]) + if value_type == 'interface': value_type = 'interface{}' return 'map[%s]%s%s' %(key_type, value_type, right) else: if not right.startswith('{') and not right.endswith('}'): @@ -973,6 +974,8 @@ def visit_BinOp(self, node): asize = self.visit(node.left.args[0]) atype = self.visit(node.left.args[1]) return '[%s]%s%s' %(asize, atype, right) + elif isinstance(node.left, ast.Name) and node.left.id=='__go__array__' and op == '<<': + return '[]%s' %self.visit(node.right) if left in self._typed_vars and self._typed_vars[left] == 'numpy.float32': left += '[_id_]' diff --git a/pythonjs/pythonjs_to_go.py b/pythonjs/pythonjs_to_go.py index 56c5fcf..8599819 100644 --- a/pythonjs/pythonjs_to_go.py +++ b/pythonjs/pythonjs_to_go.py @@ -21,6 +21,8 @@ def __init__(self, requirejs=False, insert_runtime=False): self._known_vars = set() self._kwargs_type_ = dict() + self._imports = [] + def visit_ClassDef(self, node): self._class_stack.append( node ) node._parents = set() @@ -152,9 +154,9 @@ def visit_Expr(self, node): def visit_Import(self, node): r = [alias.name.replace('__SLASH__', '/') for alias in node.names] if r: - return 'import("%s")' %';'.join(r) - else: - return '' + for name in r: + self._imports.append('import("%s");' %name) + return '' def visit_Module(self, node): header = [ @@ -173,7 +175,10 @@ def visit_Module(self, node): else: lines.append( sub ) else: - raise SyntaxError(b) + if isinstance(b, ast.Import): + pass + else: + raise SyntaxError(b) lines.append('type _kwargs_type_ struct {') for name in self._kwargs_type_: @@ -182,7 +187,7 @@ def visit_Module(self, node): lines.append( ' __use__%s bool' %name) lines.append('}') - lines = header + lines + lines = header + self._imports + lines return '\n'.join( lines ) @@ -269,12 +274,17 @@ def _visit_call_helper_go(self, node): name = self.visit(node.func) if name == '__go__': return 'go %s' %self.visit(node.args[0]) - elif name == '__gomake__': + elif name == '__go_make__': return 'make(%s)' %self.visit(node.args[0]) elif name == '__go_make_chan__': return 'make(chan %s)' %self.visit(node.args[0]) elif name == '__go__array__': - return '[]%s{}' %self.visit(node.args[0]) + if isinstance(node.args[0], ast.BinOp):# and node.args[0].op == '<<': ## todo assert right is `typedef` + a = self.visit(node.args[0].left) + return '[]%s' %a + else: + a = self.visit(node.args[0]) + return '[]%s{}' %a else: raise SyntaxError(name) @@ -507,7 +517,7 @@ def main(script, insert_runtime=True): script = runtime + '\n' + script tree = ast.parse(script) - #return GoGenerator().visit(tree) + return GoGenerator().visit(tree) try: return GoGenerator().visit(tree) except SyntaxError as err: diff --git a/pythonjs/typedpython.py b/pythonjs/typedpython.py index 9c06d9b..f5bf3f3 100644 --- a/pythonjs/typedpython.py +++ b/pythonjs/typedpython.py @@ -24,7 +24,8 @@ GO_SPECIAL_CALLS = { 'go' : '__go__', 'go.channel' : '__go_make_chan__', - 'go.array' : '__go__array__' + 'go.array' : '__go__array__', + 'go.make' : '__go_make__' } def transform_source( source, strip=False ): @@ -73,7 +74,8 @@ def transform_source( source, strip=False ): a.append(')<<{') hit_go_typedef = False elif hit_go_typedef and char==',': - a.append('),') + #a.append(', type=True),') ## this breaks function annotations that splits on ',' + a.append('< Date: Thu, 11 Sep 2014 06:20:28 -0700 Subject: [PATCH 100/100] go backend: fixed go.make extra arguments. --- pythonjs/python_to_pythonjs.py | 5 +- pythonjs/pythonjs_to_go.py | 29 ++++++-- regtests/go/chan-transfer-speed.py | 107 +++++++++++++++++++++++++++++ 3 files changed, 135 insertions(+), 6 deletions(-) create mode 100644 regtests/go/chan-transfer-speed.py diff --git a/pythonjs/python_to_pythonjs.py b/pythonjs/python_to_pythonjs.py index 4bf5339..f05a92c 100755 --- a/pythonjs/python_to_pythonjs.py +++ b/pythonjs/python_to_pythonjs.py @@ -1923,7 +1923,7 @@ def _visit_assign_helper(self, node, target): elif isinstance(target.slice, ast.Slice): code = '%s.__setslice__(%s, %s)' %(self.visit(target.value), self.visit(target.slice), self.visit(node.value)) - elif self._with_dart or self._with_ll or self._with_glsl: + elif self._with_dart or self._with_ll or self._with_glsl or self._with_go: code = '%s[ %s ] = %s' code = code % (self.visit(target.value), self.visit(target.slice.value), self.visit(node.value)) @@ -2206,7 +2206,8 @@ def visit_Call(self, node): name = self.visit(node.func) if name in typedpython.GO_SPECIAL_CALLS: name = typedpython.GO_SPECIAL_CALLS[ name ] - return '%s( %s )' %(name, self.visit(node.args[0])) + args = [self.visit(e) for e in node.args ] + return '%s( %s )' %(name, ','.join(args)) if self._with_rpc: if not self._with_rpc_name: diff --git a/pythonjs/pythonjs_to_go.py b/pythonjs/pythonjs_to_go.py index 8599819..c0ff87c 100644 --- a/pythonjs/pythonjs_to_go.py +++ b/pythonjs/pythonjs_to_go.py @@ -212,11 +212,20 @@ def visit_For(self, node): target = self.visit(node.target) lines = [] if isinstance(node.iter, ast.Call) and isinstance(node.iter.func, ast.Name): - iter = self.visit(node.iter.args[0]) if node.iter.func.id == 'range': - lines.append('for %s := 0; %s < %s; %s++ {' %(target, target, iter, target)) + if len(node.iter.args)==1: + iter = self.visit(node.iter.args[0]) + lines.append('for %s := 0; %s < %s; %s++ {' %(target, target, iter, target)) + elif len(node.iter.args)==2: + start = self.visit(node.iter.args[0]) + iter = self.visit(node.iter.args[1]) + lines.append('for %s := %s; %s < %s; %s++ {' %(target, start, target, iter, target)) + else: + raise SyntaxError('invalid for range loop') + elif node.iter.func.id == 'enumerate': + iter = self.visit(node.iter.args[0]) idx = self.visit(node.target.elts[0]) tar = self.visit(node.target.elts[1]) lines.append('for %s,%s := range %s {' %(idx,tar, iter)) @@ -275,7 +284,12 @@ def _visit_call_helper_go(self, node): if name == '__go__': return 'go %s' %self.visit(node.args[0]) elif name == '__go_make__': - return 'make(%s)' %self.visit(node.args[0]) + if len(node.args)==2: + return 'make(%s, %s)' %(self.visit(node.args[0]), self.visit(node.args[1])) + elif len(node.args)==3: + return 'make(%s, %s, %s)' %(self.visit(node.args[0]), self.visit(node.args[1]), self.visit(node.args[1])) + else: + raise SyntaxError('go make requires 2 or 3 arguments') elif name == '__go_make_chan__': return 'make(chan %s)' %self.visit(node.args[0]) elif name == '__go__array__': @@ -288,6 +302,13 @@ def _visit_call_helper_go(self, node): else: raise SyntaxError(name) + def visit_Return(self, node): + if isinstance(node.value, ast.Tuple): + return 'return %s' % ', '.join(map(self.visit, node.value.elts)) + if node.value: + return 'return %s' % self.visit(node.value) + return 'return' + def _visit_function(self, node): if self._function_stack[0] is node: self._vars = set() @@ -517,7 +538,7 @@ def main(script, insert_runtime=True): script = runtime + '\n' + script tree = ast.parse(script) - return GoGenerator().visit(tree) + #return GoGenerator().visit(tree) try: return GoGenerator().visit(tree) except SyntaxError as err: diff --git a/regtests/go/chan-transfer-speed.py b/regtests/go/chan-transfer-speed.py new file mode 100644 index 0000000..9b0c7fb --- /dev/null +++ b/regtests/go/chan-transfer-speed.py @@ -0,0 +1,107 @@ +# based on the go test by Dennis Francis +# https://github.com/dennisfrancis/gopherjs-channeltransfer-speed + + +import "github.com/gopherjs/gopherjs/js" + + +data_chan = go.channel(int) + +document = js.Global.Get("document") + +def main(): + js.Global.Get("window").Set("onload", setup) + +def setup(): + + go( receive() ) + bt = document.Call("getElementById", "startbt") + bt.Set("onclick", runtests) + + +def runtests(): + var bt = document.Call("getElementById", "startbt") + bt.Set("disabled", true) + + #go func() { + # test_calldepth() + # test_localmem() + #}() + + go( test_calldepth() ) + go( test_localmem() ) + + +def test_calldepth(): + + latency = go.make([]float64, 1000) + perf = js.Global.Get("performance") + #for cd := 1; cd <= 1000; cd++ { + for cd in range(1, 1000): + t0 = perf.Call("now").Float() + #for ii:=0; ii<50; ii++ { + for ii in range(50): + send_func(cd, 1, ii) + t1 = perf.Call("now").Float() + latency[cd-1] = (t1 - t0)/50.0 + print("test1 calldepth =", cd) + plot("ctsgraph1", latency, "Call depth", "Variation of Kilo Channel Transfers per second (KCTps) with call depth") + +def test_localmem(): + + latency = go.make([]float64, 1000) + perf = js.Global.Get("performance") + #for varsz := 1; varsz <= 1000; varsz++ { + for varsz in range(1, 1000): + t0 = perf.Call("now").Float() + #for ii:=0; ii<50; ii++ { + for ii in range(50): + send_func(1, varsz, ii) + + t1 = perf.Call("now").Float() + latency[varsz-1] = (t1 - t0)/50.0 + plot("ctsgraph2", latency, "Local variable size", "Variation of Kilo Channel Transfers per second (KCTps) with local variable size") + + +def plot(id:string, latency:[]float64, xlabel:string, title:string ): + + div = document.Call("getElementById", id) + #options = map[string]interface{}{ + options = map[string]interface{ + #"legend" : "always", + "title" : title, + "showRoller" : true, + "rollPeriod" : 1, + "ylabel" : "KCTps", + "labels" : []string("x", "CTS"), + } + + data = go.make([][]float64, len(latency)) + + #for rowid := 0; rowid < len(latency); rowid++ { + for rowid in range(len(latency)): + data[rowid] = []float64( + float64(rowid + 1), + 1.0/latency[rowid] + ) + + + js.Global.Get("Dygraph").New(div, data, options) + + +def send_func(call_depth:int, varsize:int, data:int ): + locvar = go.make([]int, varsize) + + if call_depth <= 1: + data_chan <- data + return + + send_func(call_depth-1, varsize, data) + + print(locvar) + +def receive(): + int data = 0 + while True: + data = <-data_chan + print("Received data =", data)