Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commita1b7c61

Browse files
committed
Implement sys._getframe() to the point where we can use it to get locals.
1 parentf6d7e2f commita1b7c61

File tree

5 files changed

+84
-5
lines changed

5 files changed

+84
-5
lines changed

‎tests/snippets/getframe.py‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
importsys
2+
3+
value=189
4+
locals_dict=sys._getframe().f_locals
5+
assertlocals_dict['value']==189
6+
foo='bar'
7+
assertlocals_dict['foo']==foo
8+
9+
deftest_function():
10+
x=17
11+
assertsys._getframe().f_localsisnotlocals_dict
12+
assertsys._getframe().f_locals['x']==17
13+
14+
test_function()
15+
16+
classTestClass():
17+
def__init__(self):
18+
assertsys._getframe().f_locals['self']==self
19+
20+
TestClass()

‎vm/src/frame.rs‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ extern crate rustpython_parser;
33
useself::rustpython_parser::ast;
44
use std::collections::hash_map::HashMap;
55
use std::fmt;
6+
use std::mem;
67
use std::path::PathBuf;
78

89
usesuper::builtins;
@@ -38,6 +39,7 @@ enum Block {
3839
},
3940
}
4041

42+
#[derive(Clone)]
4143
pubstructFrame{
4244
pubcode: bytecode::CodeObject,
4345
// We need 1 stack per frame
@@ -94,6 +96,8 @@ impl Frame {
9496
"<unknown>".to_string()
9597
};
9698

99+
let prev_frame = mem::replace(&mut vm.current_frame,Some(vm.ctx.new_frame(self.clone())));
100+
97101
// This is the name of the object being run:
98102
let run_obj_name =&self.code.obj_name.to_string();
99103

@@ -142,6 +146,7 @@ impl Frame {
142146
}
143147
};
144148

149+
vm.current_frame = prev_frame;
145150
value
146151
}
147152

‎vm/src/obj/objframe.rs‎

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22
33
*/
44

5+
usesuper::super::frame::Frame;
56
usesuper::super::pyobject::{
6-
AttributeProtocol,PyContext,PyFuncArgs,PyObjectRef,PyResult,TypeProtocol,
7+
AttributeProtocol,PyContext,PyFuncArgs,PyObjectKind,PyObjectRef,PyResult,TypeProtocol,
78
};
89
usesuper::super::vm::VirtualMachine;
910
usesuper::objtype;
@@ -12,6 +13,7 @@ pub fn init(context: &PyContext) {
1213
letref frame_type = context.frame_type;
1314
frame_type.set_attr("__new__", context.new_rustfunc(frame_new));
1415
frame_type.set_attr("__repr__", context.new_rustfunc(frame_repr));
16+
frame_type.set_attr("f_locals", context.new_property(frame_locals));
1517
}
1618

1719
fnframe_new(vm:&mutVirtualMachine,args:PyFuncArgs) ->PyResult{
@@ -24,3 +26,24 @@ fn frame_repr(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
2426
let repr =format!("<frame object at .. >");
2527
Ok(vm.new_str(repr))
2628
}
29+
30+
fnframe_locals(vm:&mutVirtualMachine,args:PyFuncArgs) ->PyResult{
31+
arg_check!(vm, args, required =[(frame,Some(vm.ctx.frame_type()))]);
32+
let frame =get_value(frame);
33+
let py_scope = frame.locals.clone();
34+
let py_scope = py_scope.borrow();
35+
36+
ifletPyObjectKind::Scope{ scope} =&py_scope.kind{
37+
Ok(scope.locals.clone())
38+
}else{
39+
panic!("The scope isn't a scope!");
40+
}
41+
}
42+
43+
pubfnget_value(obj:&PyObjectRef) ->Frame{
44+
ifletPyObjectKind::Frame{ frame} =&obj.borrow().kind{
45+
frame.clone()
46+
}else{
47+
panic!("Inner error getting int {:?}", obj);
48+
}
49+
}

‎vm/src/pyobject.rs‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,22 @@ impl PyContext {
459459
)
460460
}
461461

