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