5
def c():
    def a():
        print dir()

    def b():
        pass

    a()

c()

Probably a really simple question, but I can't seem to find an answer by googling. I have the code above, and I want the a method to print the namespace containing the methods a and b, i.e. I want it to print the namespace of the point form which it is called. Is this possible? Preferably in Python 2.x

2
  • I would try globals() In python 3 there is another way to do it as well Commented Feb 3, 2012 at 14:50
  • I already explained in comments on the two answers: basically I'm looking for vulnerabilities in our online testing application for our students. As appears to be correct we need to prevent the students from reverse engineering the testing code to find the solution. (Of course any student smart enough to find this out also should have enough skills to pass the exercises) Commented Feb 3, 2012 at 15:09

2 Answers 2

6

You can use inspect module from standard Python library:

import inspect

def c():
    def a():
        frame = inspect.currentframe()
        print frame.f_back.f_locals

    def b():
        pass

    a()

c()

But frames should be deleted after use, see note.


Answer to comment.

Possible way to restrict inspect features for students:

import sys
sys.modules['inspect'] = None
sys._getframe = None
Sign up to request clarification or add additional context in comments.

6 Comments

Bad idea. This is expensive and dirty
Actually, this does exactly what I was afraid was possible: students can use inspect to print the source of the functions we use to test their exercises. Thanks. Now I have a possible attack and it's up to me to find a way to protect against it
@nvcleemp, I think it's possible to restrict inspect and sys._getframe usage.
Thanks, I don't think we will ever give them exercises where they need inspect or sys._getframe, so just overwriting them, seems to be a reasonable solution.
@nvcleemp I think your best bet for a foolproof solution is PyPy's sandboxing mode.
|
2

I would go with locals() like this:

def c():
    def a(locals_):
        print locals_

    def b():
        pass

    a( locals() )

c()

3 Comments

Yes, that would work, but I can't change the signature of the function a and I can't change the point from which it is called. (Basically I'm trying to find which attacks my students could use to discover how there solutions are checked in our online testing application)
Why do you mix/inject students code with some of your code..? Looks so strange. Why not just import like a module and call functions regularly. Or eval, still sounds simpler. Or, use RestrictedPython for something truly safe.
We use an existing website (spoj.pl), but have written some custom judges to provide more feed back for our students. One of these judges takes the students code, runs it and then runs a doctest and gives the students the result of this doctest. It seems that I had paniced a bit too early: I thought they could use inspect.getsource, but since the code that is executed is generated it seems to be not possible to obtain the source code in that way.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.