Skip to content

Commit 6d7d117

Browse files
author
hartsantler
committed
fixed string.isdigit, deprecated _create_empty_object.
fixed "in" javascript test for things without special "__contains__"
1 parent c03bc6b commit 6d7d117

8 files changed

Lines changed: 102 additions & 70 deletions

README.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ Getting Started - Experimental Development Branch
4444

4545
Get Source Code::
4646

47-
git clone -b develop https://github.com/PythonScript-/PythonJS.git
47+
git clone -b develop https://github.com/PythonJS/PythonJS.git
4848

4949
Install Tornado for Python3::
5050

pythonscript.js

Lines changed: 41 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,4 @@
1-
2-
3-
4-
5-
1+
// PythonScript Runtime - regenerated on: Sun Oct 20 18:46:57 2013
62
var jsrange = function(num) {
73
"Emulates Python's range function";
84
var i, r;
@@ -306,6 +302,19 @@ return attr;
306302
base = backup;
307303
}
308304

305+
var iter = bases;
306+
for (var base=0; base < iter.length; base++) {
307+
var backup = base;
308+
base = iter[base];
309+
var getter;
310+
getter = _get_upstream_property(base, attribute);
311+
if(getter) {
312+
return getter([object]);
313+
}
314+
315+
base = backup;
316+
}
317+
309318
if("__getattr__" in __dict__) {
310319
return __dict__["__getattr__"]([object, attribute]);
311320
}
@@ -390,6 +399,22 @@ parent = backup;
390399
}
391400
window["_get_upstream_attribute"] = _get_upstream_attribute
392401

402+
var _get_upstream_property = function(base, attr) {
403+
if(attr in base.__properties__) {
404+
return base.__properties__[attr];
405+
}
406+
407+
var iter = base.bases;
408+
for (var parent=0; parent < iter.length; parent++) {
409+
var backup = parent;
410+
parent = iter[parent];
411+
return _get_upstream_property(parent, attr);
412+
parent = backup;
413+
}
414+
415+
}
416+
window["_get_upstream_property"] = _get_upstream_property
417+
393418
var set_attribute = function(object, attribute, value) {
394419
"Set an attribute on an object by updating its __dict__ property";
395420
var __dict__, __class__;
@@ -635,32 +660,14 @@ key = backup;
635660

636661
return output;
637662
}
638-
window["json_to_pythonscript"] = json_to_pythonscript
639-
663+
window["json_to_pythonscript"] = json_to_pythonscript
640664
_PythonJS_UID = 0;
641665
var _JSNew = function(T) {
642-
console.log("_JSNew->", T);
643666
return new T;
644667
}
645668
window["_JSNew"] = _JSNew
646669

