|
6 | 6 | package builtin |
7 | 7 |
|
8 | 8 | import ( |
| 9 | + "errors" |
9 | 10 | "fmt" |
| 11 | + "io" |
10 | 12 | "math/big" |
11 | 13 | "strconv" |
| 14 | + "strings" |
12 | 15 | "unicode/utf8" |
13 | 16 |
|
14 | 17 | "github.com/go-python/gpython/compile" |
@@ -44,7 +47,7 @@ func init() { |
44 | 47 | // py.MustNewMethod("hash", builtin_hash, 0, hash_doc), |
45 | 48 | py.MustNewMethod("hex", builtin_hex, 0, hex_doc), |
46 | 49 | // py.MustNewMethod("id", builtin_id, 0, id_doc), |
47 | | - // py.MustNewMethod("input", builtin_input, 0, input_doc), |
| 50 | + py.MustNewMethod("input", builtin_input, 0, input_doc), |
48 | 51 | py.MustNewMethod("isinstance", builtin_isinstance, 0, isinstance_doc), |
49 | 52 | // py.MustNewMethod("issubclass", builtin_issubclass, 0, issubclass_doc), |
50 | 53 | py.MustNewMethod("iter", builtin_iter, 0, iter_doc), |
@@ -1181,6 +1184,84 @@ func builtin_chr(self py.Object, args py.Tuple) (py.Object, error) { |
1181 | 1184 | return py.String(buf[:n]), nil |
1182 | 1185 | } |
1183 | 1186 |
|
| 1187 | +const input_doc = `input([prompt]) -> string |
| 1188 | +
|
| 1189 | +Read a string from standard input. The trailing newline is stripped. |
| 1190 | +The prompt string, if given, is printed to standard output without a |
| 1191 | +trailing newline before reading input. |
| 1192 | +If the user hits EOF (*nix: Ctrl-D, Windows: Ctrl-Z+Return), raise EOFError.` |
| 1193 | + |
| 1194 | +func builtin_input(self py.Object, args py.Tuple) (py.Object, error) { |
| 1195 | + var prompt py.Object = py.None |
| 1196 | + |
| 1197 | + err := py.UnpackTuple(args, nil, "input", 0, 1, &prompt) |
| 1198 | + if err != nil { |
| 1199 | + return nil, err |
| 1200 | + } |
| 1201 | + |
| 1202 | + // Use InputHook if available (e.g., in REPL mode) |
| 1203 | + if py.InputHook != nil { |
| 1204 | + promptStr := "" |
| 1205 | + if prompt != py.None { |
| 1206 | + s, ok := prompt.(py.String) |
| 1207 | + if !ok { |
| 1208 | + return nil, py.ExceptionNewf(py.TypeError, "input() prompt must be a string") |
| 1209 | + } |
| 1210 | + promptStr = string(s) |
| 1211 | + } |
| 1212 | + line, err := py.InputHook(promptStr) |
| 1213 | + if err != nil { |
| 1214 | + if errors.Is(err, io.EOF) { |
| 1215 | + return nil, py.ExceptionNewf(py.EOFError, "EOF when reading a line") |
| 1216 | + } |
| 1217 | + return nil, err |
| 1218 | + } |
| 1219 | + return py.String(line), nil |
| 1220 | + } |
| 1221 | + |
| 1222 | + sysModule, err := self.(*py.Module).Context.GetModule("sys") |
| 1223 | + if err != nil { |
| 1224 | + return nil, err |
| 1225 | + } |
| 1226 | + |
| 1227 | + stdin := sysModule.Globals["stdin"] |
| 1228 | + stdout := sysModule.Globals["stdout"] |
| 1229 | + |
| 1230 | + if prompt != py.None { |
| 1231 | + write, err := py.GetAttrString(stdout, "write") |
| 1232 | + if err != nil { |
| 1233 | + return nil, err |
| 1234 | + } |
| 1235 | + _, err = py.Call(write, py.Tuple{prompt}, nil) |
| 1236 | + if err != nil { |
| 1237 | + return nil, err |
| 1238 | + } |
| 1239 | + |
| 1240 | + flush, err := py.GetAttrString(stdout, "flush") |
| 1241 | + if err == nil { |
| 1242 | + py.Call(flush, nil, nil) |
| 1243 | + } |
| 1244 | + } |
| 1245 | + |
| 1246 | + readline, err := py.GetAttrString(stdin, "readline") |
| 1247 | + if err != nil { |
| 1248 | + return nil, err |
| 1249 | + } |
| 1250 | + result, err := py.Call(readline, nil, nil) |
| 1251 | + if err != nil { |
| 1252 | + return nil, err |
| 1253 | + } |
| 1254 | + line, ok := result.(py.String) |
| 1255 | + if !ok { |
| 1256 | + return nil, py.ExceptionNewf(py.TypeError, "object.readline() should return a str object, got %s", result.Type().Name) |
| 1257 | + } |
| 1258 | + if line == "" { |
| 1259 | + return nil, py.ExceptionNewf(py.EOFError, "EOF when reading a line") |
| 1260 | + } |
| 1261 | + line = py.String(strings.TrimRight(string(line), "\r\n")) |
| 1262 | + return line, nil |
| 1263 | +} |
| 1264 | + |
1184 | 1265 | const locals_doc = `locals() -> dictionary |
1185 | 1266 |
|
1186 | 1267 | Update and return a dictionary containing the current scope's local variables.` |
|
0 commit comments