On 16/08/21 1:50 am, Hope Rouselle wrote:
By the way, I'm aware that what I'm doing here is totally unsafe and I
could get my system destroyed.  I'm not planning on using this --- thank
you for your concern.  I'm just interested in understanding more about
modules.

Okay, I'll assume all the security issues have been taken are of, e.g.
by running all of this in a virtual machine...

Notice how student m0 (who really scored a zero)
first gets his grade right, but if I invoke it again, then it gets 50.0.

The best way to do this would be to run each student's file in
a separate process, so you know you're getting a completely fresh
start each time.

The second best way would be to not use import_module, but to
exec() the student's code. That way you don't create an entry in
sys.modules and don't have to worry about somehow unloading the
module.

Something like

    code = read_student_file(student_name)
    env = {} # A dict to hold the student's module-level definitions
    exec(code, env)
    grade_question1(env)
    env['procedure_x'] = key.procedure_x
    grade_question2(env)
    ...etc...

That's not the whole problem.  For reasons I don't understand, new
modules I load --- that is, different students --- get mixed with these
modifications in m0 that I made at some point in my code.

I would have to see a specific example of that. One thing to keep
in mind is that if key.procedure_x modifies any globals in the
key module, it will still modify globals in the key module -- not
the student's module -- after being transplanted there.

More generally, there are countless ways that a student's code
could modify something outside of its own module and affect the
behaviour of other student's code. This is why it would be
vastly preferable to run each test in a fresh process.

(*) If it were easy to unload modules...

It's sometimes possible to unload and reimport a module, but
only if the module's effects are completely self-contained.
That depends not only on what the module itself does, but
what other modules do with it. If any other module has imported
it, that module will still contain references to the old
module; if there are instances of a class defined in it still
existing, they will still be instances of the old version of
the class; etc.

99.999% of the time it's easier to just start again with a
fresh Python process.

--
Greg
--
https://mail.python.org/mailman/listinfo/python-list

Reply via email to