(args: CompileArgs, vm: &VirtualMachine)
| 251 | #[cfg(any(feature = "parser", feature = "compiler"))] |
| 252 | #[pyfunction] |
| 253 | fn compile(args: CompileArgs, vm: &VirtualMachine) -> PyResult { |
| 254 | #[cfg(not(feature = "ast"))] |
| 255 | { |
| 256 | _ = args; // to disable unused warning |
| 257 | return Err(vm.new_type_error("AST Not Supported")); |
| 258 | } |
| 259 | #[cfg(feature = "ast")] |
| 260 | { |
| 261 | use crate::{class::PyClassImpl, stdlib::_ast}; |
| 262 | |
| 263 | let feature_version = feature_version_from_arg(args._feature_version, vm)?; |
| 264 | |
| 265 | let mode_str = args.mode.as_str(); |
| 266 | |
| 267 | let optimize: i32 = args.optimize.map_or(Ok(-1), |v| v.try_to_primitive(vm))?; |
| 268 | let optimize: u8 = if optimize == -1 { |
| 269 | vm.state.config.settings.optimize |
| 270 | } else { |
| 271 | optimize |
| 272 | .try_into() |
| 273 | .map_err(|_| vm.new_value_error("compile() optimize value invalid"))? |
| 274 | }; |
| 275 | |
| 276 | if args |
| 277 | .source |
| 278 | .fast_isinstance(&_ast::NodeAst::make_static_type()) |
| 279 | { |
| 280 | let flags: i32 = args.flags.map_or(Ok(0), |v| v.try_to_primitive(vm))?; |
| 281 | let is_ast_only = !(flags & _ast::PY_CF_ONLY_AST).is_zero(); |
| 282 | |
| 283 | // func_type mode requires PyCF_ONLY_AST |
| 284 | if mode_str == "func_type" && !is_ast_only { |
| 285 | return Err(vm.new_value_error( |
| 286 | "compile() mode 'func_type' requires flag PyCF_ONLY_AST", |
| 287 | )); |
| 288 | } |
| 289 | |
| 290 | // compile(ast_node, ..., PyCF_ONLY_AST) returns the AST after validation |
| 291 | if is_ast_only { |
| 292 | let (expected_type, expected_name) = _ast::mode_type_and_name(mode_str) |
| 293 | .ok_or_else(|| { |
| 294 | vm.new_value_error( |
| 295 | "compile() mode must be 'exec', 'eval', 'single' or 'func_type'", |
| 296 | ) |
| 297 | })?; |
| 298 | if !args.source.fast_isinstance(&expected_type) { |
| 299 | return Err(vm.new_type_error(format!( |
| 300 | "expected {} node, got {}", |
| 301 | expected_name, |
| 302 | args.source.class().name() |
| 303 | ))); |
| 304 | } |
| 305 | _ast::validate_ast_object(vm, args.source.clone())?; |
| 306 | return Ok(args.source); |
| 307 | } |
| 308 | |
| 309 | #[cfg(not(feature = "rustpython-codegen"))] |
| 310 | { |
nothing calls this directly
no test coverage detected