diff --git a/Lib/dis.py b/Lib/dis.py index 6583cab62b8..797e0f8a088 100644 --- a/Lib/dis.py +++ b/Lib/dis.py @@ -19,7 +19,6 @@ from _opcode import get_executor - __all__ = ["code_info", "dis", "disassemble", "distb", "disco", "findlinestarts", "findlabels", "show_code", "get_instructions", "Instruction", "Bytecode"] + _opcodes_all @@ -1052,9 +1051,6 @@ def dis(self): return output.getvalue() -from _dis import * # TODO: RUSTPYTHON; Remove this import (and module) - - def main(args=None): import argparse @@ -1073,9 +1069,7 @@ def main(args=None): with open(args.infile, 'rb') as infile: source = infile.read() code = compile(source, name, "exec") - # TODO: RUSTPYTHON; Add support for `show_caches` & `show_offsets` arguments - # dis(code, show_caches=args.show_caches, show_offsets=args.show_offsets) - dis(code) + dis(code, show_caches=args.show_caches, show_offsets=args.show_offsets) if __name__ == "__main__": main() diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py index 9526bdcbbaa..a585643cba6 100644 --- a/Lib/test/test_dis.py +++ b/Lib/test/test_dis.py @@ -971,11 +971,9 @@ def test_bug_1333982(self): self.do_disassembly_test(bug1333982, dis_bug1333982) - @unittest.expectedFailure # TODO: RUSTPYTHON def test_bug_42562(self): self.do_disassembly_test(bug42562, dis_bug42562) - @unittest.expectedFailure # TODO: RUSTPYTHON def test_bug_45757(self): # Extended arg followed by NOP self.do_disassembly_test(code_bug_45757, dis_bug_45757) @@ -997,7 +995,6 @@ def test_intrinsic_1(self): self.do_disassembly_test("+a", dis_intrinsic_1_5) self.do_disassembly_test("(*a,)", dis_intrinsic_1_6) - @unittest.expectedFailure # TODO: RUSTPYTHON def test_intrinsic_2(self): self.assertIn("CALL_INTRINSIC_2 1 (INTRINSIC_PREP_RERAISE_STAR)", self.get_disassembly("try: pass\nexcept* Exception: x")) @@ -1059,19 +1056,16 @@ def test_disassemble_static_method(self): def test_disassemble_class_method(self): self.do_disassembly_test(_C.cm, dis_c_class_method) - @unittest.expectedFailure # TODO: RUSTPYTHON def test_disassemble_generator(self): gen_func_disas = self.get_disassembly(_g) # Generator function gen_disas = self.get_disassembly(_g(1)) # Generator iterator self.assertEqual(gen_disas, gen_func_disas) - @unittest.expectedFailure # TODO: RUSTPYTHON def test_disassemble_async_generator(self): agen_func_disas = self.get_disassembly(_ag) # Async generator function agen_disas = self.get_disassembly(_ag(1)) # Async generator iterator self.assertEqual(agen_disas, agen_func_disas) - @unittest.expectedFailure # TODO: RUSTPYTHON def test_disassemble_coroutine(self): coro_func_disas = self.get_disassembly(_co) # Coroutine function coro = _co(1) # Coroutine object @@ -1096,7 +1090,6 @@ def test_disassemble_try_finally(self): self.do_disassembly_test(_tryfinally, dis_tryfinally) self.do_disassembly_test(_tryfinallyconst, dis_tryfinallyconst) - @unittest.expectedFailure # TODO: RUSTPYTHON def test_dis_none(self): try: del sys.last_exc @@ -1108,7 +1101,6 @@ def test_dis_none(self): pass self.assertRaises(RuntimeError, dis.dis, None) - @unittest.expectedFailure # TODO: RUSTPYTHON def test_dis_traceback(self): self.maxDiff = None try: @@ -2198,14 +2190,12 @@ def test_assert_not_in_with_op_not_in_bytecode(self): self.assertNotInBytecode(code, "LOAD_NAME") self.assertNotInBytecode(code, "LOAD_NAME", "a") - @unittest.expectedFailure # TODO: RUSTPYTHON def test_assert_not_in_with_arg_not_in_bytecode(self): code = compile("a = 1", "", "exec") self.assertInBytecode(code, "LOAD_CONST") self.assertInBytecode(code, "LOAD_CONST", 1) self.assertNotInBytecode(code, "LOAD_CONST", 2) - @unittest.expectedFailure # TODO: RUSTPYTHON def test_assert_not_in_with_arg_in_bytecode(self): code = compile("a = 1", "", "exec") with self.assertRaises(AssertionError): diff --git a/Lib/test/test_inspect/test_inspect.py b/Lib/test/test_inspect/test_inspect.py index b9cfca6df21..7d037d0554e 100644 --- a/Lib/test/test_inspect/test_inspect.py +++ b/Lib/test/test_inspect/test_inspect.py @@ -384,8 +384,6 @@ def do_something_static(): coro.close(); gen_coro.close(); # silence warnings - # TODO: RUSTPYTHON - @unittest.expectedFailure def test_isawaitable(self): def gen(): yield self.assertFalse(inspect.isawaitable(gen())) @@ -6748,4 +6746,4 @@ def f(): if __name__ == "__main__": - unittest.main() \ No newline at end of file + unittest.main() diff --git a/Lib/test/test_unittest/testmock/testasync.py b/Lib/test/test_unittest/testmock/testasync.py index ddc6f0599c8..81d9c9c55fd 100644 --- a/Lib/test/test_unittest/testmock/testasync.py +++ b/Lib/test/test_unittest/testmock/testasync.py @@ -734,7 +734,6 @@ def __aiter__(self): pass async def __anext__(self): pass - @unittest.expectedFailure # TODO: RUSTPYTHON def test_aiter_set_return_value(self): mock_iter = AsyncMock(name="tester") mock_iter.__aiter__.return_value = [1, 2, 3] @@ -760,7 +759,6 @@ def inner_test(mock_type): inner_test(mock_type) - @unittest.expectedFailure # TODO: RUSTPYTHON def test_mock_async_for(self): async def iterate(iterator): accumulator = [] diff --git a/crates/codegen/src/compile.rs b/crates/codegen/src/compile.rs index d5fbd194866..bbc8d4235fc 100644 --- a/crates/codegen/src/compile.rs +++ b/crates/codegen/src/compile.rs @@ -377,7 +377,7 @@ enum CollectionType { impl Compiler { fn new(opts: CompileOpts, source_file: SourceFile, code_name: String) -> Self { let module_code = ir::CodeInfo { - flags: bytecode::CodeFlags::NEW_LOCALS, + flags: bytecode::CodeFlags::NEWLOCALS, source_path: source_file.name().to_owned(), private: None, blocks: vec![ir::Block::default()], @@ -749,19 +749,19 @@ impl Compiler { CompilerScope::Module => (bytecode::CodeFlags::empty(), 0, 0, 0), CompilerScope::Class => (bytecode::CodeFlags::empty(), 0, 0, 0), CompilerScope::Function | CompilerScope::AsyncFunction | CompilerScope::Lambda => ( - bytecode::CodeFlags::NEW_LOCALS | bytecode::CodeFlags::IS_OPTIMIZED, + bytecode::CodeFlags::NEWLOCALS | bytecode::CodeFlags::OPTIMIZED, 0, // Will be set later in enter_function 0, // Will be set later in enter_function 0, // Will be set later in enter_function ), CompilerScope::Comprehension => ( - bytecode::CodeFlags::NEW_LOCALS | bytecode::CodeFlags::IS_OPTIMIZED, + bytecode::CodeFlags::NEWLOCALS | bytecode::CodeFlags::OPTIMIZED, 0, 1, // comprehensions take one argument (.0) 0, ), CompilerScope::TypeParams => ( - bytecode::CodeFlags::NEW_LOCALS | bytecode::CodeFlags::IS_OPTIMIZED, + bytecode::CodeFlags::NEWLOCALS | bytecode::CodeFlags::OPTIMIZED, 0, 0, 0, @@ -1298,7 +1298,7 @@ impl Compiler { let parent_obj_name = &parent.metadata.name; // Determine if parent is a function-like scope - let is_function_parent = parent.flags.contains(bytecode::CodeFlags::IS_OPTIMIZED) + let is_function_parent = parent.flags.contains(bytecode::CodeFlags::OPTIMIZED) && !parent_obj_name.starts_with("<") // Not a special scope like , , etc. && parent_obj_name != ""; // Not the module scope @@ -1914,7 +1914,7 @@ impl Compiler { && self .current_code_info() .flags - .contains(bytecode::CodeFlags::IS_GENERATOR) + .contains(bytecode::CodeFlags::GENERATOR) { return Err(self.error_ranged( CodegenErrorType::AsyncReturnValue, @@ -2062,7 +2062,7 @@ impl Compiler { } self.push_output( - bytecode::CodeFlags::NEW_LOCALS | bytecode::CodeFlags::IS_OPTIMIZED, + bytecode::CodeFlags::NEWLOCALS | bytecode::CodeFlags::OPTIMIZED, parameters.posonlyargs.len().to_u32(), (parameters.posonlyargs.len() + parameters.args.len()).to_u32(), parameters.kwonlyargs.len().to_u32(), @@ -2080,11 +2080,11 @@ impl Compiler { } if let Some(name) = parameters.vararg.as_deref() { - self.current_code_info().flags |= bytecode::CodeFlags::HAS_VARARGS; + self.current_code_info().flags |= bytecode::CodeFlags::VARARGS; self.varname(name.name.as_str())?; } if let Some(name) = parameters.kwarg.as_deref() { - self.current_code_info().flags |= bytecode::CodeFlags::HAS_VARKEYWORDS; + self.current_code_info().flags |= bytecode::CodeFlags::VARKEYWORDS; self.varname(name.name.as_str())?; } @@ -3103,7 +3103,7 @@ impl Compiler { self.enter_function(name, parameters)?; self.current_code_info() .flags - .set(bytecode::CodeFlags::IS_COROUTINE, is_async); + .set(bytecode::CodeFlags::COROUTINE, is_async); // Set up context let prev_ctx = self.ctx; @@ -3233,7 +3233,7 @@ impl Compiler { // Enter type params scope let type_params_name = format!(""); self.push_output( - bytecode::CodeFlags::IS_OPTIMIZED | bytecode::CodeFlags::NEW_LOCALS, + bytecode::CodeFlags::OPTIMIZED | bytecode::CodeFlags::NEWLOCALS, 0, num_typeparam_args as u32, 0, @@ -3664,7 +3664,7 @@ impl Compiler { if is_generic { let type_params_name = format!(""); self.push_output( - bytecode::CodeFlags::IS_OPTIMIZED | bytecode::CodeFlags::NEW_LOCALS, + bytecode::CodeFlags::OPTIMIZED | bytecode::CodeFlags::NEWLOCALS, 0, 0, 0, @@ -6371,9 +6371,9 @@ impl Compiler { in_async_scope: prev_ctx.in_async_scope || is_async, }; - let flags = bytecode::CodeFlags::NEW_LOCALS | bytecode::CodeFlags::IS_OPTIMIZED; + let flags = bytecode::CodeFlags::NEWLOCALS | bytecode::CodeFlags::OPTIMIZED; let flags = if is_async { - flags | bytecode::CodeFlags::IS_COROUTINE + flags | bytecode::CodeFlags::COROUTINE } else { flags }; @@ -7040,7 +7040,7 @@ impl Compiler { } fn mark_generator(&mut self) { - self.current_code_info().flags |= bytecode::CodeFlags::IS_GENERATOR + self.current_code_info().flags |= bytecode::CodeFlags::GENERATOR } /// Whether the expression contains an await expression and diff --git a/crates/codegen/src/ir.rs b/crates/codegen/src/ir.rs index d29b1704c60..298566d7ad7 100644 --- a/crates/codegen/src/ir.rs +++ b/crates/codegen/src/ir.rs @@ -332,8 +332,8 @@ impl CodeInfo { let total_args = self.metadata.argcount + self.metadata.kwonlyargcount - + self.flags.contains(CodeFlags::HAS_VARARGS) as u32 - + self.flags.contains(CodeFlags::HAS_VARKEYWORDS) as u32; + + self.flags.contains(CodeFlags::VARARGS) as u32 + + self.flags.contains(CodeFlags::VARKEYWORDS) as u32; let mut found_cellarg = false; let cell2arg = self diff --git a/crates/compiler-core/src/bytecode.rs b/crates/compiler-core/src/bytecode.rs index d3a74d8828a..010e414cc89 100644 --- a/crates/compiler-core/src/bytecode.rs +++ b/crates/compiler-core/src/bytecode.rs @@ -371,28 +371,15 @@ pub struct CodeObject { bitflags! { #[derive(Copy, Clone, Debug, PartialEq)] pub struct CodeFlags: u16 { - const NEW_LOCALS = 0x01; - const IS_GENERATOR = 0x02; - const IS_COROUTINE = 0x04; - const HAS_VARARGS = 0x08; - const HAS_VARKEYWORDS = 0x10; - const IS_OPTIMIZED = 0x20; + const OPTIMIZED = 0x0001; + const NEWLOCALS = 0x0002; + const VARARGS = 0x0004; + const VARKEYWORDS = 0x0008; + const GENERATOR = 0x0020; + const COROUTINE = 0x0080; } } -impl CodeFlags { - pub const NAME_MAPPING: &'static [(&'static str, Self)] = &[ - ("GENERATOR", Self::IS_GENERATOR), - ("COROUTINE", Self::IS_COROUTINE), - ( - "ASYNC_GENERATOR", - Self::from_bits_truncate(Self::IS_GENERATOR.bits() | Self::IS_COROUTINE.bits()), - ), - ("VARARGS", Self::HAS_VARARGS), - ("VARKEYWORDS", Self::HAS_VARKEYWORDS), - ]; -} - /// an opcode argument that may be extended by a prior ExtendedArg #[derive(Copy, Clone, PartialEq, Eq)] #[repr(transparent)] @@ -1564,14 +1551,14 @@ impl CodeObject { let args = &self.varnames[..nargs]; let kwonlyargs = &self.varnames[nargs..varargs_pos]; - let vararg = if self.flags.contains(CodeFlags::HAS_VARARGS) { + let vararg = if self.flags.contains(CodeFlags::VARARGS) { let vararg = &self.varnames[varargs_pos]; varargs_pos += 1; Some(vararg) } else { None }; - let varkwarg = if self.flags.contains(CodeFlags::HAS_VARKEYWORDS) { + let varkwarg = if self.flags.contains(CodeFlags::VARKEYWORDS) { Some(&self.varnames[varargs_pos]) } else { None diff --git a/crates/stdlib/src/dis.rs b/crates/stdlib/src/dis.rs deleted file mode 100644 index 341137f91f4..00000000000 --- a/crates/stdlib/src/dis.rs +++ /dev/null @@ -1,58 +0,0 @@ -pub(crate) use decl::make_module; - -#[pymodule(name = "dis")] -mod decl { - use crate::vm::{ - PyObjectRef, PyRef, PyResult, TryFromObject, VirtualMachine, - builtins::{PyCode, PyDictRef, PyStrRef}, - bytecode::CodeFlags, - }; - - #[pyfunction] - fn dis(obj: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> { - let co = if let Ok(co) = obj.get_attr("__code__", vm) { - // Method or function: - PyRef::try_from_object(vm, co)? - } else if let Ok(co_str) = PyStrRef::try_from_object(vm, obj.clone()) { - #[cfg(not(feature = "compiler"))] - { - let _ = co_str; - return Err( - vm.new_runtime_error("dis.dis() with str argument requires `compiler` feature") - ); - } - #[cfg(feature = "compiler")] - { - vm.compile( - co_str.as_str(), - crate::vm::compiler::Mode::Exec, - "".to_owned(), - ) - .map_err(|err| vm.new_syntax_error(&err, Some(co_str.as_str())))? - } - } else { - PyRef::try_from_object(vm, obj)? - }; - disassemble(co) - } - - #[pyfunction] - fn disassemble(co: PyRef) -> PyResult<()> { - print!("{}", &co.code); - Ok(()) - } - - #[pyattr(name = "COMPILER_FLAG_NAMES")] - fn compiler_flag_names(vm: &VirtualMachine) -> PyDictRef { - let dict = vm.ctx.new_dict(); - for (name, flag) in CodeFlags::NAME_MAPPING { - dict.set_item( - &*vm.new_pyobj(flag.bits()), - vm.ctx.new_str(*name).into(), - vm, - ) - .unwrap(); - } - dict - } -} diff --git a/crates/stdlib/src/lib.rs b/crates/stdlib/src/lib.rs index 6b7796c8bad..567c584d85b 100644 --- a/crates/stdlib/src/lib.rs +++ b/crates/stdlib/src/lib.rs @@ -14,7 +14,6 @@ mod bisect; mod cmath; mod contextvars; mod csv; -mod dis; mod gc; mod bz2; @@ -132,7 +131,6 @@ pub fn get_module_inits() -> impl Iterator, StdlibInit "cmath" => cmath::make_module, "_contextvars" => contextvars::make_module, "_csv" => csv::make_module, - "_dis" => dis::make_module, "faulthandler" => faulthandler::make_module, "gc" => gc::make_module, "_hashlib" => hashlib::make_module, diff --git a/crates/vm/src/builtins/function.rs b/crates/vm/src/builtins/function.rs index 3e5048e133f..58c683d3fab 100644 --- a/crates/vm/src/builtins/function.rs +++ b/crates/vm/src/builtins/function.rs @@ -124,7 +124,7 @@ impl PyFunction { let mut vararg_offset = total_args; // Pack other positional arguments in to *args: - if code.flags.contains(bytecode::CodeFlags::HAS_VARARGS) { + if code.flags.contains(bytecode::CodeFlags::VARARGS) { let vararg_value = vm.ctx.new_tuple(args_iter.collect()); fastlocals[vararg_offset] = Some(vararg_value.into()); vararg_offset += 1; @@ -155,7 +155,7 @@ impl PyFunction { } // Do we support `**kwargs` ? - let kwargs = if code.flags.contains(bytecode::CodeFlags::HAS_VARKEYWORDS) { + let kwargs = if code.flags.contains(bytecode::CodeFlags::VARKEYWORDS) { let d = vm.ctx.new_dict(); fastlocals[vararg_offset] = Some(d.clone().into()); Some(d) @@ -414,7 +414,7 @@ impl Py { let code = self.code.lock().clone(); - let locals = if code.flags.contains(bytecode::CodeFlags::NEW_LOCALS) { + let locals = if code.flags.contains(bytecode::CodeFlags::NEWLOCALS) { ArgMapping::from_dict_exact(vm.ctx.new_dict()) } else if let Some(locals) = locals { locals @@ -436,8 +436,8 @@ impl Py { self.fill_locals_from_args(&frame, func_args, vm)?; // If we have a generator, create a new generator - let is_gen = code.flags.contains(bytecode::CodeFlags::IS_GENERATOR); - let is_coro = code.flags.contains(bytecode::CodeFlags::IS_COROUTINE); + let is_gen = code.flags.contains(bytecode::CodeFlags::GENERATOR); + let is_coro = code.flags.contains(bytecode::CodeFlags::COROUTINE); match (is_gen, is_coro) { (true, false) => { Ok(PyGenerator::new(frame, self.__name__(), self.__qualname__()).into_pyobject(vm)) diff --git a/crates/vm/src/builtins/function/jit.rs b/crates/vm/src/builtins/function/jit.rs index de0a528b734..a28335900da 100644 --- a/crates/vm/src/builtins/function/jit.rs +++ b/crates/vm/src/builtins/function/jit.rs @@ -72,7 +72,7 @@ pub fn get_jit_arg_types(func: &Py, vm: &VirtualMachine) -> PyResult if code .flags - .intersects(CodeFlags::HAS_VARARGS | CodeFlags::HAS_VARKEYWORDS) + .intersects(CodeFlags::VARARGS | CodeFlags::VARKEYWORDS) { return Err(new_jit_error( "Can't jit functions with variable number of arguments".to_owned(), diff --git a/crates/vm/src/frame.rs b/crates/vm/src/frame.rs index a5a9d2b933d..dd5fc685643 100644 --- a/crates/vm/src/frame.rs +++ b/crates/vm/src/frame.rs @@ -186,7 +186,7 @@ impl Frame { Ok(()) }; map_to_dict(&code.cellvars, &self.cells_frees)?; - if code.flags.contains(bytecode::CodeFlags::IS_OPTIMIZED) { + if code.flags.contains(bytecode::CodeFlags::OPTIMIZED) { map_to_dict(&code.freevars, &self.cells_frees[code.cellvars.len()..])?; } } @@ -1000,11 +1000,7 @@ impl ExecutingFrame<'_> { let iterable = self.pop_value(); let iter = if iterable.class().is(vm.ctx.types.coroutine_type) { // Coroutine requires CO_COROUTINE or CO_ITERABLE_COROUTINE flag - if !self - .code - .flags - .intersects(bytecode::CodeFlags::IS_COROUTINE) - { + if !self.code.flags.intersects(bytecode::CodeFlags::COROUTINE) { return Err(vm.new_type_error( "cannot 'yield from' a coroutine object in a non-coroutine generator" .to_owned(), @@ -1675,7 +1671,7 @@ impl ExecutingFrame<'_> { // arg=0: direct yield (wrapped for async generators) // arg=1: yield from await/yield-from (NOT wrapped) let wrap = oparg.get(arg) == 0; - let value = if wrap && self.code.flags.contains(bytecode::CodeFlags::IS_COROUTINE) { + let value = if wrap && self.code.flags.contains(bytecode::CodeFlags::COROUTINE) { PyAsyncGenWrappedValue(value).into_pyobject(vm) } else { value