[Zope-dev] Trying to design a PythonMethod Product

Martijn Faassen m.faassen@vet.uu.nl
Thu, 12 Aug 1999 11:37:03 +0200


Evan Simpson wrote:
[snip intro on PythonMethod]

Sounds great so far. I'd love to take a look at this and try to help you
out.

> Thoughts so far:
> 
> 1. Must store a PythonMethod as raw text for editing purposes.  Compile/hack
> on each load, or try to store the compiled function for speed?

Recompile/rehack each time the PythonMethod text is edited. This doesn't
make anything extra difficult, I think? Take a look at XML Document (get
it from CVS) for an example on how that's done. Actually, I think normal
DTML Methods and such do the same, as Zope complains if you make a
mistake with the DTML tags, I just am more familiar with the XML
Document sources. 
 
> 2. Allow simple assignment, and no other kind. "x = anything" is legal, but
> not "x[0] = ...", "x.spam = ...", "x() = ...", etc.  Tuple/list unpacking
> might also be allowed.

Huh, why not? As long as you're manipulating a list or tuple created 
locally in the DTML method, that is. It gets trickier once you allow 
DTML methods to manipulate lists that come from Zope -- somehow those
would need to be protected against meddling. But I think the DTML
expression
machinery already does some of this, right?
 
> 3. Disallow "del" and "exec" entirely.

Why disallow 'del'? exec, fine with me, though it could be made to work
by
passing anything that exec wants to execute on to the same security 
mechanisms as the PythonMethod itself. But that might be cumbersome, and
'exec' is not really very essential for me, at least. I rarely if ever
use it.
 
> 4. Restrict "import" to modules/packages found in a particular location, so
> that 'safe' modules can be used.

I haven't thought about this enough to comment, but we should take a
look
at the bastion and restricted execution modules of Python.
 
> 5. Allow "while" and "for".  Insert 'escape code' at the bottom of every
> loop, to allow PythonMethods to 'time out' after some elapsed time or loop
> count.

Make sure this works with 'continue' and 'break' too, tricky, tricky. :)
If PythonMethods time out they should give an exception, I imagine. Also
recursive functions can cause pain.

Or perhaps instead of doing this, it's easier to do something like what
was mentioned on the Python Microthreads discussion on comp.lang.python
earlier. Basically just restrict the entire PythonMethod thread to a set
amount of 'ticks'. Once the ticks are up and the Method didn't finish
properly, throw an exception, or something.

I've seen this work in programmable muds just fine -- if a process
happens to run out of ticks, it just fails, and the mud continues
running.

> 6. Allow "print" to be used to generate rendered output by replacing it with
> a function that accumulates text.  If anything other than literal "None" is
> returned, the collected "print" text is discarded, otherwise it becomes the
> return value (on "return", "return None", and on implicit return, but not on
> "x=None; return x", for example).

Hm, seems a bit too implicit for me. We have two separate reasons for 
PythonMethods here:

* Replacement of External Methods

* Replacement of DTML methods/documents

Either we replace these with two different kinds of PythonMethod, or we
can choose for something explicit to return whatever's been sent to
sys.stdout during execution of the method. Perhaps something like:
return accumulated()
Or something more complicated. I posted a message with a prototype on
this type of thing a while back to this list. Just look for the messages
with my name. :)

How does Zope do it itself? DTML docs/methods return their rendered
contents, when called. SQL methods return a list of results. External
Methods can return a list or rendered contents. Digicool folks, correct
me if I'm wrong, but I think Zope objects just return whatever they
like; a string with rendered contents, or a list, or nothing at all, or
something else. How that information is used depends on how you call the
objects (with #var, or #call, or #in, etc). PythonMethods should just
mimic that.

> 7. Either disallow "global", or redirect access to globals into a controlled
> namespace.

Disallow global, I'd say.
 
> 8. Provide the Zope standard builtins (and tags?) as builtins.

Again I refer you to my sample/simplistic implementation posted
earlier to this list.

Regards,

Martijn