Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions Lib/test/test_code.py
Original file line number Diff line number Diff line change
Expand Up @@ -249,8 +249,6 @@ def func(): pass
co.co_freevars,
co.co_cellvars)

# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_qualname(self):
self.assertEqual(
CodeTest.test_qualname.__code__.co_qualname,
Expand Down
26 changes: 24 additions & 2 deletions compiler/codegen/src/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -310,8 +310,8 @@ impl<'src> Compiler<'src> {
kwonlyarg_count: 0,
source_path: source_code.path.to_owned(),
first_line_number: OneIndexed::MIN,
obj_name: code_name,

obj_name: code_name.clone(),
qualname: Some(code_name),
blocks: vec![ir::Block::default()],
current_block: ir::BlockIdx(0),
constants: IndexSet::default(),
Expand Down Expand Up @@ -402,6 +402,13 @@ impl Compiler<'_> {
.map(|(var, _)| var.clone())
.collect();

// Calculate qualname based on the current qualified path
let qualname = if self.qualified_path.is_empty() {
Some(obj_name.clone())
} else {
Some(self.qualified_path.join("."))
};

let info = ir::CodeInfo {
flags,
posonlyarg_count,
Expand All @@ -410,6 +417,7 @@ impl Compiler<'_> {
source_path,
first_line_number,
obj_name,
qualname,

blocks: vec![ir::Block::default()],
current_block: ir::BlockIdx(0),
Expand Down Expand Up @@ -1496,6 +1504,10 @@ impl Compiler<'_> {

self.push_qualified_path(name);
let qualified_name = self.qualified_path.join(".");

// Update the qualname in the current code info
self.code_stack.last_mut().unwrap().qualname = Some(qualified_name.clone());

self.push_qualified_path("<locals>");

let (doc_str, body) = split_doc(body, &self.opts);
Expand Down Expand Up @@ -1720,6 +1732,9 @@ impl Compiler<'_> {

self.push_output(bytecode::CodeFlags::empty(), 0, 0, 0, name.to_owned());

// Update the qualname in the current code info
self.code_stack.last_mut().unwrap().qualname = Some(qualified_name.clone());

let (doc_str, body) = split_doc(body, &self.opts);

let dunder_name = self.name("__name__");
Expand Down Expand Up @@ -3495,6 +3510,9 @@ impl Compiler<'_> {
let mut func_flags = self
.enter_function(&name, parameters.as_deref().unwrap_or(&Default::default()))?;

// Lambda qualname should be <lambda>
self.code_stack.last_mut().unwrap().qualname = Some(name.clone());

self.ctx = CompileContext {
loop_data: Option::None,
in_class: prev_ctx.in_class,
Expand Down Expand Up @@ -3956,6 +3974,10 @@ impl Compiler<'_> {

// Create magnificent function <listcomp>:
self.push_output(flags, 1, 1, 0, name.to_owned());

// Set qualname for comprehension
self.code_stack.last_mut().unwrap().qualname = Some(name.to_owned());

let arg0 = self.varname(".0")?;

let return_none = init_collection.is_none();
Expand Down
5 changes: 4 additions & 1 deletion compiler/codegen/src/ir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ pub struct CodeInfo {
pub source_path: String,
pub first_line_number: OneIndexed,
pub obj_name: String, // Name of the object that created this code object
pub qualname: Option<String>, // Qualified name of the object

pub blocks: Vec<Block>,
pub current_block: BlockIdx,
Expand All @@ -99,6 +100,7 @@ impl CodeInfo {
source_path,
first_line_number,
obj_name,
qualname,

mut blocks,
current_block: _,
Expand Down Expand Up @@ -162,7 +164,8 @@ impl CodeInfo {
kwonlyarg_count,
source_path,
first_line_number: Some(first_line_number),
obj_name,
obj_name: obj_name.clone(),
qualname: qualname.unwrap_or(obj_name),

max_stackdepth,
instructions: instructions.into_boxed_slice(),
Expand Down
4 changes: 4 additions & 0 deletions compiler/core/src/bytecode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,8 @@ pub struct CodeObject<C: Constant = ConstantData> {
pub max_stackdepth: u32,
pub obj_name: C::Name,
// Name of the object that created this code object
pub qualname: C::Name,
// Qualified name of the object (like CPython's co_qualname)
pub cell2arg: Option<Box<[i32]>>,
pub constants: Box<[C]>,
pub names: Box<[C::Name]>,
Expand Down Expand Up @@ -1140,6 +1142,7 @@ impl<C: Constant> CodeObject<C> {
freevars: map_names(self.freevars),
source_path: bag.make_name(self.source_path.as_ref()),
obj_name: bag.make_name(self.obj_name.as_ref()),
qualname: bag.make_name(self.qualname.as_ref()),

instructions: self.instructions,
locations: self.locations,
Expand Down Expand Up @@ -1169,6 +1172,7 @@ impl<C: Constant> CodeObject<C> {
freevars: map_names(&self.freevars),
source_path: bag.make_name(self.source_path.as_ref()),
obj_name: bag.make_name(self.obj_name.as_ref()),
qualname: bag.make_name(self.qualname.as_ref()),

instructions: self.instructions.clone(),
locations: self.locations.clone(),
Expand Down
5 changes: 5 additions & 0 deletions compiler/core/src/marshal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,9 @@ pub fn deserialize_code<R: Read, Bag: ConstantBag>(
let len = rdr.read_u32()?;
let obj_name = bag.make_name(rdr.read_str(len)?);

let len = rdr.read_u32()?;
let qualname = bag.make_name(rdr.read_str(len)?);

let len = rdr.read_u32()?;
let cell2arg = (len != 0)
.then(|| {
Expand Down Expand Up @@ -250,6 +253,7 @@ pub fn deserialize_code<R: Read, Bag: ConstantBag>(
first_line_number,
max_stackdepth,
obj_name,
qualname,
cell2arg,
constants,
names,
Expand Down Expand Up @@ -609,6 +613,7 @@ pub fn serialize_code<W: Write, C: Constant>(buf: &mut W, code: &CodeObject<C>)
buf.write_u32(code.max_stackdepth);

write_vec(buf, code.obj_name.as_ref().as_bytes());
write_vec(buf, code.qualname.as_ref().as_bytes());

let cell2arg = code.cell2arg.as_deref().unwrap_or(&[]);
write_len(buf, cell2arg.len());
Expand Down
5 changes: 5 additions & 0 deletions vm/src/builtins/code.rs
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,10 @@ impl PyCode {
fn co_name(&self) -> PyStrRef {
self.code.obj_name.to_owned()
}
#[pygetset]
fn co_qualname(&self) -> PyStrRef {
self.code.qualname.to_owned()
}

#[pygetset]
fn co_names(&self, vm: &VirtualMachine) -> PyTupleRef {
Expand Down Expand Up @@ -401,6 +405,7 @@ impl PyCode {
source_path: source_path.as_object().as_interned_str(vm).unwrap(),
first_line_number,
obj_name: obj_name.as_object().as_interned_str(vm).unwrap(),
qualname: self.code.qualname,

max_stackdepth: self.code.max_stackdepth,
instructions: self.code.instructions.clone(),
Expand Down
Loading