Permalink
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Apr 25, 2020
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Dec 20, 2018
Jan 14, 2015
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Jan 14, 2015
Mar 19, 2018
Jan 14, 2015
Jan 14, 2015
Jan 14, 2015
Mar 19, 2018
Jan 14, 2015
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Jan 14, 2015
Mar 19, 2018
Jan 14, 2015
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Dec 18, 2019
Dec 18, 2019
Mar 19, 2018
Jan 14, 2015
Jan 14, 2015
Mar 19, 2018
Mar 19, 2018
Jan 14, 2015
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 27, 2019
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Apr 2, 2019
Mar 19, 2018
Aug 31, 2017
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Aug 31, 2017
Apr 16, 2019
Mar 19, 2018
Apr 16, 2019
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Nov 12, 2018
Nov 12, 2018
Nov 12, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Apr 2, 2019
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Aug 31, 2017
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Jan 6, 2016
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Jun 11, 2020
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Aug 31, 2017
May 24, 2019
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Feb 27, 2020
Feb 27, 2020
Feb 27, 2020
Aug 31, 2017
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Nov 14, 2018
Jan 26, 2020
Mar 19, 2018
Mar 19, 2018
Nov 15, 2019
Jul 28, 2018
Oct 27, 2019
May 3, 2020
Nov 2, 2018
Oct 27, 2019
Nov 2, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Nov 12, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Jun 29, 2017
Jun 29, 2017
Jun 29, 2017
Oct 13, 2019
Jun 29, 2017
Jul 10, 2017
Jul 10, 2017
Mar 19, 2018
Mar 19, 2018
Oct 13, 2019
Dec 27, 2019
Oct 13, 2019
Apr 25, 2020
Newer
100644
2567 lines (2352 sloc)
81.3 KB
21
if($.start === null || $.start === _b_.None){$.start = 0}
22
else if($.start < 0){
23
$.start += $.self.length
24
$.start = Math.max(0, $.start)
25
}
26
if($.end === null || $.end === _b_.None){$.end = $.self.length}
27
else if($.end < 0){
28
$.end += $.self.length
29
$.end = Math.max(0, $.end)
30
}
32
if(! isinstance($.start, _b_.int) || ! isinstance($.end, _b_.int)){
33
throw _b_.TypeError.$factory("slice indices must be integers " +
34
"or None or have an __index__ method")
35
}
52
if(!(typeof other === "string")){
53
try{return getattr(other, "__radd__")(self)}
54
catch(err){
55
throw _b_.TypeError.$factory("Can't convert " +
63
throw _b_.TypeError.$factory("'in <string>' requires " +
64
"string as left operand, not " + item.__class__)
65
}
66
if(typeof item == "string"){
67
var nbcar = item.length
68
}else{
69
var nbcar = _b_.len(item)
70
}
71
if(nbcar == 0) {return true} // a string contains the empty string
72
if(self.length == 0){return nbcar == 0}
73
for(var i = 0, len = self.length; i < len; i++){
74
if(self.substr(i, nbcar) == item){return true}
83
// __dir__must be assigned explicitely because attribute resolution for
84
// builtin classes doesn't use __mro__
88
if(other === undefined){ // compare object "self" to class "str"
89
return self === str
99
if(fmt.type && fmt.type != "s"){
100
throw _b_.ValueError.$factory("Unknown format code '" + fmt.type +
108
if(fmt.sign !== undefined){
109
throw _b_.ValueError.$factory(
110
"Sign not allowed in string format specifier")
123
if(arg < 0) {pos += self.length}
124
if(pos >= 0 && pos < self.length){return self.charAt(pos)}
125
throw _b_.IndexError.$factory("string index out of range")
126
}
127
if(isinstance(arg, slice)) {
128
var s = _b_.slice.$conv_for_seq(arg, self.length),
129
start = s.start,
130
stop = s.stop,
131
step = s.step
132
var res = "",
134
if(step > 0){
135
if(stop <= start){return ""}
136
for(var i = start; i < stop; i += step){res += self.charAt(i)}
138
if(stop >= start){return ''}
139
for(var i = start; i > stop; i += step){res += self.charAt(i)}
159
var x = prefix
160
x = (x ^ (p.charCodeAt(0) << 7)) & mask
161
for(var i = 0, len = p.length; i < len; i++){
162
x = ((1000003 * x) ^ p.charCodeAt(i)) & mask
163
}
164
x = (x ^ p.length) & mask
165
x = (x ^ suffix) & mask
234
// left adjusted
235
return s + get_char_array(padding - s.length, flags.pad_char)
236
}
237
}
238
246
if(val.__class__ === $B.long_int){
247
s = $B.long_int.to_base(val, 10)
248
}else{
249
s = val.toString()
251
if(s[0] === "-"){
252
return "-" + get_char_array(precision - s.length + 1, "0") + s.slice(1)
263
if(val === Infinity){
264
val = "inf"
265
}else if(val === -Infinity){
266
val = "-inf"
267
}else{
268
val = "nan"
290
var str_format = function(val, flags) {
291
// string format supports left and right padding
292
flags.pad_char = " " // even if 0 padding is defined, don't use it
298
if(val.__class__ === $B.long_int){
299
val = $B.long_int.to_base(val, 10)
300
}else{
301
val = parseInt(val)
319
var repr_format = function(val, flags) {
320
flags.pad_char = " " // even if 0 padding is defined, don't use it
321
return format_padding(repr(val), flags)
322
}
324
var ascii_format = function(val, flags) {
325
flags.pad_char = " " // even if 0 padding is defined, don't use it
326
return format_padding(ascii(val), flags)
327
}
339
flags.precision = parseInt(flags.precision, 10)
340
validate_precision(flags.precision)
341
}
342
return parseFloat(val)
343
}
346
var trailing_zeros = /(.*?)(0+)([eE].*)/,
347
leading_zeros = /\.(0*)/,
348
trailing_dot = /\.$/
350
var validate_precision = function(precision) {
351
// force precision to limits of javascript
356
var floating_point_format = function(val, upper, flags){
357
val = _float_helper(val, flags),
358
v = val.toString(),
359
v_len = v.length,
360
dot_idx = v.indexOf('.')
361
if(dot_idx < 0){dot_idx = v_len}
362
if(val < 1 && val > -1){
363
var zeros = leading_zeros.exec(v),
364
numzeros
365
if(zeros){
370
if(numzeros >= 4){
371
val = format_sign(val, flags) + format_float_precision(val, upper,
372
flags, _floating_g_exp_helper)
373
if(!flags.alternate){
386
return format_padding(format_sign(val, flags) +
387
format_float_precision(val, upper, flags,
388
function(val, precision) {
389
return val.toFixed(min(precision, v_len - dot_idx) +
390
numzeros)
391
}),
392
flags
393
)
394
}
395
396
if(dot_idx > flags.precision){
397
val = format_sign(val, flags) + format_float_precision(val, upper,
398
flags, _floating_g_exp_helper)
399
if(! flags.alternate){
411
return format_padding(format_sign(val, flags) +
412
format_float_precision(val, upper, flags,
413
function(val, precision) {
414
if(!flags.decimal_point){
415
precision = min(v_len - 1, 6)
416
}else if (precision > v_len){
417
if(! flags.alternate){
418
precision = v_len
419
}
421
if(precision < dot_idx){
422
precision = dot_idx
423
}
424
return val.toFixed(precision - dot_idx)
425
}),
426
flags
427
)
430
var _floating_g_exp_helper = function(val, precision, flags, upper){
431
if(precision){--precision}
434
var e_idx = val.lastIndexOf("e")
435
if(e_idx > val.length - 4){
436
val = val.substring(0, e_idx + 2) + "0" + val.substring(e_idx + 2)
439
return val
440
}
441
442
// fF
443
var floating_point_decimal_format = function(val, upper, flags) {
444
val = _float_helper(val, flags)
445
return format_padding(format_sign(val, flags) +
446
format_float_precision(val, upper, flags,
447
function(val, precision, flags) {
448
val = val.toFixed(precision)
449
if(precision === 0 && flags.alternate){
450
val += '.'
451
}
452
return val
453
}),
454
flags
455
)
456
}
457
458
var _floating_exp_helper = function(val, precision, flags, upper) {
459
val = val.toExponential(precision)
460
// pad exponent to two digits
473
return format_padding(format_sign(val, flags) +
474
format_float_precision(val, upper, flags, _floating_exp_helper), flags)
500
if(flags.alternate){
501
if(ret.charAt(0) === "-"){
502
if(upper){ret = "-0X" + ret.slice(1)}
503
else{ret = "-0x" + ret.slice(1)}
504
}else{
505
if(upper){ret = "0X" + ret}
506
else{ret = "0x" + ret}
516
if(val.__class__ === $B.long_int){
517
ret = $B.long_int.to_base(8)
518
}else{
519
ret = parseInt(val)
520
ret = ret.toString(8)
536
if(flags.alternate){
537
if(ret.charAt(0) === "-"){ret = "-0o" + ret.slice(1)}
538
else{ret = "0o" + ret}
543
function series_of_bytes(val, flags){
544
if(val.__class__ && val.__class__.$buffer_protocol){
545
var it = _b_.iter(val),
546
ints = []
547
while(true){
548
try{
549
ints.push(_b_.next(it))
550
}catch(err){
551
if(err.__class__ === _b_.StopIteration){
552
var b = _b_.bytes.$factory(ints)
553
return format_padding(_b_.bytes.decode(b, "ascii"), flags)
554
}
555
throw err
556
}
557
}
558
}else{
559
try{
560
bytes_obj = $B.$getattr(val, "__bytes__")
561
return format_padding(_b_.bytes.decode(bytes_obj), flags)
562
}catch(err){
563
if(err.__class__ === _b_.AttributeError){
564
throw _b_.TypeError.$factory("%b does not accept '" +
565
$B.class_name(val) + "'")
566
}
567
throw err
568
}
569
}
570
}
571
573
if(isinstance(val, str) && val.length == 1){
574
return val
575
}else if(isinstance(val, bytes) && val.source.length == 1){
576
val = val.source[0]
577
}else{
578
try{
579
val = _b_.int.$factory(val) // yes, floats are valid (they are cast to int)
580
}catch (err){
581
throw _b_.TypeError.$factory("%c requires int or char")
582
}
587
var num_flag = function(c, flags){
588
if(c === "0" && ! flags.padding && ! flags.decimal_point && ! flags.left){
589
flags.pad_char = "0"
595
flags.precision = (flags.precision || "") + c
596
}
597
}
598
599
var decimal_point_flag = function(val, flags) {
601
// can only have one decimal point
602
throw new UnsupportedChar()
603
}
604
flags.decimal_point = true
605
}
606
607
var neg_flag = function(val, flags){
608
flags.pad_char = " " // overrides '0' flag
626
"s": str_format,
627
"d": num_format,
628
"i": num_format,
629
"u": num_format,
630
"o": octal_format,
631
"r": repr_format,
632
"a": ascii_format,
633
"g": function(val, flags){
634
return floating_point_format(val, false, flags)
635
},
636
"G": function(val, flags){return floating_point_format(val, true, flags)},
637
"f": function(val, flags){
638
return floating_point_decimal_format(val, false, flags)
639
},
640
"F": function(val, flags){
641
return floating_point_decimal_format(val, true, flags)
642
},
643
"e": function(val, flags){
644
return floating_point_exponential_format(val, false, flags)
645
},
646
"E": function(val, flags){
647
return floating_point_exponential_format(val, true, flags)
648
},
649
"x": function(val, flags){return signed_hex_format(val, false, flags)},
650
"X": function(val, flags){return signed_hex_format(val, true, flags)},
651
"c": single_char_format,
652
"0": function(val, flags){return num_flag("0", flags)},
653
"1": function(val, flags){return num_flag("1", flags)},
654
"2": function(val, flags){return num_flag("2", flags)},
655
"3": function(val, flags){return num_flag("3", flags)},
656
"4": function(val, flags){return num_flag("4", flags)},
657
"5": function(val, flags){return num_flag("5", flags)},
658
"6": function(val, flags){return num_flag("6", flags)},
659
"7": function(val, flags){return num_flag("7", flags)},
660
"8": function(val, flags){return num_flag("8", flags)},
661
"9": function(val, flags){return num_flag("9", flags)},
662
"-": neg_flag,
663
" ": space_flag,
664
"+": sign_flag,
665
".": decimal_point_flag,
666
"#": alternate_flag
667
}
668
669
// exception thrown when an unsupported char is encountered in legacy format
716
if(self === undefined){
717
throw _b_.TypeError.$factory(
718
"not enough arguments for format string")
745
throw _b_.ValueError.$factory(
746
"unsupported format character '" + invalid_char +
747
"' (0x" + invalid_char.charCodeAt(0).toString(16) +
748
") at index " + newpos)
749
}else if(err.name === "NotANumber"){
750
var try_char = s[newpos],
751
cls = self.__class__
752
if(!cls){
753
if(typeof(self) === "string"){
754
cls = "str"
755
}else{
761
throw _b_.TypeError.$factory("%" + try_char +
762
" format: a number is required, not " + cls)
763
}else{
795
}while(pos < length)
796
797
if(argpos !== null){
798
if(args.length > argpos){
799
throw _b_.TypeError.$factory(
800
"not enough arguments for format string")
801
}else if(args.length < argpos){
802
throw _b_.TypeError.$factory(
803
"not all arguments converted during string formatting")
805
}else if(nbph == 0){
806
throw _b_.TypeError.$factory(
807
"not all arguments converted during string formatting")
815
var $ = $B.args("__mul__", 2, {self: null, other: null},
816
["self", "other"], arguments, {}, null, null)
817
if(! isinstance($.other, _b_.int)){throw _b_.TypeError.$factory(
818
"Can't multiply sequence by non-int of type '" +
830
res = self.replace(/\\/g, "\\\\")
831
// special cases
832
res = res.replace(new RegExp("\u0007", "g"), "\\x07").
833
replace(new RegExp("\b", "g"), "\\x08").
835
replace(new RegExp("\f", "g"), "\\x0c").
836
replace(new RegExp("\n", "g"), "\\n").
837
replace(new RegExp("\r", "g"), "\\r").
838
replace(new RegExp("\t", "g"), "\\t")
840
if(res.search('"') == -1 && res.search("'") == -1){
841
return "'" + res + "'"
842
}else if(self.search('"') == -1){
843
return '"' + res + '"'
844
}
845
var qesc = new RegExp("'", "g") // to escape single quote
846
res = "'" + res.replace(qesc, "\\'") + "'"
850
str.__setitem__ = function(self, attr, value){
851
throw _b_.TypeError.$factory(
852
"'str' object does not support item assignment")
854
var combining = []
855
for(var cp = 0x300; cp <= 0x36F; cp++){
856
combining.push(String.fromCharCode(cp))
857
}
858
var combining_re = new RegExp("(" + combining.join("|") + ")")
870
$comp_func += "" // source code
871
var $comps = {">": "gt", ">=": "ge", "<": "lt", "<=": "le"}
880
var $notimplemented = function(self, other){
881
throw NotImplementedError.$factory(
882
"OPERATOR not implemented for class str")
885
str.capitalize = function(self){
886
var $ = $B.args("capitalize", 1, {self}, ["self"],
887
arguments, {}, null, null)
888
if(self.length == 0){return ""}
889
return self.charAt(0).toUpperCase() + self.substr(1)
890
}
891
892
str.casefold = function(self){
893
var $ = $B.args("casefold", 1, {self}, ["self"],
894
arguments, {}, null, null),
895
res = "",
896
char,
897
cf
898
for(var i = 0, len = self.length; i < len; i++){
899
char = self.charCodeAt(i)
900
cf = $B.unicode_casefold[char]
901
if(cf){
902
cf.forEach(function(cp){
903
res += String.fromCharCode(cp)
904
})
905
}else{
906
res += self.charAt(i).toLowerCase()
907
}
908
}
909
return res
910
}
912
str.center = function(){
913
var $ = $B.args("center", 3, {self: null, width: null, fillchar: null},
914
["self", "width", "fillchar"],
915
arguments, {fillchar:" "}, null, null),
916
self = $.self
928
var $ = $B.args("count", 4, {self:null, sub:null, start:null, stop:null},
929
["self", "sub", "start", "stop"], arguments, {start:null, stop:null},
937
if($.stop !== null){_slice = _b_.slice.$factory($.start, $.stop)}
938
else{_slice = _b_.slice.$factory($.start, $.self.length)}
943
if($.sub.length == 0){
944
if($.start == $.self.length){return 1}
945
else if(substr.length == 0){return 0}
946
return substr.length + 1
948
var n = 0,
949
pos = 0
950
while(pos < substr.length){
951
pos = substr.indexOf($.sub, pos)
952
if(pos >= 0){n++; pos += $.sub.length}
953
else{break}
958
str.encode = function(){
959
var $ = $B.args("encode", 3, {self: null, encoding: null, errors: null},
960
["self", "encoding", "errors"], arguments,
961
{encoding: "utf-8", errors: "strict"}, null, null)
962
if($.encoding == "rot13" || $.encoding == "rot_13"){
967
if(("a" <= char && char <= "m") || ("A" <= char && char <= "M")){
968
res += String.fromCharCode(String.charCodeAt(char) + 13)
969
}else if(("m" < char && char <= "z") ||
970
("M" < char && char <= "Z")){
971
res += String.fromCharCode(String.charCodeAt(char) - 13)
980
// Return True if the string ends with the specified suffix, otherwise
981
// return False. suffix can also be a tuple of suffixes to look for.
982
// With optional start, test beginning at that position. With optional
986
["self", "suffix", "start", "end"],
987
arguments, {start: 0, end: null}, null, null)
994
var s = $.self.substring($.start, $.end)
995
for(var i = 0, len = suffixes.length; i < len; i++){
999
if(suffix.length <= s.length &&
1000
s.substr(s.length - suffix.length) == suffix){return true}
1006
var $ = $B.args("expandtabs", 2, {self: null, tabsize: null},
1007
["self", "tabsize"], arguments, {tabsize: 8}, null, null)
1008
var s = $B.$GetInt($.tabsize),
1009
col = 0,
1010
pos = 0,
1011
res = ""
1012
if(s == 1){return self.replace(/\t/g," ")}
1013
while(pos < self.length){
1021
res += car
1022
col = 0
1023
break
1024
default:
1025
res += car
1026
col++
1027
break
1028
}
1029
pos++
1030
}
1036
// Return the lowest index in the string where substring sub is found,
1037
// such that sub is contained in the slice s[start:end]. Optional
1038
// arguments start and end are interpreted as in slice notation.
1041
{self: null, sub: null, start: null, end: null},
1042
["self", "sub", "start", "end"],
1043
arguments, {start: 0, end: null}, null, null)
1047
if(!isinstance($.start, _b_.int)||!isinstance($.end, _b_.int)){
1048
throw _b_.TypeError.$factory("slice indices must be " +
1049
"integers or None or have an __index__ method")}
1050
// Can't use string.substring(start, end) because if end < start,
1051
// Javascript transforms it into substring(end, start)...
1052
var s = ""
1053
for(var i = $.start; i < $.end; i++){
1054
s += $.self.charAt(i)
1055
}
1057
if($.sub.length == 0 && $.start == $.self.length){return $.self.length}
1058
if(s.length + $.sub.length == 0){return -1}
1060
var last_search = s.length - $.sub.length
1061
for(var i = 0; i <= last_search; i++){
1062
if(s.substr(i, $.sub.length) == $.sub){return $.start + i}
1073
// a.x[z]!r:...
1074
// the object has attributes :
1075
// - name : "a"
1076
// - name_ext : [".x", "[z]"]
1077
// - conv : r
1078
// - spec : rest of string after :
1086
// No : in the string : it only contains a name
1087
name = fmt_string
1088
}else{
1089
// name is before the first ":"
1090
// spec (the format specification) is after
1091
name = elts[0]
1095
var elts = name.split("!")
1096
if(elts.length > 1){
1097
name = elts[0]
1098
conv = elts[1] // conversion flag
1102
// "name' may be a subscription or attribute
1103
// Put these "extensions" in the list "name_ext"
1104
function name_repl(match){
1105
name_ext.push(match)
1107
}
1108
var name_ext_re = /\.[_a-zA-Z][_a-zA-Z0-9]*|\[[_a-zA-Z][_a-zA-Z0-9]*\]|\[[0-9]+\]/g
1109
name = name.replace(name_ext_re, name_repl)
1110
}
1117
// Parse self to detect formatting instructions
1118
// Create a list "parts" made of sections of the string :
1119
// - elements of even rank are literal text
1120
// - elements of odd rank are "format objects", built from the
1121
// format strings in self (of the form {...})
1132
text += "{"
1133
pos += 2
1134
}else if(car == "}" && self.charAt(pos + 1) == "}"){
1141
// Store current literal text
1142
parts.push(text)
1143
1144
// Search the end of the format string, ie the } closing the
1145
// opening {. Since the string can contain other pairs {} for
1146
// nested formatting, an integer nb is incremented for each { and
1147
// decremented for each } ; the end of the format string is
1148
// reached when nb == 0
1149
var end = pos + 1,
1150
nb = 1
1151
while(end < _len){
1152
if(self.charAt(end) == "{"){nb++; end++}
1153
else if(self.charAt(end) == "}"){
1154
nb--; end++
1155
if(nb == 0){
1160
var fmt_obj = $B.parse_format(fmt_string)
1161
fmt_obj.raw_name = fmt_obj.name
1162
fmt_obj.raw_spec = fmt_obj.spec
1197
return parts
1198
}
1199
1200
str.format = function(self) {
1201
var $ = $B.args("format", 1, {self: null}, ["self"],
1202
arguments, {}, "$args", "$kw")
1203
1204
var parts = $B.split_format($.self)
1205
1216
1217
if(fmt.spec !== undefined){
1218
// "spec" may contain "nested replacement fields"
1219
// In this case, evaluate them using the positional
1220
// or keyword arguments passed to format()
1221
function replace_nested(name, key){
1222
if(/\d+/.exec(key)){
1223
// If key is numeric, search in positional
1224
// arguments
1225
return _b_.tuple.__getitem__($.$args,
1226
parseInt(key))
1227
}else{
1228
// Else try in keyword arguments
1229
return _b_.dict.__getitem__($.$kw, key)
1230
}
1231
}
1232
fmt.spec = fmt.spec.replace(/\{(.*?)\}/g,
1233
replace_nested)
1234
}
1236
// Numerical reference : use positional arguments
1237
var pos = parseInt(fmt.name),
1247
// Attribute
1248
value = _b_.getattr(value, ext.substr(1))
1249
}else{
1250
// Subscription
1253
if(key.charAt(0).search(/\d/) > -1){key = parseInt(key)}
1254
value = _b_.getattr(value, "__getitem__")(key)
1258
// If the conversion flag is set, first call a function to convert
1259
// the value
1260
if(fmt.conv == "a"){value = _b_.ascii(value)}
1261
else if(fmt.conv == "r"){value = _b_.repr(value)}
1262
else if(fmt.conv == "s"){value = _b_.str.$factory(value)}
1276
throw NotImplementedError.$factory(
1277
"function format_map not implemented yet")
1288
/* Return true if the string is empty or all characters in the string are
1289
ASCII, false otherwise. ASCII characters have code points in the range
1290
U+0000-U+007F. */
1291
for(var i = 0, len = self.length; i < len; i++){
1292
if(self.charCodeAt(i) > 127){return false}
1293
}
1294
return true
1295
}
1296
1297
str.isalnum = function(self){
1298
/* Return true if all characters in the string are alphanumeric and there
1299
is at least one character, false otherwise. A character c is alphanumeric
1300
if one of the following returns True: c.isalpha(), c.isdecimal(),
1301
c.isdigit(), or c.isnumeric(). */
1302
var $ = $B.args("isalnum", 1, {self: null}, ["self"],
1303
arguments, {}, null, null),
1304
char
1305
for(var i = 0, len = self.length; i < len; i++){
1306
char = self.charCodeAt(i)
1307
if(unicode_tables.Ll[char] ||
1308
unicode_tables.Lu[char] ||
1309
unicode_tables.Lm[char] ||
1310
unicode_tables.Lt[char] ||
1311
unicode_tables.Lo[char] ||
1312
unicode_tables.Nd[char] ||
1313
unicode_tables.digits[char] ||
1314
unicode_tables.numeric[char]){
1315
continue
1316
}
1317
return false
1318
}
1319
return true
1320
}
1321
1322
str.isalpha = function(self){
1323
/* Return true if all characters in the string are alphabetic and there is
1324
at least one character, false otherwise. Alphabetic characters are those
1325
characters defined in the Unicode character database as "Letter", i.e.,
1326
those with general category property being one of "Lm", "Lt", "Lu", "Ll",
1327
or "Lo". */
1328
var $ = $B.args("isalpha", 1, {self: null}, ["self"],
1329
arguments, {}, null, null),
1330
char
1331
for(var i = 0, len = self.length; i < len; i++){
1332
char = self.charCodeAt(i)
1333
if(unicode_tables.Ll[char] ||
1334
unicode_tables.Lu[char] ||
1335
unicode_tables.Lm[char] ||
1336
unicode_tables.Lt[char] ||
1337
unicode_tables.Lo[char]){
1338
continue
1339
}
1340
return false
1341
}
1342
return true
1343
}
1344
1345
str.isdecimal = function(self){
1346
/* Return true if all characters in the string are decimal characters and
1347
there is at least one character, false otherwise. Decimal characters are
1348
those that can be used to form numbers in base 10, e.g. U+0660,
1349
ARABIC-INDIC DIGIT ZERO. Formally a decimal character is a character in
1350
the Unicode General Category "Nd". */
1351
var $ = $B.args("isdecimal", 1, {self: null}, ["self"],
1352
arguments, {}, null, null),
1353
char
1354
for(var i = 0, len = self.length; i < len; i++){
1355
char = self.charCodeAt(i)
1356
if(! unicode_tables.Nd[char]){
1357
return false
1358
}
1359
}
1360
return self.length > 0
1361
}
1362
1363
str.isdigit = function(self){
1364
/* Return true if all characters in the string are digits and there is at
1365
least one character, false otherwise. */
1366
var $ = $B.args("isdigit", 1, {self: null}, ["self"],
1367
arguments, {}, null, null),
1368
char
1369
for(var i = 0, len = self.length; i < len; i++){
1370
char = self.charCodeAt(i)
1371
if(! unicode_tables.digits[char]){
1372
return false
1373
}
1374
}
1375
return self.length > 0
1376
}
1377
1378
str.isidentifier = function(self){
1379
/* Return true if the string is a valid identifier according to the
1380
language definition. */
1381
var $ = $B.args("isidentifier", 1, {self: null}, ["self"],
1382
arguments, {}, null, null),
1383
char
1384
if(self.length == 0){return false}
1385
else if(unicode_tables.XID_Start[self.charCodeAt(0)] === undefined){
1386
return false
1387
}else{
1388
for(var i = 1, len = self.length; i < len; i++){
1389
if(unicode_tables.XID_Continue[self.charCodeAt(i)] === undefined){
1390
return false
1391
}
1392
}
1393
}
1394
return true
1395
}
1396
1397
str.islower = function(self){
1398
/* Return true if all cased characters 4 in the string are lowercase and
1399
there is at least one cased character, false otherwise. */
1400
var $ = $B.args("islower", 1, {self: null}, ["self"],
1401
arguments, {}, null, null),
1402
has_cased = false,
1403
char
1404
1405
for(var i = 0, len = self.length; i < len; i++){
1406
char = self.charCodeAt(i)
1407
if(unicode_tables.Ll[char]){has_cased = true; continue}
1408
else if(unicode_tables.Lu[char] || unicode_tables.Lt[char]){
1409
return false
1410
}
1411
}
1412
return has_cased
1413
}
1414
1415
str.isnumeric = function(self){
1416
/* Return true if all characters in the string are numeric characters, and
1417
there is at least one character, false otherwise. Numeric characters
1418
include digit characters, and all characters that have the Unicode numeric
1419
value property, e.g. U+2155, VULGAR FRACTION ONE FIFTH. Formally, numeric
1420
characters are those with the property value Numeric_Type=Digit,
1421
Numeric_Type=Decimal or Numeric_Type=Numeric.*/
1422
var $ = $B.args("isnumeric", 1, {self: null}, ["self"],
1423
arguments, {}, null, null)
1424
for(var i = 0, len = self.length; i < len; i++){
1425
if(! unicode_tables.numeric[self.charCodeAt(i)]){
1426
return false
1427
}
1428
}
1429
return self.length > 0
1430
}
1431
1432
var printable,
1433
printable_gc = ['Cc', 'Cf', 'Co', 'Cs','Zl', 'Zp', 'Zs']
1434
1435
str.isprintable = function(self){
1436
/* Return true if all characters in the string are printable or the string
1437
is empty, false otherwise. Nonprintable characters are those characters
1438
defined in the Unicode character database as "Other" or "Separator",
1439
excepting the ASCII space (0x20) which is considered printable. */
1440
1441
// Set printable if not set yet
1442
if(printable === undefined){
1443
for(var i = 0; i < printable_gc.length; i++){
1444
var table = unicode_tables[printable_gc[i]]
1445
for(var cp in table){
1446
printable[cp] = true
1447
}
1448
}
1449
printable[32] = true
1450
}
1451
1452
var $ = $B.args("isprintable", 1, {self: null}, ["self"],
1453
arguments, {}, null, null),
1454
char,
1455
flag
1456
for(var i = 0, len = self.length; i < len; i++){
1457
char = self.charCodeAt(i)
1458
if(! printable[char]){
1459
return false
1460
}
1461
}
1462
return true
1463
}
1464
1465
str.isspace = function(self){
1466
/* Return true if there are only whitespace characters in the string and
1467
there is at least one character, false otherwise.
1468
1469
A character is whitespace if in the Unicode character database, either its
1470
general category is Zs ("Separator, space"), or its bidirectional class is
1471
one of WS, B, or S.*/
1472
var $ = $B.args("isspace", 1, {self: null}, ["self"],
1473
arguments, {}, null, null),
1474
char
1475
for(var i = 0, len = self.length; i < len; i++){
1476
char = self.charCodeAt(i)
1477
if(! unicode_tables.Zs[char] &&
1478
$B.unicode_bidi_whitespace.indexOf(char) == -1){
1479
return false
1480
}
1481
}
1482
return self.length > 0
1483
}
1484
1485
str.istitle = function(self){
1486
/* Return true if the string is a titlecased string and there is at least
1487
one character, for example uppercase characters may only follow uncased
1488
characters and lowercase characters only cased ones. Return false
1489
otherwise. */
1490
var $ = $B.args("istitle", 1, {self: null}, ["self"],
1491
arguments, {}, null, null)
1492
return self.length > 0 && str.title(self) == self
1493
}
1494
1495
str.isupper = function(self){
1496
/* Return true if all cased characters 4 in the string are lowercase and
1497
there is at least one cased character, false otherwise. */
1498
var $ = $B.args("islower", 1, {self: null}, ["self"],
1499
arguments, {}, null, null),
1500
has_cased = false,
1501
char
1502
1503
for(var i = 0, len = self.length; i < len; i++){
1504
char = self.charCodeAt(i)
1505
if(unicode_tables.Lu[char]){has_cased = true; continue}
1506
else if(unicode_tables.Ll[char] || unicode_tables.Lt[char]){
1524
if(! isinstance(obj2, str)){throw _b_.TypeError.$factory(
1525
"sequence item " + count + ": expected str instance, " +
1539
var $ = $B.args("ljust", 3, {self: null, width: null, fillchar:null},
1540
["self", "width", "fillchar"],
1541
arguments, {fillchar: " "}, null, null)
1547
str.lower = function(self){
1548
var $ = $B.args("lower", 1, {self: null}, ["self"],
1549
arguments, {}, null, null)
1550
return self.toLowerCase()
1551
}
1552
1554
var $ = $B.args("lstrip", 2, {self: null, chars: null}, ["self", "chars"],
1555
arguments, {chars:_b_.None}, null, null)
1556
if($.chars === _b_.None){return $.self.trimLeft()}
1557
for(var i = 0; i < $.self.length; i++){
1558
if($.chars.indexOf($.self.charAt(i)) === -1){
1559
return $.self.substring(i)
1567
var $ = $B.args("maketrans", 3, {x: null, y: null, z: null},
1568
["x", "y", "z"], arguments, {y: null, z: null}, null, null)
1573
// If there is only one argument, it must be a dictionary mapping
1574
// Unicode ordinals (integers) or characters (strings of length 1) to
1575
// Unicode ordinals, strings (of arbitrary lengths) or None. Character
1577
if(! _b_.isinstance($.x, _b_.dict)){
1578
throw _b_.TypeError.$factory(
1579
"maketrans only argument must be a dict")
1582
for(var i = 0, len = items.length; i < len; i++){
1583
var k = items[i][0],
1584
v = items[i][1]
1585
if(! _b_.isinstance(k, _b_.int)){
1586
if(_b_.isinstance(k, _b_.str) && k.length == 1){
1587
k = _b_.ord(k)
1588
}else{throw _b_.TypeError.$factory("dictionary key " + k +
1591
if(v !== _b_.None && ! _b_.isinstance(v, [_b_.int, _b_.str])){
1592
throw _b_.TypeError.$factory("dictionary value " + v +
1600
// and in the resulting dictionary, each character in x will be mapped
1601
// to the character at the same position in y
1604
}else if($.x.length !== $.y.length){
1605
throw _b_.TypeError.$factory(
1606
"maketrans arguments must be strings or same length")
1612
if(! _b_.isinstance($.z, _b_.str)){
1613
throw _b_.TypeError.$factory(
1614
"maketrans third argument must be a string")
1636
var $ = $B.args("partition", 2, {self: null, sep: null}, ["self", "sep"],
1637
arguments, {}, null, null)
1642
return _b_.tuple.$factory([$.self.substring(0, i), $.sep,
1643
$.self.substring(i + $.sep.length)])
1644
}
1645
1646
str.removeprefix = function(){
1647
var $ = $B.args("removeprefix", 2, {self: null, prefix: null},
1648
["self", "prefix"], arguments, {}, null, null)
1649
if(!_b_.isinstance($.prefix, str)){
1650
throw _b_.ValueError.$factory("prefix should be str, not " +
1651
`'${$B.class_name($.prefix)}'`)
1652
}
1653
if(str.startswith($.self, $.prefix)){
1654
return $.self.substr($.prefix.length)
1655
}
1656
return $.self.substr(0)
1657
}
1658
1659
str.removesuffix = function(){
1660
var $ = $B.args("removesuffix", 2, {self: null, prefix: null},
1661
["self", "suffix"], arguments, {}, null, null)
1662
if(!_b_.isinstance($.suffix, str)){
1663
throw _b_.ValueError.$factory("suffix should be str, not " +
1664
`'${$B.class_name($.prefix)}'`)
1665
}
1666
if($.suffix.length > 0 && str.endswith($.self, $.suffix)){
1667
return $.self.substr(0, $.self.length - $.suffix.length)
1668
}
1669
return $.self.substr(0)
1670
}
1671
1672
function $re_escape(str){
1673
var specials = "[.*+?|()$^"
1674
for(var i = 0, len = specials.length; i < len; i++){
1675
var re = new RegExp("\\"+specials.charAt(i), "g")
1676
str = str.replace(re, "\\"+specials.charAt(i))
1677
}
1678
return str
1685
var $ = $B.args("replace", 4,
1686
{self: null, old: null, $$new: null, count: null},
1687
["self", "old", "$$new", "count"],
1688
arguments, {count: -1}, null, null),
1689
count = $.count,
1690
self = $.self,
1691
old = $.old,
1692
_new = $.$$new
1699
"' object cannot be interpreted as an integer")
1700
}else if(isinstance(count, _b_.float)){
1701
throw _b_.TypeError.$factory("integer argument expected, got float")
1702
}
1703
if(count == 0){return self}
1704
if(count.__class__ == $B.long_int){count = parseInt(count.value)}
1705
if(old == ""){
1706
if(_new == ""){return self}
1707
if(self == ""){return _new}
1708
var elts = self.split("")
1709
if(count > -1 && elts.length >= count){
1710
var rest = elts.slice(count).join("")
1711
return _new + elts.slice(0, count).join(_new) + rest
1712
}else{return _new + elts.join(_new) + _new}
1727
if(count < 0){count = res.length}
1728
while(count > 0){
1729
pos = res.indexOf(old, pos)
1730
if(pos < 0){break}
1731
res = res.substr(0, pos) + _new + res.substr(pos + old.length)
1732
pos = pos + _new.length
1733
count--
1739
// Return the highest index in the string where substring sub is found,
1740
// such that sub is contained within s[start:end]. Optional arguments
1742
if(arguments.length == 2 && typeof substr == "string"){
1743
return self.lastIndexOf(substr)
1744
}
1746
{self: null, sub: null, start: null, end: null},
1747
["self", "sub", "start", "end"],
1748
arguments, {start: 0, end: null}, null, null)
1760
for(var i = $.end - sublen; i >= $.start; i--){
1761
if($.self.substr(i, sublen) == $.sub){return i}
1768
var res = str.rfind.apply(null, arguments)
1769
if(res == -1){throw _b_.ValueError.$factory("substring not found")}
1774
var $ = $B.args("rjust",3,
1775
{self: null, width: null, fillchar: null},
1776
["self", "width", "fillchar"],
1777
arguments, {fillchar: " "}, null, null)
1785
var $ = $B.args("rpartition", 2, {self: null, sep: null}, ["self", "sep"],
1786
arguments, {}, null, null)
1790
var items = str.partition(self, sep).reverse()
1791
for(var i = 0; i < items.length; i++){
1792
items[i] = items[i].split("").reverse().join("")
1798
var $ = $B.args("rsplit", 3, {self: null, sep: null, maxsplit: null},
1799
["self", "sep", "maxsplit"], arguments,
1800
{sep: _b_.None, maxsplit: -1}, null, null),
1801
sep = $.sep
1804
var rev_str = reverse($.self),
1805
rev_sep = sep === _b_.None ? sep : reverse($.sep),
1816
str.rstrip = function(self, x){
1817
var $ = $B.args("rstrip", 2, {self: null, chars: null}, ["self", "chars"],
1818
arguments, {chars: _b_.None}, null, null)
1819
if($.chars === _b_.None){return $.self.trimRight()}
1821
if($.chars.indexOf($.self.charAt(j)) == -1){
1822
return $.self.substring(0, j + 1)
1829
var $ = $B.args("split", 3, {self: null, sep: null, maxsplit: null},
1830
["self", "sep", "maxsplit"], arguments,
1831
{sep: _b_.None, maxsplit: -1}, null, null),
1832
sep = $.sep,
1833
maxsplit = $.maxsplit,
1834
self = $.self,
1835
pos = 0
1836
if(maxsplit.__class__ === $B.long_int){maxsplit = parseInt(maxsplit.value)}
1837
if(sep == ""){throw _b_.ValueError.$factory("empty separator")}
1838
if(sep === _b_.None){
1840
while(pos < self.length && self.charAt(pos).search(/\s/) > -1){pos++}
1841
if(pos === self.length - 1){return [self]}
1842
var name = ""
1844
if(self.charAt(pos).search(/\s/) == -1){
1845
if(name == ""){name = self.charAt(pos)}
1846
else{name += self.charAt(pos)}
1866
var res = [],
1867
s = "",
1868
seplen = sep.length
1869
if(maxsplit == 0){return [self]}
1870
while(pos < self.length){
1871
if(self.substr(pos, seplen) == sep){
1889
str.splitlines = function(self) {
1890
var $ = $B.args('splitlines', 2, {self: null, keepends: null},
1891
['self','keepends'], arguments, {keepends: false},
1892
null, null)
1893
if(!_b_.isinstance($.keepends,[_b_.bool, _b_.int])){
1894
throw _b_.TypeError('integer argument expected, got '+
1897
var keepends = _b_.int.$factory($.keepends),
1898
res = [],
1899
self = $.self,
1900
start = 0,
1901
pos = 0
1902
if(!self.length){
1905
while (pos < self.length) {
1906
if(self.substr(pos, 2) == '\r\n'){
1907
res.push(self.slice(start, keepends ? pos + 2 : pos))
1908
start = pos = pos+2
1909
}else if(self[pos] == '\r' || self[pos] == '\n'){
1910
res.push(self.slice(start, keepends ? pos+1 : pos))
1911
start = pos = pos+1
1912
}else{
1913
pos++
1914
}
1915
}
1916
if(start < self.length){
1917
res.push(self.slice(start))
1918
}
1919
return res
1923
// Return True if string starts with the prefix, otherwise return False.
1924
// prefix can also be a tuple of prefixes to look for. With optional
1925
// start, test string beginning at that position. With optional end,
1927
var $ = $B.args("startswith", 4,
1928
{self: null, prefix: null, start: null, end: null},
1929
["self", "prefix", "start", "end"],
1930
arguments, {start: 0, end: null}, null, null)
1937
var s = $.self.substring($.start, $.end)
1938
for(var i = 0, len = prefixes.length; i < len; i++){
1949
var $ = $B.args("strip", 2, {self: null, chars: null}, ["self", "chars"],
1950
arguments, {chars: _b_.None}, null, null)
1951
if($.chars === _b_.None){return $.self.trim()}
1952
for(var i = 0; i < $.self.length; i++){
1953
if($.chars.indexOf($.self.charAt(i)) == -1){
1954
break
1957
for(var j = $.self.length - 1; j >= i; j--){
1958
if($.chars.indexOf($.self.charAt(j)) == -1){
1959
break
1965
str.swapcase = function(self){
1966
var $ = $B.args("swapcase", 1, {self}, ["self"],
1967
arguments, {}, null, null),
1968
res = "",
1969
char
1970
1971
for(var i = 0, len = self.length; i < len; i++){
1972
char = self.charCodeAt(i)
1973
if(unicode_tables.Ll[char]){
1974
res += self.charAt(i).toUpperCase()
1975
}else if(unicode_tables.Lu[char]){
1976
res += self.charAt(i).toLowerCase()
1977
}else{
1978
res += self.charAt(i)
1979
}
1980
}
1981
return res
1982
}
1983
1984
str.title = function(self){
1985
var $ = $B.args("title", 1, {self}, ["self"],
1986
arguments, {}, null, null),
1987
state,
1988
char,
1989
res = ""
1990
for(var i = 0, len = self.length; i < len; i++){
1991
char = self.charCodeAt(i)
1992
if(unicode_tables.Ll[char]){
1993
if(! state){
1994
res += self.charAt(i).toUpperCase()
1995
state = "word"
1996
}else{
1997
res += self.charAt(i)
1998
}
1999
}else if(unicode_tables.Lu[char] || unicode_tables.Lt[char]){
2000
res += state ? self.charAt(i).toLowerCase() : self.charAt(i)
2001
state = "word"
2002
}else{
2003
state = null
2004
res += self.charAt(i)
2005
}
2006
}
2007
return res
2008
}
2009
2012
getitem = $B.$getattr(table, "__getitem__")
2013
for(var i = 0, len = self.length; i < len; i++){
2014
try{
2015
var repl = getitem(self.charCodeAt(i))
2016
if(repl !== _b_.None){
2017
if(typeof repl == "string"){
2018
res.push(repl)
2019
}else if(typeof repl == "number"){
2020
res.push(String.fromCharCode(repl))
2021
}
2030
str.upper = function(self){
2031
var $ = $B.args("upper", 1, {self: null}, ["self"],
2032
arguments, {}, null, null)
2033
return self.toUpperCase()
2034
}
2035
2038
["self", "width"], arguments, {}, null, null)
2039
if($.width <= self.length){return self}
2041
case "+":
2042
case "-":
2043
return self.charAt(0) +
2044
"0".repeat($.width - self.length) + self.substr(1)
2055
if(encoding !== undefined){
2056
// Arguments may be passed as keywords (cf. issue #1060)
2057
var $ = $B.args("str", 3, {arg: null, encoding: null, errors: null},
2058
["arg", "encoding", "errors"], arguments,
2059
{encoding: "utf-8", errors: "strict"}, null, null),
2060
encoding = $.encoding,
2061
errors = $.errors
2062
}
2073
// class or its subclasses, but the attribute __str__ of the
2074
// class metaclass (usually "type") or its subclasses (usually
2075
// "object")
2076
// The metaclass is the attribute __class__ of the class dictionary
2081
if(arg.__class__ && arg.__class__ === _b_.bytes &&
2082
encoding !== undefined){
2083
// str(bytes, encoding, errors) is equal to
2084
// bytes.decode(encoding, errors)
2087
// Implicit invocation of __str__ uses method __str__ on the class,
2088
// even if arg has an attribute __str__
2089
var klass = arg.__class__ || $B.get_class(arg)
2090
if(klass === undefined){
2091
return $B.JSObject.__str__($B.JSObject.$factory(arg))
2092
}
2095
// if not better than object.__str__, try __repr__
2096
(arg.__class__ && arg.__class__ !== _b_.object &&
2097
method.$infos && method.$infos.__func__ === _b_.object.__str__)){
2098
var method = $B.$getattr(klass, "__repr__")
2104
if($B.debug > 1){console.log(err)}
2105
console.log("Warning - no method __str__ or __repr__, " +
2106
"default to toString", arg)
2113
if(cls === undefined){
2114
throw _b_.TypeError.$factory("str.__new__(): not enough arguments")
2138
var args = [],
2139
pos = 0
2140
if(arguments.length > 0){
2141
var args = [arguments[0].valueOf()],
2142
pos = 1
2143
for(var i = 1, len = arguments.length; i < len; i++){
2144
args[pos++] = arguments[i]
2160
// Function to parse the 2nd argument of format()
2161
$B.parse_format_spec = function(spec){
2164
var pos = 0,
2165
aligns = "<>=^",
2166
digits = "0123456789",
2167
types = "bcdeEfFgGnosxX%",
2169
if(align_pos != -1){
2170
if(spec.charAt(1) && aligns.indexOf(spec.charAt(1)) != -1){
2171
// If the second char is also an alignment specifier, the
2172
// first char is the fill value
2173
this.fill = spec.charAt(0)
2174
this.align = spec.charAt(1)
2175
pos = 2
2176
}else{
2177
// The first character defines alignment : fill defaults to ' '
2192
if(car == "+" || car == "-" || car == " "){
2193
this.sign = car
2194
pos++
2195
car = spec.charAt(pos)
2197
if(car == "#"){this.alternate = true; pos++; car = spec.charAt(pos)}
2198
if(car == "0"){
2207
while(car && digits.indexOf(car) > -1){
2208
if(this.width === undefined){this.width = car}
2209
else{this.width += car}
2210
pos++
2211
car = spec.charAt(pos)
2214
if(this.width === undefined && car == "{"){
2215
// Width is determined by a parameter
2216
var end_param_pos = spec.substr(pos).search("}")
2217
this.width = spec.substring(pos, end_param_pos)
2218
console.log("width", "[" + this.width + "]")
2219
pos += end_param_pos + 1
2220
}
2221
if(car == ","){this.comma = true; pos++; car = spec.charAt(pos)}
2222
if(car == "."){
2223
if(digits.indexOf(spec.charAt(pos + 1)) == -1){
2224
throw _b_.ValueError.$factory(
2225
"Missing precision in format spec")
2227
this.precision = spec.charAt(pos + 1)
2228
pos += 2
2229
car = spec.charAt(pos)
2230
while(car && digits.indexOf(car) > -1){
2237
if(car && types.indexOf(car) > -1){
2238
this.type = car
2239
pos++
2240
car = spec.charAt(pos)
2241
}
2242
if(pos !== spec.length){
2248
return (this.fill === undefined ? "" : _b_.str.$factory(this.fill)) +
2249
(this.align || "") +
2250
(this.sign || "") +
2251
(this.alternate ? "#" : "") +
2252
(this.sign_aware ? "0" : "") +
2253
(this.width || "") +
2254
(this.comma ? "," : "") +
2255
(this.precision ? "." + this.precision : "") +
2256
(this.type || "")
2261
if(fmt.width && s.length < fmt.width){
2262
var fill = fmt.fill || " ",
2263
align = fmt.align || "<",
2264
missing = fmt.width - s.length
2266
case "<":
2267
return s + fill.repeat(missing)
2268
case ">":
2269
return fill.repeat(missing) + s
2270
case "=":
2271
if("+-".indexOf(s.charAt(0)) > -1){
2272
return s.charAt(0) + fill.repeat(missing) + s.substr(1)
2276
case "^":
2277
var left = parseInt(missing / 2)
2278
return fill.repeat(left) + s + fill.repeat(missing - left)
2291
$B.parse_fstring = function(string){
2292
// Parse a f-string
2293
var elts = [],
2294
pos = 0,
2318
}else{
2319
throw Error(" f-string: single '}' is not allowed")
2320
}
2321
}else{
2343
current += car
2344
i += 2
2345
}else{
2346
throw Error(" f-string: single '}' is not allowed")
2347
}
2348
}else{
2349
current += car
2350
i++
2351
}
2352
}
2354
}else if(ctype == "debug"){
2355
// after the equal sign, whitespace are ignored and the only
2356
// valid characters are } and :
2357
while(string.charAt(i) == " "){i++}
2358
if(string.charAt(i) == "}"){
2359
// end of debug expression
2360
elts.push(current)
2361
ctype = null
2362
current = ""
2363
pos = i + 1
2364
}
2365
}else{
2366
// End of expression is the } matching the opening {
2367
// There may be nested braces
2368
var i = pos,
2369
nb_braces = 1,
2391
// backslash is not allowed in expressions
2392
throw Error("f-string expression part cannot include a" +
2393
" backslash")
2400
throw Error("f-string: invalid conversion character:" +
2401
" expected 's', 'r', or 'a'")
2402
}else{
2416
if(string.substr(i, 3) == '"""'){
2417
var end = string.indexOf('"""', i + 3)
2418
if(end == -1){
2419
throw Error("f-string: unterminated string")
2420
}else{
2421
var trs = string.substring(i, end + 3)
2422
trs = trs.replace("\n", "\\n\\")
2427
var end = string.indexOf('"', i + 1)
2428
if(end == -1){
2429
throw Error("f-string: unterminated string")
2430
}else{
2431
current.expression += string.substring(i, end + 1)
2432
i = end + 1
2439
}else if(car == "="){
2440
// might be a "debug expression", eg f"{x=}"
2441
var ce = current.expression
2442
if(ce.length == 0 ||
2443
string.charAt(i + 1) == "=" ||
2444
"=!<>:".search(ce.charAt(ce.length - 1)) > -1){
2447
}else{
2448
// add debug string
2449
tail = car
2450
while(string.charAt(i + 1).match(/\s/)){
2451
tail += string.charAt(i + 1)
2452
i++
2453
}
2454
elts.push(current.expression + tail)
2455
// remove trailing whitespace from expression
2456
while(ce.match(/\s$/)){
2457
ce = ce.substr(0, ce.length - 1)
2458
}
2459
current.expression = ce
2460
ctype = "debug"
2461
i++
2462
}
2477
// Class for strings with surrogate pairs. We can't rely on Javascript
2478
// strings in this case because they don't count characters like Python
2479
2480
var surrogate = str.$surrogate = $B.make_class("surrogate_string", function(s){
2481
// create an instance of str subclass for strings with surrogate pairs
2482
var items = []
2483
for(var i = 0, len = s.length; i < len; i++){
2484
var code = s.charCodeAt(i)
2485
if(code >= 0xD800 && code <= 0xDBFF){
2486
i++
2487
var low = s.charCodeAt(i)
2488
code = ((code - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000
2489
}
2490
items.push(String.fromCodePoint(code))
2491
}
2492
return {
2493
__class__: str.$surrogate,
2494
items: items
2495
}
2496
})
2497
2498
surrogate.__mro__ = [str, object]
2499
2500
surrogate.__contains__ = function(self, other){
2501
return str.__contains__(self.items.join(''), other)
2502
}
2503
2504
surrogate.__getitem__ = function(self, arg){
2505
if(isinstance(arg, _b_.int)){
2506
var pos = arg
2507
if(arg < 0){
2508
pos += self.items.length
2509
}
2510
if(pos >= 0 && pos < self.items.length){
2511
if(self.items[pos].length == 2){
2512
return surrogate.$factory(self.items[pos])
2513
}
2514
return self.items[pos]
2515
}
2516
throw _b_.IndexError.$factory("string index out of range")
2517
}
2518
if(isinstance(arg, slice)) {
2519
var s = _b_.slice.$conv_for_seq(arg, self.items.length),
2520
start = s.start,
2521
stop = s.stop,
2522
step = s.step
2523
var res = "",
2524
i = null
2525
if(step > 0){
2526
if(stop <= start){return ""}
2527
for(var i = start; i < stop; i += step){
2528
res += self.items[i]
2529
}
2530
}else{
2531
if(stop >= start){return ''}
2532
for(var i = start; i > stop; i += step){
2533
res += self.items[i]
2534
}
2535
}
2536
return res
2537
}
2538
if(isinstance(arg, _b_.bool)){
2539
return surrogate.__getitem__(self, _b_.int.$factory(arg))
2540
}
2541
throw _b_.TypeError.$factory("string indices must be integers")
2542
}
2543
2544
surrogate.__hash__ = function(self){
2545
return str.__hash__(self.items.join(''))
2546
}
2547
2548
surrogate.__iter__ = function(self){
2549
return str_iterator.$factory(self.items)
2550
}
2551
2552
surrogate.__len__ = function(self){
2553
return self.items.length
2554
}
2555
2556
surrogate.__repr__ = function(self){
2557
return str.__repr__(self.items.join(''))
2558
}
2559
2560
surrogate.__str__ = function(self){
2561
return str.__str__(self.items.join(''))
2562
}
2563
2564
$B.set_func_names(surrogate, "builtins")
2565
2566