diff --git a/pyscript/README.txt b/pyscript/README.txt
index ca4daa5..b9d2a5a 100644
--- a/pyscript/README.txt
+++ b/pyscript/README.txt
@@ -1,29 +1,92 @@
-Python Page
-===========
+============
+Python Pages
+============
-Python Page provides the user with a content object that interprets
-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.
+Persistent Python Page - Content Type
+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
-code example::
+ >>> pp = PythonPage()
+ >>> pp.__parent__ = Root()
+ >>> pp.__name__ = 'pp'
+ >>> request = None
- '''
-
-
-
- '''
+Test that can produce the correct filename
- import time
- print time.asctime()
+ >>> pp._PythonPage__filename()
+ u'/pp'
- '''
-
-
-
- '''
+A simple test that checks that any lone-standing triple-quotes are
+being printed.
+
+ >>> pp.setSource(u"'''...'''\nreturn printed")
+ >>> pp(request)
+ '...\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 '''...'''\nreturn printed")
+ >>> pp(request)
+ '...\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'...'\nreturn printed")
+ >>> pp(request)
+ '...\n'
+
+... and here a triple quote with some variable replacement.
+
+ >>> pp.setSource(u"'''%s''' %x\nreturn printed")
+ >>> pp(request, x='test')
+ 'test\n'
+
+Make sure that the context of the page is available.
+
+ >>> pp.setSource(u"'''%s''' %context.__name__\nreturn printed")
+ >>> pp(request)
+ 'root\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"'''...") #'''"
+ ... 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
diff --git a/pyscript/interfaces.py b/pyscript/interfaces.py
index 0f11a0c..dfaf904 100644
--- a/pyscript/interfaces.py
+++ b/pyscript/interfaces.py
@@ -24,6 +24,7 @@ $Id$
from zope.interface import Interface
from zope import schema
+from zope.app.i18n import ZopeMessageFactory as _
class IPythonPage(Interface):
diff --git a/pyscript/script.py b/pyscript/script.py
index 7af5bd5..61b26d2 100644
--- a/pyscript/script.py
+++ b/pyscript/script.py
@@ -96,8 +96,7 @@ class PythonPage(Contained, Persistent):
self.__filename())
kw['request'] = request
kw['script'] = self
- kw['untrusted_output'] = output
- kw['printed'] = output
+ kw['untrusted_output'] = kw['printed'] = output
kw['context'] = getParent(self)
kw['script_result'] = None
self._v_compiled(kw)
@@ -113,12 +112,12 @@ class Function(object):
def __init__(self, source, filename=''):
lines = []
- lines.insert(0, 'def dummy():')
+ lines.insert(0, 'def dummy(): \n pass')
for line in source.splitlines():
lines.append(' ' + line)
lines.append('script_result = dummy()')
source = '\n'.join(lines)
- print source
+ #print source
self.code = compile(source, filename, 'exec')
def __call__(self, globals):
diff --git a/pyscript/tests.py b/pyscript/tests.py
index bd4495b..deda160 100644
--- a/pyscript/tests.py
+++ b/pyscript/tests.py
@@ -15,31 +15,28 @@
$Id$
"""
-import unittest
+import unittest, doctest
import zope.component
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 IPhysicallyLocatable
from zope.traversing.adapters import RootPhysicallyLocatable
-from zope.location.traversing import LocationPhysicallyLocatable
-
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
+
class Root(Contained):
implements(IContainmentRoot)
__parent__ = None
__name__ = 'root'
+
def setUp(test):
placelesssetup.setUp()
- sm = zope.component.getGlobalSiteManager()
- #sm.registerUtility(PythonInterpreter, IInterpreter, 'text/server-python')
ztapi.provideAdapter(None, IPhysicallyLocatable,
LocationPhysicallyLocatable)
@@ -47,10 +44,10 @@ def setUp(test):
RootPhysicallyLocatable)
-
def test_suite():
+ flags = doctest.NORMALIZE_WHITESPACE | doctest.ELLIPSIS
return unittest.TestSuite((
- DocTestSuite('cybertools.pyscript',
+ DocFileSuite('README.txt', optionflags=flags,
setUp=setUp, tearDown=placelesssetup.tearDown),
))