summaryrefslogtreecommitdiff
path: root/addons
diff options
context:
space:
mode:
authorXavier Morel <xmo@openerp.com>2012-12-03 12:47:06 +0100
committerXavier Morel <xmo@openerp.com>2012-12-03 12:47:06 +0100
commit54ea7670d36d84d47d52ede3f1d1a1c847141bc5 (patch)
treed34a46093673d758fc20c11269564814e7b71cca /addons
parent96cd88b04c086bc829f039af5c28569af26ce550 (diff)
[FIX] incorrect conversion of JS arrays to py.js lists/tuples
bzr revid: xmo@openerp.com-20121203114706-dn5sqq3glqst4g1q
Diffstat (limited to 'addons')
-rw-r--r--addons/web/doc/index.rst8
-rw-r--r--addons/web/static/lib/py.js/.hg_archival.txt4
-rw-r--r--addons/web/static/lib/py.js/doc/utility.rst22
-rw-r--r--addons/web/static/lib/py.js/lib/py.js95
4 files changed, 93 insertions, 36 deletions
diff --git a/addons/web/doc/index.rst b/addons/web/doc/index.rst
index 06534c50903..2e4367ef78f 100644
--- a/addons/web/doc/index.rst
+++ b/addons/web/doc/index.rst
@@ -11,14 +11,14 @@ Contents:
.. toctree::
:maxdepth: 1
- presentation
- async
-
+ module
testing
widget
- qweb
+
+ async
rpc
+ qweb
client_action
form_view
search_view
diff --git a/addons/web/static/lib/py.js/.hg_archival.txt b/addons/web/static/lib/py.js/.hg_archival.txt
index 110f837c7c1..1d47dff4445 100644
--- a/addons/web/static/lib/py.js/.hg_archival.txt
+++ b/addons/web/static/lib/py.js/.hg_archival.txt
@@ -1,5 +1,5 @@
repo: 076b192d0d8ab2b92d1dbcfa3da055382f30eaea
-node: 12c1b7f275a4520c74c321b7966af201a130b611
+node: 142c22b230636674a0cee6bc29e6975f0f1600a5
branch: default
latesttag: 0.7
-latesttagdistance: 6
+latesttagdistance: 9
diff --git a/addons/web/static/lib/py.js/doc/utility.rst b/addons/web/static/lib/py.js/doc/utility.rst
index 86cfb1cfe36..8bb9164885f 100644
--- a/addons/web/static/lib/py.js/doc/utility.rst
+++ b/addons/web/static/lib/py.js/doc/utility.rst
@@ -161,6 +161,28 @@ Object Protocol
:returns: ``Number``
:raises: ``TypeError`` if the object doesn't have a length
+.. function:: py.PY_getItem(o, key)
+
+ Returns the element of ``o`` corresponding to the object
+ ``key``. This is equivalent to ``o[key]``.
+
+ :param o: :class:`py.object`
+ :param key: :class:`py.object`
+ :returns: :class:`py.object`
+ :raises: ``TypeError`` if ``o`` does not support the operation, if
+ ``key`` or the return value is not a :class:`py.object`
+
+.. function:: py.PY_setItem(o, key, v)
+
+ Maps the object ``key`` to the value ``v`` in ``o``. Equivalent to
+ ``o[key] = v``.
+
+ :param o: :class:`py.object`
+ :param key: :class:`py.object`
+ :param v: :class:`py.object`
+ :raises: ``TypeError`` if ``o`` does not support the operation, or
+ if ``key`` or ``v`` are not :class:`py.object`
+
Number Protocol
---------------
diff --git a/addons/web/static/lib/py.js/lib/py.js b/addons/web/static/lib/py.js/lib/py.js
index 6e898e374c9..f36cfd665b3 100644
--- a/addons/web/static/lib/py.js/lib/py.js
+++ b/addons/web/static/lib/py.js/lib/py.js
@@ -393,18 +393,9 @@ var py = {};
switch(val.constructor) {
case Object:
- // TODO: why py.object instead of py.dict?
- var o = py.PY_call(py.object);
- for (var prop in val) {
- if (val.hasOwnProperty(prop)) {
- o[prop] = val[prop];
- }
- }
- return o;
+ return py.dict.fromJSON(val);
case Array:
- var a = py.PY_call(py.list);
- a._values = val;
- return a;
+ return py.list.fromJSON(val);
}
throw new Error("Could not convert " + val + " to a pyval");
@@ -595,6 +586,44 @@ var py = {};
}
return v;
};
+ py.PY_getItem = function (o, key) {
+ if (!('__getitem__' in o)) {
+ throw new Error(
+ "TypeError: '" + typename(o) +
+ "' object is unsubscriptable")
+ }
+ if (!py.PY_isInstance(key, py.object)) {
+ throw new Error(
+ "TypeError: '" + typename(key) +
+ "' is not a py.js object");
+ }
+ var res = o.__getitem__(key);
+ if (!py.PY_isInstance(key, py.object)) {
+ throw new Error(
+ "TypeError: __getitem__ must return a py.js object, got "
+ + typename(res));
+ }
+ return res;
+ };
+ py.PY_setItem = function (o, key, v) {
+ if (!('__setitem__' in o)) {
+ throw new Error(
+ "TypeError: '" + typename(o) +
+ "' object does not support item assignment");
+ }
+ if (!py.PY_isInstance(key, py.object)) {
+ throw new Error(
+ "TypeError: '" + typename(key) +
+ "' is not a py.js object");
+ }
+ if (!py.PY_isInstance(v, py.object)) {
+ throw new Error(
+ "TypeError: '" + typename(v) +
+ "' is not a py.js object");
+ }
+ o.__setitem__(key, v);
+ };
+
py.PY_add = function (o1, o2) {
return PY_op(o1, o2, '+');
};
@@ -679,7 +708,7 @@ var py = {};
return (this === other) ? py.True : py.False;
},
__ne__: function (other) {
- if (this.__eq__(other) === py.True) {
+ if (py.PY_isTrue(this.__eq__(other))) {
return py.False;
} else {
return py.True;
@@ -693,7 +722,7 @@ var py = {};
return this.__unicode__();
},
__unicode__: function () {
- return py.str.fromJSON('<' + this.__class__.__name__ + ' object>');
+ return py.str.fromJSON('<' + typename(this) + ' object>');
},
__nonzero__: function () {
return py.True;
@@ -934,14 +963,14 @@ var py = {};
},
__contains__: function (value) {
for(var i=0, len=this._values.length; i<len; ++i) {
- if (this._values[i].__eq__(value) === py.True) {
+ if (py.PY_isTrue(this._values[i].__eq__(value))) {
return py.True;
}
}
return py.False;
},
__getitem__: function (index) {
- return PY_ensurepy(this._values[index.toJSON()]);
+ return this._values[index.toJSON()];
},
toJSON: function () {
var out = [];
@@ -949,6 +978,16 @@ var py = {};
out.push(this._values[i].toJSON());
}
return out;
+ },
+ fromJSON: function (ar) {
+ if (!(ar instanceof Array)) {
+ throw new Error("Can only create a py.tuple from an Array");
+ }
+ var t = py.PY_call(py.tuple);
+ for(var i=0; i<ar.length; ++i) {
+ t._values.push(PY_ensurepy(ar[i]));
+ }
+ return t;
}
});
py.list = py.tuple;
@@ -1107,8 +1146,7 @@ var py = {};
}
throw new Error(
"TypeError: unsupported operand type(s) for " + op + ": '"
- + o1.__class__.__name__ + "' and '"
- + o2.__class__.__name__ + "'");
+ + typename(o1) + "' and '" + typename(o2) + "'");
};
var PY_builtins = {
@@ -1148,7 +1186,7 @@ var py = {};
case 'in':
return b.__contains__(a);
case 'not in':
- return b.__contains__(a) === py.True ? py.False : py.True;
+ return py.PY_isTrue(b.__contains__(a)) ? py.False : py.True;
case '==': case '!=': case '<>':
case '<': case '<=':
case '>': case '>=':
@@ -1183,20 +1221,20 @@ var py = {};
expr.operators[i],
left,
left = py.evaluate(expr.expressions[i+1], context));
- if (result === py.False) { return py.False; }
+ if (py.PY_not(result)) { return py.False; }
}
return py.True;
case 'not':
return py.PY_isTrue(py.evaluate(expr.first, context)) ? py.False : py.True;
case 'and':
var and_first = py.evaluate(expr.first, context);
- if (and_first.__nonzero__() === py.True) {
+ if (py.PY_isTrue(and_first.__nonzero__())) {
return py.evaluate(expr.second, context);
}
return and_first;
case 'or':
var or_first = py.evaluate(expr.first, context);
- if (or_first.__nonzero__() === py.True) {
+ if (py.PY_isTrue(or_first.__nonzero__())) {
return or_first
}
return py.evaluate(expr.second, context);
@@ -1223,26 +1261,23 @@ var py = {};
tuple_values.push(py.evaluate(
tuple_exprs[j], context));
}
- var t = py.PY_call(py.tuple);
- t._values = tuple_values;
- return t;
+ return py.tuple.fromJSON(tuple_values);
case '[':
if (expr.second) {
- return py.evaluate(expr.first, context)
- .__getitem__(py.evaluate(expr.second, context));
+ return py.PY_getItem(
+ py.evaluate(expr.first, context),
+ py.evaluate(expr.second, context));
}
var list_exprs = expr.first, list_values = [];
for (var k=0; k<list_exprs.length; ++k) {
list_values.push(py.evaluate(
list_exprs[k], context));
}
- var l = py.PY_call(py.list);
- l._values = list_values;
- return l;
+ return py.list.fromJSON(list_values);
case '{':
var dict_exprs = expr.first, dict = py.PY_call(py.dict);
for(var l=0; l<dict_exprs.length; ++l) {
- dict.__setitem__(
+ py.PY_setItem(dict,
py.evaluate(dict_exprs[l][0], context),
py.evaluate(dict_exprs[l][1], context));
}