new package pyscript, derived from zope.app.PythonPage

git-svn-id: svn://svn.cy55.de/Zope3/src/cybertools/trunk@1868 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
helmutm 2007-08-02 20:49:44 +00:00
parent dc7aa556c5
commit 273a618a28
4 changed files with 96 additions and 36 deletions

View file

@ -1,29 +1,92 @@
Python Page ============
=========== Python Pages
============
Python Page provides the user with a content object that interprets Persistent Python Page - Content Type
Python in content space. To save typing and useless messing with
output, any free-standing string and print statement are considered
for output; see the example below.
Examples:
Example >>> from cybertools.pyscript.tests import Root
------- >>> from cybertools.pyscript.script import PythonPage
Create a new content type called "Python Page" and enter the following >>> pp = PythonPage()
code example:: >>> pp.__parent__ = Root()
>>> pp.__name__ = 'pp'
>>> request = None
''' Test that can produce the correct filename
<html>
<body>
<ul>
'''
import time >>> pp._PythonPage__filename()
print time.asctime() u'/pp'
''' A simple test that checks that any lone-standing triple-quotes are
</ul> being printed.
</body>
</html> >>> pp.setSource(u"'''<html>...</html>'''\nreturn printed")
''' >>> pp(request)
'<html>...</html>\n'
Make sure that strings with prefixes work.
>>> pp.setSource(ur"ur'''test\r'''" + "\nreturn printed")
>>> pp(request)
'test\\r\n'
Make sure that Windows (\r\n) line ends also work.
>>> pp.setSource(u"if 1 == 1:\r\n\r\n '''<html>...</html>'''\nreturn printed")
>>> pp(request)
'<html>...</html>\n'
Make sure that unicode strings work as expected.
>>> #pp.setSource(u"u'''\u0442\u0435\u0441\u0442'''")
>>> #pp(request)
u'\u0442\u0435\u0441\u0442\n'
Make sure that multi-line strings work.
>>> pp.setSource(u"u'''test\ntest\ntest'''\nreturn printed")
>>> pp(request)
'test\n...test\n...test\n'
Here you can see a simple Python command...
>>> pp.setSource(u"print u'<html>...</html>'\nreturn printed")
>>> pp(request)
'<html>...</html>\n'
... and here a triple quote with some variable replacement.
>>> pp.setSource(u"'''<html>%s</html>''' %x\nreturn printed")
>>> pp(request, x='test')
'<html>test</html>\n'
Make sure that the context of the page is available.
>>> pp.setSource(u"'''<html>%s</html>''' %context.__name__\nreturn printed")
>>> pp(request)
'<html>root</html>\n'
Make sure that faulty syntax is interpreted correctly.
Note: We cannot just print the error directly, since there is a
'bug' in the Linux version of Python that does not display the filename
of the source correctly. So we construct an information string by hand.
>>> def print_err(err):
... print ('%(msg)s, %(filename)s, line %(lineno)i, offset %(offset)i'
... % err.__dict__)
...
>>> try:
... pp.setSource(u"'''<html>...</html>") #'''"
... except SyntaxError, err:
... print_err(err)
EOF while scanning triple-quoted string, /pp, line 4, offset 47
>>> try:
... pp.setSource(u"prin 'hello'")
... except SyntaxError, err:
... print_err(err)
invalid syntax, /pp, line 3, offset 16

View file

@ -24,6 +24,7 @@ $Id$
from zope.interface import Interface from zope.interface import Interface
from zope import schema from zope import schema
from zope.app.i18n import ZopeMessageFactory as _
class IPythonPage(Interface): class IPythonPage(Interface):

View file

@ -96,8 +96,7 @@ class PythonPage(Contained, Persistent):
self.__filename()) self.__filename())
kw['request'] = request kw['request'] = request
kw['script'] = self kw['script'] = self
kw['untrusted_output'] = output kw['untrusted_output'] = kw['printed'] = output
kw['printed'] = output
kw['context'] = getParent(self) kw['context'] = getParent(self)
kw['script_result'] = None kw['script_result'] = None
self._v_compiled(kw) self._v_compiled(kw)
@ -113,12 +112,12 @@ class Function(object):
def __init__(self, source, filename='<string>'): def __init__(self, source, filename='<string>'):
lines = [] lines = []
lines.insert(0, 'def dummy():') lines.insert(0, 'def dummy(): \n pass')
for line in source.splitlines(): for line in source.splitlines():
lines.append(' ' + line) lines.append(' ' + line)
lines.append('script_result = dummy()') lines.append('script_result = dummy()')
source = '\n'.join(lines) source = '\n'.join(lines)
print source #print source
self.code = compile(source, filename, 'exec') self.code = compile(source, filename, 'exec')
def __call__(self, globals): def __call__(self, globals):

View file

@ -15,31 +15,28 @@
$Id$ $Id$
""" """
import unittest
import unittest, doctest
import zope.component import zope.component
from zope.interface import implements from zope.interface import implements
from zope.testing.doctestunit import DocTestSuite from zope.location.traversing import LocationPhysicallyLocatable
from zope.testing.doctestunit import DocFileSuite
from zope.traversing.interfaces import IContainmentRoot from zope.traversing.interfaces import IContainmentRoot
from zope.traversing.interfaces import IPhysicallyLocatable from zope.traversing.interfaces import IPhysicallyLocatable
from zope.traversing.adapters import RootPhysicallyLocatable from zope.traversing.adapters import RootPhysicallyLocatable
from zope.location.traversing import LocationPhysicallyLocatable
from zope.app.container.contained import Contained from zope.app.container.contained import Contained
#from zope.app.interpreter.interfaces import IInterpreter
#from zope.app.interpreter.python import PythonInterpreter
from zope.app.testing import placelesssetup, ztapi from zope.app.testing import placelesssetup, ztapi
class Root(Contained): class Root(Contained):
implements(IContainmentRoot) implements(IContainmentRoot)
__parent__ = None __parent__ = None
__name__ = 'root' __name__ = 'root'
def setUp(test): def setUp(test):
placelesssetup.setUp() placelesssetup.setUp()
sm = zope.component.getGlobalSiteManager()
#sm.registerUtility(PythonInterpreter, IInterpreter, 'text/server-python')
ztapi.provideAdapter(None, IPhysicallyLocatable, ztapi.provideAdapter(None, IPhysicallyLocatable,
LocationPhysicallyLocatable) LocationPhysicallyLocatable)
@ -47,10 +44,10 @@ def setUp(test):
RootPhysicallyLocatable) RootPhysicallyLocatable)
def test_suite(): def test_suite():
flags = doctest.NORMALIZE_WHITESPACE | doctest.ELLIPSIS
return unittest.TestSuite(( return unittest.TestSuite((
DocTestSuite('cybertools.pyscript', DocFileSuite('README.txt', optionflags=flags,
setUp=setUp, tearDown=placelesssetup.tearDown), setUp=setUp, tearDown=placelesssetup.tearDown),
)) ))