| 338 | |
| 339 | #[cfg(feature = "parser")] |
| 340 | pub(crate) fn parse( |
| 341 | vm: &VirtualMachine, |
| 342 | source: &str, |
| 343 | mode: parser::Mode, |
| 344 | optimize: u8, |
| 345 | target_version: Option<ast::PythonVersion>, |
| 346 | type_comments: bool, |
| 347 | ) -> Result<PyObjectRef, CompileError> { |
| 348 | let source_file = SourceFileBuilder::new("".to_owned(), source.to_owned()).finish(); |
| 349 | let mut options = parser::ParseOptions::from(mode); |
| 350 | let target_version = target_version.unwrap_or(ast::PythonVersion::PY314); |
| 351 | options = options.with_target_version(target_version); |
| 352 | let parsed = parser::parse(source, options).map_err(|parse_error| { |
| 353 | let range = text_range_to_source_range(&source_file, parse_error.location); |
| 354 | ParseError { |
| 355 | error: parse_error.error, |
| 356 | raw_location: parse_error.location, |
| 357 | location: range.start.to_source_location(), |
| 358 | end_location: range.end.to_source_location(), |
| 359 | source_path: "<unknown>".to_string(), |
| 360 | is_unclosed_bracket: false, |
| 361 | } |
| 362 | })?; |
| 363 | |
| 364 | if let Some(error) = parsed.unsupported_syntax_errors().first() { |
| 365 | let range = text_range_to_source_range(&source_file, error.range()); |
| 366 | return Err(ParseError { |
| 367 | error: parser::ParseErrorType::OtherError(error.to_string()), |
| 368 | raw_location: error.range(), |
| 369 | location: range.start.to_source_location(), |
| 370 | end_location: range.end.to_source_location(), |
| 371 | source_path: "<unknown>".to_string(), |
| 372 | is_unclosed_bracket: false, |
| 373 | } |
| 374 | .into()); |
| 375 | } |
| 376 | |
| 377 | let mut top = parsed.into_syntax(); |
| 378 | if optimize > 0 { |
| 379 | fold_match_value_constants(&mut top); |
| 380 | } |
| 381 | if optimize >= 2 { |
| 382 | strip_docstrings(&mut top); |
| 383 | } |
| 384 | let top = match top { |
| 385 | ast::Mod::Module(m) => Mod::Module(m), |
| 386 | ast::Mod::Expression(e) => Mod::Expression(e), |
| 387 | }; |
| 388 | let obj = top.ast_to_object(vm, &source_file); |
| 389 | if type_comments && obj.class().is(pyast::NodeModModule::static_type()) { |
| 390 | let type_ignores = type_ignores_from_source(vm, source)?; |
| 391 | let dict = obj.as_object().dict().unwrap(); |
| 392 | dict.set_item("type_ignores", vm.ctx.new_list(type_ignores).into(), vm) |
| 393 | .unwrap(); |
| 394 | } |
| 395 | Ok(obj) |
| 396 | } |
| 397 | |