学生向けにプログラミング能力を試験するテストを作りました。
https://github.com/ernix/quiz/blob/master/q1.py

python2で書かれており、指定の機能もったメソッドをクラスに実装するテストなのですが、実行することでクラス自身が自己採点できるような作りになっています。

その中でevalのような一部のビルトイン関数を使われる事が無いよう制限をかけたいのですが、tokenizeを使ってメソッドの字面だけをパースする方法だとデコレータが使われりプライベートメソッドを呼び出した時に対応できません。

一部抜粋:

        """ test 3: keywords """
        from cStringIO import StringIO
        import inspect
        import tokenize
        code = StringIO(''.join(inspect.getsourcelines(method)[0][1:]))
        tokens = tokenize.generate_tokens(code.readline)
        name_tokens = []
        for toknum, tokval, _, _, _ in tokens:
            if toknum == tokenize.NAME and tokval in used_keyword.keys():
                name_tokens.append(tokval)

        for t in set(name_tokens):
            if t in kw_not_allowed:
                errors.append(['`%s` is not allowed' % (t)])
            elif used_keyword[t] is not None:
                errors.append([
                    '`%s` is already used in %s' % (t, used_keyword[t]),
                ])
            else:
                used_keyword[t] = f

特にinspect.getsourcelines(method)[0][1:]のあたりです。defから始まる最初の行はスキップするようになっています。

このようにメソッドの中身を単純にパースするのではなく、動的にビルトイン関数を上書きしてエラーを出すように変更することは可能でしょうか?