Skip to content
Permalink
Newer
Older
100644 1090 lines (974 sloc) 31.9 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,
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.$order++]
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.$order++]
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.$nat != 'kw' && $B.get_class(first) === $B.JSObj){
460
for(var key in first){
461
self.$string_dict[key] = [first[key], self.$order++]
462
}
463
return _b_.None
464
}else if(first.$jsobj){
465
self.$jsobj = {}
466
for(var attr in first.$jsobj){
467
self.$jsobj[attr] = first.$jsobj[attr]
470
}else if(Array.isArray(first)){
471
init_from_list(self, first)
472
return $N
Sep 5, 2014
473
}
476
$ = $ || $B.args("dict", 1, {self:null}, ["self"],
477
arguments, {}, "first", "second")
478
var args = $.first
479
if(args.length > 1){
480
throw _b_.TypeError.$factory("dict expected at most 1 argument" +
481
", got 2")
482
}else if(args.length == 1){
483
args = args[0]
484
if(args.__class__ === dict){
485
['$string_dict', '$str_hash', '$numeric_dict', '$object_dict'].
486
forEach(function(d){
487
for(key in args[d]){self[d][key] = args[d][key]}
488
})
489
}else if(_b_.isinstance(args, dict)){
492
var keys = $B.$getattr(args, "keys", null)
493
if(keys !== null){
494
var gi = $B.$getattr(args, "__getitem__", null)
495
if(gi !== null){
496
// has keys and __getitem__ : it's a mapping, iterate on
497
// keys and values
498
gi = $B.$call(gi)
499
var kiter = _b_.iter($B.$call(keys)())
500
while(true){
501
try{
502
var key = _b_.next(kiter),
503
value = gi(key)
504
dict.__setitem__(self, key, value)
505
}catch(err){
506
if(err.__class__ === _b_.StopIteration){
507
break
508
}
509
throw err
510
}
511
}
512
return $N
513
}
514
}
515
if(! Array.isArray(args)){
516
args = _b_.list.$factory(args)
517
}
518
// Form "dict([[key1, value1], [key2,value2], ...])"
519
init_from_list(self, args)
Sep 5, 2014
520
}
522
var kw = $.second.$string_dict
523
for(var attr in kw){
524
switch(typeof attr){
525
case "string":
526
self.$string_dict[attr] = [kw[attr][0], self.$order++]
527
self.$str_hash[str_hash(attr)] = attr
528
break
529
case "number":
530
self.$numeric_dict[attr] = [kw[attr][0], self.$order++]
533
si(self, attr, kw[attr][0])
Sep 5, 2014
538
}
539
Feb 11, 2018
540
dict.__iter__ = function(self) {
541
return _b_.iter(dict.$$keys(self))
Sep 5, 2014
542
}
543
544
dict.__ior__ = function(self, other){
545
// PEP 584
546
dict.update(self, other)
547
return self
548
}
549
Feb 11, 2018
550
dict.__len__ = function(self) {
553
if(self.$jsobj){
Mar 7, 2018
554
for(var attr in self.$jsobj){if(attr.charAt(0) != "$"){_count++}}
555
return _count
556
}
558
for(var k in self.$numeric_dict){_count++}
559
for(var k in self.$string_dict){_count++}
560
for(var hash in self.$object_dict){
561
_count += self.$object_dict[hash].length
562
}
Sep 5, 2014
566
Mar 7, 2018
567
dict.__ne__ = function(self, other){return ! dict.__eq__(self, other)}
Sep 5, 2014
568
Feb 11, 2018
569
dict.__new__ = function(cls){
570
if(cls === undefined){
Mar 7, 2018
571
throw _b_.TypeError.$factory("int.__new__(): not enough arguments")
573
var instance = {
575
$numeric_dict : {},
576
$object_dict : {},
579
$version: 0,
580
$order: 0
582
if(cls !== dict){
583
instance.__dict__ = $B.empty_dict()
584
}
585
return instance
588
dict.__or__ = function(self, other){
589
// PEP 584
590
if(! _b_.isinstance(other, dict)){
591
return _b_.NotImplemented
592
}
593
var res = dict.copy(self)
594
dict.update(res, other)
595
return res
596
}
597
Feb 11, 2018
598
dict.__repr__ = function(self){
599
if(self.$jsobj){ // wrapper around Javascript object
Feb 11, 2018
600
return dict.__repr__(jsobj2dict(self.$jsobj))
602
if($B.repr.enter(self)){
603
return "{...}"
604
}
605
var res = [],
607
items.forEach(function(item){
608
try{
609
res.push(repr(item[0]) + ": " + repr(item[1]))
610
}catch(err){
611
throw err
612
}
614
$B.repr.leave(self)
Mar 7, 2018
615
return "{" + res.join(", ") + "}"
Sep 5, 2014
616
}
617
618
dict.__ror__ = function(self, other){
619
// PEP 584
620
if(! _b_.isinstance(other, dict)){
621
return _b_.NotImplemented
622
}
623
var res = dict.copy(other)
624
dict.update(res, self)
625
return res
626
}
627
628
dict.__setitem__ = function(self, key, value){
Mar 7, 2018
629
var $ = $B.args("__setitem__", 3, {self: null, key: null, value: null},
630
["self", "key", "value"], arguments, {}, null, null)
631
return dict.$setitem($.self, $.key, $.value)
632
}
Nov 21, 2015
633
634
dict.$setitem = function(self, key, value, $hash){
635
// Set a dictionary item mapping key and value.
636
//
637
// If key is a string, set:
638
// - $string_dict[key] = [value, order] where "order" is an auto-increment
639
// unique id to keep track of insertion order
640
// - $str_hash[hash(key)] to key
641
//
642
// If key is a number, set $numeric_dict[key] = value
643
//
644
// If key is another object, compute its hash value:
645
// - if the hash is a key of $str_hash, and key == $str_hash[hash],
646
// replace $string_dict[$str_hash[hash]] by value
647
// - if the hash is a key of $numeric_dict, and hash == key, replace
648
// $numeric_dict[hash] by value
649
// - if the hash is a key of $object_dict: $object_dict[hash] is a list
650
// of [k, v] pairs. If key is equal to one of the "k", replace the
651
// matching v by value. Otherwise, add [key, value] to the list
652
// - else set $object_dict[hash] = [[key, value]]
653
//
654
// In all cases, increment attribute $version, used to detect dictionary
655
// changes during an iteration.
657
// Parameter $hash is only set if this method is called by setdefault.
658
// In this case the hash of key has already been computed and we
659
// know that the key is not present in the dictionary, so it's no
660
// use computing hash(key) again, nor testing equality of keys
662
if(self.$from_js){
663
// dictionary created by method to_dict of JSObject instances
664
value = $B.pyobj2jsobj(value)
665
}
666
if(self.$jsobj.__class__ === _b_.type){
667
self.$jsobj[key] = value
668
if(key == "__init__" || key == "__new__"){
669
// If class attribute __init__ or __new__ are reset,
670
// the factory function has to change
671
self.$jsobj.$factory = $B.$instance_creator(self.$jsobj)
672
}
673
}else{
674
self.$jsobj[key] = value
679
switch(typeof key){
680
case "string":
681
if(self.$string_dict === undefined){
682
console.log("pas de string dict", self, key, value)
683
}
684
if(self.$string_dict[key] !== undefined){
685
self.$string_dict[key][0] = value
686
}else{
687
self.$string_dict[key] = [value, self.$order++]
688
self.$str_hash[str_hash(key)] = key
689
self.$version++
690
}
691
return $N
692
case "number":
693
if(self.$numeric_dict[key] !== undefined){
694
// existing key: preserve order
695
self.$numeric_dict[key][0] = value
696
}else{
697
// new key
698
self.$numeric_dict[key] = [value, self.$order++]
699
self.$version++
700
}
701
return $N
704
// if we got here the key is more complex, use default method
705
706
var hash = $hash === undefined ? _b_.hash(key) : $hash,
707
_eq = function(other){return $B.rich_comp("__eq__", key, other)}
708
709
if(self.$numeric_dict[hash] !== undefined && _eq(hash)){
710
self.$numeric_dict[hash] = [value, self.$numeric_dict[hash][1]]
714
var sk = self.$str_hash[hash]
715
if(sk !== undefined && _eq(sk)){
716
self.$string_dict[sk] = [value, self.$string_dict[sk][1]]
721
// If $setitem is called from setdefault, don't test equality of key
722
// with any object
723
if($hash){
724
if(self.$object_dict[$hash] !== undefined){
725
self.$object_dict[$hash].push([key, [value, self.$order++]])
727
self.$object_dict[$hash] = [[key, [value, self.$order++]]]
728
}
729
self.$version++
730
return $N
731
}
732
var ix = rank(self, hash, key)
733
if(ix > -1){
734
// reset value
735
self.$object_dict[hash][ix][1] = [value,
736
self.$object_dict[hash][ix][1][1]]
737
return $N
738
}else if(self.$object_dict.hasOwnProperty(hash)){
739
self.$object_dict[hash].push([key, [value, self.$order++]])
741
self.$object_dict[hash] = [[key, [value, self.$order++]]]
Sep 5, 2014
745
}
746
747
dict.__str__ = function(){
748
return dict.__repr__.apply(null, arguments)
749
}
Sep 5, 2014
750
751
// add "reflected" methods
Feb 11, 2018
752
$B.make_rmethods(dict)
Sep 5, 2014
753
Feb 11, 2018
754
dict.clear = function(){
Sep 5, 2014
755
// Remove all items from the dictionary.
Mar 7, 2018
756
var $ = $B.args("clear", 1, {self: null}, ["self"], arguments, {},
757
null, null),
758
self = $.self
760
self.$numeric_dict = {}
761
self.$string_dict = {}
762
self.$str_hash = {}
763
self.$object_dict = {}
765
if(self.$jsobj){
766
for(var attr in self.$jsobj){
Mar 7, 2018
767
if(attr.charAt(0) !== "$" && attr !== "__class__"){
768
delete self.$jsobj[attr]
769
}
770
}
771
}
Sep 5, 2014
775
}
776
Feb 11, 2018
777
dict.copy = function(self){
Sep 5, 2014
778
// Return a shallow copy of the dictionary
Mar 7, 2018
779
var $ = $B.args("copy", 1, {self: null},["self"], arguments,{},
780
null, null),
781
self = $.self,
Sep 5, 2014
784
return res
785
}
786
Feb 11, 2018
787
dict.fromkeys = function(){
Nov 21, 2015
788
Mar 7, 2018
789
var $ = $B.args("fromkeys", 3, {cls: null, keys: null, value: null},
790
["cls", "keys", "value"], arguments, {value: _b_.None}, null, null),
791
keys = $.keys,
792
value = $.value
Sep 5, 2014
794
// class method
795
var klass = $.cls,
Sep 5, 2014
799
while(1){
800
try{
801
var key = _b_.next(keys_iter)
802
if(klass === dict){dict.$setitem(res, key, value)}
803
else{$B.$getattr(res, "__setitem__")(key, value)}
Sep 5, 2014
804
}catch(err){
805
if($B.is_exc(err, [_b_.StopIteration])){
Sep 5, 2014
806
return res
807
}
808
throw err
809
}
810
}
811
}
812
Feb 11, 2018
813
dict.get = function(){
Mar 7, 2018
814
var $ = $B.args("get", 3, {self: null, key: null, _default: null},
815
["self", "key", "_default"], arguments, {_default: $N}, null, null)
Feb 11, 2018
817
try{return dict.__getitem__($.self, $.key)}
818
catch(err){
819
if(_b_.isinstance(err, _b_.KeyError)){return $._default}
820
else{throw err}
821
}
822
}
823
824
var dict_items = $B.make_view("dict_items", true)
825
dict_items.$iterator = $B.make_iterator_class("dict_itemiterator")
826
Feb 11, 2018
827
dict.items = function(self){
Mar 23, 2018
828
if(arguments.length > 1){
829
var _len = arguments.length - 1,
830
_msg = "items() takes no arguments (" + _len + " given)"
831
throw _b_.TypeError.$factory(_msg)
832
}
833
var it = dict_items.$factory(to_list(self))
834
it.len_func = function(){return dict.__len__(self)}
835
return it
836
}
837
838
var dict_keys = $B.make_view("dict_keys", true)
839
dict_keys.$iterator = $B.make_iterator_class("dict_keyiterator")
Nov 21, 2015
840
Mar 23, 2018
842
if(arguments.length > 1){
843
var _len = arguments.length - 1,
844
_msg = "keys() takes no arguments (" + _len + " given)"
845
throw _b_.TypeError.$factory(_msg)
Nov 21, 2015
846
}
847
var it = dict_keys.$factory(to_list(self, 0))
848
it.len_func = function(){return dict.__len__(self)}
849
return it
Nov 21, 2015
850
}
851
Feb 11, 2018
852
dict.pop = function(){
Nov 21, 2015
853
854
var missing = {},
855
$ = $B.args("pop", 3, {self: null, key: null, _default: null},
856
["self", "key", "_default"], arguments, {_default: missing}, null, null),
857
self = $.self,
858
key = $.key,
859
_default = $._default
Nov 21, 2015
860
Sep 5, 2014
861
try{
862
var res = dict.__getitem__(self, key)
863
dict.__delitem__(self, key)
Sep 5, 2014
864
return res
865
}catch(err){
866
if(err.__class__ === _b_.KeyError){
867
if(_default !== missing){return _default}
Sep 5, 2014
868
throw err
869
}
870
throw err
871
}
872
}
873
Feb 11, 2018
874
dict.popitem = function(self){
876
var itm = _b_.next(_b_.iter(dict.items(self)))
877
dict.__delitem__(self, itm[0])
Feb 11, 2018
878
return _b_.tuple.$factory(itm)
880
if (err.__class__ == _b_.StopIteration) {
881
throw _b_.KeyError.$factory("'popitem(): dictionary is empty'")
Sep 5, 2014
884
}
885
Feb 11, 2018
886
dict.setdefault = function(){
Nov 21, 2015
887
Mar 7, 2018
888
var $ = $B.args("setdefault", 3, {self: null, key: null, _default: null},
889
["self", "key", "_default"], arguments, {_default: $N}, null, null),
890
self = $.self,
891
key = $.key,
892
_default = $._default
Nov 21, 2015
893
894
try{return dict.__getitem__(self, key)}
Sep 5, 2014
895
catch(err){
896
if(err.__class__ !== _b_.KeyError){
897
throw err
898
}
899
if(_default === undefined){_default = $N}
900
var hash = key.$hash
901
key.$hash = undefined
902
dict.$setitem(self, key, _default, hash)
Sep 5, 2014
903
return _default
904
}
905
}
906
Feb 11, 2018
907
dict.update = function(self){
Nov 21, 2015
908
Mar 7, 2018
909
var $ = $B.args("update", 1, {"self": null}, ["self"], arguments,
910
{}, "args", "kw"),
911
self = $.self,
912
args = $.args,
913
kw = $.kw
914
if(args.length > 0){
915
var o = args[0]
917
if(o.$jsobj){
918
o = jsobj2dict(o.$jsobj)
919
}
921
}else if(_b_.hasattr(o, "keys")){
922
var _keys = _b_.list.$factory($B.$call($B.$getattr(o, "keys"))())
923
for(var i = 0, len = _keys.length; i < len; i++){
924
var _value = getattr(o, "__getitem__")(_keys[i])
925
dict.$setitem(self, _keys[i], _value)
926
}
927
}else{
928
var it = _b_.iter(o),
929
i = 0
930
while(true){
931
try{
932
var item = _b_.next(it)
933
}catch(err){
934
if(err.__class__ === _b_.StopIteration){break}
935
throw err
936
}
937
try{
938
key_value = _b_.list.$factory(item)
939
}catch(err){
940
throw _b_.TypeError.$factory("cannot convert dictionary" +
941
" update sequence element #" + i + " to a sequence")
942
}
943
if(key_value.length !== 2){
944
throw _b_.ValueError.$factory("dictionary update " +
945
"sequence element #" + i + " has length " +
946
key_value.length + "; 2 is required")
947
}
948
dict.$setitem(self, key_value[0], key_value[1])
949
i++
Sep 5, 2014
952
}
Sep 5, 2014
956
}
957
958
var dict_values = $B.make_view("dict_values")
959
dict_values.$iterator = $B.make_iterator_class("dict_valueiterator")
Nov 21, 2015
960
Feb 11, 2018
961
dict.values = function(self){
Mar 23, 2018
962
if(arguments.length > 1){
963
var _len = arguments.length - 1,
964
_msg = "values() takes no arguments (" + _len + " given)"
965
throw _b_.TypeError.$factory(_msg)
Nov 21, 2015
966
}
967
var it = dict_values.$factory(to_list(self, 1))
968
it.len_func = function(){return dict.__len__(self)}
969
return it
Nov 21, 2015
970
}
971
972
dict.$factory = function(){
973
var res = dict.__new__(dict)
974
var args = [res]
975
for(var i = 0, len = arguments.length; i < len ; i++){
976
args.push(arguments[i])
977
}
978
dict.__init__.apply(null, args)
Sep 5, 2014
979
return res
980
}
Sep 5, 2014
982
_b_.dict = dict
Feb 11, 2018
984
$B.set_func_names(dict, "builtins")
986
$B.empty_dict = function(){
987
return {
988
__class__: dict,
989
$numeric_dict : {},
990
$object_dict : {},
991
$string_dict : {},
992
$str_hash: {},
993
$version: 0,
994
$order: 0
998
// This must be done after set_func_names, otherwise dict.fromkeys doesn't
999
// have the attribute $infos
1000
dict.fromkeys = _b_.classmethod.$factory(dict.fromkeys)
1001
1002
$B.getset_descriptor = $B.make_class("getset_descriptor",
1003
function(klass, attr){
1004
return {
1005
__class__: $B.getset_descriptor,
1006
__doc__: _b_.None,
1007
cls: klass,
1008
attr: attr
1009
}
1010
}
1011
)
1012
1013
$B.getset_descriptor.__repr__ = $B.getset_descriptor.__str__ = function(self){
1014
return `<attribute '${self.attr}' of '${self.cls.$infos.__name__}' objects>`
1015
}
1016
1017
$B.set_func_names($B.getset_descriptor, "builtins")
1018
1019
// Class for attribute __dict__ of classes
1020
var mappingproxy = $B.mappingproxy = $B.make_class("mappingproxy",
Feb 12, 2018
1021
function(obj){
1022
if(_b_.isinstance(obj, dict)){
1023
// obj is a dictionary, with $string_dict table such that
1024
// obj.$string_dict[key] = [value, rank]
1025
// Transform it into an object with attribute $jsobj such that
1026
// res.$jsobj[key] = value
1027
var res = $B.obj_dict(dict.$to_obj(obj))
1028
}else{
1029
var res = $B.obj_dict(obj)
1030
}
Feb 12, 2018
1031
res.__class__ = mappingproxy
1032
return res
1033
}
1034
)
Feb 12, 2018
1036
mappingproxy.__setitem__ = function(){
Mar 7, 2018
1037
throw _b_.TypeError.$factory("'mappingproxy' object does not support " +
1038
"item assignment")
1041
for(var attr in dict){
1042
if(mappingproxy[attr] !== undefined ||
1043
["__class__", "__mro__", "__new__", "__init__", "__delitem__",
1044
"clear", "fromkeys", "pop", "popitem", "setdefault",
1045
"update"].indexOf(attr) > -1){
1046
continue
1047
}
1048
if(typeof dict[attr] == "function"){
1049
mappingproxy[attr] = (function(key){
1050
return function(){
1051
return dict[key].apply(null, arguments)
1052
}
1053
})(attr)
1054
}else{
1055
mappingproxy[attr] = dict[attr]
1056
}
1057
}
1058
Feb 12, 2018
1059
$B.set_func_names(mappingproxy, "builtins")
Mar 7, 2018
1064
if(attr.charAt(0) != "$" && attr !== "__class__"){
1065
if(x[attr] === null){
1066
d.$string_dict[attr] = [_b_.None, d.$order++]
1067
}else if(x[attr] === undefined){
1068
continue
1069
}else if(x[attr].$jsobj === x){
1070
d.$string_dict[attr] = [d, d.$order++]
1072
d.$string_dict[attr] = [$B.$JS2Py(x[attr]), d.$order++]
1074
}
1075
}
1076
return d
1077
}
1079
$B.obj_dict = function(obj, from_js){
1080
var klass = obj.__class__ || $B.get_class(obj)
1081
if(klass !== undefined && klass.$native){
1082
throw _b_.AttributeError.$factory(klass.__name__ +
1083
" has no attribute '__dict__'")}
1085
res.$jsobj = obj
1086
res.$from_js = from_js // set to true if
1087
return res
1088
}
1089
Sep 5, 2014
1090
})(__BRYTHON__)