Skip to content
Permalink
Newer
Older
100644 1035 lines (923 sloc) 30.5 KB
Sep 5, 2014
1
;(function($B){
2
3
/*
4
Implementation of Python dictionaries
5
6
We can't use Javascript's Map here, because the behaviour is not exactly the
7
same (eg with keys that are instances of classes with a __hash__ method...)
8
and because Map is much slower than regular Javascript objects.
9
10
A Python dictionary is implemented as a Javascript objects with these
11
attributes:
12
. $version: an integer with an initial value of 0, incremented at each
13
insertion
14
. $numeric_dict: for keys of type int
15
. $string_dict and $str_hash: for keys of type str
16
. $object_dict: for keys of other types
17
18
The value associated to a key in $numeric_dict and $string_dict is a pair
19
[value, rank] where "value" is the value associated with the key and "rank"
20
is the value of the dict attribute $version when the pair is inserted. This
21
is required to keep track of the insertion order, mandatory since Python 3.7.
22
23
For keys that are not str or int, their hash value is computed. Since several
24
keys with the same hash can be stored in a dictionary, $object_dict[hash] is a
25
list of [key, [value, rank]] lists.
26
*/
27
28
var bltns = $B.InjectBuiltins()
29
eval(bltns)
31
var str_hash = _b_.str.__hash__,
Sep 5, 2014
33
34
var set_ops = ["eq", "add", "sub", "and", "or", "xor", "le", "lt", "ge", "gt"]
35
36
$B.make_view = function(name, set_like){
37
var klass = $B.make_class(name, function(items){
38
return {
39
__class__: klass,
40
__dict__: _b_.dict.$factory(),
41
counter: -1,
42
items: items,
43
len: items.length
44
}
45
})
46
47
if(set_like){
48
for(var i = 0, len = set_ops.length; i < len; i++){
49
var op = "__" + set_ops[i] + "__"
50
klass[op] = (function(op){
51
return function(self, other){
52
// compare set of items to other
53
return _b_.set[op](_b_.set.$factory(self),
54
_b_.set.$factory(other))
55
}
56
})(op)
57
}
58
}
59
klass.__iter__ = function(self){
60
var it = klass.$iterator.$factory(self.items)
61
it.len_func = self.len_func
62
return it
63
}
64
65
klass.__len__ = function(self){
66
return self.len
67
}
69
klass.__repr__ = function(self){
70
return klass.$infos.__name__ + '(' + _b_.repr(self.items) + ')'
71
}
72
73
$B.set_func_names(klass, "builtins")
74
return klass
75
}
76
77
// Special version of __next__ for iterators on dict keys / values / items.
78
// Checks that the dictionary size didn't change during iteration.
79
function dict_iterator_next(self){
80
if(self.len_func() != self.len){
81
throw _b_.RuntimeError.$factory("dictionary changed size during iteration")
82
}
83
self.counter++
84
if(self.counter < self.items.length){
85
return self.items[self.counter]
86
}
87
throw _b_.StopIteration.$factory("StopIteration")
88
}
89
Feb 11, 2018
90
var dict = {
Feb 11, 2018
91
__class__: _b_.type,
93
$infos: {
94
__module__: "builtins",
95
__name__: "dict"
96
},
Feb 11, 2018
97
$is_class: true,
98
$native: true
Sep 5, 2014
99
}
100
101
dict.$to_obj = function(d){
102
// Function applied to dictionary that only have string keys,
103
// return a Javascript objects with the kays mapped to the value,
104
// excluding the insertion rank
105
var res = {}
106
for(var key in d.$string_dict){
107
res[key] = d.$string_dict[key][0]
108
}
109
return res
110
}
111
112
function to_list(d, ix){
113
var items = [],
114
item
116
if(d.$jsobj){
Mar 7, 2018
119
if(attr.charAt(0) != "$"){
120
var val = d.$jsobj[attr]
121
if(val === undefined){val = _b_.NotImplemented}
122
else if(val === null){val = $N}
126
}else{
127
for(var k in d.$numeric_dict){
128
items.push([parseFloat(k), d.$numeric_dict[k]])
129
}
131
for(var k in d.$string_dict){items.push([k, d.$string_dict[k]])}
133
for(var k in d.$object_dict){
134
d.$object_dict[k].forEach(function(item){
135
items.push(item)
136
})
137
}
138
// sort by insertion order
139
items.sort(function(a, b){
140
return a[1][1] - b[1][1]
141
})
142
items = items.map(function(item){return [item[0], item[1][0]]})
145
if(ix !== undefined){
146
return items.map(function(item){return item[ix]})
147
}else{
148
items.__class__ = _b_.tuple
149
return items.map(function(item){
150
item.__class__ = _b_.tuple; return item}
151
)
152
}
Feb 9, 2015
154
155
$B.dict_to_list = to_list // used in py_types.js
156
157
// Special version of __next__ for iterators on dict keys / values / items.
158
// Checks that the dictionary size didn't change during iteration.
159
function dict_iterator_next(self){
160
if(self.len_func() != self.len){
161
throw _b_.RuntimeError.$factory("dictionary changed size during iteration")
162
}
163
self.counter++
164
if(self.counter < self.items.length){
165
return self.items[self.counter]
167
throw _b_.StopIteration.$factory("StopIteration")
171
var $copy_dict = function(left, right){
173
si = dict.$setitem
174
right.$version = right.$version || 0
175
var right_version = right.$version || 0
176
for(var i = 0, len = _l.length; i < len; i++){
177
si(left, _l[i][0], _l[i][1])
178
if(right.$version != right_version){
179
throw _b_.RuntimeError.$factory("dict mutated during update")
180
}
181
}
184
function rank(self, hash, key){
185
// Search if object key, with hash = hash(key), is in
186
// self.$object_dict
187
var pairs = self.$object_dict[hash]
188
if(pairs !== undefined){
189
for(var i = 0, len = pairs.length; i < len; i++){
190
if($B.rich_comp("__eq__", key, pairs[i][0])){
191
return i
192
}
193
}
194
}
195
return -1
196
}
197
Feb 11, 2018
198
dict.__bool__ = function () {
Mar 7, 2018
199
var $ = $B.args("__bool__", 1, {self: null}, ["self"],
200
arguments, {}, null, null)
Feb 11, 2018
201
return dict.__len__($.self) > 0
Feb 11, 2018
204
dict.__contains__ = function(){
Nov 21, 2015
205
206
var $ = $B.args("__contains__", 2, {self: null, key: null},
207
["self", "key"], arguments, {}, null, null),
208
self = $.self,
210
if(self.$is_namespace){key = $B.to_alias(key)} // issue 1244
211
212
if(self.$jsobj){
213
return self.$jsobj[key] !== undefined
214
}
216
switch(typeof key) {
218
return self.$string_dict[key] !== undefined
220
return self.$numeric_dict[key] !== undefined
221
}
222
223
var hash = _b_.hash(key)
224
if(self.$str_hash[hash] !== undefined &&
225
$B.rich_comp("__eq__", key, self.$str_hash[hash])){return true}
226
if(self.$numeric_dict[hash] !== undefined &&
227
$B.rich_comp("__eq__", key, hash)){return true}
228
return rank(self, hash, key) > -1
Sep 5, 2014
229
}
230
Feb 11, 2018
231
dict.__delitem__ = function(){
Nov 21, 2015
232
233
var $ = $B.args("__eq__", 2, {self: null, arg: null},
234
["self", "arg"], arguments, {}, null, null),
235
self = $.self,
Nov 21, 2015
237
238
if(self.$jsobj){
239
if(self.$jsobj[arg] === undefined){throw _b_.KeyError.$factory(arg)}
240
delete self.$jsobj[arg]
243
switch(typeof arg){
244
case "string":
245
if(self.$string_dict[arg] === undefined){
246
throw _b_.KeyError.$factory(_b_.str.$factory(arg))
247
}
248
delete self.$string_dict[arg]
249
delete self.$str_hash[str_hash(arg)]
251
return $N
252
case "number":
253
if(self.$numeric_dict[arg] === undefined){
254
throw _b_.KeyError.$factory(_b_.str.$factory(arg))
256
delete self.$numeric_dict[arg]
260
// go with defaults
261
262
var hash = _b_.hash(arg),
263
ix
265
if((ix = rank(self, hash, arg)) > -1){
266
self.$object_dict[hash].splice(ix, 1)
267
}else{
268
throw _b_.KeyError.$factory(_b_.str.$factory(arg))
Sep 5, 2014
273
}
274
Feb 11, 2018
275
dict.__eq__ = function(){
Mar 7, 2018
276
var $ = $B.args("__eq__", 2, {self: null, other: null},
277
["self", "other"], arguments, {}, null, null),
278
self = $.self,
279
other = $.other
281
if(! _b_.isinstance(other, dict)){return false}
283
if(self.$jsobj){self = jsobj2dict(self.$jsobj)}
284
if(other.$jsobj){other = jsobj2dict(other.$jsobj)}
285
if(dict.__len__(self) != dict.__len__(other)){
286
return false
287
}
289
if(self.$string_dict.length != other.$string_dict.length){
293
for(var k in self.$numeric_dict){
294
if(other.$numeric_dict.hasOwnProperty(k)){
295
if(!$B.rich_comp("__eq__", other.$numeric_dict[k][0],
296
self.$numeric_dict[k][0])){
297
return false
298
}
299
}else if(other.$object_dict.hasOwnProperty(k)){
300
var pairs = other.$object_dict[k],
301
flag = false
302
for(var i = 0, len = pairs.length; i < len; i++){
303
if($B.rich_comp("__eq__", k, pairs[i][0]) &&
304
$B.rich_comp("__eq__", self.$numeric_dict[k],
305
pairs[i][1])){
306
flag = true
307
break
308
}
310
if(! flag){return false}
Nov 21, 2015
313
}
314
}
315
for(var k in self.$string_dict){
316
if(!other.$string_dict.hasOwnProperty(k) ||
317
!$B.rich_comp("__eq__", other.$string_dict[k][0],
318
self.$string_dict[k][0])){
Nov 21, 2015
320
}
321
}
322
for(var hash in self.$object_dict){
323
var pairs = self.$object_dict[hash]
324
// Get all (key, value) pairs in other that have the same hash
325
var other_pairs = []
326
if(other.$numeric_dict[hash] !== undefined){
327
other_pairs.push([hash, other.$numeric_dict[hash]])
328
}
329
if(other.$object_dict[hash] !== undefined){
330
other_pairs = other_pairs.concat(other.$object_dict[hash])
331
}
332
if(other_pairs.length == 0){
333
return false
334
}
335
for(var i = 0, len_i = pairs.length; i < len_i; i++){
336
var flag = false
337
var key = pairs[i][0],
338
value = pairs[i][1][0]
339
for(var j = 0, len_j = other_pairs.length; j < len_j; j++){
340
if($B.rich_comp("__eq__", key, other_pairs[j][0]) &&
341
$B.rich_comp("__eq__", value, other_pairs[j][1][0])){
342
flag = true
343
break
349
}
350
}
351
return true
Sep 5, 2014
352
}
353
Feb 11, 2018
354
dict.__getitem__ = function(){
355
var $ = $B.args("__getitem__", 2, {self: null, arg: null},
356
["self", "arg"], arguments, {}, null, null),
357
self = $.self,
359
return dict.$getitem(self, arg)
360
}
361
362
dict.$getitem = function(self, arg){
363
if(self.$jsobj){
364
if(self.$jsobj[arg] === undefined){
365
if(self.$jsobj.hasOwnProperty(arg)){
367
}
368
throw _b_.KeyError.$factory(arg)
369
}
370
return self.$jsobj[arg]
372
373
switch(typeof arg){
374
case "string":
375
if(self.$string_dict[arg] !== undefined){
376
return self.$string_dict[arg][0]
378
break
379
case "number":
380
if(self.$numeric_dict[arg] !== undefined){
381
return self.$numeric_dict[arg][0]
383
break
384
}
385
386
// since the key is more complex use 'default' method of getting item
387
388
var hash = _b_.hash(arg),
389
_eq = function(other){return $B.rich_comp("__eq__", arg, other)}
390
391
if(typeof arg == "object"){
392
arg.$hash = hash // cache for setdefault
393
}
394
var sk = self.$str_hash[hash]
395
if(sk !== undefined && _eq(sk)){
396
return self.$string_dict[sk][0]
398
if(self.$numeric_dict[hash] !== undefined && _eq(hash)){
399
return self.$numeric_dict[hash][0]
401
if(_b_.isinstance(arg, _b_.str)){
402
// string subclass
403
var res = self.$string_dict[arg.valueOf()]
404
if(res !== undefined){return res[0]}
407
var ix = rank(self, hash, arg)
408
if(ix > -1){
409
return self.$object_dict[hash][ix][1][0]
412
if(self.__class__ !== dict){
414
var missing_method = getattr(self.__class__, "__missing__",
415
_b_.None)
416
}catch(err){
417
console.log(err)
418
419
}
420
if(missing_method !== _b_.None){
421
return missing_method(self, arg)
424
throw _b_.KeyError.$factory(arg)
Sep 5, 2014
425
}
426
427
dict.__hash__ = _b_.None
Sep 5, 2014
428
429
function init_from_list(self, args){
430
var i = -1,
431
stop = args.length - 1,
432
si = dict.__setitem__
433
while(i++ < stop){
434
var item = args[i]
435
switch(typeof item[0]) {
436
case 'string':
437
self.$string_dict[item[0]] = [item[1], self.$version]
438
self.$str_hash[str_hash(item[0])] = item[0]
439
self.$version++
440
break
441
case 'number':
442
self.$numeric_dict[item[0]] = [item[1], self.$version]
443
self.$version++
444
break
445
default:
446
si(self, item[0], item[1])
447
break
448
}
449
}
450
}
451
452
dict.__init__ = function(self, first, second){
454
if(first === undefined){return $N}
455
if(second === undefined){
456
if(first.__class__ === $B.JSObject){
457
self.$jsobj = first.js
458
return $N
459
}else if(first.$jsobj){
460
self.$jsobj = {}
461
for(var attr in first.$jsobj){
462
self.$jsobj[attr] = first.$jsobj[attr]
465
}else if(Array.isArray(first)){
466
init_from_list(self, first)
467
return $N
Sep 5, 2014
468
}
471
$ = $ || $B.args("dict", 1, {self:null}, ["self"],
472
arguments, {}, "first", "second")
473
var args = $.first
474
if(args.length > 1){
475
throw _b_.TypeError.$factory("dict expected at most 1 argument" +
476
", got 2")
477
}else if(args.length == 1){
478
args = args[0]
479
if(args.__class__ === dict){
480
['$string_dict', '$str_hash', '$numeric_dict', '$object_dict'].
481
forEach(function(d){
482
for(key in args[d]){self[d][key] = args[d][key]}
483
})
484
}else if(_b_.isinstance(args, dict)){
487
var keys = $B.$getattr(args, "keys", null)
488
if(keys !== null){
489
var gi = $B.$getattr(args, "__getitem__", null)
490
if(gi !== null){
491
// has keys and __getitem__ : it's a mapping, iterate on
492
// keys and values
493
gi = $B.$call(gi)
494
var kiter = _b_.iter($B.$call(keys)())
495
while(true){
496
try{
497
var key = _b_.next(kiter),
498
value = gi(key)
499
dict.__setitem__(self, key, value)
500
}catch(err){
501
if(err.__class__ === _b_.StopIteration){
502
break
503
}
504
throw err
505
}
506
}
507
return $N
508
}
509
}
510
if(! Array.isArray(args)){
511
args = _b_.list.$factory(args)
512
}
513
// Form "dict([[key1, value1], [key2,value2], ...])"
514
init_from_list(self, args)
Sep 5, 2014
515
}
517
var kw = $.second.$string_dict
518
for(var attr in kw){
519
switch(typeof attr){
520
case "string":
521
self.$string_dict[attr] = kw[attr]
522
self.$str_hash[str_hash(attr)] = attr
523
break
524
case "number":
525
self.$numeric_dict[attr] = kw[attr]
526
break
527
default:
528
si(self, attr, kw[attr])
529
break
530
}
Sep 5, 2014
533
}
534
Feb 11, 2018
535
dict.__iter__ = function(self) {
536
return _b_.iter(dict.$$keys(self))
Sep 5, 2014
537
}
538
Feb 11, 2018
539
dict.__len__ = function(self) {
542
if(self.$jsobj){
Mar 7, 2018
543
for(var attr in self.$jsobj){if(attr.charAt(0) != "$"){_count++}}
544
return _count
545
}
547
for(var k in self.$numeric_dict){_count++}
548
for(var k in self.$string_dict){_count++}
549
for(var hash in self.$object_dict){
550
_count += self.$object_dict[hash].length
551
}
Sep 5, 2014
555
Mar 7, 2018
556
dict.__ne__ = function(self, other){return ! dict.__eq__(self, other)}
Sep 5, 2014
557
Feb 11, 2018
558
dict.__new__ = function(cls){
559
if(cls === undefined){
Mar 7, 2018
560
throw _b_.TypeError.$factory("int.__new__(): not enough arguments")
562
var instance = {
564
$numeric_dict : {},
565
$object_dict : {},
567
$str_hash: {},
568
$version: 0
570
if(cls !== dict){
571
instance.__dict__ = _b_.dict.$factory()
572
}
573
return instance
Feb 11, 2018
576
dict.__repr__ = function(self){
577
if(self.$jsobj){ // wrapper around Javascript object
Feb 11, 2018
578
return dict.__repr__(jsobj2dict(self.$jsobj))
580
if($B.repr.enter(self)){
581
return "{...}"
582
}
583
var res = [],
585
items.forEach(function(item){
586
try{
587
res.push(repr(item[0]) + ": " + repr(item[1]))
588
}catch(err){
589
throw err
590
}
592
$B.repr.leave(self)
Mar 7, 2018
593
return "{" + res.join(", ") + "}"
Sep 5, 2014
594
}
595
596
dict.__setitem__ = function(self, key, value){
Mar 7, 2018
597
var $ = $B.args("__setitem__", 3, {self: null, key: null, value: null},
598
["self", "key", "value"], arguments, {}, null, null)
599
return dict.$setitem($.self, $.key, $.value)
600
}
Nov 21, 2015
601
602
dict.$setitem = function(self, key, value, $hash){
603
// Set a dictionary item mapping key and value.
604
//
605
// If key is a string, set:
606
// - $string_dict[key] = [value, order] where "order" is an auto-increment
607
// unique id to keep track of insertion order
608
// - $str_hash[hash(key)] to key
609
//
610
// If key is a number, set $numeric_dict[key] = value
611
//
612
// If key is another object, compute its hash value:
613
// - if the hash is a key of $str_hash, and key == $str_hash[hash],
614
// replace $string_dict[$str_hash[hash]] by value
615
// - if the hash is a key of $numeric_dict, and hash == key, replace
616
// $numeric_dict[hash] by value
617
// - if the hash is a key of $object_dict: $object_dict[hash] is a list
618
// of [k, v] pairs. If key is equal to one of the "k", replace the
619
// matching v by value. Otherwise, add [key, value] to the list
620
// - else set $object_dict[hash] = [[key, value]]
621
//
622
// In all cases, increment attribute $version, used to detect dictionary
623
// changes during an iteration.
625
// Parameter $hash is only set if this method is called by setdefault.
626
// In this case the hash of key has already been computed and we
627
// know that the key is not present in the dictionary, so it's no
628
// use computing hash(key) again, nor testing equality of keys
630
if(self.$from_js){
631
// dictionary created by method to_dict of JSObject instances
632
value = $B.pyobj2jsobj(value)
633
}
634
if(self.$jsobj.__class__ === _b_.type){
635
self.$jsobj[key] = value
636
if(key == "__init__" || key == "__new__"){
637
// If class attribute __init__ or __new__ are reset,
638
// the factory function has to change
639
self.$jsobj.$factory = $B.$instance_creator(self.$jsobj)
640
}
641
}else{
642
self.$jsobj[key] = value
647
switch(typeof key){
648
case "string":
649
if(self.$string_dict === undefined){
650
console.log("pas de string dict", self, key, value)
651
}
652
self.$string_dict[key] = [value, self.$version]
653
self.$str_hash[str_hash(key)] = key
655
return $N
656
case "number":
657
self.$numeric_dict[key] = [value, self.$version]
659
return $N
662
// if we got here the key is more complex, use default method
663
664
var hash = $hash === undefined ? _b_.hash(key) : $hash,
665
_eq = function(other){return $B.rich_comp("__eq__", key, other)}
666
667
if(self.$numeric_dict[hash] !== undefined && _eq(hash)){
668
self.$numeric_dict[hash] = [value, self.$numeric_dict[hash][1]]
672
var sk = self.$str_hash[hash]
673
if(sk !== undefined && _eq(sk)){
674
self.$string_dict[sk] = [value, self.$string_dict[sk][1]]
679
// If $setitem is called from setdefault, don't test equality of key
680
// with any object
681
if($hash){
682
if(self.$object_dict[$hash] !== undefined){
683
self.$object_dict[$hash].push([key, [value, self.$version]])
685
self.$object_dict[$hash] = [[key, [value, self.$version]]]
686
}
687
self.$version++
688
return $N
689
}
690
var ix = rank(self, hash, key)
691
if(ix > -1){
692
// reset value
693
self.$object_dict[hash][ix][1] = [value,
694
self.$object_dict[hash][ix][1][1]]
695
return $N
696
}else if(self.$object_dict.hasOwnProperty(hash)){
697
self.$object_dict[hash].push([key, [value, self.$version]])
699
self.$object_dict[hash] = [[key, [value, self.$version]]]
Sep 5, 2014
703
}
704
705
dict.__str__ = function(){
706
return dict.__repr__.apply(null, arguments)
707
}
Sep 5, 2014
708
709
// add "reflected" methods
Feb 11, 2018
710
$B.make_rmethods(dict)
Sep 5, 2014
711
Feb 11, 2018
712
dict.clear = function(){
Sep 5, 2014
713
// Remove all items from the dictionary.
Mar 7, 2018
714
var $ = $B.args("clear", 1, {self: null}, ["self"], arguments, {},
715
null, null),
716
self = $.self
718
self.$numeric_dict = {}
719
self.$string_dict = {}
720
self.$str_hash = {}
721
self.$object_dict = {}
723
if(self.$jsobj){
724
for(var attr in self.$jsobj){
Mar 7, 2018
725
if(attr.charAt(0) !== "$" && attr !== "__class__"){
726
delete self.$jsobj[attr]
727
}
728
}
729
}
Sep 5, 2014
732
}
733
Feb 11, 2018
734
dict.copy = function(self){
Sep 5, 2014
735
// Return a shallow copy of the dictionary
Mar 7, 2018
736
var $ = $B.args("copy", 1, {self: null},["self"], arguments,{},
737
null, null),
738
self = $.self,
Feb 11, 2018
739
res = _b_.dict.$factory()
Sep 5, 2014
741
return res
742
}
743
Feb 11, 2018
744
dict.fromkeys = function(){
Nov 21, 2015
745
Mar 7, 2018
746
var $ = $B.args("fromkeys", 3, {cls: null, keys: null, value: null},
747
["cls", "keys", "value"], arguments, {value: _b_.None}, null, null),
748
keys = $.keys,
749
value = $.value
Sep 5, 2014
751
// class method
752
var klass = $.cls,
Sep 5, 2014
756
while(1){
757
try{
758
var key = _b_.next(keys_iter)
759
if(klass === dict){dict.$setitem(res, key, value)}
760
else{$B.$getattr(res, "__setitem__")(key, value)}
Sep 5, 2014
761
}catch(err){
762
if($B.is_exc(err, [_b_.StopIteration])){
Sep 5, 2014
763
return res
764
}
765
throw err
766
}
767
}
768
}
769
Feb 11, 2018
770
dict.get = function(){
Mar 7, 2018
771
var $ = $B.args("get", 3, {self: null, key: null, _default: null},
772
["self", "key", "_default"], arguments, {_default: $N}, null, null)
Feb 11, 2018
774
try{return dict.__getitem__($.self, $.key)}
775
catch(err){
776
if(_b_.isinstance(err, _b_.KeyError)){return $._default}
777
else{throw err}
778
}
779
}
780
781
var dict_items = $B.make_view("dict_items", true)
782
dict_items.$iterator = $B.make_iterator_class("dict_itemiterator")
783
Feb 11, 2018
784
dict.items = function(self){
Mar 23, 2018
785
if(arguments.length > 1){
786
var _len = arguments.length - 1,
787
_msg = "items() takes no arguments (" + _len + " given)"
788
throw _b_.TypeError.$factory(_msg)
789
}
790
var it = dict_items.$factory(to_list(self))
791
it.len_func = function(){return dict.__len__(self)}
792
return it
793
}
794
795
var dict_keys = $B.make_view("dict_keys", true)
796
dict_keys.$iterator = $B.make_iterator_class("dict_keyiterator")
Nov 21, 2015
797
Mar 23, 2018
799
if(arguments.length > 1){
800
var _len = arguments.length - 1,
801
_msg = "keys() takes no arguments (" + _len + " given)"
802
throw _b_.TypeError.$factory(_msg)
Nov 21, 2015
803
}
804
var it = dict_keys.$factory(to_list(self, 0))
805
it.len_func = function(){return dict.__len__(self)}
806
return it
Nov 21, 2015
807
}
808
Feb 11, 2018
809
dict.pop = function(){
Nov 21, 2015
810
811
var missing = {},
812
$ = $B.args("pop", 3, {self: null, key: null, _default: null},
813
["self", "key", "_default"], arguments, {_default: missing}, null, null),
814
self = $.self,
815
key = $.key,
816
_default = $._default
Nov 21, 2015
817
Sep 5, 2014
818
try{
819
var res = dict.__getitem__(self, key)
820
dict.__delitem__(self, key)
Sep 5, 2014
821
return res
822
}catch(err){
823
if(err.__class__ === _b_.KeyError){
824
if(_default !== missing){return _default}
Sep 5, 2014
825
throw err
826
}
827
throw err
828
}
829
}
830
Feb 11, 2018
831
dict.popitem = function(self){
833
var itm = _b_.next(_b_.iter(dict.items(self)))
834
dict.__delitem__(self, itm[0])
Feb 11, 2018
835
return _b_.tuple.$factory(itm)
837
if (err.__class__ == _b_.StopIteration) {
838
throw _b_.KeyError.$factory("'popitem(): dictionary is empty'")
Sep 5, 2014
841
}
842
Feb 11, 2018
843
dict.setdefault = function(){
Nov 21, 2015
844
Mar 7, 2018
845
var $ = $B.args("setdefault", 3, {self: null, key: null, _default: null},
846
["self", "key", "_default"], arguments, {_default: $N}, null, null),
847
self = $.self,
848
key = $.key,
849
_default = $._default
Nov 21, 2015
850
851
try{return dict.__getitem__(self, key)}
Sep 5, 2014
852
catch(err){
853
if(err.__class__ !== _b_.KeyError){
854
throw err
855
}
856
if(_default === undefined){_default = $N}
857
var hash = key.$hash
858
key.$hash = undefined
859
dict.$setitem(self, key, _default, hash)
Sep 5, 2014
860
return _default
861
}
862
}
863
Feb 11, 2018
864
dict.update = function(self){
Nov 21, 2015
865
Mar 7, 2018
866
var $ = $B.args("update", 1, {"self": null}, ["self"], arguments,
867
{}, "args", "kw"),
868
self = $.self,
869
args = $.args,
870
kw = $.kw
871
if(args.length > 0){
872
var o = args[0]
874
if(o.$jsobj){
875
o = jsobj2dict(o.$jsobj)
876
}
878
}else if(_b_.hasattr(o, "keys")){
879
var _keys = _b_.list.$factory($B.$call($B.$getattr(o, "keys"))())
880
for(var i = 0, len = _keys.length; i < len; i++){
881
var _value = getattr(o, "__getitem__")(_keys[i])
882
dict.$setitem(self, _keys[i], _value)
883
}
884
}else{
885
var it = _b_.iter(o),
886
i = 0
887
while(true){
888
try{
889
var item = _b_.next(it)
890
}catch(err){
891
if(err.__class__ === _b_.StopIteration){break}
892
throw err
893
}
894
try{
895
key_value = _b_.list.$factory(item)
896
}catch(err){
897
throw _b_.TypeError.$factory("cannot convert dictionary" +
898
" update sequence element #" + i + " to a sequence")
899
}
900
if(key_value.length !== 2){
901
throw _b_.ValueError.$factory("dictionary update " +
902
"sequence element #" + i + " has length " +
903
key_value.length + "; 2 is required")
904
}
905
dict.$setitem(self, key_value[0], key_value[1])
906
i++
Sep 5, 2014
909
}
Sep 5, 2014
913
}
914
915
var dict_values = $B.make_view("dict_values")
916
dict_values.$iterator = $B.make_iterator_class("dict_valueiterator")
Nov 21, 2015
917
Feb 11, 2018
918
dict.values = function(self){
Mar 23, 2018
919
if(arguments.length > 1){
920
var _len = arguments.length - 1,
921
_msg = "values() takes no arguments (" + _len + " given)"
922
throw _b_.TypeError.$factory(_msg)
Nov 21, 2015
923
}
924
var it = dict_values.$factory(to_list(self, 1))
925
it.len_func = function(){return dict.__len__(self)}
926
return it
Nov 21, 2015
927
}
928
929
dict.$factory = function(){
930
var res = dict.__new__(dict)
931
var args = [res]
932
for(var i = 0, len = arguments.length; i < len ; i++){
933
args.push(arguments[i])
934
}
935
dict.__init__.apply(null, args)
Sep 5, 2014
936
return res
937
}
Sep 5, 2014
939
_b_.dict = dict
Feb 11, 2018
941
$B.set_func_names(dict, "builtins")
943
// This must be done after set_func_names, otherwise dict.fromkeys doesn't
944
// have the attribute $infos
945
dict.fromkeys = _b_.classmethod.$factory(dict.fromkeys)
946
947
$B.getset_descriptor = $B.make_class("getset_descriptor",
948
function(klass, attr){
949
return {
950
__class__: $B.getset_descriptor,
951
cls: klass,
952
attr: attr
953
}
954
}
955
)
956
957
$B.getset_descriptor.__repr__ = $B.getset_descriptor.__str__ = function(self){
958
return `<attribute '${self.attr}' of '${self.cls.$infos.__name__}' objects>`
959
}
960
961
$B.set_func_names($B.getset_descriptor, "builtins")
962
963
// Class for attribute __dict__ of classes
964
var mappingproxy = $B.mappingproxy = $B.make_class("mappingproxy",
Feb 12, 2018
965
function(obj){
966
if(_b_.isinstance(obj, dict)){
967
// obj is a dictionary, with $string_dict table such that
968
// obj.$string_dict[key] = [value, rank]
969
// Transform it into an object with attribute $jsobj such that
970
// res.$jsobj[key] = value
971
var res = $B.obj_dict(dict.$to_obj(obj))
972
}else{
973
var res = $B.obj_dict(obj)
974
}
Feb 12, 2018
975
res.__class__ = mappingproxy
976
return res
977
}
978
)
Feb 12, 2018
980
mappingproxy.__setitem__ = function(){
Mar 7, 2018
981
throw _b_.TypeError.$factory("'mappingproxy' object does not support " +
982
"item assignment")
985
for(var attr in dict){
986
if(mappingproxy[attr] !== undefined ||
987
["__class__", "__mro__", "__new__", "__init__", "__delitem__",
988
"clear", "fromkeys", "pop", "popitem", "setdefault",
989
"update"].indexOf(attr) > -1){
990
continue
991
}
992
if(typeof dict[attr] == "function"){
993
mappingproxy[attr] = (function(key){
994
return function(){
995
return dict[key].apply(null, arguments)
996
}
997
})(attr)
998
}else{
999
mappingproxy[attr] = dict[attr]
1000
}
1001
}
1002
Feb 12, 2018
1003
$B.set_func_names(mappingproxy, "builtins")
Mar 7, 2018
1008
if(attr.charAt(0) != "$" && attr !== "__class__"){
1009
if(x[attr] === null){
1010
d.$string_dict[attr] = [_b_.None, d.$version]
1011
}else if(x[attr] === undefined){
1012
continue
1013
}else if(x[attr].$jsobj === x){
1014
d.$string_dict[attr] = [d, d.$version]
1016
d.$string_dict[attr] = [$B.$JS2Py(x[attr]), d.$version]
1018
d.$version++
1019
}
1020
}
1021
return d
1022
}
1024
$B.obj_dict = function(obj, from_js){
1025
var klass = obj.__class__ || $B.get_class(obj)
1026
if(klass !== undefined && klass.$native){
1027
throw _b_.AttributeError.$factory(klass.__name__ +
1028
" has no attribute '__dict__'")}
1029
var res = _b_.dict.$factory()
1030
res.$jsobj = obj
1031
res.$from_js = from_js // set to true if
1032
return res
1033
}
1034
Sep 5, 2014
1035
})(__BRYTHON__)