
git-svn-id: svn://svn.cy55.de/Zope3/src/cybertools/trunk@2517 fd906abe-77d9-0310-91a1-e0d9ade77398
137 lines
3.3 KiB
Text
137 lines
3.3 KiB
Text
==============================================
|
|
Python Execution in Special Dynamic Namespaces
|
|
==============================================
|
|
|
|
$Id$
|
|
|
|
>>> from cybertools.meta 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 (children)
|
|
------------------------------------
|
|
|
|
>>> code = """
|
|
... topic('zope3', title='Zope 3')[
|
|
... annotation(author='jim')]
|
|
... topic('python')[
|
|
... annotation(author='guido'),
|
|
... child('zope3')]
|
|
... """
|
|
|
|
>>> from cybertools.util.jeep import Jeep
|
|
>>> from cybertools.meta.element import ElementFactory
|
|
>>> symbols = namespace.BaseNamespace()
|
|
>>> symbols['topic'] = ElementFactory(symbols, 'topic')
|
|
>>> symbols['annotation'] = ElementFactory(symbols, 'annotation')
|
|
>>> symbols['child'] = ElementFactory(symbols, 'child')
|
|
|
|
>>> exec code in symbols
|
|
|
|
>>> symbols.topic.instances
|
|
[<Element 'zope3'>, <Element 'python'>]
|
|
>>> zope3 = symbols.topic.instances[0]
|
|
>>> dict(zope3.annotation)
|
|
{'author': 'jim'}
|
|
>>> zope3.title
|
|
'Zope 3'
|
|
|
|
|
|
A Namespace Automatically Generating Elements
|
|
=============================================
|
|
|
|
>>> auto = namespace.AutoNamespace()
|
|
|
|
>>> exec "print something" in auto
|
|
something
|
|
|
|
>>> auto.something
|
|
<AutoElement '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...'
|