 c39280f58f
			
		
	
	
		c39280f58f
		
	
	
	
	
		
			
			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...'
 |