(
vm: &VirtualMachine,
source: &str,
scope: Scope,
empty_line_given: bool,
continuing_block: bool,
)
| 20 | } |
| 21 | |
| 22 | fn shell_exec( |
| 23 | vm: &VirtualMachine, |
| 24 | source: &str, |
| 25 | scope: Scope, |
| 26 | empty_line_given: bool, |
| 27 | continuing_block: bool, |
| 28 | ) -> ShellExecResult { |
| 29 | // compiling expects only UNIX style line endings, and will replace windows line endings |
| 30 | // internally. Since we might need to analyze the source to determine if an error could be |
| 31 | // resolved by future input, we need the location from the error to match the source code that |
| 32 | // was actually compiled. |
| 33 | #[cfg(windows)] |
| 34 | let source = &source.replace("\r\n", "\n"); |
| 35 | match vm.compile(source, compiler::Mode::Single, "<stdin>".to_owned()) { |
| 36 | Ok(code) => { |
| 37 | if empty_line_given || !continuing_block { |
| 38 | // We want to execute the full code |
| 39 | match vm.run_code_obj(code, scope) { |
| 40 | Ok(_val) => ShellExecResult::Ok, |
| 41 | Err(err) => ShellExecResult::PyErr(err), |
| 42 | } |
| 43 | } else { |
| 44 | // We can just return an ok result |
| 45 | ShellExecResult::Ok |
| 46 | } |
| 47 | } |
| 48 | Err(CompileError::Parse(ParseError { |
| 49 | error: ParseErrorType::Lexical(LexicalErrorType::Eof), |
| 50 | .. |
| 51 | })) => ShellExecResult::ContinueLine, |
| 52 | Err(CompileError::Parse(ParseError { |
| 53 | error: |
| 54 | ParseErrorType::Lexical(LexicalErrorType::FStringError( |
| 55 | InterpolatedStringErrorType::UnterminatedTripleQuotedString, |
| 56 | )), |
| 57 | .. |
| 58 | })) => ShellExecResult::ContinueLine, |
| 59 | Err(err) => { |
| 60 | // Check if the error is from an unclosed triple quoted string (which should always |
| 61 | // continue) |
| 62 | if let CompileError::Parse(ParseError { |
| 63 | error: ParseErrorType::Lexical(LexicalErrorType::UnclosedStringError), |
| 64 | raw_location, |
| 65 | .. |
| 66 | }) = err |
| 67 | { |
| 68 | let loc = raw_location.start().to_usize(); |
| 69 | let mut iter = source.chars(); |
| 70 | if let Some(quote) = iter.nth(loc) |
| 71 | && iter.next() == Some(quote) |
| 72 | && iter.next() == Some(quote) |
| 73 | { |
| 74 | return ShellExecResult::ContinueLine; |
| 75 | } |
| 76 | }; |
| 77 | |
| 78 | // bad_error == true if we are handling an error that should be thrown even if we are continuing |
| 79 | // if its an indentation error, set to true if we are continuing and the error is on column 0, |
no test coverage detected