462+
pubfnnew_frame(&self,frame:Frame) ->PyObjectRef{
463+
PyObject::new(PyObjectKind::Frame{frame: frame},self.frame_type())
464+
}
465+
466+
pubfnnew_property(&self,function:RustPyFunc) ->PyObjectRef{
467+
let fget =self.new_rustfunc(function);
468+
let py_obj =PyObject::new(
469+
PyObjectKind::Instance{
470+
dict:self.new_dict(),
471+
},
472+
self.property_type(),
473+
);
474+
py_obj.set_attr("fget", fget.clone());
475+
py_obj
476+
}
477+
462478
pubfnnew_function(
463479
&self,
464480
code_obj:PyObjectRef,
@@ -782,6 +798,9 @@ pub enum PyObjectKind {
782798
Code{
783799
code: bytecode::CodeObject,
784800
},
801+
Frame{
802+
frame:Frame,
803+
},
785804
Function{
786805
code:PyObjectRef,
787806
scope:PyObjectRef,
@@ -856,6 +875,7 @@ impl fmt::Debug for PyObjectKind {
856875
} =>write!(f,"class {:?}", name),
857876
&PyObjectKind::Instance{dict: _} =>write!(f,"instance"),
858877
&PyObjectKind::RustFunction{function: _} =>write!(f,"rust function"),
878+
&PyObjectKind::Frame{ ..} =>write!(f,"frame"),
859879
}
860880
}
861881
}
@@ -913,6 +933,7 @@ impl PyObject {
913933
PyObjectKind::Code{code: _} =>format!("<code>"),
914934
PyObjectKind::Function{ ..} =>format!("<func>"),
915935
PyObjectKind::Generator{ ..} =>format!("<generator>"),
936+
PyObjectKind::Frame{ ..} =>format!("<frame>"),
916937
PyObjectKind::BoundMethod{ ..} =>format!("<bound-method>"),
917938
PyObjectKind::RustFunction{function: _} =>format!("<rustfunc>"),
918939
PyObjectKind::Module{ref name,dict: _} =>format!("<module '{}'>", name),

‎vm/src/sysmodule.rs‎

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
usesuper::pyobject::{DictProtocol,PyContext,PyObjectRef};
1+
usesuper::pyobject::{DictProtocol,PyContext,PyFuncArgs,PyObjectRef,PyResult};
2+
usesuper::vm::VirtualMachine;
23
use std::env;
34

45
/*
@@ -11,6 +12,14 @@ fn argv(ctx: &PyContext) -> PyObjectRef {
1112
ctx.new_list(argv)
1213
}
1314

15+
fngetframe(vm:&mutVirtualMachine,_args:PyFuncArgs) ->PyResult{
16+
ifletSome(frame) =&vm.current_frame{
17+
Ok(frame.clone())
18+
}else{
19+
panic!("Current frame is undefined!")
20+
}
21+
}
22+
1423
pubfnmk_module(ctx:&PyContext) ->PyObjectRef{
1524
let path_list =match env::var_os("PYTHONPATH"){
1625
Some(paths) => env::split_paths(&paths)
@@ -23,8 +32,9 @@ pub fn mk_module(ctx: &PyContext) -> PyObjectRef {
2332
let sys_name ="sys".to_string();
2433
let sys_mod = ctx.new_module(&sys_name, ctx.new_scope(None));
2534
modules.set_item(&sys_name, sys_mod.clone());
26-
sys_mod.set_item(&"modules".to_string(), modules);
27-
sys_mod.set_item(&"argv".to_string(),argv(ctx));
28-
sys_mod.set_item(&"path".to_string(), path);
35+
sys_mod.set_item("modules", modules);
36+
sys_mod.set_item("argv",argv(ctx));
37+
sys_mod.set_item("path", path);
38+
sys_mod.set_item("_getframe", ctx.new_rustfunc(getframe));
2939
sys_mod
3040
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp