Permalink
Mar 6, 2021
Mar 19, 2018
Mar 19, 2018
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
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
2763 lines (2552 sloc)
84 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
}
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
79
if(!(typeof other === "string")){
80
try{return getattr(other, "__radd__")(self)}
81
catch(err){
82
throw _b_.TypeError.$factory("Can't convert " +
90
throw _b_.TypeError.$factory("'in <string>' requires " +
91
"string as left operand, not " + item.__class__)
92
}
93
if(typeof item == "string"){
94
var nbcar = item.length
95
}else{
96
var nbcar = _b_.len(item)
97
}
98
if(nbcar == 0){
99
// a string contains the empty string
100
return true
101
}
102
if(self.length == 0){
103
return nbcar == 0
104
}
117
// __dir__must be assigned explicitely because attribute resolution for
118
// builtin classes doesn't use __mro__
130
if(fmt.type && fmt.type != "s"){
131
throw _b_.ValueError.$factory("Unknown format code '" + fmt.type +
139
if(fmt.sign !== undefined){
140
throw _b_.ValueError.$factory(
141
"Sign not allowed in string format specifier")
155
if(arg < 0){
156
pos += self.length
157
}
158
if(pos >= 0 && pos < chars.length){
159
return chars[pos]
160
}
164
var s = _b_.slice.$conv_for_seq(arg, self.length),
165
start = s.start,
166
stop = s.stop,
167
step = s.step
168
var res = "",
171
if(stop <= start){
172
return ""
173
}
174
for(var i = start; i < stop; i += step){
175
res += chars[i]
176
}
178
if(stop >= start){
179
return ''
180
}
181
for(var i = start; i > stop; i += step){
182
res += chars[i]
183
}
187
if(isinstance(arg, _b_.bool)){
188
return self.__getitem__(_b_.int.$factory(arg))
189
}
244
// found at
245
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/length
246
return [...self].length
283
// left adjusted
284
return s + get_char_array(padding - s.length, flags.pad_char)
285
}
286
}
287
295
if(val.__class__ === $B.long_int){
296
s = $B.long_int.to_base(val, 10)
297
}else{
298
s = val.toString()
300
if(s[0] === "-"){
301
return "-" + get_char_array(precision - s.length + 1, "0") + s.slice(1)
312
if(val === Infinity){
313
val = "inf"
314
}else if(val === -Infinity){
315
val = "-inf"
316
}else{
317
val = "nan"
339
var str_format = function(val, flags) {
340
// string format supports left and right padding
341
flags.pad_char = " " // even if 0 padding is defined, don't use it
347
if(val.__class__ === $B.long_int){
348
val = $B.long_int.to_base(val, 10)
349
}else{
350
val = parseInt(val)
368
var repr_format = function(val, flags) {
369
flags.pad_char = " " // even if 0 padding is defined, don't use it
370
return format_padding(repr(val), flags)
371
}
373
var ascii_format = function(val, flags) {
374
flags.pad_char = " " // even if 0 padding is defined, don't use it
375
return format_padding(ascii(val), flags)
376
}
388
flags.precision = parseInt(flags.precision, 10)
389
validate_precision(flags.precision)
390
}
391
return parseFloat(val)
392
}
395
var trailing_zeros = /(.*?)(0+)([eE].*)/,
396
leading_zeros = /\.(0*)/,
397
trailing_dot = /\.$/
399
var validate_precision = function(precision) {
400
// force precision to limits of javascript
405
var floating_point_format = function(val, upper, flags){
406
val = _float_helper(val, flags),
407
v = val.toString(),
408
v_len = v.length,
409
dot_idx = v.indexOf('.')
410
if(dot_idx < 0){dot_idx = v_len}
411
if(val < 1 && val > -1){
412
var zeros = leading_zeros.exec(v),
413
numzeros
414
if(zeros){
419
if(numzeros >= 4){
420
val = format_sign(val, flags) + format_float_precision(val, upper,
421
flags, _floating_g_exp_helper)
422
if(!flags.alternate){
435
return format_padding(format_sign(val, flags) +
436
format_float_precision(val, upper, flags,
437
function(val, precision) {
438
return val.toFixed(min(precision, v_len - dot_idx) +
439
numzeros)
440
}),
441
flags
442
)
443
}
444
445
if(dot_idx > flags.precision){
446
val = format_sign(val, flags) + format_float_precision(val, upper,
447
flags, _floating_g_exp_helper)
448
if(! flags.alternate){
460
return format_padding(format_sign(val, flags) +
461
format_float_precision(val, upper, flags,
462
function(val, precision) {
463
if(!flags.decimal_point){
464
precision = min(v_len - 1, 6)
465
}else if (precision > v_len){
466
if(! flags.alternate){
467
precision = v_len
468
}
470
if(precision < dot_idx){
471
precision = dot_idx
472
}
473
return val.toFixed(precision - dot_idx)
474
}),
475
flags
476
)
479
var _floating_g_exp_helper = function(val, precision, flags, upper){
480
if(precision){--precision}
483
var e_idx = val.lastIndexOf("e")
484
if(e_idx > val.length - 4){
485
val = val.substring(0, e_idx + 2) + "0" + val.substring(e_idx + 2)
488
return val
489
}
490
491
// fF
492
var floating_point_decimal_format = function(val, upper, flags) {
493
val = _float_helper(val, flags)
494
return format_padding(format_sign(val, flags) +
495
format_float_precision(val, upper, flags,
496
function(val, precision, flags) {
497
val = val.toFixed(precision)
498
if(precision === 0 && flags.alternate){
499
val += '.'
500
}
501
return val
502
}),
503
flags
504
)
505
}
506
507
var _floating_exp_helper = function(val, precision, flags, upper) {
508
val = val.toExponential(precision)
509
// pad exponent to two digits
522
return format_padding(format_sign(val, flags) +
523
format_float_precision(val, upper, flags, _floating_exp_helper), flags)
549
if(flags.alternate){
550
if(ret.charAt(0) === "-"){
551
if(upper){ret = "-0X" + ret.slice(1)}
552
else{ret = "-0x" + ret.slice(1)}
553
}else{
554
if(upper){ret = "0X" + ret}
555
else{ret = "0x" + ret}
565
if(val.__class__ === $B.long_int){
566
ret = $B.long_int.to_base(8)
567
}else{
568
ret = parseInt(val)
569
ret = ret.toString(8)
585
if(flags.alternate){
586
if(ret.charAt(0) === "-"){ret = "-0o" + ret.slice(1)}
587
else{ret = "0o" + ret}
592
function series_of_bytes(val, flags){
593
if(val.__class__ && val.__class__.$buffer_protocol){
594
var it = _b_.iter(val),
595
ints = []
596
while(true){
597
try{
598
ints.push(_b_.next(it))
599
}catch(err){
600
if(err.__class__ === _b_.StopIteration){
601
var b = _b_.bytes.$factory(ints)
602
return format_padding(_b_.bytes.decode(b, "ascii"), flags)
603
}
604
throw err
605
}
606
}
607
}else{
608
try{
609
bytes_obj = $B.$getattr(val, "__bytes__")
610
return format_padding(_b_.bytes.decode(bytes_obj), flags)
611
}catch(err){
612
if(err.__class__ === _b_.AttributeError){
613
throw _b_.TypeError.$factory("%b does not accept '" +
614
$B.class_name(val) + "'")
615
}
616
throw err
617
}
618
}
619
}
620
622
if(isinstance(val, str) && val.length == 1){
623
return val
624
}else if(isinstance(val, bytes) && val.source.length == 1){
625
val = val.source[0]
626
}else{
627
try{
628
val = _b_.int.$factory(val) // yes, floats are valid (they are cast to int)
629
}catch (err){
630
throw _b_.TypeError.$factory("%c requires int or char")
631
}
636
var num_flag = function(c, flags){
637
if(c === "0" && ! flags.padding && ! flags.decimal_point && ! flags.left){
638
flags.pad_char = "0"
644
flags.precision = (flags.precision || "") + c
645
}
646
}
647
648
var decimal_point_flag = function(val, flags) {
650
// can only have one decimal point
651
throw new UnsupportedChar()
652
}
653
flags.decimal_point = true
654
}
655
656
var neg_flag = function(val, flags){
657
flags.pad_char = " " // overrides '0' flag
675
"s": str_format,
676
"d": num_format,
677
"i": num_format,
678
"u": num_format,
679
"o": octal_format,
680
"r": repr_format,
681
"a": ascii_format,
682
"g": function(val, flags){
683
return floating_point_format(val, false, flags)
684
},
685
"G": function(val, flags){return floating_point_format(val, true, flags)},
686
"f": function(val, flags){
687
return floating_point_decimal_format(val, false, flags)
688
},
689
"F": function(val, flags){
690
return floating_point_decimal_format(val, true, flags)
691
},
692
"e": function(val, flags){
693
return floating_point_exponential_format(val, false, flags)
694
},
695
"E": function(val, flags){
696
return floating_point_exponential_format(val, true, flags)
697
},
698
"x": function(val, flags){return signed_hex_format(val, false, flags)},
699
"X": function(val, flags){return signed_hex_format(val, true, flags)},
700
"c": single_char_format,
701
"0": function(val, flags){return num_flag("0", flags)},
702
"1": function(val, flags){return num_flag("1", flags)},
703
"2": function(val, flags){return num_flag("2", flags)},
704
"3": function(val, flags){return num_flag("3", flags)},
705
"4": function(val, flags){return num_flag("4", flags)},
706
"5": function(val, flags){return num_flag("5", flags)},
707
"6": function(val, flags){return num_flag("6", flags)},
708
"7": function(val, flags){return num_flag("7", flags)},
709
"8": function(val, flags){return num_flag("8", flags)},
710
"9": function(val, flags){return num_flag("9", flags)},
711
"-": neg_flag,
712
" ": space_flag,
713
"+": sign_flag,
714
".": decimal_point_flag,
715
"#": alternate_flag
716
}
717
718
// exception thrown when an unsupported char is encountered in legacy format
764
if(self === undefined){
765
throw _b_.TypeError.$factory(
766
"not enough arguments for format string")
793
throw _b_.ValueError.$factory(
794
"unsupported format character '" + invalid_char +
795
"' (0x" + invalid_char.charCodeAt(0).toString(16) +
796
") at index " + newpos)
797
}else if(err.name === "NotANumber"){
798
var try_char = s[newpos],
799
cls = self.__class__
800
if(!cls){
801
if(typeof(self) === "string"){
802
cls = "str"
803
}else{
809
throw _b_.TypeError.$factory("%" + try_char +
810
" format: a number is required, not " + cls)
811
}else{
843
}while(pos < length)
844
845
if(argpos !== null){
846
if(args.length > argpos){
847
throw _b_.TypeError.$factory(
848
"not enough arguments for format string")
849
}else if(args.length < argpos){
850
throw _b_.TypeError.$factory(
851
"not all arguments converted during string formatting")
853
}else if(nbph == 0){
854
throw _b_.TypeError.$factory(
855
"not all arguments converted during string formatting")
863
var $ = $B.args("__mul__", 2, {self: null, other: null},
864
["self", "other"], arguments, {}, null, null)
865
if(! isinstance($.other, _b_.int)){throw _b_.TypeError.$factory(
866
"Can't multiply sequence by non-int of type '" +
877
var t = {
878
8: "\\x08",
879
9: "\\t",
880
10: "\\n",
881
11: "\\x0b",
882
12: "\\x0c",
883
13: "\\r",
884
92: "\\\\"
885
}
886
var repl = '',
887
chars = to_chars(self)
888
for(var i = 0; i < chars.length; i++){
889
var cp = _b_.ord(chars[i])
890
if(t[cp] !== undefined){
891
repl += t[cp]
892
}else if($B.is_unicode_cn(cp)){
911
if(res.search('"') == -1 && res.search("'") == -1){
912
return "'" + res + "'"
913
}else if(self.search('"') == -1){
914
return '"' + res + '"'
915
}
916
var qesc = new RegExp("'", "g") // to escape single quote
917
res = "'" + res.replace(qesc, "\\'") + "'"
921
str.__setattr__ = function(self, attr, value){
922
if(typeof self === "string"){
923
if(str.hasOwnProperty(attr)){
925
attr + "' is read-only")
926
}else{
927
throw _b_.AttributeError.$factory(
928
"'str' object has no attribute '" + attr + "'")
929
}
930
}
931
// str subclass : use __dict__
932
_b_.dict.$setitem(self.__dict__, attr, value)
933
return $N
934
}
935
936
str.__setitem__ = function(self, attr, value){
937
throw _b_.TypeError.$factory(
938
"'str' object does not support item assignment")
941
var combining = []
942
for(var cp = 0x300; cp <= 0x36F; cp++){
943
combining.push(String.fromCharCode(cp))
944
}
948
var repl = '',
949
chars = to_chars(self)
950
if(chars.length == self.length){
951
return self.replace(combining_re, "\u200B$1")
952
}
953
for(var i = 0; i < chars.length; i++){
954
var cp = _b_.ord(chars[i])
955
if(cp >= 0x300 && cp <= 0x36F){
956
repl += "\u200B" + chars[i]
957
}else{
958
repl += chars[i]
959
}
960
}
961
return repl
971
$comp_func += "" // source code
972
var $comps = {">": "gt", ">=": "ge", "<": "lt", "<=": "le"}
981
var $notimplemented = function(self, other){
982
throw NotImplementedError.$factory(
983
"OPERATOR not implemented for class str")
986
str.capitalize = function(self){
987
var $ = $B.args("capitalize", 1, {self}, ["self"],
988
arguments, {}, null, null)
992
return self.charAt(0).toUpperCase() + self.substr(1)
993
}
994
995
str.casefold = function(self){
996
var $ = $B.args("casefold", 1, {self}, ["self"],
997
arguments, {}, null, null),
998
res = "",
999
char,
1000
cf,
1001
chars = to_chars($.self)
1002
1003
for(var i = 0, len = chars.length; i < len; i++){
1004
char = chars[i]
1005
cf = $B.unicode_casefold[char]
1006
if(cf){
1007
cf.forEach(function(cp){
1008
res += String.fromCharCode(cp)
1009
})
1010
}else{
1017
str.center = function(){
1018
var $ = $B.args("center", 3, {self: null, width: null, fillchar: null},
1019
["self", "width", "fillchar"],
1020
arguments, {fillchar:" "}, null, null),
1021
self = $.self
1025
var pad = parseInt(($.width - self.length) / 2),
1026
res = $.fillchar.repeat(pad)
1035
var $ = $B.args("count", 4, {self:null, sub:null, start:null, stop:null},
1036
["self", "sub", "start", "stop"], arguments, {start:null, stop:null},
1038
if(!(typeof $.sub == "string")){
1039
throw _b_.TypeError.$factory("Can't convert '" + $B.class_name($.sub) +
1040
"' object to str implicitly")
1041
}
1045
if($.stop !== null){
1046
_slice = _b_.slice.$factory($.start, $.stop)
1047
}else{
1048
_slice = _b_.slice.$factory($.start, $.self.length)
1049
}
1057
if($.start == $.self.length){
1058
return 1
1059
}else if(substr.length == 0){
1060
return 0
1061
}
1064
var n = 0,
1065
pos = 0
1066
while(pos < substr.length){
1067
pos = substr.indexOf($.sub, pos)
1078
str.encode = function(){
1079
var $ = $B.args("encode", 3, {self: null, encoding: null, errors: null},
1080
["self", "encoding", "errors"], arguments,
1081
{encoding: "utf-8", errors: "strict"}, null, null)
1082
if($.encoding == "rot13" || $.encoding == "rot_13"){
1085
for(var i = 0, len = $.self.length; i < len ; i++){
1086
var char = $.self.charAt(i)
1087
if(("a" <= char && char <= "m") || ("A" <= char && char <= "M")){
1088
res += String.fromCharCode(String.charCodeAt(char) + 13)
1089
}else if(("m" < char && char <= "z") ||
1090
("M" < char && char <= "Z")){
1091
res += String.fromCharCode(String.charCodeAt(char) - 13)
1100
// Return True if the string ends with the specified suffix, otherwise
1101
// return False. suffix can also be a tuple of suffixes to look for.
1102
// With optional start, test beginning at that position. With optional
1106
["self", "suffix", "start", "end"],
1107
arguments, {start: 0, end: null}, null, null)
1120
if(! _b_.isinstance(suffix, str)){
1121
throw _b_.TypeError.$factory(
1122
"endswith first arg must be str or a tuple of str, not int")
1123
}
1133
var $ = $B.args("expandtabs", 2, {self: null, tabsize: null},
1134
["self", "tabsize"], arguments, {tabsize: 8}, null, null)
1135
var s = $B.$GetInt($.tabsize),
1136
col = 0,
1137
pos = 0,
1138
res = "",
1139
chars = to_chars(self)
1140
if(s == 1){
1141
return self.replace(/\t/g," ")
1142
}
1143
while(pos < chars.length){
1144
var car = chars[pos]
1154
res += car
1155
col = 0
1156
break
1157
default:
1158
res += car
1159
col++
1160
break
1161
}
1162
pos++
1163
}
1164
return res
1168
// Return the lowest index in the string where substring sub is found,
1169
// such that sub is contained in the slice s[start:end]. Optional
1170
// arguments start and end are interpreted as in slice notation.
1173
{self: null, sub: null, start: null, end: null},
1174
["self", "sub", "start", "end"],
1175
arguments, {start: 0, end: null}, null, null)
1179
if(!isinstance($.start, _b_.int)||!isinstance($.end, _b_.int)){
1180
throw _b_.TypeError.$factory("slice indices must be " +
1181
"integers or None or have an __index__ method")}
1182
// Can't use string.substring(start, end) because if end < start,
1183
// Javascript transforms it into substring(end, start)...
1184
var s = ""
1185
for(var i = $.start; i < $.end; i++){
1186
s += $.self.charAt(i)
1187
}
1189
var len = str.__len__($.self)
1190
1191
if($.sub.length == 0 && $.start == len){
1192
return len
1193
}
1194
if(s.length + $.sub.length == 0){
1195
return -1
1196
}
1198
var last_search = s.length - $.sub.length
1199
for(var i = 0; i <= last_search; i++){
1200
if(s.substr(i, $.sub.length) == $.sub){
1201
return $.start + str.__len__(s.substr(0, i))
1202
}
1213
// a.x[z]!r:...
1214
// the object has attributes :
1215
// - name : "a"
1216
// - name_ext : [".x", "[z]"]
1217
// - conv : r
1218
// - spec : rest of string after :
1226
// No : in the string : it only contains a name
1227
name = fmt_string
1228
}else{
1229
// name is before the first ":"
1230
// spec (the format specification) is after
1231
name = elts[0]
1235
var elts = name.split("!")
1236
if(elts.length > 1){
1237
name = elts[0]
1238
conv = elts[1] // conversion flag
1242
// "name' may be a subscription or attribute
1243
// Put these "extensions" in the list "name_ext"
1244
function name_repl(match){
1245
name_ext.push(match)
1247
}
1248
var name_ext_re = /\.[_a-zA-Z][_a-zA-Z0-9]*|\[[_a-zA-Z][_a-zA-Z0-9]*\]|\[[0-9]+\]/g
1249
name = name.replace(name_ext_re, name_repl)
1250
}
1257
// Parse self to detect formatting instructions
1258
// Create a list "parts" made of sections of the string :
1259
// - elements of even rank are literal text
1260
// - elements of odd rank are "format objects", built from the
1261
// format strings in self (of the form {...})
1272
text += "{"
1273
pos += 2
1274
}else if(car == "}" && self.charAt(pos + 1) == "}"){
1281
// Store current literal text
1282
parts.push(text)
1283
1284
// Search the end of the format string, ie the } closing the
1285
// opening {. Since the string can contain other pairs {} for
1286
// nested formatting, an integer nb is incremented for each { and
1287
// decremented for each } ; the end of the format string is
1288
// reached when nb == 0
1289
var end = pos + 1,
1290
nb = 1
1291
while(end < _len){
1292
if(self.charAt(end) == "{"){nb++; end++}
1293
else if(self.charAt(end) == "}"){
1294
nb--; end++
1295
if(nb == 0){
1300
var fmt_obj = $B.parse_format(fmt_string)
1301
fmt_obj.raw_name = fmt_obj.name
1302
fmt_obj.raw_spec = fmt_obj.spec
1341
// Special management of keyword arguments if str.format is called by
1342
// str.format_map(mapping) : the argument "mapping" might not be a
1343
// dictionary
1344
var last_arg = $B.last(arguments)
1345
if(last_arg.$nat == "mapping"){
1346
var mapping = last_arg.mapping,
1347
getitem = $B.$getattr(mapping, "__getitem__")
1348
// Get the rest of the arguments
1349
var args = []
1350
for(var i = 0, len = arguments.length - 1; i < len; i++){
1351
args.push(arguments[i])
1352
}
1353
var $ = $B.args("format", 1, {self: null}, ["self"],
1354
args, {}, "$args", null)
1355
}else{
1356
var $ = $B.args("format", 1, {self: null}, ["self"],
1357
arguments, {}, "$args", "$kw"),
1358
mapping = $.$kw, // dictionary
1359
getitem = function(key){
1360
return _b_.dict.$getitem(mapping, key)
1361
}
1362
}
1375
1376
if(fmt.spec !== undefined){
1377
// "spec" may contain "nested replacement fields"
1378
// In this case, evaluate them using the positional
1379
// or keyword arguments passed to format()
1380
function replace_nested(name, key){
1381
if(/\d+/.exec(key)){
1382
// If key is numeric, search in positional
1383
// arguments
1384
return _b_.tuple.__getitem__($.$args,
1385
parseInt(key))
1386
}else{
1387
// Else try in keyword arguments
1388
return _b_.dict.__getitem__($.$kw, key)
1389
}
1390
}
1391
fmt.spec = fmt.spec.replace(/\{(.*?)\}/g,
1392
replace_nested)
1393
}
1395
// Numerical reference : use positional arguments
1396
var pos = parseInt(fmt.name),
1406
// Attribute
1407
value = _b_.getattr(value, ext.substr(1))
1408
}else{
1409
// Subscription
1412
if(key.charAt(0).search(/\d/) > -1){key = parseInt(key)}
1413
value = _b_.getattr(value, "__getitem__")(key)
1417
// If the conversion flag is set, first call a function to convert
1418
// the value
1419
if(fmt.conv == "a"){value = _b_.ascii(value)}
1420
else if(fmt.conv == "r"){value = _b_.repr(value)}
1421
else if(fmt.conv == "s"){value = _b_.str.$factory(value)}
1434
str.format_map = function(self, mapping){
1435
var $ = $B.args("format_map", 2, {self: null, mapping: null},
1436
['self', 'mapping'], arguments, {}, null, null)
1437
return str.format(self, {$nat: 'mapping', mapping})
1450
/* Return true if the string is empty or all characters in the string are
1451
ASCII, false otherwise. ASCII characters have code points in the range
1452
U+0000-U+007F. */
1461
str.isalnum = function(self){
1462
/* Return true if all characters in the string are alphanumeric and there
1463
is at least one character, false otherwise. A character c is alphanumeric
1464
if one of the following returns True: c.isalpha(), c.isdecimal(),
1465
c.isdigit(), or c.isnumeric(). */
1466
var $ = $B.args("isalnum", 1, {self: null}, ["self"],
1467
arguments, {}, null, null),
1468
cp
1469
for(var char of to_chars(self)){
1470
cp = _b_.ord(char)
1471
if(unicode_tables.Ll[cp] ||
1472
unicode_tables.Lu[cp] ||
1473
unicode_tables.Lm[cp] ||
1474
unicode_tables.Lt[cp] ||
1475
unicode_tables.Lo[cp] ||
1476
unicode_tables.Nd[cp] ||
1477
unicode_tables.digits[cp] ||
1478
unicode_tables.numeric[cp]){
1479
continue
1480
}
1481
return false
1482
}
1483
return true
1484
}
1485
1486
str.isalpha = function(self){
1487
/* Return true if all characters in the string are alphabetic and there is
1488
at least one character, false otherwise. Alphabetic characters are those
1489
characters defined in the Unicode character database as "Letter", i.e.,
1490
those with general category property being one of "Lm", "Lt", "Lu", "Ll",
1491
or "Lo". */
1492
var $ = $B.args("isalpha", 1, {self: null}, ["self"],
1493
arguments, {}, null, null),
1494
cp
1495
for(var char of to_chars(self)){
1496
cp = _b_.ord(char)
1497
if(unicode_tables.Ll[cp] ||
1498
unicode_tables.Lu[cp] ||
1499
unicode_tables.Lm[cp] ||
1500
unicode_tables.Lt[cp] ||
1501
unicode_tables.Lo[cp]){
1502
continue
1503
}
1504
return false
1505
}
1506
return true
1507
}
1508
1509
str.isdecimal = function(self){
1510
/* Return true if all characters in the string are decimal characters and
1511
there is at least one character, false otherwise. Decimal characters are
1512
those that can be used to form numbers in base 10, e.g. U+0660,
1513
ARABIC-INDIC DIGIT ZERO. Formally a decimal character is a character in
1514
the Unicode General Category "Nd". */
1515
var $ = $B.args("isdecimal", 1, {self: null}, ["self"],
1516
arguments, {}, null, null),
1517
cp
1518
for(var char of to_chars(self)){
1519
cp = _b_.ord(char)
1520
if(! unicode_tables.Nd[cp]){
1521
return false
1522
}
1523
}
1524
return self.length > 0
1525
}
1526
1527
str.isdigit = function(self){
1528
/* Return true if all characters in the string are digits and there is at
1529
least one character, false otherwise. */
1530
var $ = $B.args("isdigit", 1, {self: null}, ["self"],
1531
arguments, {}, null, null),
1532
cp
1533
for(var char of to_chars(self)){
1534
cp = _b_.ord(char)
1535
if(! unicode_tables.digits[cp]){
1536
return false
1537
}
1538
}
1539
return self.length > 0
1540
}
1541
1542
str.isidentifier = function(self){
1543
/* Return true if the string is a valid identifier according to the
1544
language definition. */
1545
var $ = $B.args("isidentifier", 1, {self: null}, ["self"],
1549
}
1550
var chars = to_chars(self)
1551
if(unicode_tables.XID_Start[_b_.ord(chars[0])] === undefined){
1554
for(var char of chars){
1555
var cp = _b_.ord(char)
1556
if(unicode_tables.XID_Continue[cp] === undefined){
1557
return false
1558
}
1559
}
1560
}
1561
return true
1562
}
1563
1564
str.islower = function(self){
1565
/* Return true if all cased characters 4 in the string are lowercase and
1566
there is at least one cased character, false otherwise. */
1567
var $ = $B.args("islower", 1, {self: null}, ["self"],
1568
arguments, {}, null, null),
1569
has_cased = false,
1572
for(var char of to_chars(self)){
1573
cp = _b_.ord(char)
1574
if(unicode_tables.Ll[cp]){
1575
has_cased = true
1576
continue
1577
}else if(unicode_tables.Lu[cp] || unicode_tables.Lt[cp]){
1578
return false
1579
}
1580
}
1581
return has_cased
1582
}
1583
1584
str.isnumeric = function(self){
1585
/* Return true if all characters in the string are numeric characters, and
1586
there is at least one character, false otherwise. Numeric characters
1587
include digit characters, and all characters that have the Unicode numeric
1588
value property, e.g. U+2155, VULGAR FRACTION ONE FIFTH. Formally, numeric
1589
characters are those with the property value Numeric_Type=Digit,
1590
Numeric_Type=Decimal or Numeric_Type=Numeric.*/
1591
var $ = $B.args("isnumeric", 1, {self: null}, ["self"],
1592
arguments, {}, null, null)
1601
var unprintable = {},
1602
unprintable_gc = ['Cc', 'Cf', 'Co', 'Cs','Zl', 'Zp', 'Zs']
1603
1604
str.isprintable = function(self){
1605
/* Return true if all characters in the string are printable or the string
1606
is empty, false otherwise. Nonprintable characters are those characters
1607
defined in the Unicode character database as "Other" or "Separator",
1608
excepting the ASCII space (0x20) which is considered printable. */
1609
1610
// Set unprintable if not set yet
1611
if(Object.keys(unprintable).length == 0){
1612
for(var i = 0; i < unprintable_gc.length; i++){
1613
var table = unicode_tables[unprintable_gc[i]]
1624
return false
1625
}
1626
}
1627
return true
1628
}
1629
1630
str.isspace = function(self){
1631
/* Return true if there are only whitespace characters in the string and
1632
there is at least one character, false otherwise.
1633
1634
A character is whitespace if in the Unicode character database, either its
1635
general category is Zs ("Separator, space"), or its bidirectional class is
1636
one of WS, B, or S.*/
1637
var $ = $B.args("isspace", 1, {self: null}, ["self"],
1638
arguments, {}, null, null),
1639
cp
1640
for(var char of to_chars(self)){
1641
cp = _b_.ord(char)
1642
if(! unicode_tables.Zs[cp] &&
1643
$B.unicode_bidi_whitespace.indexOf(cp) == -1){
1644
return false
1645
}
1646
}
1647
return self.length > 0
1648
}
1649
1650
str.istitle = function(self){
1651
/* Return true if the string is a titlecased string and there is at least
1652
one character, for example uppercase characters may only follow uncased
1653
characters and lowercase characters only cased ones. Return false
1654
otherwise. */
1655
var $ = $B.args("istitle", 1, {self: null}, ["self"],
1656
arguments, {}, null, null)
1657
return self.length > 0 && str.title(self) == self
1658
}
1659
1660
str.isupper = function(self){
1661
/* Return true if all cased characters 4 in the string are lowercase and
1662
there is at least one cased character, false otherwise. */
1663
var $ = $B.args("islower", 1, {self: null}, ["self"],
1664
arguments, {}, null, null),
1668
for(var char of to_chars(self)){
1669
cp = _b_.ord(char)
1670
if(unicode_tables.Lu[cp]){
1671
is_upper = true
1672
continue
1673
}else if(unicode_tables.Ll[cp] || unicode_tables.Lt[cp]){
1691
if(! isinstance(obj2, str)){
1692
throw _b_.TypeError.$factory("sequence item " + count +
1693
": expected str instance, " + $B.class_name(obj2) +
1694
" found")
1695
}
1708
var $ = $B.args("ljust", 3, {self: null, width: null, fillchar:null},
1709
["self", "width", "fillchar"],
1713
if($.width <= len){
1714
return self
1715
}
1716
return self + $.fillchar.repeat($.width - len)
1719
str.lower = function(self){
1720
var $ = $B.args("lower", 1, {self: null}, ["self"],
1721
arguments, {}, null, null)
1722
return self.toLowerCase()
1723
}
1724
1726
var $ = $B.args("lstrip", 2, {self: null, chars: null}, ["self", "chars"],
1727
arguments, {chars:_b_.None}, null, null)
1728
if($.chars === _b_.None){
1729
return $.self.trimLeft()
1730
}
1731
var chars = to_chars(self)
1732
for(var i = 0, len = chars.length; i < len; i++){
1733
if($.chars.indexOf(chars[i]) === -1){
1734
return chars.slice(i).join('')
1742
var $ = $B.args("maketrans", 3, {x: null, y: null, z: null},
1743
["x", "y", "z"], arguments, {y: null, z: null}, null, null)
1748
// If there is only one argument, it must be a dictionary mapping
1749
// Unicode ordinals (integers) or characters (strings of length 1) to
1750
// Unicode ordinals, strings (of arbitrary lengths) or None. Character
1752
if(! _b_.isinstance($.x, _b_.dict)){
1753
throw _b_.TypeError.$factory(
1754
"maketrans only argument must be a dict")
1757
for(var i = 0, len = items.length; i < len; i++){
1758
var k = items[i][0],
1759
v = items[i][1]
1760
if(! _b_.isinstance(k, _b_.int)){
1761
if(_b_.isinstance(k, _b_.str) && k.length == 1){
1762
k = _b_.ord(k)
1763
}else{throw _b_.TypeError.$factory("dictionary key " + k +
1766
if(v !== _b_.None && ! _b_.isinstance(v, [_b_.int, _b_.str])){
1767
throw _b_.TypeError.$factory("dictionary value " + v +
1775
// and in the resulting dictionary, each character in x will be mapped
1776
// to the character at the same position in y
1779
}else if($.x.length !== $.y.length){
1780
throw _b_.TypeError.$factory(
1781
"maketrans arguments must be strings or same length")
1787
if(! _b_.isinstance($.z, _b_.str)){
1788
throw _b_.TypeError.$factory(
1789
"maketrans third argument must be a string")
1811
var $ = $B.args("partition", 2, {self: null, sep: null}, ["self", "sep"],
1812
arguments, {}, null, null)
1817
var chars = to_chars(self),
1818
i = chars.indexOf($.sep)
1819
if(i == -1){
1820
return _b_.tuple.$factory([$.self, "", ""])
1821
}
1822
return _b_.tuple.$factory([chars.slice(0, i).join(''), $.sep,
1823
chars.slice(i + $.sep.length).join('')])
1826
str.removeprefix = function(){
1827
var $ = $B.args("removeprefix", 2, {self: null, prefix: null},
1828
["self", "prefix"], arguments, {}, null, null)
1829
if(!_b_.isinstance($.prefix, str)){
1830
throw _b_.ValueError.$factory("prefix should be str, not " +
1831
`'${$B.class_name($.prefix)}'`)
1832
}
1833
if(str.startswith($.self, $.prefix)){
1834
return $.self.substr($.prefix.length)
1835
}
1836
return $.self.substr(0)
1837
}
1838
1839
str.removesuffix = function(){
1840
var $ = $B.args("removesuffix", 2, {self: null, prefix: null},
1841
["self", "suffix"], arguments, {}, null, null)
1842
if(!_b_.isinstance($.suffix, str)){
1843
throw _b_.ValueError.$factory("suffix should be str, not " +
1844
`'${$B.class_name($.prefix)}'`)
1845
}
1846
if($.suffix.length > 0 && str.endswith($.self, $.suffix)){
1847
return $.self.substr(0, $.self.length - $.suffix.length)
1848
}
1849
return $.self.substr(0)
1850
}
1851
1852
function $re_escape(str){
1853
var specials = "[.*+?|()$^"
1854
for(var i = 0, len = specials.length; i < len; i++){
1855
var re = new RegExp("\\"+specials.charAt(i), "g")
1856
str = str.replace(re, "\\"+specials.charAt(i))
1857
}
1858
return str
1865
var $ = $B.args("replace", 4,
1866
{self: null, old: null, $$new: null, count: null},
1867
["self", "old", "$$new", "count"],
1868
arguments, {count: -1}, null, null),
1869
count = $.count,
1870
self = $.self,
1871
old = $.old,
1872
_new = $.$$new
1879
"' object cannot be interpreted as an integer")
1880
}else if(isinstance(count, _b_.float)){
1881
throw _b_.TypeError.$factory("integer argument expected, got float")
1882
}
1883
if(count == 0){
1884
return self
1885
}
1886
if(count.__class__ == $B.long_int){
1887
count = parseInt(count.value)
1888
}
1890
if(_new == ""){
1891
return self
1892
}
1893
if(self == ""){
1894
return _new
1895
}
1896
var elts = self.split("")
1897
if(count > -1 && elts.length >= count){
1898
var rest = elts.slice(count).join("")
1899
return _new + elts.slice(0, count).join(_new) + rest
1925
res = res.substr(0, pos) + _new + res.substr(pos + old.length)
1926
pos = pos + _new.length
1927
count--
1933
// Return the highest index in the string where substring sub is found,
1934
// such that sub is contained within s[start:end]. Optional arguments
1936
if(arguments.length == 2 && typeof substr == "string"){
1937
return self.lastIndexOf(substr)
1938
}
1940
{self: null, sub: null, start: null, end: null},
1941
["self", "sub", "start", "end"],
1942
arguments, {start: 0, end: null}, null, null)
1949
if($.start > $.self.length){
1950
return -1
1951
}else{
1952
return str.__len__($.self)
1953
}
1959
if($.self.substr(i, sublen) == $.sub){
1960
return str.__len__($.self.substr(0, i))
1961
}
1976
var $ = $B.args("rjust",3,
1977
{self: null, width: null, fillchar: null},
1978
["self", "width", "fillchar"],
1979
arguments, {fillchar: " "}, null, null)
1989
var $ = $B.args("rpartition", 2, {self: null, sep: null}, ["self", "sep"],
1990
arguments, {}, null, null)
1994
var items = str.partition(self, sep).reverse()
1995
for(var i = 0; i < items.length; i++){
1996
items[i] = items[i].split("").reverse().join("")
2002
var $ = $B.args("rsplit", 3, {self: null, sep: null, maxsplit: null},
2003
["self", "sep", "maxsplit"], arguments,
2004
{sep: _b_.None, maxsplit: -1}, null, null),
2005
sep = $.sep
2008
var rev_str = reverse($.self),
2009
rev_sep = sep === _b_.None ? sep : reverse($.sep),
2020
str.rstrip = function(self, x){
2021
var $ = $B.args("rstrip", 2, {self: null, chars: null}, ["self", "chars"],
2023
if($.chars === _b_.None){
2024
return $.self.trimRight()
2025
}
2026
var chars = to_chars(self)
2027
for(var j = chars.length - 1; j >= 0; j--){
2028
if($.chars.indexOf(chars[j]) == -1){
2029
return chars.slice(0, j + 1).join('')
2036
var $ = $B.args("split", 3, {self: null, sep: null, maxsplit: null},
2037
["self", "sep", "maxsplit"], arguments,
2038
{sep: _b_.None, maxsplit: -1}, null, null),
2039
sep = $.sep,
2040
maxsplit = $.maxsplit,
2041
self = $.self,
2042
pos = 0
2043
if(maxsplit.__class__ === $B.long_int){
2044
maxsplit = parseInt(maxsplit.value)
2045
}
2046
if(sep == ""){
2047
throw _b_.ValueError.$factory("empty separator")
2048
}
2051
while(pos < self.length && self.charAt(pos).search(/\s/) > -1){
2052
pos++
2053
}
2054
if(pos === self.length - 1){
2055
return [self]
2056
}
2060
if(name == ""){
2061
name = self.charAt(pos)
2062
}else{
2063
name += self.charAt(pos)
2064
}
2086
var res = [],
2087
s = "",
2088
seplen = sep.length
2089
if(maxsplit == 0){return [self]}
2090
while(pos < self.length){
2091
if(self.substr(pos, seplen) == sep){
2109
str.splitlines = function(self) {
2110
var $ = $B.args('splitlines', 2, {self: null, keepends: null},
2111
['self','keepends'], arguments, {keepends: false},
2112
null, null)
2113
if(!_b_.isinstance($.keepends,[_b_.bool, _b_.int])){
2114
throw _b_.TypeError('integer argument expected, got '+
2117
var keepends = _b_.int.$factory($.keepends),
2118
res = [],
2119
self = $.self,
2120
start = 0,
2121
pos = 0
2122
if(!self.length){
2126
if(self.substr(pos, 2) == '\r\n'){
2127
res.push(self.slice(start, keepends ? pos + 2 : pos))
2128
start = pos = pos+2
2129
}else if(self[pos] == '\r' || self[pos] == '\n'){
2130
res.push(self.slice(start, keepends ? pos+1 : pos))
2131
start = pos = pos+1
2132
}else{
2133
pos++
2134
}
2135
}
2136
if(start < self.length){
2137
res.push(self.slice(start))
2138
}
2139
return res
2143
// Return True if string starts with the prefix, otherwise return False.
2144
// prefix can also be a tuple of prefixes to look for. With optional
2145
// start, test string beginning at that position. With optional end,
2147
var $ = $B.args("startswith", 4,
2148
{self: null, prefix: null, start: null, end: null},
2149
["self", "prefix", "start", "end"],
2150
arguments, {start: 0, end: null}, null, null)
2162
if(! _b_.isinstance(prefix, str)){
2163
throw _b_.TypeError.$factory("endswith first arg must be str " +
2164
"or a tuple of str, not int")
2165
}
2166
if(s.substr(0, prefix.length) == prefix){
2167
return true
2168
}
2174
var $ = $B.args("strip", 2, {self: null, chars: null}, ["self", "chars"],
2175
arguments, {chars: _b_.None}, null, null)
2176
if($.chars === _b_.None){
2177
return $.self.trim()
2178
}
2179
var chars = to_chars($.self)
2180
for(var i = 0; i < chars.length; i++){
2181
if($.chars.indexOf(chars[i]) == -1){
2185
for(var j = chars.length - 1; j >= i; j--){
2186
if($.chars.indexOf(chars[j]) == -1){
2193
str.swapcase = function(self){
2194
var $ = $B.args("swapcase", 1, {self}, ["self"],
2195
arguments, {}, null, null),
2196
res = "",
2197
cp
2198
2199
for(var char of to_chars(self)){
2200
cp = _b_.ord(char)
2201
if(unicode_tables.Ll[cp]){
2202
res += char.toUpperCase()
2203
}else if(unicode_tables.Lu[cp]){
2204
res += char.toLowerCase()
2207
}
2208
}
2209
return res
2210
}
2211
2212
str.title = function(self){
2213
var $ = $B.args("title", 1, {self}, ["self"],
2214
arguments, {}, null, null),
2215
state,
2218
for(var char of to_chars(self)){
2219
cp = _b_.ord(char)
2220
if(unicode_tables.Ll[cp]){
2227
}else if(unicode_tables.Lu[cp] || unicode_tables.Lt[cp]){
2228
res += state ? char.toLowerCase() : char
2240
getitem = $B.$getattr(table, "__getitem__"),
2241
cp
2242
for(var char of to_chars(self)){
2243
cp = _b_.ord(char)
2247
if(typeof repl == "string"){
2248
res.push(repl)
2249
}else if(typeof repl == "number"){
2250
res.push(String.fromCharCode(repl))
2251
}
2260
str.upper = function(self){
2261
var $ = $B.args("upper", 1, {self: null}, ["self"],
2262
arguments, {}, null, null)
2263
return self.toUpperCase()
2264
}
2265
2268
["self", "width"], arguments, {}, null, null),
2269
len = str.__len__(self)
2270
if($.width <= len){
2271
return self
2272
}
2292
if(encoding !== undefined){
2293
// Arguments may be passed as keywords (cf. issue #1060)
2294
var $ = $B.args("str", 3, {arg: null, encoding: null, errors: null},
2295
["arg", "encoding", "errors"], arguments,
2296
{encoding: "utf-8", errors: "strict"}, null, null),
2297
encoding = $.encoding,
2298
errors = $.errors
2299
}
2310
// class or its subclasses, but the attribute __str__ of the
2311
// class metaclass (usually "type") or its subclasses (usually
2312
// "object")
2313
// The metaclass is the attribute __class__ of the class dictionary
2318
if(arg.__class__ && arg.__class__ === _b_.bytes &&
2319
encoding !== undefined){
2320
// str(bytes, encoding, errors) is equal to
2321
// bytes.decode(encoding, errors)
2324
// Implicit invocation of __str__ uses method __str__ on the class,
2325
// even if arg has an attribute __str__
2326
var klass = arg.__class__ || $B.get_class(arg)
2332
// if not better than object.__str__, try __repr__
2333
(arg.__class__ && arg.__class__ !== _b_.object &&
2334
method.$infos && method.$infos.__func__ === _b_.object.__str__)){
2335
var method = $B.$getattr(klass, "__repr__")
2341
if($B.debug > 1){console.log(err)}
2342
console.log("Warning - no method __str__ or __repr__, " +
2343
"default to toString", arg)
2350
if(cls === undefined){
2351
throw _b_.TypeError.$factory("str.__new__(): not enough arguments")
2375
var args = [],
2376
pos = 0
2377
if(arguments.length > 0){
2378
var args = [arguments[0].valueOf()],
2379
pos = 1
2380
for(var i = 1, len = arguments.length; i < len; i++){
2381
args[pos++] = arguments[i]
2398
// Function to parse the 2nd argument of format()
2399
$B.parse_format_spec = function(spec){
2403
var pos = 0,
2404
aligns = "<>=^",
2405
digits = "0123456789",
2406
types = "bcdeEfFgGnosxX%",
2408
if(align_pos != -1){
2409
if(spec.charAt(1) && aligns.indexOf(spec.charAt(1)) != -1){
2410
// If the second char is also an alignment specifier, the
2411
// first char is the fill value
2412
this.fill = spec.charAt(0)
2413
this.align = spec.charAt(1)
2414
pos = 2
2415
}else{
2416
// The first character defines alignment : fill defaults to ' '
2431
if(car == "+" || car == "-" || car == " "){
2432
this.sign = car
2433
pos++
2434
car = spec.charAt(pos)
2449
if(this.width === undefined){
2450
this.width = car
2451
}else{
2452
this.width += car
2453
}
2460
if(this.width === undefined && car == "{"){
2461
// Width is determined by a parameter
2462
var end_param_pos = spec.substr(pos).search("}")
2463
this.width = spec.substring(pos, end_param_pos)
2464
console.log("width", "[" + this.width + "]")
2465
pos += end_param_pos + 1
2466
}
2467
if(car == ","){
2468
this.comma = true
2469
pos++
2470
car = spec.charAt(pos)
2471
}
2472
if(car == "."){
2473
if(digits.indexOf(spec.charAt(pos + 1)) == -1){
2474
throw _b_.ValueError.$factory(
2475
"Missing precision in format spec")
2477
this.precision = spec.charAt(pos + 1)
2478
pos += 2
2479
car = spec.charAt(pos)
2480
while(car && digits.indexOf(car) > -1){
2487
if(car && types.indexOf(car) > -1){
2488
this.type = car
2489
pos++
2490
car = spec.charAt(pos)
2491
}
2492
if(pos !== spec.length){
2498
return (this.fill === undefined ? "" : _b_.str.$factory(this.fill)) +
2499
(this.align || "") +
2500
(this.sign || "") +
2501
(this.alternate ? "#" : "") +
2502
(this.sign_aware ? "0" : "") +
2503
(this.width || "") +
2504
(this.comma ? "," : "") +
2505
(this.precision ? "." + this.precision : "") +
2506
(this.type || "")
2511
if(fmt.width && s.length < fmt.width){
2512
var fill = fmt.fill || " ",
2513
align = fmt.align || "<",
2514
missing = fmt.width - s.length
2516
case "<":
2517
return s + fill.repeat(missing)
2518
case ">":
2519
return fill.repeat(missing) + s
2520
case "=":
2521
if("+-".indexOf(s.charAt(0)) > -1){
2522
return s.charAt(0) + fill.repeat(missing) + s.substr(1)
2526
case "^":
2527
var left = parseInt(missing / 2)
2528
return fill.repeat(left) + s + fill.repeat(missing - left)
2541
function fstring_error(msg, pos){
2542
error = Error(msg)
2543
error.position = pos
2544
throw error
2545
}
2546
2547
$B.parse_fstring = function(string){
2548
// Parse a f-string
2549
var elts = [],
2550
pos = 0,
2612
}else if(ctype == "debug"){
2613
// after the equal sign, whitespace are ignored and the only
2614
// valid characters are } and :
2615
while(string.charAt(i) == " "){i++}
2616
if(string.charAt(i) == "}"){
2617
// end of debug expression
2618
elts.push(current)
2619
ctype = null
2620
current = ""
2621
pos = i + 1
2622
}
2623
}else{
2624
// End of expression is the } matching the opening {
2625
// There may be nested braces
2626
var i = pos,
2627
nb_braces = 1,
2640
if(current.expression == ""){
2641
fstring_error("f-string: empty expression not allowed",
2642
pos)
2643
}
2653
// backslash is not allowed in expressions
2654
throw Error("f-string expression part cannot include a" +
2655
" backslash")
2662
throw Error("f-string: invalid conversion character:" +
2663
" expected 's', 'r', or 'a'")
2664
}else{
2678
if(string.substr(i, 3) == '"""'){
2679
var end = string.indexOf('"""', i + 3)
2680
if(end == -1){
2682
}else{
2683
var trs = string.substring(i, end + 3)
2684
trs = trs.replace("\n", "\\n\\")
2703
var ce = current.expression,
2704
last_char = ce.charAt(ce.length - 1),
2705
last_char_re = ('()'.indexOf(last_char) > -1 ? "\\" : "") + last_char
2710
"=!<>:".search(last_char_re) > -1){
2711
current.expression += car //+ string.charAt(i + 1)
2712
i += 1
2713
}else{
2714
// add debug string
2715
tail = car
2716
while(string.charAt(i + 1).match(/\s/)){
2717
tail += string.charAt(i + 1)
2718
i++
2719
}
2720
elts.push(current.expression + tail)
2721
// remove trailing whitespace from expression
2722
while(ce.match(/\s$/)){
2723
ce = ce.substr(0, ce.length - 1)
2724
}
2725
current.expression = ce
2726
ctype = "debug"
2727
i++
2728
}
2744
if(i >= 0x10000 && i <= 0x10FFFF){
2745
var code = (i - 0x10000)
2746
return String.fromCodePoint(0xD800 | (code >> 10)) +
2747
String.fromCodePoint(0xDC00 | (code & 0x3FF))
2748
}else{
2749
return String.fromCodePoint(i)
2750
}
2751
}
2754
if(c.length == 1){
2755
return c.charCodeAt(0)
2756
}
2757
var code = 0x10000
2758
code += (c.charCodeAt(0) & 0x03FF) << 10
2759
code += (c.charCodeAt(1) & 0x03FF)
2760
return code
2761
}
2762