Skip to content

Commit a90fb2b

Browse files
committed
Merge branch 'summer25'
2 parents 83b8ec2 + 9ea378d commit a90fb2b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+4845
-541
lines changed

.github/workflows/test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ jobs:
1212
- name: Use Node.js
1313
uses: actions/setup-node@v1
1414
with:
15-
node-version: "12.x"
15+
node-version: "16.x"
1616
- run: npm ci
1717
- run: npm run build
1818
- run: npm test

CONTRIBUTING.md

Lines changed: 116 additions & 108 deletions
Large diffs are not rendered by default.

gen/astnodes.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1049,10 +1049,12 @@ Sk.astnodes.keyword = function keyword(/* {identifier} */ arg, /* {expr_ty} */
10491049

10501050
/** @constructor */
10511051
Sk.astnodes.alias = function alias(/* {identifier} */ name, /* {identifier} */
1052-
asname)
1052+
asname, lineno, col_offset)
10531053
{
10541054
this.name = name;
10551055
this.asname = asname;
1056+
this.lineno = lineno;
1057+
this.col_offset = col_offset;
10561058
return this;
10571059
}
10581060

src/abstract.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -986,7 +986,7 @@ Sk.abstr.setUpInheritance = function (childName, child, parent, metaclass) {
986986
Object.setPrototypeOf(child, metaclass.prototype);
987987
Object.setPrototypeOf(child.prototype, parentproto);
988988
Object.defineProperties(child.prototype, {
989-
sk$object: { value: child, writable: true },
989+
sk$object: { value: true, writable: true },
990990
ob$type: { value: child, writable: true },
991991
tp$name: { value: childName, writable: true },
992992
tp$base: { value: parent, writable: true },

src/ast.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -735,7 +735,7 @@ function aliasForImportName (c, n) {
735735
if (NCH(n) === 3) {
736736
str = CHILD(n, 2).value;
737737
}
738-
return new Sk.astnodes.alias(name, str == null ? null : strobj(str));
738+
return new Sk.astnodes.alias(name, str == null ? null : strobj(str), n.lineno, n.col_offset);
739739
case SYM.dotted_as_name:
740740
if (NCH(n) === 1) {
741741
n = CHILD(n, 0);
@@ -750,19 +750,19 @@ function aliasForImportName (c, n) {
750750
break;
751751
case SYM.dotted_name:
752752
if (NCH(n) === 1) {
753-
return new Sk.astnodes.alias(strobj(CHILD(n, 0).value), null);
753+
return new Sk.astnodes.alias(strobj(CHILD(n, 0).value), null, n.lineno, n.col_offset);
754754
}
755755
else {
756756
// create a string of the form a.b.c
757757
str = "";
758758
for (i = 0; i < NCH(n); i += 2) {
759759
str += CHILD(n, i).value + ".";
760760
}
761-
return new Sk.astnodes.alias(strobj(str.substr(0, str.length - 1)), null);
761+
return new Sk.astnodes.alias(strobj(str.substr(0, str.length - 1)), null, n.lineno, n.col_offset);
762762
}
763763
break;
764764
case TOK.T_STAR:
765-
return new Sk.astnodes.alias(strobj("*"), null);
765+
return new Sk.astnodes.alias(strobj("*"), null, n.lineno, n.col_offset);
766766
default:
767767
throw new Sk.builtin.SyntaxError("unexpected import name", c.c_filename, n.lineno);
768768
}
@@ -1072,7 +1072,7 @@ function ast_for_call(c, n, func, allowgen)
10721072
key = e.id;
10731073
for (k = 0; k < nkeywords; k++) {
10741074
tmp = keywords[k].arg;
1075-
if (tmp && tmp === key) {
1075+
if (tmp && tmp.v === key.v) {
10761076
ast_error(c, chch,
10771077
"keyword argument repeated");
10781078
return NULL;

src/builtin/sys.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,9 +132,11 @@ var $builtinmodule = function (name) {
132132

133133
sys.__stdout__ = new Sk.builtin.file(new Sk.builtin.str("/dev/stdout"), new Sk.builtin.str("w"));
134134
sys.__stdin__ = new Sk.builtin.file(new Sk.builtin.str("/dev/stdin"), new Sk.builtin.str("r"));
135+
sys.__stderr__ = new Sk.builtin.file(new Sk.builtin.str("/dev/stderr"), new Sk.builtin.str("w"));
135136

136137
sys.stdout = sys.__stdout__;
137138
sys.stdin = sys.__stdin__;
139+
sys.stderr = sys.__stderr__;
138140

139141
return sys;
140142
};

src/builtindict.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ Sk.builtins = {
3838

3939
"BaseException" : Sk.builtin.BaseException,
4040
"AttributeError" : Sk.builtin.AttributeError,
41+
"ArithmeticError" : Sk.builtin.ArithmeticError,
4142
"ValueError" : Sk.builtin.ValueError,
4243
"Exception" : Sk.builtin.Exception,
4344
"ZeroDivisionError" : Sk.builtin.ZeroDivisionError,
@@ -145,7 +146,7 @@ Sk.abstr.setUpModuleMethods("builtins", Sk.builtins, {
145146
$meth(name, globals, _locals, formlist, level) {
146147
if (!Sk.builtin.checkString(name)) {
147148
throw new Sk.builtin.TypeError("__import__() argument 1 must be str, not " + name.tp$name);
148-
} else if (name === Sk.builtin.str.$empty && level.v === 0) {
149+
} else if (name.v === "" && level.v === 0) {
149150
throw new Sk.builtin.ValueError("Empty module name");
150151
}
151152
// check globals - locals is just ignored __import__

src/bytes.js

Lines changed: 34 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@ const supportedEncodings = {
55
utf: "utf-8",
66
utf8: "utf-8",
77
utf_8: "utf-8",
8+
latin_1: "latin1", // browser spec
89
ascii: "ascii",
10+
utf16: "utf-16",
11+
utf_16: "utf-16",
912
};
1013

1114
var space_reg = /\s+/g;
@@ -19,8 +22,8 @@ function normalizeEncoding(encoding) {
1922
return supported;
2023
}
2124
}
22-
const Encoder = new TextEncoder();
23-
const Decoder = new TextDecoder();
25+
const UtfEncoder = new TextEncoder();
26+
const UtfDecoder = new TextDecoder();
2427

2528
/**
2629
* @constructor
@@ -77,7 +80,12 @@ Sk.builtin.bytes = Sk.abstr.buildNativeClass("bytes", {
7780
if (args.length <= 1 && +kwargs.length === 0) {
7881
pySource = args[0];
7982
} else {
80-
[pySource, encoding, errors] = Sk.abstr.copyKeywordsToNamedArgs("bytes", [null, "pySource", "errors"], args, kwargs);
83+
[pySource, encoding, errors] = Sk.abstr.copyKeywordsToNamedArgs(
84+
"bytes",
85+
[null, "encoding", "errors"],
86+
args,
87+
kwargs
88+
);
8189
({ encoding, errors } = checkGetEncodingErrors("bytes", encoding, errors));
8290
if (!Sk.builtin.checkString(pySource)) {
8391
throw new Sk.builtin.TypeError("encoding or errors without a string argument");
@@ -965,19 +973,25 @@ function checkGetEncodingErrors(funcname, encoding, errors) {
965973
return { encoding: encoding, errors: errors };
966974
}
967975

976+
function checkErrorsIsValid(errors) {
977+
if (!(errors === "strict" || errors === "ignore" || errors === "replace")) {
978+
throw new Sk.builtin.LookupError(
979+
"Unsupported or invalid error type '" + errors + "'"
980+
);
981+
}
982+
}
983+
968984
function strEncode(pyStr, encoding, errors) {
969985
const source = pyStr.$jsstr();
970986
encoding = normalizeEncoding(encoding);
971-
if (!(errors === "strict" || errors === "ignore" || errors === "replace")) {
972-
throw new Sk.builtin.NotImplementedError("'" + errors + "' error handling not implemented in Skulpt");
973-
}
987+
checkErrorsIsValid(errors);
974988
let uint8;
975989
if (encoding === "ascii") {
976990
uint8 = encodeAscii(source, errors);
977991
} else if (encoding === "utf-8") {
978-
uint8 = Encoder.encode(source);
992+
uint8 = UtfEncoder.encode(source);
979993
} else {
980-
throw new Sk.builtin.LookupError("unknown encoding: " + encoding);
994+
throw new Sk.builtin.LookupError("Unsupported or unknown encoding: '" + encoding + "'");
981995
}
982996
return new Sk.builtin.bytes(uint8);
983997
}
@@ -1040,8 +1054,8 @@ function decodeAscii(source, errors) {
10401054
return final;
10411055
}
10421056

1043-
function decodeUtf(source, errors) {
1044-
const string = Decoder.decode(source);
1057+
function decode(decoder, source, errors, encoding) {
1058+
const string = decoder.decode(source);
10451059
if (errors === "replace") {
10461060
return string;
10471061
} else if (errors === "strict") {
@@ -1050,7 +1064,7 @@ function decodeUtf(source, errors) {
10501064
return string;
10511065
}
10521066
throw new Sk.builtin.UnicodeDecodeError(
1053-
"'utf-8' codec can't decode byte 0x" + source[i].toString(16) + " in position " + i + ": invalid start byte"
1067+
`'${encoding}' codec can't decode byte 0x ${source[i].toString(16)} in position ${i}: invalid start byte`
10541068
);
10551069
}
10561070
return string.replace(//g, "");
@@ -1060,17 +1074,21 @@ function bytesDecode(encoding, errors) {
10601074
({ encoding, errors } = checkGetEncodingErrors("decode", encoding, errors));
10611075
encoding = normalizeEncoding(encoding);
10621076

1063-
if (!(errors === "strict" || errors === "ignore" || errors === "replace")) {
1064-
throw new Sk.builtin.NotImplementedError("'" + errors + "' error handling not implemented in Skulpt");
1065-
}
1077+
checkErrorsIsValid(errors);
10661078

10671079
let jsstr;
10681080
if (encoding === "ascii") {
10691081
jsstr = decodeAscii(this.v, errors);
10701082
} else if (encoding === "utf-8") {
1071-
jsstr = decodeUtf(this.v, errors);
1083+
jsstr = decode(UtfDecoder, this.v, errors, encoding);
10721084
} else {
1073-
throw new Sk.builtin.LookupError("unknown encoding: " + encoding);
1085+
let decoder;
1086+
try {
1087+
decoder = new TextDecoder(encoding);
1088+
} catch (e) {
1089+
throw new Sk.builtin.LookupError(`Unsupported or unknown encoding: ${encoding}. ${e.message}`);
1090+
}
1091+
jsstr = decode(decoder, this.v, errors, encoding);
10741092
}
10751093
return new Sk.builtin.str(jsstr);
10761094
}

src/compile.js

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -136,8 +136,9 @@ function fixReserved(name) {
136136
return name + "_$rw$";
137137
}
138138

139+
const reservedSuffix = /_\$rw\$$/;
139140
function unfixReserved(name) {
140-
return name.replace(/_\$rw\$$/, "");
141+
return name.replace(reservedSuffix, "");
141142
}
142143

143144
function mangleName (priv, ident) {
@@ -950,7 +951,7 @@ Compiler.prototype.vexpr = function (e, data, augvar, augsubs) {
950951
}
951952
// else fall through and make a string instead
952953
case Sk.astnodes.Str:
953-
return this.makeConstant("new Sk.builtin.str(", getJsLiteralForString(e.s.$jsstr()), ")");
954+
return this.makeConstant("new Sk.builtin.str(", getJsLiteralForString(e.s.$jsstr()), ",true)");
954955
case Sk.astnodes.Attribute:
955956
if (e.ctx !== Sk.astnodes.AugLoad && e.ctx !== Sk.astnodes.AugStore) {
956957
val = this.vexpr(e.value);
@@ -1950,9 +1951,9 @@ Compiler.prototype.buildcodeobj = function (n, coname, decorator_list, args, cal
19501951
if (args && args.kwarg) {
19511952
kwarg = args.kwarg;
19521953
}
1953-
if (!Sk.__future__.python3 && args && args.kwonlyargs && args.kwonlyargs.length != 0) {
1954-
throw new Sk.builtin.SyntaxError("Keyword-only arguments are not supported in Python 2");
1955-
}
1954+
// if (!Sk.__future__.python3 && args && args.kwonlyargs && args.kwonlyargs.length != 0) {
1955+
// throw new Sk.builtin.SyntaxError("Keyword-only arguments are not supported in Python 2");
1956+
// }
19561957

19571958
//
19581959
// enter the new scope, and create the first block

src/constants.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ Sk.builtin.str.$imag = new Sk.builtin.str("imag");
1313
Sk.builtin.str.$real = new Sk.builtin.str("real");
1414

1515
Sk.builtin.str.$abs = new Sk.builtin.str("__abs__");
16+
Sk.builtin.str.$ann = new Sk.builtin.str("__annotations__");
1617
Sk.builtin.str.$bases = new Sk.builtin.str("__bases__");
1718
Sk.builtin.str.$bytes = new Sk.builtin.str("__bytes__");
1819
Sk.builtin.str.$call = new Sk.builtin.str("__call__");

0 commit comments

Comments
 (0)