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 12, 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
2562 lines (2347 sloc)
81.2 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
174
if(str_hash_cache[self] !== undefined){
175
$B.nb_cache++
176
return str_hash_cache[self]
177
}
178
return str_hash_cache[self] = fnv(self)
229
// left adjusted
230
return s + get_char_array(padding - s.length, flags.pad_char)
231
}
232
}
233
241
if(val.__class__ === $B.long_int){
242
s = $B.long_int.to_base(val, 10)
243
}else{
244
s = val.toString()
246
if(s[0] === "-"){
247
return "-" + get_char_array(precision - s.length + 1, "0") + s.slice(1)
258
if(val === Infinity){
259
val = "inf"
260
}else if(val === -Infinity){
261
val = "-inf"
262
}else{
263
val = "nan"
285
var str_format = function(val, flags) {
286
// string format supports left and right padding
287
flags.pad_char = " " // even if 0 padding is defined, don't use it
293
if(val.__class__ === $B.long_int){
294
val = $B.long_int.to_base(val, 10)
295
}else{
296
val = parseInt(val)
314
var repr_format = function(val, flags) {
315
flags.pad_char = " " // even if 0 padding is defined, don't use it
316
return format_padding(repr(val), flags)
317
}
319
var ascii_format = function(val, flags) {
320
flags.pad_char = " " // even if 0 padding is defined, don't use it
321
return format_padding(ascii(val), flags)
322
}
334
flags.precision = parseInt(flags.precision, 10)
335
validate_precision(flags.precision)
336
}
337
return parseFloat(val)
338
}
341
var trailing_zeros = /(.*?)(0+)([eE].*)/,
342
leading_zeros = /\.(0*)/,
343
trailing_dot = /\.$/
345
var validate_precision = function(precision) {
346
// force precision to limits of javascript
351
var floating_point_format = function(val, upper, flags){
352
val = _float_helper(val, flags),
353
v = val.toString(),
354
v_len = v.length,
355
dot_idx = v.indexOf('.')
356
if(dot_idx < 0){dot_idx = v_len}
357
if(val < 1 && val > -1){
358
var zeros = leading_zeros.exec(v),
359
numzeros
360
if(zeros){
365
if(numzeros >= 4){
366
val = format_sign(val, flags) + format_float_precision(val, upper,
367
flags, _floating_g_exp_helper)
368
if(!flags.alternate){
381
return format_padding(format_sign(val, flags) +
382
format_float_precision(val, upper, flags,
383
function(val, precision) {
384
return val.toFixed(min(precision, v_len - dot_idx) +
385
numzeros)
386
}),
387
flags
388
)
389
}
390
391
if(dot_idx > flags.precision){
392
val = format_sign(val, flags) + format_float_precision(val, upper,
393
flags, _floating_g_exp_helper)
394
if(! flags.alternate){
406
return format_padding(format_sign(val, flags) +
407
format_float_precision(val, upper, flags,
408
function(val, precision) {
409
if(!flags.decimal_point){
410
precision = min(v_len - 1, 6)
411
}else if (precision > v_len){
412
if(! flags.alternate){
413
precision = v_len
414
}
416
if(precision < dot_idx){
417
precision = dot_idx
418
}
419
return val.toFixed(precision - dot_idx)
420
}),
421
flags
422
)
425
var _floating_g_exp_helper = function(val, precision, flags, upper){
426
if(precision){--precision}
429
var e_idx = val.lastIndexOf("e")
430
if(e_idx > val.length - 4){
431
val = val.substring(0, e_idx + 2) + "0" + val.substring(e_idx + 2)
434
return val
435
}
436
437
// fF
438
var floating_point_decimal_format = function(val, upper, flags) {
439
val = _float_helper(val, flags)
440
return format_padding(format_sign(val, flags) +
441
format_float_precision(val, upper, flags,
442
function(val, precision, flags) {
443
val = val.toFixed(precision)
444
if(precision === 0 && flags.alternate){
445
val += '.'
446
}
447
return val
448
}),
449
flags
450
)
451
}
452
453
var _floating_exp_helper = function(val, precision, flags, upper) {
454
val = val.toExponential(precision)
455
// pad exponent to two digits
468
return format_padding(format_sign(val, flags) +
469
format_float_precision(val, upper, flags, _floating_exp_helper), flags)
495
if(flags.alternate){
496
if(ret.charAt(0) === "-"){
497
if(upper){ret = "-0X" + ret.slice(1)}
498
else{ret = "-0x" + ret.slice(1)}
499
}else{
500
if(upper){ret = "0X" + ret}
501
else{ret = "0x" + ret}
511
if(val.__class__ === $B.long_int){
512
ret = $B.long_int.to_base(8)
513
}else{
514
ret = parseInt(val)
515
ret = ret.toString(8)
531
if(flags.alternate){
532
if(ret.charAt(0) === "-"){ret = "-0o" + ret.slice(1)}
533
else{ret = "0o" + ret}
538
function series_of_bytes(val, flags){
539
if(val.__class__ && val.__class__.$buffer_protocol){
540
var it = _b_.iter(val),
541
ints = []
542
while(true){
543
try{
544
ints.push(_b_.next(it))
545
}catch(err){
546
if(err.__class__ === _b_.StopIteration){
547
var b = _b_.bytes.$factory(ints)
548
return format_padding(_b_.bytes.decode(b, "ascii"), flags)
549
}
550
throw err
551
}
552
}
553
}else{
554
try{
555
bytes_obj = $B.$getattr(val, "__bytes__")
556
return format_padding(_b_.bytes.decode(bytes_obj), flags)
557
}catch(err){
558
if(err.__class__ === _b_.AttributeError){
559
throw _b_.TypeError.$factory("%b does not accept '" +
560
$B.class_name(val) + "'")
561
}
562
throw err
563
}
564
}
565
}
566
568
if(isinstance(val, str) && val.length == 1){
569
return val
570
}else if(isinstance(val, bytes) && val.source.length == 1){
571
val = val.source[0]
572
}else{
573
try{
574
val = _b_.int.$factory(val) // yes, floats are valid (they are cast to int)
575
}catch (err){
576
throw _b_.TypeError.$factory("%c requires int or char")
577
}
582
var num_flag = function(c, flags){
583
if(c === "0" && ! flags.padding && ! flags.decimal_point && ! flags.left){
584
flags.pad_char = "0"
590
flags.precision = (flags.precision || "") + c
591
}
592
}
593
594
var decimal_point_flag = function(val, flags) {
596
// can only have one decimal point
597
throw new UnsupportedChar()
598
}
599
flags.decimal_point = true
600
}
601
602
var neg_flag = function(val, flags){
603
flags.pad_char = " " // overrides '0' flag
621
"s": str_format,
622
"d": num_format,
623
"i": num_format,
624
"u": num_format,
625
"o": octal_format,
626
"r": repr_format,
627
"a": ascii_format,
628
"g": function(val, flags){
629
return floating_point_format(val, false, flags)
630
},
631
"G": function(val, flags){return floating_point_format(val, true, flags)},
632
"f": function(val, flags){
633
return floating_point_decimal_format(val, false, flags)
634
},
635
"F": function(val, flags){
636
return floating_point_decimal_format(val, true, flags)
637
},
638
"e": function(val, flags){
639
return floating_point_exponential_format(val, false, flags)
640
},
641
"E": function(val, flags){
642
return floating_point_exponential_format(val, true, flags)
643
},
644
"x": function(val, flags){return signed_hex_format(val, false, flags)},
645
"X": function(val, flags){return signed_hex_format(val, true, flags)},
646
"c": single_char_format,
647
"0": function(val, flags){return num_flag("0", flags)},
648
"1": function(val, flags){return num_flag("1", flags)},
649
"2": function(val, flags){return num_flag("2", flags)},
650
"3": function(val, flags){return num_flag("3", flags)},
651
"4": function(val, flags){return num_flag("4", flags)},
652
"5": function(val, flags){return num_flag("5", flags)},
653
"6": function(val, flags){return num_flag("6", flags)},
654
"7": function(val, flags){return num_flag("7", flags)},
655
"8": function(val, flags){return num_flag("8", flags)},
656
"9": function(val, flags){return num_flag("9", flags)},
657
"-": neg_flag,
658
" ": space_flag,
659
"+": sign_flag,
660
".": decimal_point_flag,
661
"#": alternate_flag
662
}
663
664
// exception thrown when an unsupported char is encountered in legacy format
711
if(self === undefined){
712
throw _b_.TypeError.$factory(
713
"not enough arguments for format string")
740
throw _b_.ValueError.$factory(
741
"unsupported format character '" + invalid_char +
742
"' (0x" + invalid_char.charCodeAt(0).toString(16) +
743
") at index " + newpos)
744
}else if(err.name === "NotANumber"){
745
var try_char = s[newpos],
746
cls = self.__class__
747
if(!cls){
748
if(typeof(self) === "string"){
749
cls = "str"
750
}else{
756
throw _b_.TypeError.$factory("%" + try_char +
757
" format: a number is required, not " + cls)
758
}else{
790
}while(pos < length)
791
792
if(argpos !== null){
793
if(args.length > argpos){
794
throw _b_.TypeError.$factory(
795
"not enough arguments for format string")
796
}else if(args.length < argpos){
797
throw _b_.TypeError.$factory(
798
"not all arguments converted during string formatting")
800
}else if(nbph == 0){
801
throw _b_.TypeError.$factory(
802
"not all arguments converted during string formatting")
810
var $ = $B.args("__mul__", 2, {self: null, other: null},
811
["self", "other"], arguments, {}, null, null)
812
if(! isinstance($.other, _b_.int)){throw _b_.TypeError.$factory(
813
"Can't multiply sequence by non-int of type '" +
825
res = self.replace(/\\/g, "\\\\")
826
// special cases
827
res = res.replace(new RegExp("\u0007", "g"), "\\x07").
828
replace(new RegExp("\b", "g"), "\\x08").
830
replace(new RegExp("\f", "g"), "\\x0c").
831
replace(new RegExp("\n", "g"), "\\n").
832
replace(new RegExp("\r", "g"), "\\r").
833
replace(new RegExp("\t", "g"), "\\t")
835
if(res.search('"') == -1 && res.search("'") == -1){
836
return "'" + res + "'"
837
}else if(self.search('"') == -1){
838
return '"' + res + '"'
839
}
840
var qesc = new RegExp("'", "g") // to escape single quote
841
res = "'" + res.replace(qesc, "\\'") + "'"
845
str.__setitem__ = function(self, attr, value){
846
throw _b_.TypeError.$factory(
847
"'str' object does not support item assignment")
849
var combining = []
850
for(var cp = 0x300; cp <= 0x36F; cp++){
851
combining.push(String.fromCharCode(cp))
852
}
853
var combining_re = new RegExp("(" + combining.join("|") + ")")
865
$comp_func += "" // source code
866
var $comps = {">": "gt", ">=": "ge", "<": "lt", "<=": "le"}
875
var $notimplemented = function(self, other){
876
throw NotImplementedError.$factory(
877
"OPERATOR not implemented for class str")
880
str.capitalize = function(self){
881
var $ = $B.args("capitalize", 1, {self}, ["self"],
882
arguments, {}, null, null)
883
if(self.length == 0){return ""}
884
return self.charAt(0).toUpperCase() + self.substr(1)
885
}
886
887
str.casefold = function(self){
888
var $ = $B.args("casefold", 1, {self}, ["self"],
889
arguments, {}, null, null),
890
res = "",
891
char,
892
cf
893
for(var i = 0, len = self.length; i < len; i++){
894
char = self.charCodeAt(i)
895
cf = $B.unicode_casefold[char]
896
if(cf){
897
cf.forEach(function(cp){
898
res += String.fromCharCode(cp)
899
})
900
}else{
901
res += self.charAt(i).toLowerCase()
902
}
903
}
904
return res
905
}
907
str.center = function(){
908
var $ = $B.args("center", 3, {self: null, width: null, fillchar: null},
909
["self", "width", "fillchar"],
910
arguments, {fillchar:" "}, null, null),
911
self = $.self
923
var $ = $B.args("count", 4, {self:null, sub:null, start:null, stop:null},
924
["self", "sub", "start", "stop"], arguments, {start:null, stop:null},
932
if($.stop !== null){_slice = _b_.slice.$factory($.start, $.stop)}
933
else{_slice = _b_.slice.$factory($.start, $.self.length)}
938
if($.sub.length == 0){
939
if($.start == $.self.length){return 1}
940
else if(substr.length == 0){return 0}
941
return substr.length + 1
943
var n = 0,
944
pos = 0
945
while(pos < substr.length){
946
pos = substr.indexOf($.sub, pos)
947
if(pos >= 0){n++; pos += $.sub.length}
948
else{break}
953
str.encode = function(){
954
var $ = $B.args("encode", 3, {self: null, encoding: null, errors: null},
955
["self", "encoding", "errors"], arguments,
956
{encoding: "utf-8", errors: "strict"}, null, null)
957
if($.encoding == "rot13" || $.encoding == "rot_13"){
962
if(("a" <= char && char <= "m") || ("A" <= char && char <= "M")){
963
res += String.fromCharCode(String.charCodeAt(char) + 13)
964
}else if(("m" < char && char <= "z") ||
965
("M" < char && char <= "Z")){
966
res += String.fromCharCode(String.charCodeAt(char) - 13)
975
// Return True if the string ends with the specified suffix, otherwise
976
// return False. suffix can also be a tuple of suffixes to look for.
977
// With optional start, test beginning at that position. With optional
981
["self", "suffix", "start", "end"],
982
arguments, {start: 0, end: null}, null, null)
989
var s = $.self.substring($.start, $.end)
990
for(var i = 0, len = suffixes.length; i < len; i++){
994
if(suffix.length <= s.length &&
995
s.substr(s.length - suffix.length) == suffix){return true}
1001
var $ = $B.args("expandtabs", 2, {self: null, tabsize: null},
1002
["self", "tabsize"], arguments, {tabsize: 8}, null, null)
1003
var s = $B.$GetInt($.tabsize),
1004
col = 0,
1005
pos = 0,
1006
res = ""
1007
if(s == 1){return self.replace(/\t/g," ")}
1008
while(pos < self.length){
1016
res += car
1017
col = 0
1018
break
1019
default:
1020
res += car
1021
col++
1022
break
1023
}
1024
pos++
1025
}
1031
// Return the lowest index in the string where substring sub is found,
1032
// such that sub is contained in the slice s[start:end]. Optional
1033
// arguments start and end are interpreted as in slice notation.
1036
{self: null, sub: null, start: null, end: null},
1037
["self", "sub", "start", "end"],
1038
arguments, {start: 0, end: null}, null, null)
1042
if(!isinstance($.start, _b_.int)||!isinstance($.end, _b_.int)){
1043
throw _b_.TypeError.$factory("slice indices must be " +
1044
"integers or None or have an __index__ method")}
1045
// Can't use string.substring(start, end) because if end < start,
1046
// Javascript transforms it into substring(end, start)...
1047
var s = ""
1048
for(var i = $.start; i < $.end; i++){
1049
s += $.self.charAt(i)
1050
}
1052
if($.sub.length == 0 && $.start == $.self.length){return $.self.length}
1053
if(s.length + $.sub.length == 0){return -1}
1055
var last_search = s.length - $.sub.length
1056
for(var i = 0; i <= last_search; i++){
1057
if(s.substr(i, $.sub.length) == $.sub){return $.start + i}
1068
// a.x[z]!r:...
1069
// the object has attributes :
1070
// - name : "a"
1071
// - name_ext : [".x", "[z]"]
1072
// - conv : r
1073
// - spec : rest of string after :
1081
// No : in the string : it only contains a name
1082
name = fmt_string
1083
}else{
1084
// name is before the first ":"
1085
// spec (the format specification) is after
1086
name = elts[0]
1090
var elts = name.split("!")
1091
if(elts.length > 1){
1092
name = elts[0]
1093
conv = elts[1] // conversion flag
1097
// "name' may be a subscription or attribute
1098
// Put these "extensions" in the list "name_ext"
1099
function name_repl(match){
1100
name_ext.push(match)
1102
}
1103
var name_ext_re = /\.[_a-zA-Z][_a-zA-Z0-9]*|\[[_a-zA-Z][_a-zA-Z0-9]*\]|\[[0-9]+\]/g
1104
name = name.replace(name_ext_re, name_repl)
1105
}
1112
// Parse self to detect formatting instructions
1113
// Create a list "parts" made of sections of the string :
1114
// - elements of even rank are literal text
1115
// - elements of odd rank are "format objects", built from the
1116
// format strings in self (of the form {...})
1127
text += "{"
1128
pos += 2
1129
}else if(car == "}" && self.charAt(pos + 1) == "}"){
1136
// Store current literal text
1137
parts.push(text)
1138
1139
// Search the end of the format string, ie the } closing the
1140
// opening {. Since the string can contain other pairs {} for
1141
// nested formatting, an integer nb is incremented for each { and
1142
// decremented for each } ; the end of the format string is
1143
// reached when nb == 0
1144
var end = pos + 1,
1145
nb = 1
1146
while(end < _len){
1147
if(self.charAt(end) == "{"){nb++; end++}
1148
else if(self.charAt(end) == "}"){
1149
nb--; end++
1150
if(nb == 0){
1155
var fmt_obj = $B.parse_format(fmt_string)
1156
fmt_obj.raw_name = fmt_obj.name
1157
fmt_obj.raw_spec = fmt_obj.spec
1192
return parts
1193
}
1194
1195
str.format = function(self) {
1196
var $ = $B.args("format", 1, {self: null}, ["self"],
1197
arguments, {}, "$args", "$kw")
1198
1199
var parts = $B.split_format($.self)
1200
1211
1212
if(fmt.spec !== undefined){
1213
// "spec" may contain "nested replacement fields"
1214
// In this case, evaluate them using the positional
1215
// or keyword arguments passed to format()
1216
function replace_nested(name, key){
1217
if(/\d+/.exec(key)){
1218
// If key is numeric, search in positional
1219
// arguments
1220
return _b_.tuple.__getitem__($.$args,
1221
parseInt(key))
1222
}else{
1223
// Else try in keyword arguments
1224
return _b_.dict.__getitem__($.$kw, key)
1225
}
1226
}
1227
fmt.spec = fmt.spec.replace(/\{(.*?)\}/g,
1228
replace_nested)
1229
}
1231
// Numerical reference : use positional arguments
1232
var pos = parseInt(fmt.name),
1242
// Attribute
1243
value = _b_.getattr(value, ext.substr(1))
1244
}else{
1245
// Subscription
1248
if(key.charAt(0).search(/\d/) > -1){key = parseInt(key)}
1249
value = _b_.getattr(value, "__getitem__")(key)
1253
// If the conversion flag is set, first call a function to convert
1254
// the value
1255
if(fmt.conv == "a"){value = _b_.ascii(value)}
1256
else if(fmt.conv == "r"){value = _b_.repr(value)}
1257
else if(fmt.conv == "s"){value = _b_.str.$factory(value)}
1271
throw NotImplementedError.$factory(
1272
"function format_map not implemented yet")
1283
/* Return true if the string is empty or all characters in the string are
1284
ASCII, false otherwise. ASCII characters have code points in the range
1285
U+0000-U+007F. */
1286
for(var i = 0, len = self.length; i < len; i++){
1287
if(self.charCodeAt(i) > 127){return false}
1288
}
1289
return true
1290
}
1291
1292
str.isalnum = function(self){
1293
/* Return true if all characters in the string are alphanumeric and there
1294
is at least one character, false otherwise. A character c is alphanumeric
1295
if one of the following returns True: c.isalpha(), c.isdecimal(),
1296
c.isdigit(), or c.isnumeric(). */
1297
var $ = $B.args("isalnum", 1, {self: null}, ["self"],
1298
arguments, {}, null, null),
1299
char
1300
for(var i = 0, len = self.length; i < len; i++){
1301
char = self.charCodeAt(i)
1302
if(unicode_tables.Ll[char] ||
1303
unicode_tables.Lu[char] ||
1304
unicode_tables.Lm[char] ||
1305
unicode_tables.Lt[char] ||
1306
unicode_tables.Lo[char] ||
1307
unicode_tables.Nd[char] ||
1308
unicode_tables.digits[char] ||
1309
unicode_tables.numeric[char]){
1310
continue
1311
}
1312
return false
1313
}
1314
return true
1315
}
1316
1317
str.isalpha = function(self){
1318
/* Return true if all characters in the string are alphabetic and there is
1319
at least one character, false otherwise. Alphabetic characters are those
1320
characters defined in the Unicode character database as "Letter", i.e.,
1321
those with general category property being one of "Lm", "Lt", "Lu", "Ll",
1322
or "Lo". */
1323
var $ = $B.args("isalpha", 1, {self: null}, ["self"],
1324
arguments, {}, null, null),
1325
char
1326
for(var i = 0, len = self.length; i < len; i++){
1327
char = self.charCodeAt(i)
1328
if(unicode_tables.Ll[char] ||
1329
unicode_tables.Lu[char] ||
1330
unicode_tables.Lm[char] ||
1331
unicode_tables.Lt[char] ||
1332
unicode_tables.Lo[char]){
1333
continue
1334
}
1335
return false
1336
}
1337
return true
1338
}
1339
1340
str.isdecimal = function(self){
1341
/* Return true if all characters in the string are decimal characters and
1342
there is at least one character, false otherwise. Decimal characters are
1343
those that can be used to form numbers in base 10, e.g. U+0660,
1344
ARABIC-INDIC DIGIT ZERO. Formally a decimal character is a character in
1345
the Unicode General Category "Nd". */
1346
var $ = $B.args("isdecimal", 1, {self: null}, ["self"],
1347
arguments, {}, null, null),
1348
char
1349
for(var i = 0, len = self.length; i < len; i++){
1350
char = self.charCodeAt(i)
1351
if(! unicode_tables.Nd[char]){
1352
return false
1353
}
1354
}
1355
return self.length > 0
1356
}
1357
1358
str.isdigit = function(self){
1359
/* Return true if all characters in the string are digits and there is at
1360
least one character, false otherwise. */
1361
var $ = $B.args("isdigit", 1, {self: null}, ["self"],
1362
arguments, {}, null, null),
1363
char
1364
for(var i = 0, len = self.length; i < len; i++){
1365
char = self.charCodeAt(i)
1366
if(! unicode_tables.digits[char]){
1367
return false
1368
}
1369
}
1370
return self.length > 0
1371
}
1372
1373
str.isidentifier = function(self){
1374
/* Return true if the string is a valid identifier according to the
1375
language definition. */
1376
var $ = $B.args("isidentifier", 1, {self: null}, ["self"],
1377
arguments, {}, null, null),
1378
char
1379
if(self.length == 0){return false}
1380
else if(unicode_tables.XID_Start[self.charCodeAt(0)] === undefined){
1381
return false
1382
}else{
1383
for(var i = 1, len = self.length; i < len; i++){
1384
if(unicode_tables.XID_Continue[self.charCodeAt(i)] === undefined){
1385
return false
1386
}
1387
}
1388
}
1389
return true
1390
}
1391
1392
str.islower = function(self){
1393
/* Return true if all cased characters 4 in the string are lowercase and
1394
there is at least one cased character, false otherwise. */
1395
var $ = $B.args("islower", 1, {self: null}, ["self"],
1396
arguments, {}, null, null),
1397
has_cased = false,
1398
char
1399
1400
for(var i = 0, len = self.length; i < len; i++){
1401
char = self.charCodeAt(i)
1402
if(unicode_tables.Ll[char]){has_cased = true; continue}
1403
else if(unicode_tables.Lu[char] || unicode_tables.Lt[char]){
1404
return false
1405
}
1406
}
1407
return has_cased
1408
}
1409
1410
str.isnumeric = function(self){
1411
/* Return true if all characters in the string are numeric characters, and
1412
there is at least one character, false otherwise. Numeric characters
1413
include digit characters, and all characters that have the Unicode numeric
1414
value property, e.g. U+2155, VULGAR FRACTION ONE FIFTH. Formally, numeric
1415
characters are those with the property value Numeric_Type=Digit,
1416
Numeric_Type=Decimal or Numeric_Type=Numeric.*/
1417
var $ = $B.args("isnumeric", 1, {self: null}, ["self"],
1418
arguments, {}, null, null)
1419
for(var i = 0, len = self.length; i < len; i++){
1420
if(! unicode_tables.numeric[self.charCodeAt(i)]){
1421
return false
1422
}
1423
}
1424
return self.length > 0
1425
}
1426
1427
var printable,
1428
printable_gc = ['Cc', 'Cf', 'Co', 'Cs','Zl', 'Zp', 'Zs']
1429
1430
str.isprintable = function(self){
1431
/* Return true if all characters in the string are printable or the string
1432
is empty, false otherwise. Nonprintable characters are those characters
1433
defined in the Unicode character database as "Other" or "Separator",
1434
excepting the ASCII space (0x20) which is considered printable. */
1435
1436
// Set printable if not set yet
1437
if(printable === undefined){
1438
for(var i = 0; i < printable_gc.length; i++){
1439
var table = unicode_tables[printable_gc[i]]
1440
for(var cp in table){
1441
printable[cp] = true
1442
}
1443
}
1444
printable[32] = true
1445
}
1446
1447
var $ = $B.args("isprintable", 1, {self: null}, ["self"],
1448
arguments, {}, null, null),
1449
char,
1450
flag
1451
for(var i = 0, len = self.length; i < len; i++){
1452
char = self.charCodeAt(i)
1453
if(! printable[char]){
1454
return false
1455
}
1456
}
1457
return true
1458
}
1459
1460
str.isspace = function(self){
1461
/* Return true if there are only whitespace characters in the string and
1462
there is at least one character, false otherwise.
1463
1464
A character is whitespace if in the Unicode character database, either its
1465
general category is Zs ("Separator, space"), or its bidirectional class is
1466
one of WS, B, or S.*/
1467
var $ = $B.args("isspace", 1, {self: null}, ["self"],
1468
arguments, {}, null, null),
1469
char
1470
for(var i = 0, len = self.length; i < len; i++){
1471
char = self.charCodeAt(i)
1472
if(! unicode_tables.Zs[char] &&
1473
$B.unicode_bidi_whitespace.indexOf(char) == -1){
1474
return false
1475
}
1476
}
1477
return self.length > 0
1478
}
1479
1480
str.istitle = function(self){
1481
/* Return true if the string is a titlecased string and there is at least
1482
one character, for example uppercase characters may only follow uncased
1483
characters and lowercase characters only cased ones. Return false
1484
otherwise. */
1485
var $ = $B.args("istitle", 1, {self: null}, ["self"],
1486
arguments, {}, null, null)
1487
return self.length > 0 && str.title(self) == self
1488
}
1489
1490
str.isupper = function(self){
1491
/* Return true if all cased characters 4 in the string are lowercase and
1492
there is at least one cased character, false otherwise. */
1493
var $ = $B.args("islower", 1, {self: null}, ["self"],
1494
arguments, {}, null, null),
1495
has_cased = false,
1496
char
1497
1498
for(var i = 0, len = self.length; i < len; i++){
1499
char = self.charCodeAt(i)
1500
if(unicode_tables.Lu[char]){has_cased = true; continue}
1501
else if(unicode_tables.Ll[char] || unicode_tables.Lt[char]){
1519
if(! isinstance(obj2, str)){throw _b_.TypeError.$factory(
1520
"sequence item " + count + ": expected str instance, " +
1534
var $ = $B.args("ljust", 3, {self: null, width: null, fillchar:null},
1535
["self", "width", "fillchar"],
1536
arguments, {fillchar: " "}, null, null)
1542
str.lower = function(self){
1543
var $ = $B.args("lower", 1, {self: null}, ["self"],
1544
arguments, {}, null, null)
1545
return self.toLowerCase()
1546
}
1547
1549
var $ = $B.args("lstrip", 2, {self: null, chars: null}, ["self", "chars"],
1550
arguments, {chars:_b_.None}, null, null)
1551
if($.chars === _b_.None){return $.self.trimLeft()}
1552
for(var i = 0; i < $.self.length; i++){
1553
if($.chars.indexOf($.self.charAt(i)) === -1){
1554
return $.self.substring(i)
1562
var $ = $B.args("maketrans", 3, {x: null, y: null, z: null},
1563
["x", "y", "z"], arguments, {y: null, z: null}, null, null)
1568
// If there is only one argument, it must be a dictionary mapping
1569
// Unicode ordinals (integers) or characters (strings of length 1) to
1570
// Unicode ordinals, strings (of arbitrary lengths) or None. Character
1572
if(! _b_.isinstance($.x, _b_.dict)){
1573
throw _b_.TypeError.$factory(
1574
"maketrans only argument must be a dict")
1577
for(var i = 0, len = items.length; i < len; i++){
1578
var k = items[i][0],
1579
v = items[i][1]
1580
if(! _b_.isinstance(k, _b_.int)){
1581
if(_b_.isinstance(k, _b_.str) && k.length == 1){
1582
k = _b_.ord(k)
1583
}else{throw _b_.TypeError.$factory("dictionary key " + k +
1586
if(v !== _b_.None && ! _b_.isinstance(v, [_b_.int, _b_.str])){
1587
throw _b_.TypeError.$factory("dictionary value " + v +
1595
// and in the resulting dictionary, each character in x will be mapped
1596
// to the character at the same position in y
1599
}else if($.x.length !== $.y.length){
1600
throw _b_.TypeError.$factory(
1601
"maketrans arguments must be strings or same length")
1607
if(! _b_.isinstance($.z, _b_.str)){
1608
throw _b_.TypeError.$factory(
1609
"maketrans third argument must be a string")
1631
var $ = $B.args("partition", 2, {self: null, sep: null}, ["self", "sep"],
1632
arguments, {}, null, null)
1637
return _b_.tuple.$factory([$.self.substring(0, i), $.sep,
1638
$.self.substring(i + $.sep.length)])
1639
}
1640
1641
str.removeprefix = function(){
1642
var $ = $B.args("removeprefix", 2, {self: null, prefix: null},
1643
["self", "prefix"], arguments, {}, null, null)
1644
if(!_b_.isinstance($.prefix, str)){
1645
throw _b_.ValueError.$factory("prefix should be str, not " +
1646
`'${$B.class_name($.prefix)}'`)
1647
}
1648
if(str.startswith($.self, $.prefix)){
1649
return $.self.substr($.prefix.length)
1650
}
1651
return $.self.substr(0)
1652
}
1653
1654
str.removesuffix = function(){
1655
var $ = $B.args("removesuffix", 2, {self: null, prefix: null},
1656
["self", "suffix"], arguments, {}, null, null)
1657
if(!_b_.isinstance($.suffix, str)){
1658
throw _b_.ValueError.$factory("suffix should be str, not " +
1659
`'${$B.class_name($.prefix)}'`)
1660
}
1661
if($.suffix.length > 0 && str.endswith($.self, $.suffix)){
1662
return $.self.substr(0, $.self.length - $.suffix.length)
1663
}
1664
return $.self.substr(0)
1665
}
1666
1667
function $re_escape(str){
1668
var specials = "[.*+?|()$^"
1669
for(var i = 0, len = specials.length; i < len; i++){
1670
var re = new RegExp("\\"+specials.charAt(i), "g")
1671
str = str.replace(re, "\\"+specials.charAt(i))
1672
}
1673
return str
1680
var $ = $B.args("replace", 4,
1681
{self: null, old: null, $$new: null, count: null},
1682
["self", "old", "$$new", "count"],
1683
arguments, {count: -1}, null, null),
1684
count = $.count,
1685
self = $.self,
1686
old = $.old,
1687
_new = $.$$new
1694
"' object cannot be interpreted as an integer")
1695
}else if(isinstance(count, _b_.float)){
1696
throw _b_.TypeError.$factory("integer argument expected, got float")
1697
}
1698
if(count == 0){return self}
1699
if(count.__class__ == $B.long_int){count = parseInt(count.value)}
1700
if(old == ""){
1701
if(_new == ""){return self}
1702
if(self == ""){return _new}
1703
var elts = self.split("")
1704
if(count > -1 && elts.length >= count){
1705
var rest = elts.slice(count).join("")
1706
return _new + elts.slice(0, count).join(_new) + rest
1707
}else{return _new + elts.join(_new) + _new}
1722
if(count < 0){count = res.length}
1723
while(count > 0){
1724
pos = res.indexOf(old, pos)
1725
if(pos < 0){break}
1726
res = res.substr(0, pos) + _new + res.substr(pos + old.length)
1727
pos = pos + _new.length
1728
count--
1734
// Return the highest index in the string where substring sub is found,
1735
// such that sub is contained within s[start:end]. Optional arguments
1737
if(arguments.length == 2 && typeof substr == "string"){
1738
return self.lastIndexOf(substr)
1739
}
1741
{self: null, sub: null, start: null, end: null},
1742
["self", "sub", "start", "end"],
1743
arguments, {start: 0, end: null}, null, null)
1755
for(var i = $.end - sublen; i >= $.start; i--){
1756
if($.self.substr(i, sublen) == $.sub){return i}
1763
var res = str.rfind.apply(null, arguments)
1764
if(res == -1){throw _b_.ValueError.$factory("substring not found")}
1769
var $ = $B.args("rjust",3,
1770
{self: null, width: null, fillchar: null},
1771
["self", "width", "fillchar"],
1772
arguments, {fillchar: " "}, null, null)
1780
var $ = $B.args("rpartition", 2, {self: null, sep: null}, ["self", "sep"],
1781
arguments, {}, null, null)
1785
var items = str.partition(self, sep).reverse()
1786
for(var i = 0; i < items.length; i++){
1787
items[i] = items[i].split("").reverse().join("")
1793
var $ = $B.args("rsplit", 3, {self: null, sep: null, maxsplit: null},
1794
["self", "sep", "maxsplit"], arguments,
1795
{sep: _b_.None, maxsplit: -1}, null, null),
1796
sep = $.sep
1799
var rev_str = reverse($.self),
1800
rev_sep = sep === _b_.None ? sep : reverse($.sep),
1811
str.rstrip = function(self, x){
1812
var $ = $B.args("rstrip", 2, {self: null, chars: null}, ["self", "chars"],
1813
arguments, {chars: _b_.None}, null, null)
1814
if($.chars === _b_.None){return $.self.trimRight()}
1816
if($.chars.indexOf($.self.charAt(j)) == -1){
1817
return $.self.substring(0, j + 1)
1824
var $ = $B.args("split", 3, {self: null, sep: null, maxsplit: null},
1825
["self", "sep", "maxsplit"], arguments,
1826
{sep: _b_.None, maxsplit: -1}, null, null),
1827
sep = $.sep,
1828
maxsplit = $.maxsplit,
1829
self = $.self,
1830
pos = 0
1831
if(maxsplit.__class__ === $B.long_int){maxsplit = parseInt(maxsplit.value)}
1832
if(sep == ""){throw _b_.ValueError.$factory("empty separator")}
1833
if(sep === _b_.None){
1835
while(pos < self.length && self.charAt(pos).search(/\s/) > -1){pos++}
1836
if(pos === self.length - 1){return [self]}
1837
var name = ""
1839
if(self.charAt(pos).search(/\s/) == -1){
1840
if(name == ""){name = self.charAt(pos)}
1841
else{name += self.charAt(pos)}
1861
var res = [],
1862
s = "",
1863
seplen = sep.length
1864
if(maxsplit == 0){return [self]}
1865
while(pos < self.length){
1866
if(self.substr(pos, seplen) == sep){
1884
str.splitlines = function(self) {
1885
var $ = $B.args('splitlines', 2, {self: null, keepends: null},
1886
['self','keepends'], arguments, {keepends: false},
1887
null, null)
1888
if(!_b_.isinstance($.keepends,[_b_.bool, _b_.int])){
1889
throw _b_.TypeError('integer argument expected, got '+
1892
var keepends = _b_.int.$factory($.keepends),
1893
res = [],
1894
self = $.self,
1895
start = 0,
1896
pos = 0
1897
if(!self.length){
1900
while (pos < self.length) {
1901
if(self.substr(pos, 2) == '\r\n'){
1902
res.push(self.slice(start, keepends ? pos + 2 : pos))
1903
start = pos = pos+2
1904
}else if(self[pos] == '\r' || self[pos] == '\n'){
1905
res.push(self.slice(start, keepends ? pos+1 : pos))
1906
start = pos = pos+1
1907
}else{
1908
pos++
1909
}
1910
}
1911
if(start < self.length){
1912
res.push(self.slice(start))
1913
}
1914
return res
1918
// Return True if string starts with the prefix, otherwise return False.
1919
// prefix can also be a tuple of prefixes to look for. With optional
1920
// start, test string beginning at that position. With optional end,
1922
var $ = $B.args("startswith", 4,
1923
{self: null, prefix: null, start: null, end: null},
1924
["self", "prefix", "start", "end"],
1925
arguments, {start: 0, end: null}, null, null)
1932
var s = $.self.substring($.start, $.end)
1933
for(var i = 0, len = prefixes.length; i < len; i++){
1944
var $ = $B.args("strip", 2, {self: null, chars: null}, ["self", "chars"],
1945
arguments, {chars: _b_.None}, null, null)
1946
if($.chars === _b_.None){return $.self.trim()}
1947
for(var i = 0; i < $.self.length; i++){
1948
if($.chars.indexOf($.self.charAt(i)) == -1){
1949
break
1952
for(var j = $.self.length - 1; j >= i; j--){
1953
if($.chars.indexOf($.self.charAt(j)) == -1){
1954
break
1960
str.swapcase = function(self){
1961
var $ = $B.args("swapcase", 1, {self}, ["self"],
1962
arguments, {}, null, null),
1963
res = "",
1964
char
1965
1966
for(var i = 0, len = self.length; i < len; i++){
1967
char = self.charCodeAt(i)
1968
if(unicode_tables.Ll[char]){
1969
res += self.charAt(i).toUpperCase()
1970
}else if(unicode_tables.Lu[char]){
1971
res += self.charAt(i).toLowerCase()
1972
}else{
1973
res += self.charAt(i)
1974
}
1975
}
1976
return res
1977
}
1978
1979
str.title = function(self){
1980
var $ = $B.args("title", 1, {self}, ["self"],
1981
arguments, {}, null, null),
1982
state,
1983
char,
1984
res = ""
1985
for(var i = 0, len = self.length; i < len; i++){
1986
char = self.charCodeAt(i)
1987
if(unicode_tables.Ll[char]){
1988
if(! state){
1989
res += self.charAt(i).toUpperCase()
1990
state = "word"
1991
}else{
1992
res += self.charAt(i)
1993
}
1994
}else if(unicode_tables.Lu[char] || unicode_tables.Lt[char]){
1995
res += state ? self.charAt(i).toLowerCase() : self.charAt(i)
1996
state = "word"
1997
}else{
1998
state = null
1999
res += self.charAt(i)
2000
}
2001
}
2002
return res
2003
}
2004
2007
getitem = $B.$getattr(table, "__getitem__")
2008
for(var i = 0, len = self.length; i < len; i++){
2009
try{
2010
var repl = getitem(self.charCodeAt(i))
2011
if(repl !== _b_.None){
2012
if(typeof repl == "string"){
2013
res.push(repl)
2014
}else if(typeof repl == "number"){
2015
res.push(String.fromCharCode(repl))
2016
}
2025
str.upper = function(self){
2026
var $ = $B.args("upper", 1, {self: null}, ["self"],
2027
arguments, {}, null, null)
2028
return self.toUpperCase()
2029
}
2030
2033
["self", "width"], arguments, {}, null, null)
2034
if($.width <= self.length){return self}
2036
case "+":
2037
case "-":
2038
return self.charAt(0) +
2039
"0".repeat($.width - self.length) + self.substr(1)
2050
if(encoding !== undefined){
2051
// Arguments may be passed as keywords (cf. issue #1060)
2052
var $ = $B.args("str", 3, {arg: null, encoding: null, errors: null},
2053
["arg", "encoding", "errors"], arguments,
2054
{encoding: "utf-8", errors: "strict"}, null, null),
2055
encoding = $.encoding,
2056
errors = $.errors
2057
}
2068
// class or its subclasses, but the attribute __str__ of the
2069
// class metaclass (usually "type") or its subclasses (usually
2070
// "object")
2071
// The metaclass is the attribute __class__ of the class dictionary
2076
if(arg.__class__ && arg.__class__ === _b_.bytes &&
2077
encoding !== undefined){
2078
// str(bytes, encoding, errors) is equal to
2079
// bytes.decode(encoding, errors)
2082
// Implicit invocation of __str__ uses method __str__ on the class,
2083
// even if arg has an attribute __str__
2084
var klass = arg.__class__ || $B.get_class(arg)
2085
if(klass === undefined){
2086
return $B.JSObject.__str__($B.JSObject.$factory(arg))
2087
}
2090
// if not better than object.__str__, try __repr__
2091
(arg.__class__ && arg.__class__ !== _b_.object &&
2092
method.$infos && method.$infos.__func__ === _b_.object.__str__)){
2093
var method = $B.$getattr(klass, "__repr__")
2099
if($B.debug > 1){console.log(err)}
2100
console.log("Warning - no method __str__ or __repr__, " +
2101
"default to toString", arg)
2108
if(cls === undefined){
2109
throw _b_.TypeError.$factory("str.__new__(): not enough arguments")
2133
var args = [],
2134
pos = 0
2135
if(arguments.length > 0){
2136
var args = [arguments[0].valueOf()],
2137
pos = 1
2138
for(var i = 1, len = arguments.length; i < len; i++){
2139
args[pos++] = arguments[i]
2155
// Function to parse the 2nd argument of format()
2156
$B.parse_format_spec = function(spec){
2159
var pos = 0,
2160
aligns = "<>=^",
2161
digits = "0123456789",
2162
types = "bcdeEfFgGnosxX%",
2164
if(align_pos != -1){
2165
if(spec.charAt(1) && aligns.indexOf(spec.charAt(1)) != -1){
2166
// If the second char is also an alignment specifier, the
2167
// first char is the fill value
2168
this.fill = spec.charAt(0)
2169
this.align = spec.charAt(1)
2170
pos = 2
2171
}else{
2172
// The first character defines alignment : fill defaults to ' '
2187
if(car == "+" || car == "-" || car == " "){
2188
this.sign = car
2189
pos++
2190
car = spec.charAt(pos)
2192
if(car == "#"){this.alternate = true; pos++; car = spec.charAt(pos)}
2193
if(car == "0"){
2202
while(car && digits.indexOf(car) > -1){
2203
if(this.width === undefined){this.width = car}
2204
else{this.width += car}
2205
pos++
2206
car = spec.charAt(pos)
2209
if(this.width === undefined && car == "{"){
2210
// Width is determined by a parameter
2211
var end_param_pos = spec.substr(pos).search("}")
2212
this.width = spec.substring(pos, end_param_pos)
2213
console.log("width", "[" + this.width + "]")
2214
pos += end_param_pos + 1
2215
}
2216
if(car == ","){this.comma = true; pos++; car = spec.charAt(pos)}
2217
if(car == "."){
2218
if(digits.indexOf(spec.charAt(pos + 1)) == -1){
2219
throw _b_.ValueError.$factory(
2220
"Missing precision in format spec")
2222
this.precision = spec.charAt(pos + 1)
2223
pos += 2
2224
car = spec.charAt(pos)
2225
while(car && digits.indexOf(car) > -1){
2232
if(car && types.indexOf(car) > -1){
2233
this.type = car
2234
pos++
2235
car = spec.charAt(pos)
2236
}
2237
if(pos !== spec.length){
2243
return (this.fill === undefined ? "" : _b_.str.$factory(this.fill)) +
2244
(this.align || "") +
2245
(this.sign || "") +
2246
(this.alternate ? "#" : "") +
2247
(this.sign_aware ? "0" : "") +
2248
(this.width || "") +
2249
(this.comma ? "," : "") +
2250
(this.precision ? "." + this.precision : "") +
2251
(this.type || "")
2256
if(fmt.width && s.length < fmt.width){
2257
var fill = fmt.fill || " ",
2258
align = fmt.align || "<",
2259
missing = fmt.width - s.length
2261
case "<":
2262
return s + fill.repeat(missing)
2263
case ">":
2264
return fill.repeat(missing) + s
2265
case "=":
2266
if("+-".indexOf(s.charAt(0)) > -1){
2267
return s.charAt(0) + fill.repeat(missing) + s.substr(1)
2271
case "^":
2272
var left = parseInt(missing / 2)
2273
return fill.repeat(left) + s + fill.repeat(missing - left)
2286
$B.parse_fstring = function(string){
2287
// Parse a f-string
2288
var elts = [],
2289
pos = 0,
2313
}else{
2314
throw Error(" f-string: single '}' is not allowed")
2315
}
2316
}else{
2338
current += car
2339
i += 2
2340
}else{
2341
throw Error(" f-string: single '}' is not allowed")
2342
}
2343
}else{
2344
current += car
2345
i++
2346
}
2347
}
2349
}else if(ctype == "debug"){
2350
// after the equal sign, whitespace are ignored and the only
2351
// valid characters are } and :
2352
while(string.charAt(i) == " "){i++}
2353
if(string.charAt(i) == "}"){
2354
// end of debug expression
2355
elts.push(current)
2356
ctype = null
2357
current = ""
2358
pos = i + 1
2359
}
2360
}else{
2361
// End of expression is the } matching the opening {
2362
// There may be nested braces
2363
var i = pos,
2364
nb_braces = 1,
2386
// backslash is not allowed in expressions
2387
throw Error("f-string expression part cannot include a" +
2388
" backslash")
2395
throw Error("f-string: invalid conversion character:" +
2396
" expected 's', 'r', or 'a'")
2397
}else{
2411
if(string.substr(i, 3) == '"""'){
2412
var end = string.indexOf('"""', i + 3)
2413
if(end == -1){
2414
throw Error("f-string: unterminated string")
2415
}else{
2416
var trs = string.substring(i, end + 3)
2417
trs = trs.replace("\n", "\\n\\")
2422
var end = string.indexOf('"', i + 1)
2423
if(end == -1){
2424
throw Error("f-string: unterminated string")
2425
}else{
2426
current.expression += string.substring(i, end + 1)
2427
i = end + 1
2434
}else if(car == "="){
2435
// might be a "debug expression", eg f"{x=}"
2436
var ce = current.expression
2437
if(ce.length == 0 ||
2438
string.charAt(i + 1) == "=" ||
2439
"=!<>:".search(ce.charAt(ce.length - 1)) > -1){
2442
}else{
2443
// add debug string
2444
tail = car
2445
while(string.charAt(i + 1).match(/\s/)){
2446
tail += string.charAt(i + 1)
2447
i++
2448
}
2449
elts.push(current.expression + tail)
2450
// remove trailing whitespace from expression
2451
while(ce.match(/\s$/)){
2452
ce = ce.substr(0, ce.length - 1)
2453
}
2454
current.expression = ce
2455
ctype = "debug"
2456
i++
2457
}
2472
// Class for strings with surrogate pairs. We can't rely on Javascript
2473
// strings in this case because they don't count characters like Python
2474
2475
var surrogate = str.$surrogate = $B.make_class("surrogate_string", function(s){
2476
// create an instance of str subclass for strings with surrogate pairs
2477
var items = []
2478
for(var i = 0, len = s.length; i < len; i++){
2479
var code = s.charCodeAt(i)
2480
if(code >= 0xD800 && code <= 0xDBFF){
2481
i++
2482
var low = s.charCodeAt(i)
2483
code = ((code - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000
2484
}
2485
items.push(String.fromCodePoint(code))
2486
}
2487
return {
2488
__class__: str.$surrogate,
2489
items: items
2490
}
2491
})
2492
2493
surrogate.__mro__ = [str, object]
2494
2495
surrogate.__contains__ = function(self, other){
2496
return str.__contains__(self.items.join(''), other)
2497
}
2498
2499
surrogate.__getitem__ = function(self, arg){
2500
if(isinstance(arg, _b_.int)){
2501
var pos = arg
2502
if(arg < 0){
2503
pos += self.items.length
2504
}
2505
if(pos >= 0 && pos < self.items.length){
2506
if(self.items[pos].length == 2){
2507
return surrogate.$factory(self.items[pos])
2508
}
2509
return self.items[pos]
2510
}
2511
throw _b_.IndexError.$factory("string index out of range")
2512
}
2513
if(isinstance(arg, slice)) {
2514
var s = _b_.slice.$conv_for_seq(arg, self.items.length),
2515
start = s.start,
2516
stop = s.stop,
2517
step = s.step
2518
var res = "",
2519
i = null
2520
if(step > 0){
2521
if(stop <= start){return ""}
2522
for(var i = start; i < stop; i += step){
2523
res += self.items[i]
2524
}
2525
}else{
2526
if(stop >= start){return ''}
2527
for(var i = start; i > stop; i += step){
2528
res += self.items[i]
2529
}
2530
}
2531
return res
2532
}
2533
if(isinstance(arg, _b_.bool)){
2534
return surrogate.__getitem__(self, _b_.int.$factory(arg))
2535
}
2536
throw _b_.TypeError.$factory("string indices must be integers")
2537
}
2538
2539
surrogate.__hash__ = function(self){
2540
return str.__hash__(self.items.join(''))
2541
}
2542
2543
surrogate.__iter__ = function(self){
2544
return str_iterator.$factory(self.items)
2545
}
2546
2547
surrogate.__len__ = function(self){
2548
return self.items.length
2549
}
2550
2551
surrogate.__repr__ = function(self){
2552
return str.__repr__(self.items.join(''))
2553
}
2554
2555
surrogate.__str__ = function(self){
2556
return str.__str__(self.items.join(''))
2557
}
2558
2559
$B.set_func_names(surrogate, "builtins")
2560
2561