647670
_JSNew.pythonscript_function=true;
648-
var _create_empty_object = function(arr) {
649-
var o;
650-
o = Object.create( null );
651-
var iter = arr;
652-
for (var i=0; i < iter.length; i++) {
653-
var backup = i;
654-
i = iter[i];
655-
o[ i ] = true;
656-
i = backup;
657-
}
658-
659-
return o;
660-
}
661-
window["_create_empty_object"] = _create_empty_object
662-
663-
_create_empty_object.pythonscript_function=true;
664671
var int = function(args, kwargs) {
665672
var signature, arguments;
666673
signature = {"kwargs": Object(), "args": create_array("a")};
@@ -785,12 +792,12 @@ return this.indexOf( a );
785792
String.prototype.index=func;
786793
var func = function() {
787794
var digits;
788-
digits = _create_empty_object( ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"] );
795+
digits = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"];
789796
var iter = this;
790797
for (var char=0; char < iter.length; char++) {
791798
var backup = char;
792799
char = iter[char];
793-
if(char in digits || digits["__contains__"](char)) {
800+
if(char in digits || Object.hasOwnProperty(digits, "__contains__") && digits["__contains__"](char)) {
794801
/*pass*/
795802
}
796803
else {
@@ -811,15 +818,16 @@ _setup_str_prototype.pythonscript_function = true;
811818
_setup_str_prototype(create_array(), Object());
812819
var _setup_array_prototype = function(args, kwargs) {
813820
var func = function(a) {
814-
var e;
815-
e = _create_empty_object( this );
816-
if(a in e) {
821+
var i;
822+
i = 0;
823+
while(i < this.length) {
824+
if(this[i] == a) {
817825
return true;
818826
}
819-
else {
820-
return false;
821-
}
822827

828+
i += 1;
829+
}
830+
return false;
823831
}
824832

825833
Array.prototype.__contains__=func;
@@ -2160,4 +2168,4 @@ window["__array_to_ascii"] = __array_to_ascii
21602168

21612169
__array_to_ascii.pythonscript_function = true;
21622170
window["__array_attrs"]["to_ascii"] = __array_to_ascii;
2163-
array = create_class("array", window["__array_parents"], window["__array_attrs"], window["__array_properties"]);
2171+
array = create_class("array", window["__array_parents"], window["__array_attrs"], window["__array_properties"]);

pythonscript/python_to_pythonjs.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -392,7 +392,7 @@ def visit_ClassDef(self, node):
392392
writer.write('window["__%s_properties"] = JSObject()' % name)
393393

394394
for base in node.bases:
395-
code = '__%s_parents.push(%s)' % (name, self.visit(base))
395+
code = 'window["__%s_parents"].push(%s)' % (name, self.visit(base))
396396
writer.write(code)
397397
if isinstance(base, Name):
398398
self._class_parents[ name ].add( base.id )
@@ -591,6 +591,7 @@ def visit_Compare(self, node):
591591
a = ( self.visit(node.comparators[i]), left )
592592
if self._with_js: ## this makes "if 'x' in Array" work like Python: "if 'x' in list" - TODO fix this for js-objects
593593
comp.append( '%s in %s or' %(a[1], a[0]) ) ## this is ugly, but it works
594+
comp.append( 'Object.hasOwnProperty(%s, "__contains__") and' %a[0])
594595
comp.append( "%s['__contains__'](%s)" %a )
595596
else:
596597
comp.append( "get_attribute(get_attribute(%s, '__contains__'), '__call__')([%s], JSObject())" %a )

runtime/builtins.py

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,18 @@
33

44
with javascript:
55
def _JSNew(T):
6-
print '_JSNew->', T
76
return JS("new T")
87

9-
def _create_empty_object(arr):
10-
o = Object.create(null)
11-
for i in arr:
12-
o[ i ] = True
13-
return o
8+
## This can not be trusted because Object.hasOwnProperty will fail on an empty object with
9+
## TypeError: Cannot convert object to primitive value
10+
## It was not a good idea in the first place to try to use Javascript's "in" operator to
11+
## test if something had an attribute, because if something was a string that throws an error
12+
## note: Object.hasOwnProperty always returns false with strings and numbers.
13+
#def _create_empty_object(arr):
14+
# o = Object.create(null)
15+
# for i in arr:
16+
# o[ i ] = True
17+
# return o
1418

1519
def int(a):
1620
with javascript:
@@ -88,7 +92,7 @@ def func(a):
8892

8993
@String.prototype.isdigit
9094
def func():
91-
digits = _create_empty_object( ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'] )
95+
digits = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
9296
for char in this:
9397
if char in digits: pass
9498
else: return False
@@ -102,11 +106,11 @@ def _setup_array_prototype():
102106

103107
@Array.prototype.__contains__
104108
def func(a):
105-
e = _create_empty_object( this )
106-
if JS("a in e"): ## JS() so that we don't call __contains__ again
107-
return True
108-
else:
109-
return False
109+
i = 0
110+
while i < this.length:
111+
if this[i] == a: return True
112+
i += 1
113+
return False
110114

111115
@Array.prototype.__len__
112116
def func():

runtime/pythonpythonjs.py

Lines changed: 10 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -224,25 +224,11 @@ def method():
224224
else:
225225
return attr
226226

227-
228-
#for i in jsrange(bases.length): ## this calls get_attribute, ugly!
229-
# var(base, attr)
230-
# base = bases[i]
231-
# attr = get_attribute(base, attribute)
232-
# if attr:
233-
# if JS("{}.toString.call(attr) === '[object Function]'"):
234-
# def method():
235-
# var(args)
236-
# args = arguments
237-
# if(args.length > 0):
238-
# args[0].splice(0, 0, object)
239-
# else:
240-
# args = [object]
241-
# return attr.apply(None, args)
242-
# method.is_wrapper = True
243-
# return method
244-
# else:
245-
# return attr
227+
for base in bases: ## upstream property getters come before __getattr__
228+
var( getter )
229+
getter = _get_upstream_property(base, attribute)
230+
if getter:
231+
return getter( [object] )
246232

247233
if '__getattr__' in __dict__:
248234
return __dict__['__getattr__']( [object, attribute])
@@ -281,7 +267,11 @@ def _get_upstream_attribute(base, attr):
281267
for parent in base.bases:
282268
return _get_upstream_attribute(parent, attr)
283269

284-
270+
def _get_upstream_property(base, attr):
271+
if attr in base.__properties__:
272+
return base.__properties__[ attr ]
273+
for parent in base.bases:
274+
return _get_upstream_property(parent, attr)
285275

286276
def set_attribute(object, attribute, value):
287277
"""Set an attribute on an object by updating its __dict__ property"""

tests/property_decorator.html

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@
22
<head>
33
<script src="pythonscript.js"></script>
44

5-
<script type="text/python" closure="true">
5+
<script type="text/python" closure="false">
6+
67

78
class A:
89
def __init__(self):
10+
print 'A.init-------'
911
self._x = 1
1012
self._y = 2
1113
self._z = 3
@@ -15,7 +17,7 @@
1517
return self._x
1618
@x.setter
1719
def x(self,value):
18-
self._x = value
20+
self._x = value + 1000
1921

2022
@property
2123
def y(self):
@@ -31,7 +33,15 @@
3133
def z(self,value):
3234
self._z = value
3335

36+
class B( A ):
37+
pass
38+
39+
def unknown(x): ## TODO make closure compatible
40+
return x
41+
3442
def test():
43+
global a, b, c
44+
print 'testing A...'
3545
a = A()
3646
print( a.x )
3747
print( a.y )
@@ -40,6 +50,23 @@
4050
a.x = 100
4151
print( a.x )
4252

53+
print 'testing B...'
54+
b = B()
55+
print( b.x )
56+
print( b.y )
57+
print( b.z )
58+
59+
b.x = 100
60+
print( b.x )
61+
62+
print 'testing B as unknown type'
63+
c = unknown( b )
64+
print( c.x )
65+
print( c.y )
66+
print( c.z )
67+
c.x = 101 ## TODO fix setters on unknown types
68+
print( c.x )
69+
4370
</script>
4471
</head>
4572

tests/test_string.html

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,11 @@
3737
print a.upper()
3838
print 'LOWERED'.lower()
3939
print a.index( 'e' )
40+
print 'testing isdigit'
4041
print a, '.isdigit->', a.isdigit()
4142
print '100.isdigit->', '100'.isdigit()
4243

44+
print 'testing functional style str(x)'
4345
s = str('functional style ok')
4446
print s
4547
e = str( 100 )

tests/threejs_nested_attribute_lookup_decorators.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from three import *
1111

1212
def test():
13-
cam = PerspectiveCamera( 45, 640, 480, 0.01, 10000)
13+
cam = PerspectiveCamera( 45, 640/480, 0.01, 10000)
1414
p = cam.position
1515
p.z = 100
1616
print( p.z )

0 commit comments

Comments
 (0)