Skip to content
Permalink
Newer
Older
100644 1184 lines (1065 sloc) 34.6 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", "le", "lt", "ge", "gt",
35
"sub", "rsub", "and", "or", "xor"]
36
37
// methods to compare non set-like views
38
function is_sublist(t1, t2){
39
// Return true if all elements of t1 are in t2
40
for(var i = 0, ilen = t1.length; i < ilen; i++){
41
var x = t1[i],
42
flag = false
43
for(var j = 0, jlen = t2.length; j < jlen; j++){
44
if($B.rich_comp("__eq__", x, t2[j])){
45
t2.splice(j, 1)
46
flag = true
47
break
48
}
49
}
50
if(! flag){
51
return false
52
}
53
}
54
return true
55
}
56
57
dict_view_op = {
58
__eq__: function(t1, t2){
59
return t1.length == t2.length && is_sublist(t1, t2)
60
},
61
__ne__: function(t1, t2){
62
return ! dict_view_op.__eq__(t1, t2)
63
},
64
__lt__: function(t1, t2){
65
return t1.length < t2.length && is_sublist(t1, t2)
66
},
67
__gt__: function(t1, t2){
68
return dict_view_op.__lt__(t2, t1)
69
},
70
__le__: function(t1, t2){
71
return t1.length <= t2.length && is_sublist(t1, t2)
72
},
73
__ge__: function(t1, t2){
74
return dict_view_op.__le__(t2, t1)
75
},
76
__and__: function(t1, t2){
77
var items = []
78
for(var i = 0, ilen = t1.length; i < ilen; i++){
79
var x = t1[i]
80
flag = false
81
for(var j = 0, jlen = t2.length; j < jlen; j++){
82
if($B.rich_comp("__eq__", x, t2[j])){
83
t2.splice(j, 1)
84
items.push(x)
85
break
86
}
87
}
88
}
89
return items
90
},
91
__or__: function(t1, t2){
92
var items = t1
93
for(var j = 0, jlen = t2.length; j < jlen; j++){
94
var y = t2[j],
95
flag = false
96
for(var i = 0, ilen = t1.length; i < ilen; i++){
97
if($B.rich_comp("__eq__", y, t1[i])){
98
t2.splice(j, 1)
99
flag = true
100
break
101
}
102
}
103
if(! flag){
104
items.push(y)
105
}
106
}
107
return items
108
}
110
}
111
112
$B.make_view = function(name){
113
var klass = $B.make_class(name, function(items, set_like){
114
return {
115
__class__: klass,
117
counter: -1,
118
items: items,
119
len: items.length,
120
set_like: set_like
121
}
122
})
123
124
for(var i = 0, len = set_ops.length; i < len; i++){
125
var op = "__" + set_ops[i] + "__"
126
klass[op] = (function(op){
127
return function(self, other){
128
// compare set of items to other
129
if(self.set_like){
130
return _b_.set[op](_b_.set.$factory(self),
131
_b_.set.$factory(other))
132
}else{
133
// Non-set like views can only be compared to
134
// instances of the same class
135
if(other.__class__ !== klass){
136
return false
137
}
138
var other_items = _b_.list.$factory(other)
139
return dict_view_op[op](self.items, other_items)
140
}
141
}
142
})(op)
143
}
144
klass.__iter__ = function(self){
145
var it = klass.$iterator.$factory(self.items)
146
it.len_func = self.len_func
147
return it
148
}
149
150
klass.__len__ = function(self){
151
return self.len
152
}
154
klass.__repr__ = function(self){
155
return klass.$infos.__name__ + '(' + _b_.repr(self.items) + ')'
156
}
157
158
$B.set_func_names(klass, "builtins")
159
return klass
160
}
161
162
// Special version of __next__ for iterators on dict keys / values / items.
163
// Checks that the dictionary size didn't change during iteration.
164
function dict_iterator_next(self){
165
if(self.len_func() != self.len){
166
throw _b_.RuntimeError.$factory("dictionary changed size during iteration")
167
}
168
self.counter++
169
if(self.counter < self.items.length){
170
return self.items[self.counter]
171
}
172
throw _b_.StopIteration.$factory("StopIteration")
173
}
174
Feb 11, 2018
175
var dict = {
Feb 11, 2018
176
__class__: _b_.type,
178
$infos: {
179
__module__: "builtins",
180
__name__: "dict"
181
},
Feb 11, 2018
182
$is_class: true,
183
$native: true
Sep 5, 2014
184
}
185
186
dict.$to_obj = function(d){
187
// Function applied to dictionary that only have string keys,
188
// return a Javascript objects with the kays mapped to the value,
189
// excluding the insertion rank
190
var res = {}
191
for(var key in d.$string_dict){
192
res[key] = d.$string_dict[key][0]
193
}
194
return res
195
}
196
197
function to_list(d, ix){
198
var items = [],
199
item
201
if(d.$jsobj){
Mar 7, 2018
204
if(attr.charAt(0) != "$"){
205
var val = d.$jsobj[attr]
206
if(val === undefined){val = _b_.NotImplemented}
207
else if(val === null){val = $N}
211
}else{
212
for(var k in d.$numeric_dict){
213
items.push([parseFloat(k), d.$numeric_dict[k]])
214
}
216
for(var k in d.$string_dict){items.push([k, d.$string_dict[k]])}
218
for(var k in d.$object_dict){
219
d.$object_dict[k].forEach(function(item){
220
items.push(item)
221
})
222
}
223
// sort by insertion order
224
items.sort(function(a, b){
225
return a[1][1] - b[1][1]
226
})
227
items = items.map(function(item){return [item[0], item[1][0]]})
230
if(ix !== undefined){
231
return items.map(function(item){return item[ix]})
232
}else{
233
items.__class__ = _b_.tuple
234
return items.map(function(item){
235
item.__class__ = _b_.tuple; return item}
236
)
237
}
Feb 9, 2015
239
240
$B.dict_to_list = to_list // used in py_types.js
241
242
// Special version of __next__ for iterators on dict keys / values / items.
243
// Checks that the dictionary size didn't change during iteration.
244
function dict_iterator_next(self){
245
if(self.len_func() != self.len){
246
throw _b_.RuntimeError.$factory("dictionary changed size during iteration")
247
}
248
self.counter++
249
if(self.counter < self.items.length){
250
return self.items[self.counter]
252
throw _b_.StopIteration.$factory("StopIteration")
256
var $copy_dict = function(left, right){
258
si = dict.$setitem
259
right.$version = right.$version || 0
260
var right_version = right.$version || 0
261
for(var i = 0, len = _l.length; i < len; i++){
262
si(left, _l[i][0], _l[i][1])
263
if(right.$version != right_version){
264
throw _b_.RuntimeError.$factory("dict mutated during update")
265
}
266
}
269
function rank(self, hash, key){
270
// Search if object key, with hash = hash(key), is in
271
// self.$object_dict
272
var pairs = self.$object_dict[hash]
273
if(pairs !== undefined){
274
for(var i = 0, len = pairs.length; i < len; i++){
275
if($B.rich_comp("__eq__", key, pairs[i][0])){
276
return i
277
}
278
}
279
}
280
return -1
281
}
282
Feb 11, 2018
283
dict.__bool__ = function () {
Mar 7, 2018
284
var $ = $B.args("__bool__", 1, {self: null}, ["self"],
285
arguments, {}, null, null)
Feb 11, 2018
286
return dict.__len__($.self) > 0
Feb 11, 2018
289
dict.__contains__ = function(){
Nov 21, 2015
290
291
var $ = $B.args("__contains__", 2, {self: null, key: null},
292
["self", "key"], arguments, {}, null, null),
293
self = $.self,
295
if(self.$is_namespace){key = $B.to_alias(key)} // issue 1244
296
297
if(self.$jsobj){
298
return self.$jsobj[key] !== undefined
299
}
301
switch(typeof key) {
303
return self.$string_dict[key] !== undefined
305
return self.$numeric_dict[key] !== undefined
306
}
307
308
var hash = _b_.hash(key)
309
if(self.$str_hash[hash] !== undefined &&
310
$B.rich_comp("__eq__", key, self.$str_hash[hash])){return true}
311
if(self.$numeric_dict[hash] !== undefined &&
312
$B.rich_comp("__eq__", key, hash)){return true}
313
return rank(self, hash, key) > -1
Sep 5, 2014
314
}
315
Feb 11, 2018
316
dict.__delitem__ = function(){
Nov 21, 2015
317
318
var $ = $B.args("__eq__", 2, {self: null, arg: null},
319
["self", "arg"], arguments, {}, null, null),
320
self = $.self,
Nov 21, 2015
322
323
if(self.$jsobj){
324
if(self.$jsobj[arg] === undefined){throw _b_.KeyError.$factory(arg)}
325
delete self.$jsobj[arg]
328
switch(typeof arg){
329
case "string":
330
if(self.$string_dict[arg] === undefined){
331
throw _b_.KeyError.$factory(_b_.str.$factory(arg))
332
}
333
delete self.$string_dict[arg]
334
delete self.$str_hash[str_hash(arg)]
336
return $N
337
case "number":
338
if(self.$numeric_dict[arg] === undefined){
339
throw _b_.KeyError.$factory(_b_.str.$factory(arg))
341
delete self.$numeric_dict[arg]
345
// go with defaults
346
347
var hash = _b_.hash(arg),
348
ix
350
if((ix = rank(self, hash, arg)) > -1){
351
self.$object_dict[hash].splice(ix, 1)
352
}else{
353
throw _b_.KeyError.$factory(_b_.str.$factory(arg))
Sep 5, 2014
358
}
359
Feb 11, 2018
360
dict.__eq__ = function(){
Mar 7, 2018
361
var $ = $B.args("__eq__", 2, {self: null, other: null},
362
["self", "other"], arguments, {}, null, null),
363
self = $.self,
364
other = $.other
366
if(! _b_.isinstance(other, dict)){return false}
368
if(self.$jsobj){self = jsobj2dict(self.$jsobj)}
369
if(other.$jsobj){other = jsobj2dict(other.$jsobj)}
370
if(dict.__len__(self) != dict.__len__(other)){
371
return false
372
}
374
if(self.$string_dict.length != other.$string_dict.length){
378
for(var k in self.$numeric_dict){
379
if(other.$numeric_dict.hasOwnProperty(k)){
380
if(!$B.rich_comp("__eq__", other.$numeric_dict[k][0],
381
self.$numeric_dict[k][0])){
382
return false
383
}
384
}else if(other.$object_dict.hasOwnProperty(k)){
385
var pairs = other.$object_dict[k],
386
flag = false
387
for(var i = 0, len = pairs.length; i < len; i++){
388
if($B.rich_comp("__eq__", k, pairs[i][0]) &&
389
$B.rich_comp("__eq__", self.$numeric_dict[k],
390
pairs[i][1])){
391
flag = true
392
break
393
}
395
if(! flag){return false}
Nov 21, 2015
398
}
399
}
400
for(var k in self.$string_dict){
401
if(!other.$string_dict.hasOwnProperty(k) ||
402
!$B.rich_comp("__eq__", other.$string_dict[k][0],
403
self.$string_dict[k][0])){
Nov 21, 2015
405
}
406
}
407
for(var hash in self.$object_dict){
408
var pairs = self.$object_dict[hash]
409
// Get all (key, value) pairs in other that have the same hash
410
var other_pairs = []
411
if(other.$numeric_dict[hash] !== undefined){
412
other_pairs.push([hash, other.$numeric_dict[hash]])
413
}
414
if(other.$object_dict[hash] !== undefined){
415
other_pairs = other_pairs.concat(other.$object_dict[hash])
416
}
417
if(other_pairs.length == 0){
418
return false
419
}
420
for(var i = 0, len_i = pairs.length; i < len_i; i++){
421
var flag = false
422
var key = pairs[i][0],
423
value = pairs[i][1][0]
424
for(var j = 0, len_j = other_pairs.length; j < len_j; j++){
425
if($B.rich_comp("__eq__", key, other_pairs[j][0]) &&
426
$B.rich_comp("__eq__", value, other_pairs[j][1][0])){
427
flag = true
428
break
434
}
435
}
436
return true
Sep 5, 2014
437
}
438
Feb 11, 2018
439
dict.__getitem__ = function(){
440
var $ = $B.args("__getitem__", 2, {self: null, arg: null},
441
["self", "arg"], arguments, {}, null, null),
442
self = $.self,
444
return dict.$getitem(self, arg)
445
}
446
447
dict.$getitem = function(self, arg){
448
if(self.$jsobj){
449
if(self.$jsobj[arg] === undefined){
450
if(self.$jsobj.hasOwnProperty(arg)){
452
}
453
throw _b_.KeyError.$factory(arg)
454
}
455
return self.$jsobj[arg]
457
458
switch(typeof arg){
459
case "string":
460
if(self.$string_dict[arg] !== undefined){
461
return self.$string_dict[arg][0]
463
break
464
case "number":
465
if(self.$numeric_dict[arg] !== undefined){
466
return self.$numeric_dict[arg][0]
468
break
469
}
470
471
// since the key is more complex use 'default' method of getting item
472
473
var hash = _b_.hash(arg),
474
_eq = function(other){return $B.rich_comp("__eq__", arg, other)}
475
476
if(typeof arg == "object"){
477
arg.$hash = hash // cache for setdefault
478
}
479
var sk = self.$str_hash[hash]
480
if(sk !== undefined && _eq(sk)){
481
return self.$string_dict[sk][0]
483
if(self.$numeric_dict[hash] !== undefined && _eq(hash)){
484
return self.$numeric_dict[hash][0]
486
if(_b_.isinstance(arg, _b_.str)){
487
// string subclass
488
var res = self.$string_dict[arg.valueOf()]
489
if(res !== undefined){return res[0]}
492
var ix = rank(self, hash, arg)
493
if(ix > -1){
494
return self.$object_dict[hash][ix][1][0]
497
if(self.__class__ !== dict){
499
var missing_method = getattr(self.__class__, "__missing__",
500
_b_.None)
501
}catch(err){
502
console.log(err)
503
504
}
505
if(missing_method !== _b_.None){
506
return missing_method(self, arg)
509
throw _b_.KeyError.$factory(arg)
Sep 5, 2014
510
}
511
512
dict.__hash__ = _b_.None
Sep 5, 2014
513
514
function init_from_list(self, args){
515
var i = -1,
516
stop = args.length - 1,
517
si = dict.__setitem__
518
while(i++ < stop){
519
var item = args[i]
520
switch(typeof item[0]) {
521
case 'string':
522
self.$string_dict[item[0]] = [item[1], self.$order++]
523
self.$str_hash[str_hash(item[0])] = item[0]
524
self.$version++
525
break
526
case 'number':
527
self.$numeric_dict[item[0]] = [item[1], self.$order++]
528
self.$version++
529
break
530
default:
531
si(self, item[0], item[1])
532
break
533
}
534
}
535
}
536
537
dict.__init__ = function(self, first, second){
539
if(first === undefined){return $N}
540
if(second === undefined){
541
if(first.$nat != 'kw' && $B.get_class(first) === $B.JSObj){
542
for(var key in first){
543
self.$string_dict[key] = [first[key], self.$order++]
544
}
545
return _b_.None
546
}else if(first.$jsobj){
547
self.$jsobj = {}
548
for(var attr in first.$jsobj){
549
self.$jsobj[attr] = first.$jsobj[attr]
552
}else if(Array.isArray(first)){
553
init_from_list(self, first)
554
return $N
Sep 5, 2014
555
}
558
$ = $ || $B.args("dict", 1, {self:null}, ["self"],
559
arguments, {}, "first", "second")
560
var args = $.first
561
if(args.length > 1){
562
throw _b_.TypeError.$factory("dict expected at most 1 argument" +
563
", got 2")
564
}else if(args.length == 1){
565
args = args[0]
566
if(args.__class__ === dict){
567
['$string_dict', '$str_hash', '$numeric_dict', '$object_dict'].
568
forEach(function(d){
569
for(key in args[d]){self[d][key] = args[d][key]}
570
})
571
}else if(_b_.isinstance(args, dict)){
574
var keys = $B.$getattr(args, "keys", null)
575
if(keys !== null){
576
var gi = $B.$getattr(args, "__getitem__", null)
577
if(gi !== null){
578
// has keys and __getitem__ : it's a mapping, iterate on
579
// keys and values
580
gi = $B.$call(gi)
581
var kiter = _b_.iter($B.$call(keys)())
582
while(true){
583
try{
584
var key = _b_.next(kiter),
585
value = gi(key)
586
dict.__setitem__(self, key, value)
587
}catch(err){
588
if(err.__class__ === _b_.StopIteration){
589
break
590
}
591
throw err
592
}
593
}
594
return $N
595
}
596
}
597
if(! Array.isArray(args)){
598
args = _b_.list.$factory(args)
599
}
600
// Form "dict([[key1, value1], [key2,value2], ...])"
601
init_from_list(self, args)
Sep 5, 2014
602
}
604
var kw = $.second.$string_dict
605
for(var attr in kw){
606
switch(typeof attr){
607
case "string":
608
self.$string_dict[attr] = [kw[attr][0], self.$order++]
609
self.$str_hash[str_hash(attr)] = attr
610
break
611
case "number":
612
self.$numeric_dict[attr] = [kw[attr][0], self.$order++]
615
si(self, attr, kw[attr][0])
Sep 5, 2014
620
}
621
Feb 11, 2018
622
dict.__iter__ = function(self) {
623
return _b_.iter(dict.$$keys(self))
Sep 5, 2014
624
}
625
626
dict.__ior__ = function(self, other){
627
// PEP 584
628
dict.update(self, other)
629
return self
630
}
631
Feb 11, 2018
632
dict.__len__ = function(self) {
635
if(self.$jsobj){
Mar 7, 2018
636
for(var attr in self.$jsobj){if(attr.charAt(0) != "$"){_count++}}
637
return _count
638
}
640
for(var k in self.$numeric_dict){_count++}
641
for(var k in self.$string_dict){_count++}
642
for(var hash in self.$object_dict){
643
_count += self.$object_dict[hash].length
644
}
Sep 5, 2014
648
Mar 7, 2018
649
dict.__ne__ = function(self, other){return ! dict.__eq__(self, other)}
Sep 5, 2014
650
Feb 11, 2018
651
dict.__new__ = function(cls){
652
if(cls === undefined){
Mar 7, 2018
653
throw _b_.TypeError.$factory("int.__new__(): not enough arguments")
655
var instance = {
657
$numeric_dict : {},
658
$object_dict : {},
661
$version: 0,
662
$order: 0
664
if(cls !== dict){
665
instance.__dict__ = $B.empty_dict()
666
}
667
return instance
670
dict.__or__ = function(self, other){
671
// PEP 584
672
if(! _b_.isinstance(other, dict)){
673
return _b_.NotImplemented
674
}
675
var res = dict.copy(self)
676
dict.update(res, other)
677
return res
678
}
679
Feb 11, 2018
680
dict.__repr__ = function(self){
681
if(self.$jsobj){ // wrapper around Javascript object
Feb 11, 2018
682
return dict.__repr__(jsobj2dict(self.$jsobj))
684
if($B.repr.enter(self)){
685
return "{...}"
686
}
687
var res = [],
689
items.forEach(function(item){
690
try{
691
res.push(repr(item[0]) + ": " + repr(item[1]))
692
}catch(err){
693
throw err
694
}
696
$B.repr.leave(self)
Mar 7, 2018
697
return "{" + res.join(", ") + "}"
Sep 5, 2014
698
}
699
700
dict.__ror__ = function(self, other){
701
// PEP 584
702
if(! _b_.isinstance(other, dict)){
703
return _b_.NotImplemented
704
}
705
var res = dict.copy(other)
706
dict.update(res, self)
707
return res
708
}
709
710
dict.__setitem__ = function(self, key, value){
Mar 7, 2018
711
var $ = $B.args("__setitem__", 3, {self: null, key: null, value: null},
712
["self", "key", "value"], arguments, {}, null, null)
713
return dict.$setitem($.self, $.key, $.value)
714
}
Nov 21, 2015
715
716
dict.$setitem = function(self, key, value, $hash){
717
// Set a dictionary item mapping key and value.
718
//
719
// If key is a string, set:
720
// - $string_dict[key] = [value, order] where "order" is an auto-increment
721
// unique id to keep track of insertion order
722
// - $str_hash[hash(key)] to key
723
//
724
// If key is a number, set $numeric_dict[key] = value
725
//
726
// If key is another object, compute its hash value:
727
// - if the hash is a key of $str_hash, and key == $str_hash[hash],
728
// replace $string_dict[$str_hash[hash]] by value
729
// - if the hash is a key of $numeric_dict, and hash == key, replace
730
// $numeric_dict[hash] by value
731
// - if the hash is a key of $object_dict: $object_dict[hash] is a list
732
// of [k, v] pairs. If key is equal to one of the "k", replace the
733
// matching v by value. Otherwise, add [key, value] to the list
734
// - else set $object_dict[hash] = [[key, value]]
735
//
736
// In all cases, increment attribute $version, used to detect dictionary
737
// changes during an iteration.
739
// Parameter $hash is only set if this method is called by setdefault.
740
// In this case the hash of key has already been computed and we
741
// know that the key is not present in the dictionary, so it's no
742
// use computing hash(key) again, nor testing equality of keys
744
if(self.$from_js){
745
// dictionary created by method to_dict of JSObj instances
746
value = $B.pyobj2jsobj(value)
747
}
748
if(self.$jsobj.__class__ === _b_.type){
749
self.$jsobj[key] = value
750
if(key == "__init__" || key == "__new__"){
751
// If class attribute __init__ or __new__ are reset,
752
// the factory function has to change
753
self.$jsobj.$factory = $B.$instance_creator(self.$jsobj)
754
}
755
}else{
756
self.$jsobj[key] = value
761
switch(typeof key){
762
case "string":
763
if(self.$string_dict === undefined){
764
console.log("pas de string dict", self, key, value)
765
}
766
if(self.$string_dict[key] !== undefined){
767
self.$string_dict[key][0] = value
768
}else{
769
self.$string_dict[key] = [value, self.$order++]
770
self.$str_hash[str_hash(key)] = key
771
self.$version++
772
}
773
return $N
774
case "number":
775
if(self.$numeric_dict[key] !== undefined){
776
// existing key: preserve order
777
self.$numeric_dict[key][0] = value
778
}else{
779
// new key
780
self.$numeric_dict[key] = [value, self.$order++]
781
self.$version++
782
}
783
return $N
786
// if we got here the key is more complex, use default method
787
788
var hash = $hash === undefined ? _b_.hash(key) : $hash,
789
_eq = function(other){return $B.rich_comp("__eq__", key, other)}
790
791
if(self.$numeric_dict[hash] !== undefined && _eq(hash)){
792
self.$numeric_dict[hash] = [value, self.$numeric_dict[hash][1]]
796
var sk = self.$str_hash[hash]
797
if(sk !== undefined && _eq(sk)){
798
self.$string_dict[sk] = [value, self.$string_dict[sk][1]]
803
// If $setitem is called from setdefault, don't test equality of key
804
// with any object
805
if($hash){
806
if(self.$object_dict[$hash] !== undefined){
807
self.$object_dict[$hash].push([key, [value, self.$order++]])
809
self.$object_dict[$hash] = [[key, [value, self.$order++]]]
810
}
811
self.$version++
812
return $N
813
}
814
var ix = rank(self, hash, key)
815
if(ix > -1){
816
// reset value
817
self.$object_dict[hash][ix][1] = [value,
818
self.$object_dict[hash][ix][1][1]]
819
return $N
820
}else if(self.$object_dict.hasOwnProperty(hash)){
821
self.$object_dict[hash].push([key, [value, self.$order++]])
823
self.$object_dict[hash] = [[key, [value, self.$order++]]]
Sep 5, 2014
827
}
828
829
dict.__str__ = function(){
830
return dict.__repr__.apply(null, arguments)
831
}
Sep 5, 2014
832
833
// add "reflected" methods
Feb 11, 2018
834
$B.make_rmethods(dict)
Sep 5, 2014
835
Feb 11, 2018
836
dict.clear = function(){
Sep 5, 2014
837
// Remove all items from the dictionary.
Mar 7, 2018
838
var $ = $B.args("clear", 1, {self: null}, ["self"], arguments, {},
839
null, null),
840
self = $.self
842
self.$numeric_dict = {}
843
self.$string_dict = {}
844
self.$str_hash = {}
845
self.$object_dict = {}
847
if(self.$jsobj){
848
for(var attr in self.$jsobj){
Mar 7, 2018
849
if(attr.charAt(0) !== "$" && attr !== "__class__"){
850
delete self.$jsobj[attr]
851
}
852
}
853
}
Sep 5, 2014
857
}
858
Feb 11, 2018
859
dict.copy = function(self){
Sep 5, 2014
860
// Return a shallow copy of the dictionary
Mar 7, 2018
861
var $ = $B.args("copy", 1, {self: null},["self"], arguments,{},
862
null, null),
863
self = $.self,
Sep 5, 2014
866
return res
867
}
868
Feb 11, 2018
869
dict.fromkeys = function(){
Nov 21, 2015
870
Mar 7, 2018
871
var $ = $B.args("fromkeys", 3, {cls: null, keys: null, value: null},
872
["cls", "keys", "value"], arguments, {value: _b_.None}, null, null),
873
keys = $.keys,
874
value = $.value
Sep 5, 2014
876
// class method
877
var klass = $.cls,
Sep 5, 2014
881
while(1){
882
try{
883
var key = _b_.next(keys_iter)
884
if(klass === dict){dict.$setitem(res, key, value)}
885
else{$B.$getattr(res, "__setitem__")(key, value)}
Sep 5, 2014
886
}catch(err){
887
if($B.is_exc(err, [_b_.StopIteration])){
Sep 5, 2014
888
return res
889
}
890
throw err
891
}
892
}
893
}
894
Feb 11, 2018
895
dict.get = function(){
Mar 7, 2018
896
var $ = $B.args("get", 3, {self: null, key: null, _default: null},
897
["self", "key", "_default"], arguments, {_default: $N}, null, null)
Feb 11, 2018
899
try{return dict.__getitem__($.self, $.key)}
900
catch(err){
901
if(_b_.isinstance(err, _b_.KeyError)){return $._default}
902
else{throw err}
903
}
904
}
905
906
var dict_items = $B.make_view("dict_items", true)
907
dict_items.$iterator = $B.make_iterator_class("dict_itemiterator")
908
Feb 11, 2018
909
dict.items = function(self){
Mar 23, 2018
910
if(arguments.length > 1){
911
var _len = arguments.length - 1,
912
_msg = "items() takes no arguments (" + _len + " given)"
913
throw _b_.TypeError.$factory(_msg)
914
}
915
var items = to_list(self),
916
set_like = true
917
// Check if all values are hashable
918
for(var i = 0, len = items.length; i < len; i++){
919
try{
920
_b_.hash(items[i][1])
921
}catch(err){
922
set_like = false
923
break
924
}
925
}
926
var it = dict_items.$factory(to_list(self), set_like)
927
it.len_func = function(){return dict.__len__(self)}
928
return it
929
}
930
931
var dict_keys = $B.make_view("dict_keys")
932
dict_keys.$iterator = $B.make_iterator_class("dict_keyiterator")
Nov 21, 2015
933
Mar 23, 2018
935
if(arguments.length > 1){
936
var _len = arguments.length - 1,
937
_msg = "keys() takes no arguments (" + _len + " given)"
938
throw _b_.TypeError.$factory(_msg)
Nov 21, 2015
939
}
940
var it = dict_keys.$factory(to_list(self, 0), true)
941
it.len_func = function(){return dict.__len__(self)}
942
return it
Nov 21, 2015
943
}
944
Feb 11, 2018
945
dict.pop = function(){
Nov 21, 2015
946
947
var missing = {},
948
$ = $B.args("pop", 3, {self: null, key: null, _default: null},
949
["self", "key", "_default"], arguments, {_default: missing}, null, null),
950
self = $.self,
951
key = $.key,
952
_default = $._default
Nov 21, 2015
953
Sep 5, 2014
954
try{
955
var res = dict.__getitem__(self, key)
956
dict.__delitem__(self, key)
Sep 5, 2014
957
return res
958
}catch(err){
959
if(err.__class__ === _b_.KeyError){
960
if(_default !== missing){return _default}
Sep 5, 2014
961
throw err
962
}
963
throw err
964
}
965
}
966
Feb 11, 2018
967
dict.popitem = function(self){
969
var itm = _b_.next(_b_.iter(dict.items(self)))
970
dict.__delitem__(self, itm[0])
Feb 11, 2018
971
return _b_.tuple.$factory(itm)
973
if (err.__class__ == _b_.StopIteration) {
974
throw _b_.KeyError.$factory("'popitem(): dictionary is empty'")
Sep 5, 2014
977
}
978
Feb 11, 2018
979
dict.setdefault = function(){
Nov 21, 2015
980
Mar 7, 2018
981
var $ = $B.args("setdefault", 3, {self: null, key: null, _default: null},
982
["self", "key", "_default"], arguments, {_default: $N}, null, null),
983
self = $.self,
984
key = $.key,
985
_default = $._default
Nov 21, 2015
986
987
try{return dict.__getitem__(self, key)}
Sep 5, 2014
988
catch(err){
989
if(err.__class__ !== _b_.KeyError){
990
throw err
991
}
992
if(_default === undefined){_default = $N}
993
var hash = key.$hash
994
key.$hash = undefined
995
dict.$setitem(self, key, _default, hash)
Sep 5, 2014
996
return _default
997
}
998
}
999
Feb 11, 2018
1000
dict.update = function(self){
Nov 21, 2015
1001
Mar 7, 2018
1002
var $ = $B.args("update", 1, {"self": null}, ["self"], arguments,
1003
{}, "args", "kw"),
1004
self = $.self,
1005
args = $.args,
1006
kw = $.kw
1007
if(args.length > 0){
1008
var o = args[0]
1010
if(o.$jsobj){
1011
o = jsobj2dict(o.$jsobj)
1012
}
1014
}else if(_b_.hasattr(o, "keys")){
1015
var _keys = _b_.list.$factory($B.$call($B.$getattr(o, "keys"))())
1016
for(var i = 0, len = _keys.length; i < len; i++){
1017
var _value = getattr(o, "__getitem__")(_keys[i])
1018
dict.$setitem(self, _keys[i], _value)
1019
}
1020
}else{
1021
var it = _b_.iter(o),
1022
i = 0
1023
while(true){
1024
try{
1025
var item = _b_.next(it)
1026
}catch(err){
1027
if(err.__class__ === _b_.StopIteration){break}
1028
throw err
1029
}
1030
try{
1031
key_value = _b_.list.$factory(item)
1032
}catch(err){
1033
throw _b_.TypeError.$factory("cannot convert dictionary" +
1034
" update sequence element #" + i + " to a sequence")
1035
}
1036
if(key_value.length !== 2){
1037
throw _b_.ValueError.$factory("dictionary update " +
1038
"sequence element #" + i + " has length " +
1039
key_value.length + "; 2 is required")
1040
}
1041
dict.$setitem(self, key_value[0], key_value[1])
1042
i++
Sep 5, 2014
1045
}
Sep 5, 2014
1049
}
1050
1051
var dict_values = $B.make_view("dict_values")
1052
dict_values.$iterator = $B.make_iterator_class("dict_valueiterator")
Nov 21, 2015
1053
Feb 11, 2018
1054
dict.values = function(self){
Mar 23, 2018
1055
if(arguments.length > 1){
1056
var _len = arguments.length - 1,
1057
_msg = "values() takes no arguments (" + _len + " given)"
1058
throw _b_.TypeError.$factory(_msg)
Nov 21, 2015
1059
}
1060
var values = to_list(self, 1)
1061
var it = dict_values.$factory(to_list(self, 1), false)
1062
it.len_func = function(){return dict.__len__(self)}
1063
return it
Nov 21, 2015
1064
}
1065
1066
dict.$factory = function(){
1067
var res = dict.__new__(dict)
1068
var args = [res]
1069
for(var i = 0, len = arguments.length; i < len ; i++){
1070
args.push(arguments[i])
1071
}
1072
dict.__init__.apply(null, args)
Sep 5, 2014
1073
return res
1074
}
Sep 5, 2014
1076
_b_.dict = dict
Feb 11, 2018
1078
$B.set_func_names(dict, "builtins")
1079
1080
$B.empty_dict = function(){
1081
return {
1082
__class__: dict,
1083
$numeric_dict : {},
1084
$object_dict : {},
1085
$string_dict : {},
1086
$str_hash: {},
1087
$version: 0,
1088
$order: 0
1092
// This must be done after set_func_names, otherwise dict.fromkeys doesn't
1093
// have the attribute $infos
1094
dict.fromkeys = _b_.classmethod.$factory(dict.fromkeys)
1095
1096
$B.getset_descriptor = $B.make_class("getset_descriptor",
1097
function(klass, attr){
1098
return {
1099
__class__: $B.getset_descriptor,
1100
__doc__: _b_.None,
1101
cls: klass,
1102
attr: attr
1103
}
1104
}
1105
)
1106
1107
$B.getset_descriptor.__repr__ = $B.getset_descriptor.__str__ = function(self){
1108
return `<attribute '${self.attr}' of '${self.cls.$infos.__name__}' objects>`
1109
}
1110
1111
$B.set_func_names($B.getset_descriptor, "builtins")
1112
1113
// Class for attribute __dict__ of classes
1114
var mappingproxy = $B.mappingproxy = $B.make_class("mappingproxy",
Feb 12, 2018
1115
function(obj){
1116
if(_b_.isinstance(obj, dict)){
1117
// obj is a dictionary, with $string_dict table such that
1118
// obj.$string_dict[key] = [value, rank]
1119
// Transform it into an object with attribute $jsobj such that
1120
// res.$jsobj[key] = value
1121
var res = $B.obj_dict(dict.$to_obj(obj))
1122
}else{
1123
var res = $B.obj_dict(obj)
1124
}
Feb 12, 2018
1125
res.__class__ = mappingproxy
1126
return res
1127
}
1128
)
Feb 12, 2018
1130
mappingproxy.__setitem__ = function(){
Mar 7, 2018
1131
throw _b_.TypeError.$factory("'mappingproxy' object does not support " +
1132
"item assignment")
1135
for(var attr in dict){
1136
if(mappingproxy[attr] !== undefined ||
1137
["__class__", "__mro__", "__new__", "__init__", "__delitem__",
1138
"clear", "fromkeys", "pop", "popitem", "setdefault",
1139
"update"].indexOf(attr) > -1){
1140
continue
1141
}
1142
if(typeof dict[attr] == "function"){
1143
mappingproxy[attr] = (function(key){
1144
return function(){
1145
return dict[key].apply(null, arguments)
1146
}
1147
})(attr)
1148
}else{
1149
mappingproxy[attr] = dict[attr]
1150
}
1151
}
1152
Feb 12, 2018
1153
$B.set_func_names(mappingproxy, "builtins")
Mar 7, 2018
1158
if(attr.charAt(0) != "$" && attr !== "__class__"){
1159
if(x[attr] === null){
1160
d.$string_dict[attr] = [_b_.None, d.$order++]
1161
}else if(x[attr] === undefined){
1162
continue
1163
}else if(x[attr].$jsobj === x){
1164
d.$string_dict[attr] = [d, d.$order++]
1166
d.$string_dict[attr] = [$B.$JS2Py(x[attr]), d.$order++]
1168
}
1169
}
1170
return d
1171
}
1173
$B.obj_dict = function(obj, from_js){
1174
var klass = obj.__class__ || $B.get_class(obj)
1175
if(klass !== undefined && klass.$native){
1176
throw _b_.AttributeError.$factory(klass.__name__ +
1177
" has no attribute '__dict__'")}
1179
res.$jsobj = obj
1180
res.$from_js = from_js // set to true if
1181
return res
1182
}
1183
Sep 5, 2014
1184
})(__BRYTHON__)