
git-svn-id: svn://svn.cy55.de/Zope3/src/cybertools/trunk@2508 fd906abe-77d9-0310-91a1-e0d9ade77398
135 lines
3.2 KiB
Text
135 lines
3.2 KiB
Text
==============================================
|
|
Python Execution in Special Dynamic Namespaces
|
|
==============================================
|
|
|
|
$Id$
|
|
|
|
>>> from cybertools.util import namespace
|
|
|
|
|
|
A Very Restricted Basic Namespace
|
|
=================================
|
|
|
|
>>> minimal = namespace.BaseNamespace()
|
|
|
|
We
|
|
|
|
>>> code = """
|
|
... print 'Hello'
|
|
... # a comment
|
|
... print dir('')
|
|
... print '__builtins__:', __builtins__
|
|
... output('something')
|
|
... a = 'a is a variable'
|
|
... if a:
|
|
... print a
|
|
... """
|
|
>>> exec code in minimal
|
|
Hello
|
|
['__add__', ..., 'zfill']
|
|
__builtins__: {}
|
|
something
|
|
a is a variable
|
|
|
|
Assignments in code executed in a namespace may be accessed as attributes
|
|
of the namespace later.
|
|
|
|
>>> minimal.a
|
|
'a is a variable'
|
|
|
|
By setting the ``__builtins__`` mapping to an empty dictionary the minimal
|
|
namespace provides a secure restricted execution environment.
|
|
|
|
>>> exec "import os" in minimal
|
|
Traceback (most recent call last):
|
|
...
|
|
ImportError: __import__ not found
|
|
|
|
>>> exec "f = open('dummy.txt', 'w')" in minimal
|
|
Traceback (most recent call last):
|
|
...
|
|
NameError: open
|
|
|
|
Elements and sub-elements
|
|
-------------------------
|
|
|
|
>>> code = """
|
|
... topic('zope3', title='Zope 3')[
|
|
... annotation(author='jim')]
|
|
... topic('python')[
|
|
... annotation(author='guido'),
|
|
... child('zope3')]
|
|
... """
|
|
|
|
>>> from cybertools.util.jeep import Jeep
|
|
>>> topics = Jeep()
|
|
>>> symbols = namespace.BaseNamespace()
|
|
>>> symbols['topic'] = namespace.Element(symbols, 'topic', topics)
|
|
>>> symbols['annotation'] = namespace.Element(symbols, 'annotation')
|
|
>>> symbols['child'] = namespace.Element(symbols, 'child')
|
|
|
|
>>> exec code in symbols
|
|
|
|
>>> dict(topics)
|
|
{'python': <Element 'python'>, 'zope3': <Element 'zope3'>}
|
|
|
|
>>> dict(topics['python'].subElements)
|
|
{'zope3': <Element 'zope3'>, 'annotation': <Element 'annotation'>}
|
|
|
|
|
|
A Namespace Automatically Generating Elements
|
|
=============================================
|
|
|
|
>>> auto = namespace.AutoNamespace()
|
|
|
|
>>> exec "print something" in auto
|
|
something
|
|
|
|
>>> auto.something
|
|
<Element 'something'>
|
|
|
|
|
|
Execution of Python Code in a Namespace
|
|
=======================================
|
|
|
|
To simplify some standard use cases for working with namespaces the
|
|
module provides two classes for execution of Python code with appropriate
|
|
simple error handling.
|
|
|
|
Evaluation of Python expressions
|
|
--------------------------------
|
|
|
|
When evaluating an expression we always get a pair with the resulting
|
|
value and an - hopefully empty - error string.
|
|
|
|
>>> ev = namespace.Evaluator(auto)
|
|
>>> ev.evaluate('25 * 25')
|
|
(625, '')
|
|
|
|
>>> ev.evaluate('30/0')
|
|
(None, 'Traceback...ZeroDivisionError...')
|
|
|
|
Trying to execute a statement leads to a syntax error.
|
|
|
|
>>> ev.evaluate('print something_else')
|
|
(None, 'Traceback...SyntaxError...')
|
|
|
|
But we can explicitly allow the execution of statements. The result
|
|
of executing a statement is None.
|
|
|
|
>>> ev = namespace.Evaluator(auto, allowExec=True)
|
|
>>> ev.evaluate('print something_else')
|
|
something_else
|
|
(None, '')
|
|
>>> ev.evaluate('25 * 25')
|
|
(625, '')
|
|
|
|
Execution of Statements
|
|
-----------------------
|
|
|
|
>>> ex = namespace.Executor(auto)
|
|
>>> ex.execute('number = 25')
|
|
''
|
|
|
|
>>> ex.execute('30/0')
|
|
'Traceback...ZeroDivisionError...'
|