Permalink
Mar 6, 2021
Mar 19, 2018
Mar 19, 2018
Apr 5, 2021
Mar 6, 2021
Mar 19, 2018
Mar 19, 2018
Apr 25, 2020
Mar 6, 2021
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 6, 2021
Mar 19, 2018
Mar 6, 2021
Mar 6, 2021
Mar 6, 2021
Mar 30, 2021
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 6, 2021
Mar 19, 2018
Mar 16, 2021
Mar 16, 2021
Mar 19, 2018
Mar 27, 2019
Mar 6, 2021
Mar 19, 2018
Mar 19, 2018
Mar 6, 2021
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 6, 2021
Mar 6, 2021
Mar 6, 2021
Mar 19, 2018
Apr 2, 2019
Apr 2, 2019
Mar 19, 2018
Aug 31, 2017
Mar 19, 2018
Mar 6, 2021
Mar 19, 2018
Mar 6, 2021
Aug 31, 2017
Apr 16, 2019
Mar 19, 2018
Apr 16, 2019
Mar 6, 2021
Mar 19, 2018
Mar 6, 2021
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Nov 12, 2018
Nov 22, 2020
Nov 12, 2018
Mar 19, 2018
Mar 19, 2018
Nov 22, 2020
Mar 6, 2021
Mar 6, 2021
Mar 6, 2021
Mar 6, 2021
Mar 6, 2021
Mar 6, 2021
Mar 6, 2021
Sep 27, 2020
Sep 27, 2020
Mar 6, 2021
Mar 6, 2021
Mar 6, 2021
Mar 19, 2018
Mar 6, 2021
Mar 19, 2018
Mar 6, 2021
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 6, 2021
Jun 11, 2020
Mar 19, 2018
Mar 19, 2018
Apr 5, 2021
Mar 19, 2018
Mar 6, 2021
Mar 6, 2021
Mar 19, 2018
Mar 19, 2018
Aug 31, 2017
May 24, 2019
Mar 19, 2018
Mar 6, 2021
Mar 6, 2021
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 6, 2021
Mar 19, 2018
Mar 6, 2021
Mar 6, 2021
Mar 6, 2021
Mar 19, 2018
Feb 27, 2020
Feb 27, 2020
Feb 27, 2020
Aug 31, 2017
Mar 19, 2018
Mar 6, 2021
Mar 19, 2018
Mar 6, 2021
Mar 6, 2021
Mar 6, 2021
Mar 6, 2021
Mar 6, 2021
Mar 6, 2021
Jan 26, 2020
Mar 6, 2021
Nov 15, 2019
Jul 28, 2018
Oct 27, 2019
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 6, 2021
Nov 12, 2018
Mar 6, 2021
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Dec 12, 2020
Jun 29, 2017
Oct 13, 2019
Jun 29, 2017
Dec 12, 2020
Jul 10, 2017
Jul 10, 2017
Mar 19, 2018
Mar 19, 2018
Jun 20, 2020
Nov 30, 2020
Oct 13, 2019
Jan 18, 2021
Jan 18, 2021
Newer
100644
2781 lines (2569 sloc)
84.5 KB
9
10
$B.has_surrogate = function(s){
11
// Check if there are "surrogate pairs" characters in string s
12
for(var i = 0; i < s.length; i++){
13
code = s.charCodeAt(i)
14
if(code >= 0xD800 && code <= 0xDBFF){
15
return true
16
}
17
}
18
return false
19
}
20
33
if($.start === null || $.start === _b_.None){$.start = 0}
34
else if($.start < 0){
35
$.start += $.self.length
36
$.start = Math.max(0, $.start)
37
}
38
if($.end === null || $.end === _b_.None){$.end = $.self.length}
39
else if($.end < 0){
40
$.end += $.self.length
41
$.end = Math.max(0, $.end)
42
}
44
if(! isinstance($.start, _b_.int) || ! isinstance($.end, _b_.int)){
45
throw _b_.TypeError.$factory("slice indices must be integers " +
46
"or None or have an __index__ method")
47
}
57
throw _b_.TypeError.$factory((prefix || '') +
58
"must be str, not " + $B.class_name(obj))
62
function to_chars(s){
63
// Transform Javascript string s into a list of Python characters
64
// (2 JS chars if surrogate, 1 otherwise)
65
var chars = []
66
for(var i = 0, len = s.length; i < len; i++){
67
var code = s.charCodeAt(i)
68
if(code >= 0xD800 && code <= 0xDBFF){
69
chars.push(s.substr(i, 2))
70
i++
71
}else{
72
chars.push(s.charAt(i))
73
}
74
}
75
return chars
76
}
77
78
function to_codepoints(s){
79
// Transform Javascript string s into a list of codepoints
80
var cps = []
81
for(var i = 0, len = s.length; i < len; i++){
82
var code = s.charCodeAt(i)
83
if(code >= 0xD800 && code <= 0xDBFF){
84
var v = 0x10000
85
v += (code & 0x03FF) << 10
86
v += (s.charCodeAt(i + 1) & 0x03FF)
87
cps.push(v)
88
i++
89
}else{
90
cps.push(code)
91
}
92
}
93
return cps
94
}
95
97
if(!(typeof other === "string")){
98
try{return getattr(other, "__radd__")(self)}
99
catch(err){
100
throw _b_.TypeError.$factory("Can't convert " +
108
throw _b_.TypeError.$factory("'in <string>' requires " +
109
"string as left operand, not " + item.__class__)
110
}
111
if(typeof item == "string"){
112
var nbcar = item.length
113
}else{
114
var nbcar = _b_.len(item)
115
}
116
if(nbcar == 0){
117
// a string contains the empty string
118
return true
119
}
120
if(self.length == 0){
121
return nbcar == 0
122
}
135
// __dir__must be assigned explicitely because attribute resolution for
136
// builtin classes doesn't use __mro__
148
if(fmt.type && fmt.type != "s"){
149
throw _b_.ValueError.$factory("Unknown format code '" + fmt.type +
157
if(fmt.sign !== undefined){
158
throw _b_.ValueError.$factory(
159
"Sign not allowed in string format specifier")
173
if(arg < 0){
174
pos += self.length
175
}
176
if(pos >= 0 && pos < chars.length){
177
return chars[pos]
178
}
182
var s = _b_.slice.$conv_for_seq(arg, self.length),
183
start = s.start,
184
stop = s.stop,
185
step = s.step
186
var res = "",
189
if(stop <= start){
190
return ""
191
}
192
for(var i = start; i < stop; i += step){
193
res += chars[i]
194
}
196
if(stop >= start){
197
return ''
198
}
199
for(var i = start; i > stop; i += step){
200
res += chars[i]
201
}
205
if(isinstance(arg, _b_.bool)){
206
return self.__getitem__(_b_.int.$factory(arg))
207
}
262
// found at
263
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/length
264
return [...self].length
301
// left adjusted
302
return s + get_char_array(padding - s.length, flags.pad_char)
303
}
304
}
305
313
if(val.__class__ === $B.long_int){
314
s = $B.long_int.to_base(val, 10)
315
}else{
316
s = val.toString()
318
if(s[0] === "-"){
319
return "-" + get_char_array(precision - s.length + 1, "0") + s.slice(1)
330
if(val === Infinity){
331
val = "inf"
332
}else if(val === -Infinity){
333
val = "-inf"
334
}else{
335
val = "nan"
357
var str_format = function(val, flags) {
358
// string format supports left and right padding
359
flags.pad_char = " " // even if 0 padding is defined, don't use it
365
if(val.__class__ === $B.long_int){
366
val = $B.long_int.to_base(val, 10)
367
}else{
368
val = parseInt(val)
386
var repr_format = function(val, flags) {
387
flags.pad_char = " " // even if 0 padding is defined, don't use it
388
return format_padding(repr(val), flags)
389
}
391
var ascii_format = function(val, flags) {
392
flags.pad_char = " " // even if 0 padding is defined, don't use it
393
return format_padding(ascii(val), flags)
394
}
406
flags.precision = parseInt(flags.precision, 10)
407
validate_precision(flags.precision)
408
}
409
return parseFloat(val)
410
}
413
var trailing_zeros = /(.*?)(0+)([eE].*)/,
414
leading_zeros = /\.(0*)/,
415
trailing_dot = /\.$/
417
var validate_precision = function(precision) {
418
// force precision to limits of javascript
423
var floating_point_format = function(val, upper, flags){
424
val = _float_helper(val, flags),
425
v = val.toString(),
426
v_len = v.length,
427
dot_idx = v.indexOf('.')
428
if(dot_idx < 0){dot_idx = v_len}
429
if(val < 1 && val > -1){
430
var zeros = leading_zeros.exec(v),
431
numzeros
432
if(zeros){
437
if(numzeros >= 4){
438
val = format_sign(val, flags) + format_float_precision(val, upper,
439
flags, _floating_g_exp_helper)
440
if(!flags.alternate){
453
return format_padding(format_sign(val, flags) +
454
format_float_precision(val, upper, flags,
455
function(val, precision) {
456
return val.toFixed(min(precision, v_len - dot_idx) +
457
numzeros)
458
}),
459
flags
460
)
461
}
462
463
if(dot_idx > flags.precision){
464
val = format_sign(val, flags) + format_float_precision(val, upper,
465
flags, _floating_g_exp_helper)
466
if(! flags.alternate){
478
return format_padding(format_sign(val, flags) +
479
format_float_precision(val, upper, flags,
480
function(val, precision) {
481
if(!flags.decimal_point){
482
precision = min(v_len - 1, 6)
483
}else if (precision > v_len){
484
if(! flags.alternate){
485
precision = v_len
486
}
488
if(precision < dot_idx){
489
precision = dot_idx
490
}
491
return val.toFixed(precision - dot_idx)
492
}),
493
flags
494
)
497
var _floating_g_exp_helper = function(val, precision, flags, upper){
498
if(precision){--precision}
501
var e_idx = val.lastIndexOf("e")
502
if(e_idx > val.length - 4){
503
val = val.substring(0, e_idx + 2) + "0" + val.substring(e_idx + 2)
506
return val
507
}
508
509
// fF
510
var floating_point_decimal_format = function(val, upper, flags) {
511
val = _float_helper(val, flags)
512
return format_padding(format_sign(val, flags) +
513
format_float_precision(val, upper, flags,
514
function(val, precision, flags) {
515
val = val.toFixed(precision)
516
if(precision === 0 && flags.alternate){
517
val += '.'
518
}
519
return val
520
}),
521
flags
522
)
523
}
524
525
var _floating_exp_helper = function(val, precision, flags, upper) {
526
val = val.toExponential(precision)
527
// pad exponent to two digits
540
return format_padding(format_sign(val, flags) +
541
format_float_precision(val, upper, flags, _floating_exp_helper), flags)
567
if(flags.alternate){
568
if(ret.charAt(0) === "-"){
569
if(upper){ret = "-0X" + ret.slice(1)}
570
else{ret = "-0x" + ret.slice(1)}
571
}else{
572
if(upper){ret = "0X" + ret}
573
else{ret = "0x" + ret}
583
if(val.__class__ === $B.long_int){
584
ret = $B.long_int.to_base(8)
585
}else{
586
ret = parseInt(val)
587
ret = ret.toString(8)
603
if(flags.alternate){
604
if(ret.charAt(0) === "-"){ret = "-0o" + ret.slice(1)}
605
else{ret = "0o" + ret}
610
function series_of_bytes(val, flags){
611
if(val.__class__ && val.__class__.$buffer_protocol){
612
var it = _b_.iter(val),
613
ints = []
614
while(true){
615
try{
616
ints.push(_b_.next(it))
617
}catch(err){
618
if(err.__class__ === _b_.StopIteration){
619
var b = _b_.bytes.$factory(ints)
620
return format_padding(_b_.bytes.decode(b, "ascii"), flags)
621
}
622
throw err
623
}
624
}
625
}else{
626
try{
627
bytes_obj = $B.$getattr(val, "__bytes__")
628
return format_padding(_b_.bytes.decode(bytes_obj), flags)
629
}catch(err){
630
if(err.__class__ === _b_.AttributeError){
631
throw _b_.TypeError.$factory("%b does not accept '" +
632
$B.class_name(val) + "'")
633
}
634
throw err
635
}
636
}
637
}
638
640
if(isinstance(val, str) && val.length == 1){
641
return val
642
}else if(isinstance(val, bytes) && val.source.length == 1){
643
val = val.source[0]
644
}else{
645
try{
646
val = _b_.int.$factory(val) // yes, floats are valid (they are cast to int)
647
}catch (err){
648
throw _b_.TypeError.$factory("%c requires int or char")
649
}
654
var num_flag = function(c, flags){
655
if(c === "0" && ! flags.padding && ! flags.decimal_point && ! flags.left){
656
flags.pad_char = "0"
662
flags.precision = (flags.precision || "") + c
663
}
664
}
665
666
var decimal_point_flag = function(val, flags) {
668
// can only have one decimal point
669
throw new UnsupportedChar()
670
}
671
flags.decimal_point = true
672
}
673
674
var neg_flag = function(val, flags){
675
flags.pad_char = " " // overrides '0' flag
693
"s": str_format,
694
"d": num_format,
695
"i": num_format,
696
"u": num_format,
697
"o": octal_format,
698
"r": repr_format,
699
"a": ascii_format,
700
"g": function(val, flags){
701
return floating_point_format(val, false, flags)
702
},
703
"G": function(val, flags){return floating_point_format(val, true, flags)},
704
"f": function(val, flags){
705
return floating_point_decimal_format(val, false, flags)
706
},
707
"F": function(val, flags){
708
return floating_point_decimal_format(val, true, flags)
709
},
710
"e": function(val, flags){
711
return floating_point_exponential_format(val, false, flags)
712
},
713
"E": function(val, flags){
714
return floating_point_exponential_format(val, true, flags)
715
},
716
"x": function(val, flags){return signed_hex_format(val, false, flags)},
717
"X": function(val, flags){return signed_hex_format(val, true, flags)},
718
"c": single_char_format,
719
"0": function(val, flags){return num_flag("0", flags)},
720
"1": function(val, flags){return num_flag("1", flags)},
721
"2": function(val, flags){return num_flag("2", flags)},
722
"3": function(val, flags){return num_flag("3", flags)},
723
"4": function(val, flags){return num_flag("4", flags)},
724
"5": function(val, flags){return num_flag("5", flags)},
725
"6": function(val, flags){return num_flag("6", flags)},
726
"7": function(val, flags){return num_flag("7", flags)},
727
"8": function(val, flags){return num_flag("8", flags)},
728
"9": function(val, flags){return num_flag("9", flags)},
729
"-": neg_flag,
730
" ": space_flag,
731
"+": sign_flag,
732
".": decimal_point_flag,
733
"#": alternate_flag
734
}
735
736
// exception thrown when an unsupported char is encountered in legacy format
782
if(self === undefined){
783
throw _b_.TypeError.$factory(
784
"not enough arguments for format string")
811
throw _b_.ValueError.$factory(
812
"unsupported format character '" + invalid_char +
813
"' (0x" + invalid_char.charCodeAt(0).toString(16) +
814
") at index " + newpos)
815
}else if(err.name === "NotANumber"){
816
var try_char = s[newpos],
817
cls = self.__class__
818
if(!cls){
819
if(typeof(self) === "string"){
820
cls = "str"
821
}else{
827
throw _b_.TypeError.$factory("%" + try_char +
828
" format: a number is required, not " + cls)
829
}else{
861
}while(pos < length)
862
863
if(argpos !== null){
864
if(args.length > argpos){
865
throw _b_.TypeError.$factory(
866
"not enough arguments for format string")
867
}else if(args.length < argpos){
868
throw _b_.TypeError.$factory(
869
"not all arguments converted during string formatting")
871
}else if(nbph == 0){
872
throw _b_.TypeError.$factory(
873
"not all arguments converted during string formatting")
881
var $ = $B.args("__mul__", 2, {self: null, other: null},
882
["self", "other"], arguments, {}, null, null)
883
if(! isinstance($.other, _b_.int)){throw _b_.TypeError.$factory(
884
"Can't multiply sequence by non-int of type '" +
895
var t = {
896
8: "\\x08",
897
9: "\\t",
898
10: "\\n",
899
11: "\\x0b",
900
12: "\\x0c",
901
13: "\\r",
902
92: "\\\\"
903
}
904
var repl = '',
905
chars = to_chars(self)
906
for(var i = 0; i < chars.length; i++){
907
var cp = _b_.ord(chars[i])
908
if(t[cp] !== undefined){
909
repl += t[cp]
910
}else if($B.is_unicode_cn(cp)){
929
if(res.search('"') == -1 && res.search("'") == -1){
930
return "'" + res + "'"
931
}else if(self.search('"') == -1){
932
return '"' + res + '"'
933
}
934
var qesc = new RegExp("'", "g") // to escape single quote
935
res = "'" + res.replace(qesc, "\\'") + "'"
939
str.__setattr__ = function(self, attr, value){
940
if(typeof self === "string"){
941
if(str.hasOwnProperty(attr)){
943
attr + "' is read-only")
944
}else{
945
throw _b_.AttributeError.$factory(
946
"'str' object has no attribute '" + attr + "'")
947
}
948
}
949
// str subclass : use __dict__
950
_b_.dict.$setitem(self.__dict__, attr, value)
951
return $N
952
}
953
954
str.__setitem__ = function(self, attr, value){
955
throw _b_.TypeError.$factory(
956
"'str' object does not support item assignment")
959
var combining = []
960
for(var cp = 0x300; cp <= 0x36F; cp++){
961
combining.push(String.fromCharCode(cp))
962
}
966
var repl = '',
967
chars = to_chars(self)
968
if(chars.length == self.length){
969
return self.replace(combining_re, "\u200B$1")
970
}
971
for(var i = 0; i < chars.length; i++){
972
var cp = _b_.ord(chars[i])
973
if(cp >= 0x300 && cp <= 0x36F){
974
repl += "\u200B" + chars[i]
975
}else{
976
repl += chars[i]
977
}
978
}
979
return repl
989
$comp_func += "" // source code
990
var $comps = {">": "gt", ">=": "ge", "<": "lt", "<=": "le"}
999
var $notimplemented = function(self, other){
1000
throw NotImplementedError.$factory(
1001
"OPERATOR not implemented for class str")
1004
str.capitalize = function(self){
1005
var $ = $B.args("capitalize", 1, {self}, ["self"],
1006
arguments, {}, null, null)
1010
return self.charAt(0).toUpperCase() + self.substr(1)
1011
}
1012
1013
str.casefold = function(self){
1014
var $ = $B.args("casefold", 1, {self}, ["self"],
1015
arguments, {}, null, null),
1016
res = "",
1017
char,
1018
cf,
1019
chars = to_chars($.self)
1020
1021
for(var i = 0, len = chars.length; i < len; i++){
1022
char = chars[i]
1023
cf = $B.unicode_casefold[char]
1024
if(cf){
1025
cf.forEach(function(cp){
1026
res += String.fromCharCode(cp)
1027
})
1028
}else{
1035
str.center = function(){
1036
var $ = $B.args("center", 3, {self: null, width: null, fillchar: null},
1037
["self", "width", "fillchar"],
1038
arguments, {fillchar:" "}, null, null),
1039
self = $.self
1043
var pad = parseInt(($.width - self.length) / 2),
1044
res = $.fillchar.repeat(pad)
1053
var $ = $B.args("count", 4, {self:null, sub:null, start:null, stop:null},
1054
["self", "sub", "start", "stop"], arguments, {start:null, stop:null},
1056
if(!(typeof $.sub == "string")){
1057
throw _b_.TypeError.$factory("Can't convert '" + $B.class_name($.sub) +
1058
"' object to str implicitly")
1059
}
1063
if($.stop !== null){
1064
_slice = _b_.slice.$factory($.start, $.stop)
1065
}else{
1066
_slice = _b_.slice.$factory($.start, $.self.length)
1067
}
1075
if($.start == $.self.length){
1076
return 1
1077
}else if(substr.length == 0){
1078
return 0
1079
}
1082
var n = 0,
1083
pos = 0
1084
while(pos < substr.length){
1085
pos = substr.indexOf($.sub, pos)
1096
str.encode = function(){
1097
var $ = $B.args("encode", 3, {self: null, encoding: null, errors: null},
1098
["self", "encoding", "errors"], arguments,
1099
{encoding: "utf-8", errors: "strict"}, null, null)
1100
if($.encoding == "rot13" || $.encoding == "rot_13"){
1103
for(var i = 0, len = $.self.length; i < len ; i++){
1104
var char = $.self.charAt(i)
1105
if(("a" <= char && char <= "m") || ("A" <= char && char <= "M")){
1106
res += String.fromCharCode(String.charCodeAt(char) + 13)
1107
}else if(("m" < char && char <= "z") ||
1108
("M" < char && char <= "Z")){
1109
res += String.fromCharCode(String.charCodeAt(char) - 13)
1118
// Return True if the string ends with the specified suffix, otherwise
1119
// return False. suffix can also be a tuple of suffixes to look for.
1120
// With optional start, test beginning at that position. With optional
1124
["self", "suffix", "start", "end"],
1125
arguments, {start: 0, end: null}, null, null)
1138
if(! _b_.isinstance(suffix, str)){
1139
throw _b_.TypeError.$factory(
1140
"endswith first arg must be str or a tuple of str, not int")
1141
}
1151
var $ = $B.args("expandtabs", 2, {self: null, tabsize: null},
1152
["self", "tabsize"], arguments, {tabsize: 8}, null, null)
1153
var s = $B.$GetInt($.tabsize),
1154
col = 0,
1155
pos = 0,
1156
res = "",
1157
chars = to_chars(self)
1158
if(s == 1){
1159
return self.replace(/\t/g," ")
1160
}
1161
while(pos < chars.length){
1162
var car = chars[pos]
1172
res += car
1173
col = 0
1174
break
1175
default:
1176
res += car
1177
col++
1178
break
1179
}
1180
pos++
1181
}
1182
return res
1186
// Return the lowest index in the string where substring sub is found,
1187
// such that sub is contained in the slice s[start:end]. Optional
1188
// arguments start and end are interpreted as in slice notation.
1191
{self: null, sub: null, start: null, end: null},
1192
["self", "sub", "start", "end"],
1193
arguments, {start: 0, end: null}, null, null)
1197
if(!isinstance($.start, _b_.int)||!isinstance($.end, _b_.int)){
1198
throw _b_.TypeError.$factory("slice indices must be " +
1199
"integers or None or have an __index__ method")}
1200
// Can't use string.substring(start, end) because if end < start,
1201
// Javascript transforms it into substring(end, start)...
1202
var s = ""
1203
for(var i = $.start; i < $.end; i++){
1204
s += $.self.charAt(i)
1205
}
1207
var len = str.__len__($.self)
1208
1209
if($.sub.length == 0 && $.start == len){
1210
return len
1211
}
1212
if(s.length + $.sub.length == 0){
1213
return -1
1214
}
1216
var last_search = s.length - $.sub.length
1217
for(var i = 0; i <= last_search; i++){
1218
if(s.substr(i, $.sub.length) == $.sub){
1219
return $.start + str.__len__(s.substr(0, i))
1220
}
1231
// a.x[z]!r:...
1232
// the object has attributes :
1233
// - name : "a"
1234
// - name_ext : [".x", "[z]"]
1235
// - conv : r
1236
// - spec : rest of string after :
1244
// No : in the string : it only contains a name
1245
name = fmt_string
1246
}else{
1247
// name is before the first ":"
1248
// spec (the format specification) is after
1249
name = elts[0]
1253
var elts = name.split("!")
1254
if(elts.length > 1){
1255
name = elts[0]
1256
conv = elts[1] // conversion flag
1260
// "name' may be a subscription or attribute
1261
// Put these "extensions" in the list "name_ext"
1262
function name_repl(match){
1263
name_ext.push(match)
1265
}
1266
var name_ext_re = /\.[_a-zA-Z][_a-zA-Z0-9]*|\[[_a-zA-Z][_a-zA-Z0-9]*\]|\[[0-9]+\]/g
1267
name = name.replace(name_ext_re, name_repl)
1268
}
1275
// Parse self to detect formatting instructions
1276
// Create a list "parts" made of sections of the string :
1277
// - elements of even rank are literal text
1278
// - elements of odd rank are "format objects", built from the
1279
// format strings in self (of the form {...})
1290
text += "{"
1291
pos += 2
1292
}else if(car == "}" && self.charAt(pos + 1) == "}"){
1299
// Store current literal text
1300
parts.push(text)
1301
1302
// Search the end of the format string, ie the } closing the
1303
// opening {. Since the string can contain other pairs {} for
1304
// nested formatting, an integer nb is incremented for each { and
1305
// decremented for each } ; the end of the format string is
1306
// reached when nb == 0
1307
var end = pos + 1,
1308
nb = 1
1309
while(end < _len){
1310
if(self.charAt(end) == "{"){nb++; end++}
1311
else if(self.charAt(end) == "}"){
1312
nb--; end++
1313
if(nb == 0){
1318
var fmt_obj = $B.parse_format(fmt_string)
1319
fmt_obj.raw_name = fmt_obj.name
1320
fmt_obj.raw_spec = fmt_obj.spec
1359
// Special management of keyword arguments if str.format is called by
1360
// str.format_map(mapping) : the argument "mapping" might not be a
1361
// dictionary
1362
var last_arg = $B.last(arguments)
1363
if(last_arg.$nat == "mapping"){
1364
var mapping = last_arg.mapping,
1365
getitem = $B.$getattr(mapping, "__getitem__")
1366
// Get the rest of the arguments
1367
var args = []
1368
for(var i = 0, len = arguments.length - 1; i < len; i++){
1369
args.push(arguments[i])
1370
}
1371
var $ = $B.args("format", 1, {self: null}, ["self"],
1372
args, {}, "$args", null)
1373
}else{
1374
var $ = $B.args("format", 1, {self: null}, ["self"],
1375
arguments, {}, "$args", "$kw"),
1376
mapping = $.$kw, // dictionary
1377
getitem = function(key){
1378
return _b_.dict.$getitem(mapping, key)
1379
}
1380
}
1393
1394
if(fmt.spec !== undefined){
1395
// "spec" may contain "nested replacement fields"
1396
// In this case, evaluate them using the positional
1397
// or keyword arguments passed to format()
1398
function replace_nested(name, key){
1399
if(/\d+/.exec(key)){
1400
// If key is numeric, search in positional
1401
// arguments
1402
return _b_.tuple.__getitem__($.$args,
1403
parseInt(key))
1404
}else{
1405
// Else try in keyword arguments
1406
return _b_.dict.__getitem__($.$kw, key)
1407
}
1408
}
1409
fmt.spec = fmt.spec.replace(/\{(.*?)\}/g,
1410
replace_nested)
1411
}
1413
// Numerical reference : use positional arguments
1414
var pos = parseInt(fmt.name),
1424
// Attribute
1425
value = _b_.getattr(value, ext.substr(1))
1426
}else{
1427
// Subscription
1430
if(key.charAt(0).search(/\d/) > -1){key = parseInt(key)}
1431
value = _b_.getattr(value, "__getitem__")(key)
1435
// If the conversion flag is set, first call a function to convert
1436
// the value
1437
if(fmt.conv == "a"){value = _b_.ascii(value)}
1438
else if(fmt.conv == "r"){value = _b_.repr(value)}
1439
else if(fmt.conv == "s"){value = _b_.str.$factory(value)}
1452
str.format_map = function(self, mapping){
1453
var $ = $B.args("format_map", 2, {self: null, mapping: null},
1454
['self', 'mapping'], arguments, {}, null, null)
1455
return str.format(self, {$nat: 'mapping', mapping})
1468
/* Return true if the string is empty or all characters in the string are
1469
ASCII, false otherwise. ASCII characters have code points in the range
1470
U+0000-U+007F. */
1479
str.isalnum = function(self){
1480
/* Return true if all characters in the string are alphanumeric and there
1481
is at least one character, false otherwise. A character c is alphanumeric
1482
if one of the following returns True: c.isalpha(), c.isdecimal(),
1483
c.isdigit(), or c.isnumeric(). */
1484
var $ = $B.args("isalnum", 1, {self: null}, ["self"],
1485
arguments, {}, null, null),
1486
cp
1487
for(var char of to_chars(self)){
1488
cp = _b_.ord(char)
1489
if(unicode_tables.Ll[cp] ||
1490
unicode_tables.Lu[cp] ||
1491
unicode_tables.Lm[cp] ||
1492
unicode_tables.Lt[cp] ||
1493
unicode_tables.Lo[cp] ||
1494
unicode_tables.Nd[cp] ||
1495
unicode_tables.digits[cp] ||
1496
unicode_tables.numeric[cp]){
1497
continue
1498
}
1499
return false
1500
}
1501
return true
1502
}
1503
1504
str.isalpha = function(self){
1505
/* Return true if all characters in the string are alphabetic and there is
1506
at least one character, false otherwise. Alphabetic characters are those
1507
characters defined in the Unicode character database as "Letter", i.e.,
1508
those with general category property being one of "Lm", "Lt", "Lu", "Ll",
1509
or "Lo". */
1510
var $ = $B.args("isalpha", 1, {self: null}, ["self"],
1511
arguments, {}, null, null),
1512
cp
1513
for(var char of to_chars(self)){
1514
cp = _b_.ord(char)
1515
if(unicode_tables.Ll[cp] ||
1516
unicode_tables.Lu[cp] ||
1517
unicode_tables.Lm[cp] ||
1518
unicode_tables.Lt[cp] ||
1519
unicode_tables.Lo[cp]){
1520
continue
1521
}
1522
return false
1523
}
1524
return true
1525
}
1526
1527
str.isdecimal = function(self){
1528
/* Return true if all characters in the string are decimal characters and
1529
there is at least one character, false otherwise. Decimal characters are
1530
those that can be used to form numbers in base 10, e.g. U+0660,
1531
ARABIC-INDIC DIGIT ZERO. Formally a decimal character is a character in
1532
the Unicode General Category "Nd". */
1533
var $ = $B.args("isdecimal", 1, {self: null}, ["self"],
1534
arguments, {}, null, null),
1535
cp
1536
for(var char of to_chars(self)){
1537
cp = _b_.ord(char)
1538
if(! unicode_tables.Nd[cp]){
1539
return false
1540
}
1541
}
1542
return self.length > 0
1543
}
1544
1545
str.isdigit = function(self){
1546
/* Return true if all characters in the string are digits and there is at
1547
least one character, false otherwise. */
1548
var $ = $B.args("isdigit", 1, {self: null}, ["self"],
1549
arguments, {}, null, null),
1550
cp
1551
for(var char of to_chars(self)){
1552
cp = _b_.ord(char)
1553
if(! unicode_tables.digits[cp]){
1554
return false
1555
}
1556
}
1557
return self.length > 0
1558
}
1559
1560
str.isidentifier = function(self){
1561
/* Return true if the string is a valid identifier according to the
1562
language definition. */
1563
var $ = $B.args("isidentifier", 1, {self: null}, ["self"],
1567
}
1568
var chars = to_chars(self)
1569
if(unicode_tables.XID_Start[_b_.ord(chars[0])] === undefined){
1572
for(var char of chars){
1573
var cp = _b_.ord(char)
1574
if(unicode_tables.XID_Continue[cp] === undefined){
1575
return false
1576
}
1577
}
1578
}
1579
return true
1580
}
1581
1582
str.islower = function(self){
1583
/* Return true if all cased characters 4 in the string are lowercase and
1584
there is at least one cased character, false otherwise. */
1585
var $ = $B.args("islower", 1, {self: null}, ["self"],
1586
arguments, {}, null, null),
1587
has_cased = false,
1590
for(var char of to_chars(self)){
1591
cp = _b_.ord(char)
1592
if(unicode_tables.Ll[cp]){
1593
has_cased = true
1594
continue
1595
}else if(unicode_tables.Lu[cp] || unicode_tables.Lt[cp]){
1596
return false
1597
}
1598
}
1599
return has_cased
1600
}
1601
1602
str.isnumeric = function(self){
1603
/* Return true if all characters in the string are numeric characters, and
1604
there is at least one character, false otherwise. Numeric characters
1605
include digit characters, and all characters that have the Unicode numeric
1606
value property, e.g. U+2155, VULGAR FRACTION ONE FIFTH. Formally, numeric
1607
characters are those with the property value Numeric_Type=Digit,
1608
Numeric_Type=Decimal or Numeric_Type=Numeric.*/
1609
var $ = $B.args("isnumeric", 1, {self: null}, ["self"],
1610
arguments, {}, null, null)
1619
var unprintable = {},
1620
unprintable_gc = ['Cc', 'Cf', 'Co', 'Cs','Zl', 'Zp', 'Zs']
1621
1622
str.isprintable = function(self){
1623
/* Return true if all characters in the string are printable or the string
1624
is empty, false otherwise. Nonprintable characters are those characters
1625
defined in the Unicode character database as "Other" or "Separator",
1626
excepting the ASCII space (0x20) which is considered printable. */
1627
1628
// Set unprintable if not set yet
1629
if(Object.keys(unprintable).length == 0){
1630
for(var i = 0; i < unprintable_gc.length; i++){
1631
var table = unicode_tables[unprintable_gc[i]]
1642
return false
1643
}
1644
}
1645
return true
1646
}
1647
1648
str.isspace = function(self){
1649
/* Return true if there are only whitespace characters in the string and
1650
there is at least one character, false otherwise.
1651
1652
A character is whitespace if in the Unicode character database, either its
1653
general category is Zs ("Separator, space"), or its bidirectional class is
1654
one of WS, B, or S.*/
1655
var $ = $B.args("isspace", 1, {self: null}, ["self"],
1656
arguments, {}, null, null),
1657
cp
1658
for(var char of to_chars(self)){
1659
cp = _b_.ord(char)
1660
if(! unicode_tables.Zs[cp] &&
1661
$B.unicode_bidi_whitespace.indexOf(cp) == -1){
1662
return false
1663
}
1664
}
1665
return self.length > 0
1666
}
1667
1668
str.istitle = function(self){
1669
/* Return true if the string is a titlecased string and there is at least
1670
one character, for example uppercase characters may only follow uncased
1671
characters and lowercase characters only cased ones. Return false
1672
otherwise. */
1673
var $ = $B.args("istitle", 1, {self: null}, ["self"],
1674
arguments, {}, null, null)
1675
return self.length > 0 && str.title(self) == self
1676
}
1677
1678
str.isupper = function(self){
1679
/* Return true if all cased characters 4 in the string are lowercase and
1680
there is at least one cased character, false otherwise. */
1681
var $ = $B.args("islower", 1, {self: null}, ["self"],
1682
arguments, {}, null, null),
1686
for(var char of to_chars(self)){
1687
cp = _b_.ord(char)
1688
if(unicode_tables.Lu[cp]){
1689
is_upper = true
1690
continue
1691
}else if(unicode_tables.Ll[cp] || unicode_tables.Lt[cp]){
1709
if(! isinstance(obj2, str)){
1710
throw _b_.TypeError.$factory("sequence item " + count +
1711
": expected str instance, " + $B.class_name(obj2) +
1712
" found")
1713
}
1726
var $ = $B.args("ljust", 3, {self: null, width: null, fillchar:null},
1727
["self", "width", "fillchar"],
1731
if($.width <= len){
1732
return self
1733
}
1734
return self + $.fillchar.repeat($.width - len)
1737
str.lower = function(self){
1738
var $ = $B.args("lower", 1, {self: null}, ["self"],
1739
arguments, {}, null, null)
1740
return self.toLowerCase()
1741
}
1742
1744
var $ = $B.args("lstrip", 2, {self: null, chars: null}, ["self", "chars"],
1745
arguments, {chars:_b_.None}, null, null)
1746
if($.chars === _b_.None){
1747
return $.self.trimLeft()
1748
}
1749
var chars = to_chars(self)
1750
for(var i = 0, len = chars.length; i < len; i++){
1751
if($.chars.indexOf(chars[i]) === -1){
1752
return chars.slice(i).join('')
1760
var $ = $B.args("maketrans", 3, {x: null, y: null, z: null},
1761
["x", "y", "z"], arguments, {y: null, z: null}, null, null)
1766
// If there is only one argument, it must be a dictionary mapping
1767
// Unicode ordinals (integers) or characters (strings of length 1) to
1768
// Unicode ordinals, strings (of arbitrary lengths) or None. Character
1770
if(! _b_.isinstance($.x, _b_.dict)){
1771
throw _b_.TypeError.$factory(
1772
"maketrans only argument must be a dict")
1775
for(var i = 0, len = items.length; i < len; i++){
1776
var k = items[i][0],
1777
v = items[i][1]
1778
if(! _b_.isinstance(k, _b_.int)){
1779
if(_b_.isinstance(k, _b_.str) && k.length == 1){
1780
k = _b_.ord(k)
1781
}else{throw _b_.TypeError.$factory("dictionary key " + k +
1784
if(v !== _b_.None && ! _b_.isinstance(v, [_b_.int, _b_.str])){
1785
throw _b_.TypeError.$factory("dictionary value " + v +
1793
// and in the resulting dictionary, each character in x will be mapped
1794
// to the character at the same position in y
1797
}else if($.x.length !== $.y.length){
1798
throw _b_.TypeError.$factory(
1799
"maketrans arguments must be strings or same length")
1805
if(! _b_.isinstance($.z, _b_.str)){
1806
throw _b_.TypeError.$factory(
1807
"maketrans third argument must be a string")
1829
var $ = $B.args("partition", 2, {self: null, sep: null}, ["self", "sep"],
1830
arguments, {}, null, null)
1837
if(i == -1){
1838
return _b_.tuple.$factory([$.self, "", ""])
1839
}
1840
return _b_.tuple.$factory([chars.slice(0, i).join(''), $.sep,
1841
chars.slice(i + $.sep.length).join('')])
1844
str.removeprefix = function(){
1845
var $ = $B.args("removeprefix", 2, {self: null, prefix: null},
1846
["self", "prefix"], arguments, {}, null, null)
1847
if(!_b_.isinstance($.prefix, str)){
1848
throw _b_.ValueError.$factory("prefix should be str, not " +
1849
`'${$B.class_name($.prefix)}'`)
1850
}
1851
if(str.startswith($.self, $.prefix)){
1852
return $.self.substr($.prefix.length)
1853
}
1854
return $.self.substr(0)
1855
}
1856
1857
str.removesuffix = function(){
1858
var $ = $B.args("removesuffix", 2, {self: null, prefix: null},
1859
["self", "suffix"], arguments, {}, null, null)
1860
if(!_b_.isinstance($.suffix, str)){
1861
throw _b_.ValueError.$factory("suffix should be str, not " +
1862
`'${$B.class_name($.prefix)}'`)
1863
}
1864
if($.suffix.length > 0 && str.endswith($.self, $.suffix)){
1865
return $.self.substr(0, $.self.length - $.suffix.length)
1866
}
1867
return $.self.substr(0)
1868
}
1869
1870
function $re_escape(str){
1871
var specials = "[.*+?|()$^"
1872
for(var i = 0, len = specials.length; i < len; i++){
1873
var re = new RegExp("\\"+specials.charAt(i), "g")
1874
str = str.replace(re, "\\"+specials.charAt(i))
1875
}
1876
return str
1883
var $ = $B.args("replace", 4,
1884
{self: null, old: null, $$new: null, count: null},
1885
["self", "old", "$$new", "count"],
1886
arguments, {count: -1}, null, null),
1887
count = $.count,
1888
self = $.self,
1889
old = $.old,
1890
_new = $.$$new
1892
check_str(old, "replace() argument 1 ")
1893
check_str(_new, "replace() argument 2 ")
1897
"' object cannot be interpreted as an integer")
1898
}else if(isinstance(count, _b_.float)){
1899
throw _b_.TypeError.$factory("integer argument expected, got float")
1900
}
1901
if(count == 0){
1902
return self
1903
}
1904
if(count.__class__ == $B.long_int){
1905
count = parseInt(count.value)
1906
}
1908
if(_new == ""){
1909
return self
1910
}
1911
if(self == ""){
1912
return _new
1913
}
1914
var elts = self.split("")
1915
if(count > -1 && elts.length >= count){
1916
var rest = elts.slice(count).join("")
1917
return _new + elts.slice(0, count).join(_new) + rest
1943
res = res.substr(0, pos) + _new + res.substr(pos + old.length)
1944
pos = pos + _new.length
1945
count--
1951
// Return the highest index in the string where substring sub is found,
1952
// such that sub is contained within s[start:end]. Optional arguments
1954
if(arguments.length == 2 && typeof substr == "string"){
1955
return self.lastIndexOf(substr)
1956
}
1958
{self: null, sub: null, start: null, end: null},
1959
["self", "sub", "start", "end"],
1960
arguments, {start: 0, end: null}, null, null)
1967
if($.start > $.self.length){
1968
return -1
1969
}else{
1970
return str.__len__($.self)
1971
}
1977
if($.self.substr(i, sublen) == $.sub){
1978
return str.__len__($.self.substr(0, i))
1979
}
1994
var $ = $B.args("rjust",3,
1995
{self: null, width: null, fillchar: null},
1996
["self", "width", "fillchar"],
1997
arguments, {fillchar: " "}, null, null)
2007
var $ = $B.args("rpartition", 2, {self: null, sep: null}, ["self", "sep"],
2008
arguments, {}, null, null)
2012
var items = str.partition(self, sep).reverse()
2013
for(var i = 0; i < items.length; i++){
2014
items[i] = items[i].split("").reverse().join("")
2020
var $ = $B.args("rsplit", 3, {self: null, sep: null, maxsplit: null},
2021
["self", "sep", "maxsplit"], arguments,
2022
{sep: _b_.None, maxsplit: -1}, null, null),
2023
sep = $.sep
2026
var rev_str = reverse($.self),
2027
rev_sep = sep === _b_.None ? sep : reverse($.sep),
2038
str.rstrip = function(self, x){
2039
var $ = $B.args("rstrip", 2, {self: null, chars: null}, ["self", "chars"],
2041
if($.chars === _b_.None){
2042
return $.self.trimRight()
2043
}
2044
var chars = to_chars(self)
2045
for(var j = chars.length - 1; j >= 0; j--){
2046
if($.chars.indexOf(chars[j]) == -1){
2047
return chars.slice(0, j + 1).join('')
2054
var $ = $B.args("split", 3, {self: null, sep: null, maxsplit: null},
2055
["self", "sep", "maxsplit"], arguments,
2056
{sep: _b_.None, maxsplit: -1}, null, null),
2057
sep = $.sep,
2058
maxsplit = $.maxsplit,
2059
self = $.self,
2060
pos = 0
2061
if(maxsplit.__class__ === $B.long_int){
2062
maxsplit = parseInt(maxsplit.value)
2063
}
2064
if(sep == ""){
2065
throw _b_.ValueError.$factory("empty separator")
2066
}
2069
while(pos < self.length && self.charAt(pos).search(/\s/) > -1){
2070
pos++
2071
}
2072
if(pos === self.length - 1){
2073
return [self]
2074
}
2078
if(name == ""){
2079
name = self.charAt(pos)
2080
}else{
2081
name += self.charAt(pos)
2082
}
2104
var res = [],
2105
s = "",
2106
seplen = sep.length
2107
if(maxsplit == 0){return [self]}
2108
while(pos < self.length){
2109
if(self.substr(pos, seplen) == sep){
2127
str.splitlines = function(self) {
2128
var $ = $B.args('splitlines', 2, {self: null, keepends: null},
2129
['self','keepends'], arguments, {keepends: false},
2130
null, null)
2131
if(!_b_.isinstance($.keepends,[_b_.bool, _b_.int])){
2132
throw _b_.TypeError('integer argument expected, got '+
2135
var keepends = _b_.int.$factory($.keepends),
2136
res = [],
2137
self = $.self,
2138
start = 0,
2139
pos = 0
2140
if(!self.length){
2144
if(self.substr(pos, 2) == '\r\n'){
2145
res.push(self.slice(start, keepends ? pos + 2 : pos))
2146
start = pos = pos+2
2147
}else if(self[pos] == '\r' || self[pos] == '\n'){
2148
res.push(self.slice(start, keepends ? pos+1 : pos))
2149
start = pos = pos+1
2150
}else{
2151
pos++
2152
}
2153
}
2154
if(start < self.length){
2155
res.push(self.slice(start))
2156
}
2157
return res
2161
// Return True if string starts with the prefix, otherwise return False.
2162
// prefix can also be a tuple of prefixes to look for. With optional
2163
// start, test string beginning at that position. With optional end,
2165
var $ = $B.args("startswith", 4,
2166
{self: null, prefix: null, start: null, end: null},
2167
["self", "prefix", "start", "end"],
2168
arguments, {start: 0, end: null}, null, null)
2180
if(! _b_.isinstance(prefix, str)){
2181
throw _b_.TypeError.$factory("endswith first arg must be str " +
2182
"or a tuple of str, not int")
2183
}
2184
if(s.substr(0, prefix.length) == prefix){
2185
return true
2186
}
2192
var $ = $B.args("strip", 2, {self: null, chars: null}, ["self", "chars"],
2193
arguments, {chars: _b_.None}, null, null)
2194
if($.chars === _b_.None){
2195
return $.self.trim()
2196
}
2197
var chars = to_chars($.self)
2198
for(var i = 0; i < chars.length; i++){
2199
if($.chars.indexOf(chars[i]) == -1){
2203
for(var j = chars.length - 1; j >= i; j--){
2204
if($.chars.indexOf(chars[j]) == -1){
2211
str.swapcase = function(self){
2212
var $ = $B.args("swapcase", 1, {self}, ["self"],
2213
arguments, {}, null, null),
2214
res = "",
2215
cp
2216
2217
for(var char of to_chars(self)){
2218
cp = _b_.ord(char)
2219
if(unicode_tables.Ll[cp]){
2220
res += char.toUpperCase()
2221
}else if(unicode_tables.Lu[cp]){
2222
res += char.toLowerCase()
2225
}
2226
}
2227
return res
2228
}
2229
2230
str.title = function(self){
2231
var $ = $B.args("title", 1, {self}, ["self"],
2232
arguments, {}, null, null),
2233
state,
2236
for(var char of to_chars(self)){
2237
cp = _b_.ord(char)
2238
if(unicode_tables.Ll[cp]){
2245
}else if(unicode_tables.Lu[cp] || unicode_tables.Lt[cp]){
2246
res += state ? char.toLowerCase() : char
2258
getitem = $B.$getattr(table, "__getitem__"),
2259
cp
2260
for(var char of to_chars(self)){
2261
cp = _b_.ord(char)
2265
if(typeof repl == "string"){
2266
res.push(repl)
2267
}else if(typeof repl == "number"){
2268
res.push(String.fromCharCode(repl))
2269
}
2278
str.upper = function(self){
2279
var $ = $B.args("upper", 1, {self: null}, ["self"],
2280
arguments, {}, null, null)
2281
return self.toUpperCase()
2282
}
2283
2286
["self", "width"], arguments, {}, null, null),
2287
len = str.__len__(self)
2288
if($.width <= len){
2289
return self
2290
}
2310
if(encoding !== undefined){
2311
// Arguments may be passed as keywords (cf. issue #1060)
2312
var $ = $B.args("str", 3, {arg: null, encoding: null, errors: null},
2313
["arg", "encoding", "errors"], arguments,
2314
{encoding: "utf-8", errors: "strict"}, null, null),
2315
encoding = $.encoding,
2316
errors = $.errors
2317
}
2328
// class or its subclasses, but the attribute __str__ of the
2329
// class metaclass (usually "type") or its subclasses (usually
2330
// "object")
2331
// The metaclass is the attribute __class__ of the class dictionary
2336
if(arg.__class__ && arg.__class__ === _b_.bytes &&
2337
encoding !== undefined){
2338
// str(bytes, encoding, errors) is equal to
2339
// bytes.decode(encoding, errors)
2342
// Implicit invocation of __str__ uses method __str__ on the class,
2343
// even if arg has an attribute __str__
2344
var klass = arg.__class__ || $B.get_class(arg)
2350
// if not better than object.__str__, try __repr__
2351
(arg.__class__ && arg.__class__ !== _b_.object &&
2352
method.$infos && method.$infos.__func__ === _b_.object.__str__)){
2353
var method = $B.$getattr(klass, "__repr__")
2359
if($B.debug > 1){console.log(err)}
2360
console.log("Warning - no method __str__ or __repr__, " +
2361
"default to toString", arg)
2368
if(cls === undefined){
2369
throw _b_.TypeError.$factory("str.__new__(): not enough arguments")
2393
var args = [],
2394
pos = 0
2395
if(arguments.length > 0){
2396
var args = [arguments[0].valueOf()],
2397
pos = 1
2398
for(var i = 1, len = arguments.length; i < len; i++){
2399
args[pos++] = arguments[i]
2416
// Function to parse the 2nd argument of format()
2417
$B.parse_format_spec = function(spec){
2421
var pos = 0,
2422
aligns = "<>=^",
2423
digits = "0123456789",
2424
types = "bcdeEfFgGnosxX%",
2426
if(align_pos != -1){
2427
if(spec.charAt(1) && aligns.indexOf(spec.charAt(1)) != -1){
2428
// If the second char is also an alignment specifier, the
2429
// first char is the fill value
2430
this.fill = spec.charAt(0)
2431
this.align = spec.charAt(1)
2432
pos = 2
2433
}else{
2434
// The first character defines alignment : fill defaults to ' '
2449
if(car == "+" || car == "-" || car == " "){
2450
this.sign = car
2451
pos++
2452
car = spec.charAt(pos)
2467
if(this.width === undefined){
2468
this.width = car
2469
}else{
2470
this.width += car
2471
}
2478
if(this.width === undefined && car == "{"){
2479
// Width is determined by a parameter
2480
var end_param_pos = spec.substr(pos).search("}")
2481
this.width = spec.substring(pos, end_param_pos)
2482
console.log("width", "[" + this.width + "]")
2483
pos += end_param_pos + 1
2484
}
2485
if(car == ","){
2486
this.comma = true
2487
pos++
2488
car = spec.charAt(pos)
2489
}
2490
if(car == "."){
2491
if(digits.indexOf(spec.charAt(pos + 1)) == -1){
2492
throw _b_.ValueError.$factory(
2493
"Missing precision in format spec")
2495
this.precision = spec.charAt(pos + 1)
2496
pos += 2
2497
car = spec.charAt(pos)
2498
while(car && digits.indexOf(car) > -1){
2505
if(car && types.indexOf(car) > -1){
2506
this.type = car
2507
pos++
2508
car = spec.charAt(pos)
2509
}
2510
if(pos !== spec.length){
2516
return (this.fill === undefined ? "" : _b_.str.$factory(this.fill)) +
2517
(this.align || "") +
2518
(this.sign || "") +
2519
(this.alternate ? "#" : "") +
2520
(this.sign_aware ? "0" : "") +
2521
(this.width || "") +
2522
(this.comma ? "," : "") +
2523
(this.precision ? "." + this.precision : "") +
2524
(this.type || "")
2529
if(fmt.width && s.length < fmt.width){
2530
var fill = fmt.fill || " ",
2531
align = fmt.align || "<",
2532
missing = fmt.width - s.length
2534
case "<":
2535
return s + fill.repeat(missing)
2536
case ">":
2537
return fill.repeat(missing) + s
2538
case "=":
2539
if("+-".indexOf(s.charAt(0)) > -1){
2540
return s.charAt(0) + fill.repeat(missing) + s.substr(1)
2544
case "^":
2545
var left = parseInt(missing / 2)
2546
return fill.repeat(left) + s + fill.repeat(missing - left)
2559
function fstring_error(msg, pos){
2560
error = Error(msg)
2561
error.position = pos
2562
throw error
2563
}
2564
2565
$B.parse_fstring = function(string){
2566
// Parse a f-string
2567
var elts = [],
2568
pos = 0,
2630
}else if(ctype == "debug"){
2631
// after the equal sign, whitespace are ignored and the only
2632
// valid characters are } and :
2633
while(string.charAt(i) == " "){i++}
2634
if(string.charAt(i) == "}"){
2635
// end of debug expression
2636
elts.push(current)
2637
ctype = null
2638
current = ""
2639
pos = i + 1
2640
}
2641
}else{
2642
// End of expression is the } matching the opening {
2643
// There may be nested braces
2644
var i = pos,
2645
nb_braces = 1,
2658
if(current.expression == ""){
2659
fstring_error("f-string: empty expression not allowed",
2660
pos)
2661
}
2671
// backslash is not allowed in expressions
2672
throw Error("f-string expression part cannot include a" +
2673
" backslash")
2680
throw Error("f-string: invalid conversion character:" +
2681
" expected 's', 'r', or 'a'")
2682
}else{
2696
if(string.substr(i, 3) == '"""'){
2697
var end = string.indexOf('"""', i + 3)
2698
if(end == -1){
2700
}else{
2701
var trs = string.substring(i, end + 3)
2702
trs = trs.replace("\n", "\\n\\")
2721
var ce = current.expression,
2722
last_char = ce.charAt(ce.length - 1),
2723
last_char_re = ('()'.indexOf(last_char) > -1 ? "\\" : "") + last_char
2728
"=!<>:".search(last_char_re) > -1){
2729
current.expression += car //+ string.charAt(i + 1)
2730
i += 1
2731
}else{
2732
// add debug string
2733
tail = car
2734
while(string.charAt(i + 1).match(/\s/)){
2735
tail += string.charAt(i + 1)
2736
i++
2737
}
2738
elts.push(current.expression + tail)
2739
// remove trailing whitespace from expression
2740
while(ce.match(/\s$/)){
2741
ce = ce.substr(0, ce.length - 1)
2742
}
2743
current.expression = ce
2744
ctype = "debug"
2745
i++
2746
}
2762
if(i >= 0x10000 && i <= 0x10FFFF){
2763
var code = (i - 0x10000)
2764
return String.fromCodePoint(0xD800 | (code >> 10)) +
2765
String.fromCodePoint(0xDC00 | (code & 0x3FF))
2766
}else{
2767
return String.fromCodePoint(i)
2768
}
2769
}
2772
if(c.length == 1){
2773
return c.charCodeAt(0)
2774
}
2775
var code = 0x10000
2776
code += (c.charCodeAt(0) & 0x03FF) << 10
2777
code += (c.charCodeAt(1) & 0x03FF)
2778
return code
2779
}
2780