Skip to content

Commit 4c48520

Browse files
Merge pull request #703 from RustPython/add_class_cell
Add __class__ cell to method scopes.
2 parents 32cb599 + 1958e47 commit 4c48520

File tree

3 files changed

+18
-5
lines changed

3 files changed

+18
-5
lines changed

tests/snippets/class.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,18 @@ def __init__(self, x):
2222
self.x = x
2323

2424
def get_x(self):
25+
assert __class__ is Bar
2526
return self.x
2627

2728
@classmethod
2829
def fubar(cls, x):
30+
assert __class__ is cls
2931
assert cls is Bar
3032
assert x == 2
3133

3234
@staticmethod
3335
def kungfu(x):
36+
assert __class__ is Bar
3437
assert x == 3
3538

3639

vm/src/builtins.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use crate::obj::objtype;
2020
use crate::frame::Scope;
2121
use crate::function::{Args, OptionalArg, PyFuncArgs};
2222
use crate::pyobject::{
23-
AttributeProtocol, IdProtocol, PyContext, PyObjectRef, PyResult, TypeProtocol,
23+
AttributeProtocol, DictProtocol, IdProtocol, PyContext, PyObjectRef, PyResult, TypeProtocol,
2424
};
2525
use crate::vm::VirtualMachine;
2626

@@ -842,7 +842,10 @@ pub fn builtin_build_class_(vm: &mut VirtualMachine, mut args: PyFuncArgs) -> Py
842842
let prepare = vm.get_attribute(metaclass.clone(), prepare_name)?;
843843
let namespace = vm.invoke(prepare, vec![name_arg.clone(), bases.clone()])?;
844844

845-
vm.invoke_with_locals(function, namespace.clone())?;
845+
let cells = vm.new_dict();
846846

847-
vm.call_method(&metaclass, "__call__", vec![name_arg, bases, namespace])
847+
vm.invoke_with_locals(function, cells.clone(), namespace.clone())?;
848+
let class = vm.call_method(&metaclass, "__call__", vec![name_arg, bases, namespace])?;
849+
cells.set_item(&vm.ctx, "__class__", class.clone());
850+
Ok(class)
848851
}

vm/src/vm.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -359,14 +359,21 @@ impl VirtualMachine {
359359
}
360360
}
361361

362-
pub fn invoke_with_locals(&mut self, function: PyObjectRef, locals: PyObjectRef) -> PyResult {
362+
pub fn invoke_with_locals(
363+
&mut self,
364+
function: PyObjectRef,
365+
cells: PyObjectRef,
366+
locals: PyObjectRef,
367+
) -> PyResult {
363368
if let Some(PyFunction {
364369
code,
365370
scope,
366371
defaults: _,
367372
}) = &function.payload()
368373
{
369-
let scope = scope.child_scope_with_locals(locals);
374+
let scope = scope
375+
.child_scope_with_locals(cells)
376+
.child_scope_with_locals(locals);
370377
let frame = self.ctx.new_frame(code.clone(), scope);
371378
return self.run_frame_full(frame);
372379
}

0 commit comments

Comments
 (0)