Skip to content
Permalink
Newer
Older
100644 1061 lines (946 sloc) 31 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
539
dict.__ior__ = function(self, other){
540
// PEP 584
541
dict.update(self, other)
542
return self
543
}
544
Feb 11, 2018
545
dict.__len__ = function(self) {
548
if(self.$jsobj){
Mar 7, 2018
549
for(var attr in self.$jsobj){if(attr.charAt(0) != "$"){_count++}}
550
return _count
551
}
553
for(var k in self.$numeric_dict){_count++}
554
for(var k in self.$string_dict){_count++}
555
for(var hash in self.$object_dict){
556
_count += self.$object_dict[hash].length
557
}
Sep 5, 2014
561
Mar 7, 2018
562
dict.__ne__ = function(self, other){return ! dict.__eq__(self, other)}
Sep 5, 2014
563
Feb 11, 2018
564
dict.__new__ = function(cls){
565
if(cls === undefined){
Mar 7, 2018
566
throw _b_.TypeError.$factory("int.__new__(): not enough arguments")
568
var instance = {
570
$numeric_dict : {},
571
$object_dict : {},
573
$str_hash: {},
574
$version: 0
576
if(cls !== dict){
577
instance.__dict__ = _b_.dict.$factory()
578
}
579
return instance
582
dict.__or__ = function(self, other){
583
// PEP 584
584
if(! _b_.isinstance(other, dict)){
585
return _b_.NotImplemented
586
}
587
var res = dict.copy(self)
588
dict.update(res, other)
589
return res
590
}
591
Feb 11, 2018
592
dict.__repr__ = function(self){
593
if(self.$jsobj){ // wrapper around Javascript object
Feb 11, 2018
594
return dict.__repr__(jsobj2dict(self.$jsobj))
596
if($B.repr.enter(self)){
597
return "{...}"
598
}
599
var res = [],
601
items.forEach(function(item){
602
try{
603
res.push(repr(item[0]) + ": " + repr(item[1]))
604
}catch(err){
605
throw err
606
}
608
$B.repr.leave(self)
Mar 7, 2018
609
return "{" + res.join(", ") + "}"
Sep 5, 2014
610
}
611
612
dict.__ror__ = function(self, other){
613
// PEP 584
614
if(! _b_.isinstance(other, dict)){
615
return _b_.NotImplemented
616
}
617
var res = dict.copy(other)
618
dict.update(res, self)
619
return res
620
}
621
622
dict.__setitem__ = function(self, key, value){
Mar 7, 2018
623
var $ = $B.args("__setitem__", 3, {self: null, key: null, value: null},
624
["self", "key", "value"], arguments, {}, null, null)
625
return dict.$setitem($.self, $.key, $.value)
626
}
Nov 21, 2015
627
628
dict.$setitem = function(self, key, value, $hash){
629
// Set a dictionary item mapping key and value.
630
//
631
// If key is a string, set:
632
// - $string_dict[key] = [value, order] where "order" is an auto-increment
633
// unique id to keep track of insertion order
634
// - $str_hash[hash(key)] to key
635
//
636
// If key is a number, set $numeric_dict[key] = value
637
//
638
// If key is another object, compute its hash value:
639
// - if the hash is a key of $str_hash, and key == $str_hash[hash],
640
// replace $string_dict[$str_hash[hash]] by value
641
// - if the hash is a key of $numeric_dict, and hash == key, replace
642
// $numeric_dict[hash] by value
643
// - if the hash is a key of $object_dict: $object_dict[hash] is a list
644
// of [k, v] pairs. If key is equal to one of the "k", replace the
645
// matching v by value. Otherwise, add [key, value] to the list
646
// - else set $object_dict[hash] = [[key, value]]
647
//
648
// In all cases, increment attribute $version, used to detect dictionary
649
// changes during an iteration.
651
// Parameter $hash is only set if this method is called by setdefault.
652
// In this case the hash of key has already been computed and we
653
// know that the key is not present in the dictionary, so it's no
654
// use computing hash(key) again, nor testing equality of keys
656
if(self.$from_js){
657
// dictionary created by method to_dict of JSObject instances
658
value = $B.pyobj2jsobj(value)
659
}
660
if(self.$jsobj.__class__ === _b_.type){
661
self.$jsobj[key] = value
662
if(key == "__init__" || key == "__new__"){
663
// If class attribute __init__ or __new__ are reset,
664
// the factory function has to change
665
self.$jsobj.$factory = $B.$instance_creator(self.$jsobj)
666
}
667
}else{
668
self.$jsobj[key] = value
673
switch(typeof key){
674
case "string":
675
if(self.$string_dict === undefined){
676
console.log("pas de string dict", self, key, value)
677
}
678
self.$string_dict[key] = [value, self.$version]
679
self.$str_hash[str_hash(key)] = key
681
return $N
682
case "number":
683
self.$numeric_dict[key] = [value, self.$version]
685
return $N
688
// if we got here the key is more complex, use default method
689
690
var hash = $hash === undefined ? _b_.hash(key) : $hash,
691
_eq = function(other){return $B.rich_comp("__eq__", key, other)}
692
693
if(self.$numeric_dict[hash] !== undefined && _eq(hash)){
694
self.$numeric_dict[hash] = [value, self.$numeric_dict[hash][1]]
698
var sk = self.$str_hash[hash]
699
if(sk !== undefined && _eq(sk)){
700
self.$string_dict[sk] = [value, self.$string_dict[sk][1]]
705
// If $setitem is called from setdefault, don't test equality of key
706
// with any object
707
if($hash){
708
if(self.$object_dict[$hash] !== undefined){
709
self.$object_dict[$hash].push([key, [value, self.$version]])
711
self.$object_dict[$hash] = [[key, [value, self.$version]]]
712
}
713
self.$version++
714
return $N
715
}
716
var ix = rank(self, hash, key)
717
if(ix > -1){
718
// reset value
719
self.$object_dict[hash][ix][1] = [value,
720
self.$object_dict[hash][ix][1][1]]
721
return $N
722
}else if(self.$object_dict.hasOwnProperty(hash)){
723
self.$object_dict[hash].push([key, [value, self.$version]])
725
self.$object_dict[hash] = [[key, [value, self.$version]]]
Sep 5, 2014
729
}
730
731
dict.__str__ = function(){
732
return dict.__repr__.apply(null, arguments)
733
}
Sep 5, 2014
734
735
// add "reflected" methods
Feb 11, 2018
736
$B.make_rmethods(dict)
Sep 5, 2014
737
Feb 11, 2018
738
dict.clear = function(){
Sep 5, 2014
739
// Remove all items from the dictionary.
Mar 7, 2018
740
var $ = $B.args("clear", 1, {self: null}, ["self"], arguments, {},
741
null, null),
742
self = $.self
744
self.$numeric_dict = {}
745
self.$string_dict = {}
746
self.$str_hash = {}
747
self.$object_dict = {}
749
if(self.$jsobj){
750
for(var attr in self.$jsobj){
Mar 7, 2018
751
if(attr.charAt(0) !== "$" && attr !== "__class__"){
752
delete self.$jsobj[attr]
753
}
754
}
755
}
Sep 5, 2014
758
}
759
Feb 11, 2018
760
dict.copy = function(self){
Sep 5, 2014
761
// Return a shallow copy of the dictionary
Mar 7, 2018
762
var $ = $B.args("copy", 1, {self: null},["self"], arguments,{},
763
null, null),
764
self = $.self,
Feb 11, 2018
765
res = _b_.dict.$factory()
Sep 5, 2014
767
return res
768
}
769
Feb 11, 2018
770
dict.fromkeys = function(){
Nov 21, 2015
771
Mar 7, 2018
772
var $ = $B.args("fromkeys", 3, {cls: null, keys: null, value: null},
773
["cls", "keys", "value"], arguments, {value: _b_.None}, null, null),
774
keys = $.keys,
775
value = $.value
Sep 5, 2014
777
// class method
778
var klass = $.cls,
Sep 5, 2014
782
while(1){
783
try{
784
var key = _b_.next(keys_iter)
785
if(klass === dict){dict.$setitem(res, key, value)}
786
else{$B.$getattr(res, "__setitem__")(key, value)}
Sep 5, 2014
787
}catch(err){
788
if($B.is_exc(err, [_b_.StopIteration])){
Sep 5, 2014
789
return res
790
}
791
throw err
792
}
793
}
794
}
795
Feb 11, 2018
796
dict.get = function(){
Mar 7, 2018
797
var $ = $B.args("get", 3, {self: null, key: null, _default: null},
798
["self", "key", "_default"], arguments, {_default: $N}, null, null)
Feb 11, 2018
800
try{return dict.__getitem__($.self, $.key)}
801
catch(err){
802
if(_b_.isinstance(err, _b_.KeyError)){return $._default}
803
else{throw err}
804
}
805
}
806
807
var dict_items = $B.make_view("dict_items", true)
808
dict_items.$iterator = $B.make_iterator_class("dict_itemiterator")
809
Feb 11, 2018
810
dict.items = function(self){
Mar 23, 2018
811
if(arguments.length > 1){
812
var _len = arguments.length - 1,
813
_msg = "items() takes no arguments (" + _len + " given)"
814
throw _b_.TypeError.$factory(_msg)
815
}
816
var it = dict_items.$factory(to_list(self))
817
it.len_func = function(){return dict.__len__(self)}
818
return it
819
}
820
821
var dict_keys = $B.make_view("dict_keys", true)
822
dict_keys.$iterator = $B.make_iterator_class("dict_keyiterator")
Nov 21, 2015
823
Mar 23, 2018
825
if(arguments.length > 1){
826
var _len = arguments.length - 1,
827
_msg = "keys() takes no arguments (" + _len + " given)"
828
throw _b_.TypeError.$factory(_msg)
Nov 21, 2015
829
}
830
var it = dict_keys.$factory(to_list(self, 0))
831
it.len_func = function(){return dict.__len__(self)}
832
return it
Nov 21, 2015
833
}
834
Feb 11, 2018
835
dict.pop = function(){
Nov 21, 2015
836
837
var missing = {},
838
$ = $B.args("pop", 3, {self: null, key: null, _default: null},
839
["self", "key", "_default"], arguments, {_default: missing}, null, null),
840
self = $.self,
841
key = $.key,
842
_default = $._default
Nov 21, 2015
843
Sep 5, 2014
844
try{
845
var res = dict.__getitem__(self, key)
846
dict.__delitem__(self, key)
Sep 5, 2014
847
return res
848
}catch(err){
849
if(err.__class__ === _b_.KeyError){
850
if(_default !== missing){return _default}
Sep 5, 2014
851
throw err
852
}
853
throw err
854
}
855
}
856
Feb 11, 2018
857
dict.popitem = function(self){
859
var itm = _b_.next(_b_.iter(dict.items(self)))
860
dict.__delitem__(self, itm[0])
Feb 11, 2018
861
return _b_.tuple.$factory(itm)
863
if (err.__class__ == _b_.StopIteration) {
864
throw _b_.KeyError.$factory("'popitem(): dictionary is empty'")
Sep 5, 2014
867
}
868
Feb 11, 2018
869
dict.setdefault = function(){
Nov 21, 2015
870
Mar 7, 2018
871
var $ = $B.args("setdefault", 3, {self: null, key: null, _default: null},
872
["self", "key", "_default"], arguments, {_default: $N}, null, null),
873
self = $.self,
874
key = $.key,
875
_default = $._default
Nov 21, 2015
876
877
try{return dict.__getitem__(self, key)}
Sep 5, 2014
878
catch(err){
879
if(err.__class__ !== _b_.KeyError){
880
throw err
881
}
882
if(_default === undefined){_default = $N}
883
var hash = key.$hash
884
key.$hash = undefined
885
dict.$setitem(self, key, _default, hash)
Sep 5, 2014
886
return _default
887
}
888
}
889
Feb 11, 2018
890
dict.update = function(self){
Nov 21, 2015
891
Mar 7, 2018
892
var $ = $B.args("update", 1, {"self": null}, ["self"], arguments,
893
{}, "args", "kw"),
894
self = $.self,
895
args = $.args,
896
kw = $.kw
897
if(args.length > 0){
898
var o = args[0]
900
if(o.$jsobj){
901
o = jsobj2dict(o.$jsobj)
902
}
904
}else if(_b_.hasattr(o, "keys")){
905
var _keys = _b_.list.$factory($B.$call($B.$getattr(o, "keys"))())
906
for(var i = 0, len = _keys.length; i < len; i++){
907
var _value = getattr(o, "__getitem__")(_keys[i])
908
dict.$setitem(self, _keys[i], _value)
909
}
910
}else{
911
var it = _b_.iter(o),
912
i = 0
913
while(true){
914
try{
915
var item = _b_.next(it)
916
}catch(err){
917
if(err.__class__ === _b_.StopIteration){break}
918
throw err
919
}
920
try{
921
key_value = _b_.list.$factory(item)
922
}catch(err){
923
throw _b_.TypeError.$factory("cannot convert dictionary" +
924
" update sequence element #" + i + " to a sequence")
925
}
926
if(key_value.length !== 2){
927
throw _b_.ValueError.$factory("dictionary update " +
928
"sequence element #" + i + " has length " +
929
key_value.length + "; 2 is required")
930
}
931
dict.$setitem(self, key_value[0], key_value[1])
932
i++
Sep 5, 2014
935
}
Sep 5, 2014
939
}
940
941
var dict_values = $B.make_view("dict_values")
942
dict_values.$iterator = $B.make_iterator_class("dict_valueiterator")
Nov 21, 2015
943
Feb 11, 2018
944
dict.values = function(self){
Mar 23, 2018
945
if(arguments.length > 1){
946
var _len = arguments.length - 1,
947
_msg = "values() takes no arguments (" + _len + " given)"
948
throw _b_.TypeError.$factory(_msg)
Nov 21, 2015
949
}
950
var it = dict_values.$factory(to_list(self, 1))
951
it.len_func = function(){return dict.__len__(self)}
952
return it
Nov 21, 2015
953
}
954
955
dict.$factory = function(){
956
var res = dict.__new__(dict)
957
var args = [res]
958
for(var i = 0, len = arguments.length; i < len ; i++){
959
args.push(arguments[i])
960
}
961
dict.__init__.apply(null, args)
Sep 5, 2014
962
return res
963
}
Sep 5, 2014
965
_b_.dict = dict
Feb 11, 2018
967
$B.set_func_names(dict, "builtins")
969
// This must be done after set_func_names, otherwise dict.fromkeys doesn't
970
// have the attribute $infos
971
dict.fromkeys = _b_.classmethod.$factory(dict.fromkeys)
972
973
$B.getset_descriptor = $B.make_class("getset_descriptor",
974
function(klass, attr){
975
return {
976
__class__: $B.getset_descriptor,
977
cls: klass,
978
attr: attr
979
}
980
}
981
)
982
983
$B.getset_descriptor.__repr__ = $B.getset_descriptor.__str__ = function(self){
984
return `<attribute '${self.attr}' of '${self.cls.$infos.__name__}' objects>`
985
}
986
987
$B.set_func_names($B.getset_descriptor, "builtins")
988
989
// Class for attribute __dict__ of classes
990
var mappingproxy = $B.mappingproxy = $B.make_class("mappingproxy",
Feb 12, 2018
991
function(obj){
992
if(_b_.isinstance(obj, dict)){
993
// obj is a dictionary, with $string_dict table such that
994
// obj.$string_dict[key] = [value, rank]
995
// Transform it into an object with attribute $jsobj such that
996
// res.$jsobj[key] = value
997
var res = $B.obj_dict(dict.$to_obj(obj))
998
}else{
999
var res = $B.obj_dict(obj)
1000
}
Feb 12, 2018
1001
res.__class__ = mappingproxy
1002
return res
1003
}
1004
)
Feb 12, 2018
1006
mappingproxy.__setitem__ = function(){
Mar 7, 2018
1007
throw _b_.TypeError.$factory("'mappingproxy' object does not support " +
1008
"item assignment")
1011
for(var attr in dict){
1012
if(mappingproxy[attr] !== undefined ||
1013
["__class__", "__mro__", "__new__", "__init__", "__delitem__",
1014
"clear", "fromkeys", "pop", "popitem", "setdefault",
1015
"update"].indexOf(attr) > -1){
1016
continue
1017
}
1018
if(typeof dict[attr] == "function"){
1019
mappingproxy[attr] = (function(key){
1020
return function(){
1021
return dict[key].apply(null, arguments)
1022
}
1023
})(attr)
1024
}else{
1025
mappingproxy[attr] = dict[attr]
1026
}
1027
}
1028
Feb 12, 2018
1029
$B.set_func_names(mappingproxy, "builtins")
Mar 7, 2018
1034
if(attr.charAt(0) != "$" && attr !== "__class__"){
1035
if(x[attr] === null){
1036
d.$string_dict[attr] = [_b_.None, d.$version]
1037
}else if(x[attr] === undefined){
1038
continue
1039
}else if(x[attr].$jsobj === x){
1040
d.$string_dict[attr] = [d, d.$version]
1042
d.$string_dict[attr] = [$B.$JS2Py(x[attr]), d.$version]
1044
d.$version++
1045
}
1046
}
1047
return d
1048
}
1050
$B.obj_dict = function(obj, from_js){
1051
var klass = obj.__class__ || $B.get_class(obj)
1052
if(klass !== undefined && klass.$native){
1053
throw _b_.AttributeError.$factory(klass.__name__ +
1054
" has no attribute '__dict__'")}
1055
var res = _b_.dict.$factory()
1056
res.$jsobj = obj
1057
res.$from_js = from_js // set to true if
1058
return res
1059
}
1060
Sep 5, 2014
1061
})(__BRYTHON__)