| 106 | |
| 107 | impl IterNext for PyTokenizerIter { |
| 108 | fn next(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<PyIterReturn> { |
| 109 | let mut state = zelf.state.read().clone(); |
| 110 | |
| 111 | loop { |
| 112 | match &mut state.phase { |
| 113 | TokenizerPhase::Reading { source } => { |
| 114 | let line = zelf.readline(vm)?; |
| 115 | if line.is_empty() { |
| 116 | let accumulated = core::mem::take(source); |
| 117 | let parsed = parse_unchecked_source(&accumulated, PySourceType::Python); |
| 118 | let tokens: Vec<Token> = parsed.tokens().iter().copied().collect(); |
| 119 | let errors: Vec<ParseError> = parsed.errors().to_vec(); |
| 120 | let line_index = LineIndex::from_source_text(&accumulated); |
| 121 | let implicit_nl = !accumulated.ends_with('\n'); |
| 122 | state.phase = TokenizerPhase::Yielding { |
| 123 | source: accumulated, |
| 124 | tokens, |
| 125 | errors, |
| 126 | index: 0, |
| 127 | line_index, |
| 128 | need_implicit_nl: implicit_nl, |
| 129 | pending_fstring_parts: Vec::new(), |
| 130 | pending_empty_fstring_middle: None, |
| 131 | }; |
| 132 | } else { |
| 133 | source.push_str(&line); |
| 134 | } |
| 135 | } |
| 136 | TokenizerPhase::Yielding { .. } => { |
| 137 | let result = emit_next_token(&mut state, zelf.extra_tokens, vm)?; |
| 138 | *zelf.state.write() = state; |
| 139 | return Ok(result); |
| 140 | } |
| 141 | TokenizerPhase::Done => { |
| 142 | return Ok(PyIterReturn::StopIteration(None)); |
| 143 | } |
| 144 | } |
| 145 | } |
| 146 | } |
| 147 | } |
| 148 | |
| 149 | /// Emit the next token from the Yielding phase. |