diff -Nru zope.pagetemplate-4.0.1/bootstrap.py zope.pagetemplate-4.0.4/bootstrap.py --- zope.pagetemplate-4.0.1/bootstrap.py 2013-01-23 19:44:46.000000000 +0000 +++ zope.pagetemplate-4.0.4/bootstrap.py 2013-03-16 00:22:28.000000000 +0000 @@ -18,102 +18,148 @@ use the -c option to specify an alternate configuration file. """ -import os, shutil, sys, tempfile, urllib2 +import os, shutil, sys, tempfile from optparse import OptionParser tmpeggs = tempfile.mkdtemp() -is_jython = sys.platform.startswith('java') +usage = '''\ +[DESIRED PYTHON FOR BUILDOUT] bootstrap.py [options] -# parsing arguments -parser = OptionParser() -parser.add_option("-v", "--version", dest="version", - help="use a specific zc.buildout version") -parser.add_option("-d", "--distribute", - action="store_true", dest="distribute", default=False, - help="Use Disribute rather than Setuptools.") +Bootstraps a buildout-based project. -parser.add_option("-c", None, action="store", dest="config_file", +Simply run this script in a directory containing a buildout.cfg, using the +Python that you want bin/buildout to use. + +Note that by using --setup-source and --download-base to point to +local resources, you can keep this script from going over the network. +''' + +parser = OptionParser(usage=usage) +parser.add_option("-v", "--version", help="use a specific zc.buildout version") + +parser.add_option("-t", "--accept-buildout-test-releases", + dest='accept_buildout_test_releases', + action="store_true", default=False, + help=("Normally, if you do not specify a --version, the " + "bootstrap script and buildout gets the newest " + "*final* versions of zc.buildout and its recipes and " + "extensions for you. If you use this flag, " + "bootstrap and buildout will get the newest releases " + "even if they are alphas or betas.")) +parser.add_option("-c", "--config-file", help=("Specify the path to the buildout configuration " "file to be used.")) +parser.add_option("-f", "--find-links", + help=("Specify a URL to search for buildout releases")) -options, args = parser.parse_args() - -# if -c was provided, we push it back into args for buildout' main function -if options.config_file is not None: - args += ['-c', options.config_file] -if options.version is not None: - VERSION = '==%s' % options.version -else: - VERSION = '' +options, args = parser.parse_args() -USE_DISTRIBUTE = options.distribute -args = args + ['bootstrap'] +###################################################################### +# load/install distribute to_reload = False try: - import pkg_resources + import pkg_resources, setuptools if not hasattr(pkg_resources, '_distribute'): to_reload = True raise ImportError except ImportError: ez = {} - if USE_DISTRIBUTE: - exec urllib2.urlopen('http://python-distribute.org/distribute_setup.py' - ).read() in ez - ez['use_setuptools'](to_dir=tmpeggs, download_delay=0, no_fake=True) - else: - exec urllib2.urlopen('http://peak.telecommunity.com/dist/ez_setup.py' - ).read() in ez - ez['use_setuptools'](to_dir=tmpeggs, download_delay=0) + + try: + from urllib.request import urlopen + except ImportError: + from urllib2 import urlopen + + exec(urlopen('http://python-distribute.org/distribute_setup.py').read(), ez) + setup_args = dict(to_dir=tmpeggs, download_delay=0, no_fake=True) + ez['use_setuptools'](**setup_args) if to_reload: reload(pkg_resources) - else: - import pkg_resources + import pkg_resources + # This does not (always?) update the default working set. We will + # do it. + for path in sys.path: + if path not in pkg_resources.working_set.entries: + pkg_resources.working_set.add_entry(path) -if sys.platform == 'win32': - def quote(c): - if ' ' in c: - return '"%s"' % c # work around spawn lamosity on windows - else: - return c -else: - def quote (c): - return c +###################################################################### +# Install buildout -cmd = 'from setuptools.command.easy_install import main; main()' ws = pkg_resources.working_set -if USE_DISTRIBUTE: - requirement = 'distribute' -else: - requirement = 'setuptools' - -if is_jython: - import subprocess - - assert subprocess.Popen([sys.executable] + ['-c', quote(cmd), '-mqNxd', - quote(tmpeggs), 'zc.buildout' + VERSION], - env=dict(os.environ, - PYTHONPATH= - ws.find(pkg_resources.Requirement.parse(requirement)).location - ), - ).wait() == 0 - -else: - assert os.spawnle( - os.P_WAIT, sys.executable, quote (sys.executable), - '-c', quote (cmd), '-mqNxd', quote (tmpeggs), 'zc.buildout' + VERSION, - dict(os.environ, - PYTHONPATH= - ws.find(pkg_resources.Requirement.parse(requirement)).location - ), - ) == 0 +cmd = [sys.executable, '-c', + 'from setuptools.command.easy_install import main; main()', + '-mZqNxd', tmpeggs] + +find_links = os.environ.get( + 'bootstrap-testing-find-links', + options.find_links or + ('http://downloads.buildout.org/' + if options.accept_buildout_test_releases else None) + ) +if find_links: + cmd.extend(['-f', find_links]) + +distribute_path = ws.find( + pkg_resources.Requirement.parse('distribute')).location + +requirement = 'zc.buildout' +version = options.version +if version is None and not options.accept_buildout_test_releases: + # Figure out the most recent final version of zc.buildout. + import setuptools.package_index + _final_parts = '*final-', '*final' + def _final_version(parsed_version): + for part in parsed_version: + if (part[:1] == '*') and (part not in _final_parts): + return False + return True + index = setuptools.package_index.PackageIndex( + search_path=[distribute_path]) + if find_links: + index.add_find_links((find_links,)) + req = pkg_resources.Requirement.parse(requirement) + if index.obtain(req) is not None: + best = [] + bestv = None + for dist in index[req.project_name]: + distv = dist.parsed_version + if _final_version(distv): + if bestv is None or distv > bestv: + best = [dist] + bestv = distv + elif distv == bestv: + best.append(dist) + if best: + best.sort() + version = best[-1].version +if version: + requirement = '=='.join((requirement, version)) +cmd.append(requirement) + +import subprocess +if subprocess.call(cmd, env=dict(os.environ, PYTHONPATH=distribute_path)) != 0: + raise Exception( + "Failed to execute command:\n%s", + repr(cmd)[1:-1]) + +###################################################################### +# Import and run buildout ws.add_entry(tmpeggs) -ws.require('zc.buildout' + VERSION) +ws.require(requirement) import zc.buildout.buildout + +if not [a for a in args if '=' not in a]: + args.append('bootstrap') + +# if -c was provided, we push it back into args for buildout' main function +if options.config_file is not None: + args[0:0] = ['-c', options.config_file] + zc.buildout.buildout.main(args) shutil.rmtree(tmpeggs) diff -Nru zope.pagetemplate-4.0.1/buildout.cfg zope.pagetemplate-4.0.4/buildout.cfg --- zope.pagetemplate-4.0.1/buildout.cfg 2013-01-23 19:44:46.000000000 +0000 +++ zope.pagetemplate-4.0.4/buildout.cfg 2013-03-16 00:22:28.000000000 +0000 @@ -1,6 +1,7 @@ [buildout] develop = . parts = py test testcompat coverage-test coverage-report +versions = versions [test] recipe = zc.recipe.testrunner @@ -20,7 +21,7 @@ [coverage-test] recipe = zc.recipe.testrunner -eggs = zope.pagetemplate [test] +eggs = zope.pagetemplate [test, untrusted] defaults = ['--coverage', '../../coverage'] [coverage-report] @@ -28,3 +29,10 @@ eggs = z3c.coverage scripts = coverage=coverage-report arguments = ('coverage', 'coverage/report') + +[versions] +zope.i18n=4.0.0a3 +zope.publisher = 4.0.0a2 +zope.security = 4.0.0a4 +zope.traversing = 4.0.0a2 +zope.tal = 4.0.0a1 diff -Nru zope.pagetemplate-4.0.1/CHANGES.txt zope.pagetemplate-4.0.4/CHANGES.txt --- zope.pagetemplate-4.0.1/CHANGES.txt 2013-01-23 19:47:43.000000000 +0000 +++ zope.pagetemplate-4.0.4/CHANGES.txt 2013-03-16 00:22:28.000000000 +0000 @@ -2,6 +2,31 @@ CHANGES ======= +4.0.4 (2013-03-15) +------------------ + +- Make sure ``ZopePythonExpr`` and ``PythonExpr`` are separate classes even + when ``zope.untrustedpython`` is not available. Fixes a ZCML conflict error + in ``zope.app.pagetemplate``. + +4.0.3 (2013-02-28) +------------------ + +- Only allow ``zope.untrustedpython`` to be a dependency in Python 2. + +- Fix buildout to work properly. + +4.0.2 (2013-02-22) +------------------ + +- Migrated from ``zope.security.untrustedpython`` to ``zope.untrustedpython``. + +- Made ``zope.untrustedpython`` an extra dependency. Without it, python + expressions are not protected, even though path expressions are still + security wrapped. + +- Added support for Python 3.3. + 4.0.1 (2012-01-23) ------------------ diff -Nru zope.pagetemplate-4.0.1/debian/changelog zope.pagetemplate-4.0.4/debian/changelog --- zope.pagetemplate-4.0.1/debian/changelog 2013-01-30 18:04:17.000000000 +0000 +++ zope.pagetemplate-4.0.4/debian/changelog 2014-07-13 16:35:21.000000000 +0000 @@ -1,3 +1,17 @@ +zope.pagetemplate (4.0.4-0ubuntu2) utopic; urgency=medium + + * No change rebuild for transition to python-zope.untrustedpython. + + -- Barry Warsaw Sun, 13 Jul 2014 12:35:18 -0400 + +zope.pagetemplate (4.0.4-0ubuntu1) utopic; urgency=medium + + * New upstream release. + * d/patches/lp1339898.patch: Work around a DEP-8 test failure. + * d/control: Bumped Standards-Version to 3.9.5 with no changes necessary. + + -- Barry Warsaw Wed, 09 Jul 2014 17:53:18 -0400 + zope.pagetemplate (4.0.1-0ubuntu1) raring; urgency=low * New upstream release. diff -Nru zope.pagetemplate-4.0.1/debian/control zope.pagetemplate-4.0.4/debian/control --- zope.pagetemplate-4.0.1/debian/control 2013-01-30 18:01:45.000000000 +0000 +++ zope.pagetemplate-4.0.4/debian/control 2014-07-13 16:31:00.000000000 +0000 @@ -7,7 +7,7 @@ python-all (>= 2.6.6-3~), python-setuptools, python-van.pydeb -Standards-Version: 3.9.4 +Standards-Version: 3.9.5 X-Python-Version: >= 2.6 Homepage: http://pypi.python.org/pypi/zope.pagetemplate diff -Nru zope.pagetemplate-4.0.1/debian/patches/lp1339898.patch zope.pagetemplate-4.0.4/debian/patches/lp1339898.patch --- zope.pagetemplate-4.0.1/debian/patches/lp1339898.patch 1970-01-01 00:00:00.000000000 +0000 +++ zope.pagetemplate-4.0.4/debian/patches/lp1339898.patch 2014-07-13 16:31:00.000000000 +0000 @@ -0,0 +1,26 @@ +Description: Account for a superficial DEP-8 test failure. +Author: Barry Warsaw +Bug: https://bugs.launchpad.net/zopeproject/+bug/1339898 + +--- a/src/zope/pagetemplate/tests/output/teeshop1.html ++++ b/src/zope/pagetemplate/tests/output/teeshop1.html +@@ -43,7 +43,8 @@ + Description: + This is the tee for those who LOVE Zope. Show your heart on your tee. + +-

++

+ + + +@@ -60,7 +61,8 @@ + Description: + This is the tee for Jim Fulton. He's the Zope Pope! + +-

++

+ + + diff -Nru zope.pagetemplate-4.0.1/debian/patches/series zope.pagetemplate-4.0.4/debian/patches/series --- zope.pagetemplate-4.0.1/debian/patches/series 1970-01-01 00:00:00.000000000 +0000 +++ zope.pagetemplate-4.0.4/debian/patches/series 2014-07-13 16:31:00.000000000 +0000 @@ -0,0 +1 @@ +lp1339898.patch diff -Nru zope.pagetemplate-4.0.1/MANIFEST.in zope.pagetemplate-4.0.4/MANIFEST.in --- zope.pagetemplate-4.0.1/MANIFEST.in 2013-01-23 19:44:46.000000000 +0000 +++ zope.pagetemplate-4.0.4/MANIFEST.in 2013-03-16 00:22:28.000000000 +0000 @@ -1,4 +1,5 @@ include *.txt include bootstrap.py include buildout.cfg +include tox.ini recursive-include src *.txt *.html *.pt diff -Nru zope.pagetemplate-4.0.1/PKG-INFO zope.pagetemplate-4.0.4/PKG-INFO --- zope.pagetemplate-4.0.1/PKG-INFO 2013-01-23 19:50:04.000000000 +0000 +++ zope.pagetemplate-4.0.4/PKG-INFO 2013-03-16 00:22:44.000000000 +0000 @@ -1,6 +1,6 @@ -Metadata-Version: 1.0 +Metadata-Version: 1.1 Name: zope.pagetemplate -Version: 4.0.1 +Version: 4.0.4 Summary: Zope Page Templates Home-page: http://pypi.python.org/pypi/zope.pagetemplate Author: Zope Foundation and Contributors @@ -117,6 +117,31 @@ CHANGES ======= + 4.0.4 (2013-03-15) + ------------------ + + - Make sure ``ZopePythonExpr`` and ``PythonExpr`` are separate classes even + when ``zope.untrustedpython`` is not available. Fixes a ZCML conflict error + in ``zope.app.pagetemplate``. + + 4.0.3 (2013-02-28) + ------------------ + + - Only allow ``zope.untrustedpython`` to be a dependency in Python 2. + + - Fix buildout to work properly. + + 4.0.2 (2013-02-22) + ------------------ + + - Migrated from ``zope.security.untrustedpython`` to ``zope.untrustedpython``. + + - Made ``zope.untrustedpython`` an extra dependency. Without it, python + expressions are not protected, even though path expressions are still + security wrapped. + + - Added support for Python 3.3. + 4.0.1 (2012-01-23) ------------------ @@ -257,6 +282,8 @@ Classifier: Programming Language :: Python :: 2 Classifier: Programming Language :: Python :: 2.6 Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.3 Classifier: Natural Language :: English Classifier: Operating System :: OS Independent Classifier: Topic :: Internet :: WWW/HTTP diff -Nru zope.pagetemplate-4.0.1/setup.py zope.pagetemplate-4.0.4/setup.py --- zope.pagetemplate-4.0.1/setup.py 2013-01-23 19:48:19.000000000 +0000 +++ zope.pagetemplate-4.0.4/setup.py 2013-03-16 00:22:28.000000000 +0000 @@ -19,8 +19,11 @@ """Setup for zope.pagetemplate package """ import os +import sys from setuptools import setup, find_packages +PY3 = sys.version_info[0] >= 3 + def read(*rnames): return open(os.path.join(os.path.dirname(__file__), *rnames)).read() @@ -62,10 +65,11 @@ 'zope.testing', 'zope.proxy', 'zope.security', -] +] + (['zope.untrustedpython'] if not PY3 else []) + setup(name='zope.pagetemplate', - version='4.0.1', + version='4.0.4', author='Zope Foundation and Contributors', author_email='zope-dev@zope.org', description='Zope Page Templates', @@ -90,6 +94,8 @@ 'Programming Language :: Python :: 2', 'Programming Language :: Python :: 2.6', 'Programming Language :: Python :: 2.7', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.3', 'Natural Language :: English', 'Operating System :: OS Independent', 'Topic :: Internet :: WWW/HTTP', @@ -101,11 +107,12 @@ namespace_packages=['zope'], extras_require=dict( test=TESTS_REQUIRE, + untrusted=['zope.untrustedpython'] if not PY3 else [], ), install_requires=['setuptools', + 'six', 'zope.interface', 'zope.component', - 'zope.security [untrustedpython]', 'zope.tales', 'zope.tal', 'zope.i18n', diff -Nru zope.pagetemplate-4.0.1/src/zope/pagetemplate/engine.py zope.pagetemplate-4.0.4/src/zope/pagetemplate/engine.py --- zope.pagetemplate-4.0.1/src/zope/pagetemplate/engine.py 2013-01-23 19:44:46.000000000 +0000 +++ zope.pagetemplate-4.0.4/src/zope/pagetemplate/engine.py 2013-03-16 00:22:28.000000000 +0000 @@ -25,11 +25,16 @@ from zope.traversing.interfaces import IPathAdapter, ITraversable from zope.traversing.interfaces import TraversalError from zope.traversing.adapters import traversePathElement -from zope.security.untrustedpython import rcompile from zope.security.proxy import ProxyFactory, removeSecurityProxy -from zope.security.untrustedpython.builtins import SafeBuiltins from zope.i18n import translate +try: + from zope.untrustedpython import rcompile + from zope.untrustedpython.builtins import SafeBuiltins + HAVE_UNTRUSTED = True +except ImportError: + HAVE_UNTRUSTED = False + from zope.tales.expressions import PathExpr, StringExpr, NotExpr, DeferExpr from zope.tales.expressions import SimpleModuleImporter from zope.tales.pythonexpr import PythonExpr @@ -90,13 +95,15 @@ class ZopePythonExpr(PythonExpr): - def __call__(self, econtext): - __traceback_info__ = self.text - vars = self._bind_used_names(econtext, SafeBuiltins) - return eval(self._code, vars) + if HAVE_UNTRUSTED: + + def __call__(self, econtext): + __traceback_info__ = self.text + vars = self._bind_used_names(econtext, SafeBuiltins) + return eval(self._code, vars) - def _compile(self, text, filename): - return rcompile.compile(text, filename, 'eval') + def _compile(self, text, filename): + return rcompile.compile(text, filename, 'eval') class ZopeContextBase(Context): @@ -307,14 +314,17 @@ ForbiddenAttribute: ('_getframe', ) The results of Python expressions evaluated by this engine are - wrapped in security proxies:: + wrapped in security proxies if the 'untrusted' extra is installed:: >>> r = context.evaluate('python: {12: object()}.values') - >>> type(r) - - >>> r = context.evaluate('python: {12: object()}.values()[0].__class__') - >>> type(r) - + >>> str(type(r).__name__) == ( + ... '_Proxy' if HAVE_UNTRUSTED else + ... 'builtin_function_or_method') + True + + >>> r = context.evaluate('python: {12: object()}[12].__class__') + >>> str(type(r).__name__) == '_Proxy' or not HAVE_UNTRUSTED + True General path expressions provide objects that are wrapped in security proxies as well:: diff -Nru zope.pagetemplate-4.0.1/src/zope/pagetemplate/pagetemplatefile.py zope.pagetemplate-4.0.4/src/zope/pagetemplate/pagetemplatefile.py --- zope.pagetemplate-4.0.1/src/zope/pagetemplate/pagetemplatefile.py 2013-01-23 19:44:46.000000000 +0000 +++ zope.pagetemplate-4.0.4/src/zope/pagetemplate/pagetemplatefile.py 2013-03-16 00:22:28.000000000 +0000 @@ -23,13 +23,14 @@ import re import logging +import six from zope.pagetemplate.pagetemplate import PageTemplate DEFAULT_ENCODING = "utf-8" meta_pattern = re.compile( - r'\s*\s*', + br'\s*\s*', re.IGNORECASE) def package_home(gdict): @@ -41,6 +42,10 @@ _v_last_read = 0 + #_error_start = b'' + #_newline = b'\n' + def __init__(self, filename, _prefix=None): path = self.get_path_from_prefix(_prefix) self.filename = os.path.join(path, filename) @@ -59,14 +64,15 @@ def _prepare_html(self, text): match = meta_pattern.search(text) if match is not None: - type_, encoding = match.groups() + type_, encoding = (x.decode('utf-8') for x in match.groups()) # TODO: Shouldn't / stripping # be in PageTemplate.__call__()? - text = meta_pattern.sub("", text) + text = meta_pattern.sub(b"", text) else: type_ = None encoding = DEFAULT_ENCODING - return unicode(text, encoding), type_ + text = text.decode(encoding) + return text, type_ def _read_file(self): __traceback_info__ = self.filename @@ -77,13 +83,8 @@ f.close() raise type_ = sniff_type(text) - if type_ == "text/xml": - text += f.read() - else: - # For HTML, we really want the file read in text mode: - f.close() - f = open(self.filename) - text = f.read() + text += f.read() + if type_ != "text/xml": text, type_ = self._prepare_html(text) f.close() return text, type_ @@ -114,12 +115,12 @@ raise TypeError("non-picklable object") XML_PREFIXES = [ - "' + _newline = '\n' content_type = 'text/html' expand = 1 @@ -143,17 +146,28 @@ except: return ('Macro expansion failed', '%s: %s' % sys.exc_info()[:2]) + def _convert(self, string, text): + """Adjust the string type to the type of text""" + if isinstance(text, six.binary_type): + return string.encode('utf-8') + else: + return string + def write(self, text): # We accept both, since the text can either come from a file (and the # parser will take care of the encoding) or from a TTW template, in # which case we already have unicode. - assert isinstance(text, (str, unicode)) + assert isinstance(text, (six.string_types, six.binary_type)) + + def bs(s): + """Bytes or str""" + return self._convert(s, text) - if text.startswith(_error_start): - errend = text.find('-->') + if text.startswith(bs(self._error_start)): + errend = text.find(bs(self._error_end)) if errend >= 0: text = text[errend + 3:] - if text[:1] == "\n": + if text[:1] == bs(self._newline): text = text[1:] if self._text != text: self._text = text @@ -165,6 +179,9 @@ def read(self, request=None): """Gets the source, sometimes with macros expanded.""" self._cook_check() + def bs(s): + """Bytes or str""" + return self._convert(s, self._text) if not self._v_errors: if not self.expand: return self._text @@ -175,13 +192,13 @@ context = self.pt_getContext(self, request) return self.pt_render(context, source=1) except: - return ('%s\n Macro expansion failed\n %s\n-->\n%s' % - (_error_start, "%s: %s" % sys.exc_info()[:2], - self._text) ) - - return ('%s\n %s\n-->\n%s' % (_error_start, - '\n'.join(self._v_errors), - self._text)) + return (bs('%s\n Macro expansion failed\n %s\n-->\n' % + (_error_start, "%s: %s" % sys.exc_info()[:2])) + + self._text) + + return bs('%s\n %s\n-->\n' % (self._error_start, + '\n'.join(self._v_errors))) + \ + self._text def pt_source_file(self): """To be overridden.""" diff -Nru zope.pagetemplate-4.0.1/src/zope/pagetemplate/tests/input/checkpathalt.html zope.pagetemplate-4.0.4/src/zope/pagetemplate/tests/input/checkpathalt.html --- zope.pagetemplate-4.0.1/src/zope/pagetemplate/tests/input/checkpathalt.html 2013-01-23 19:44:46.000000000 +0000 +++ zope.pagetemplate-4.0.4/src/zope/pagetemplate/tests/input/checkpathalt.html 2013-03-16 00:22:28.000000000 +0000 @@ -11,7 +11,7 @@

Z

Z

-

Z

+

Z

diff -Nru zope.pagetemplate-4.0.1/src/zope/pagetemplate/tests/test_basictemplate.py zope.pagetemplate-4.0.4/src/zope/pagetemplate/tests/test_basictemplate.py --- zope.pagetemplate-4.0.1/src/zope/pagetemplate/tests/test_basictemplate.py 2013-01-23 19:44:46.000000000 +0000 +++ zope.pagetemplate-4.0.4/src/zope/pagetemplate/tests/test_basictemplate.py 2013-03-16 00:22:28.000000000 +0000 @@ -68,8 +68,8 @@ self.t.write("xyz") try: self.t.pt_render({}) - except zope.pagetemplate.pagetemplate.PTRuntimeError, e: - self.assertEquals( + except zope.pagetemplate.pagetemplate.PTRuntimeError as e: + self.assertEqual( str(e), "['Compilation failed', 'zope.tal.taldefs.TALError:" " TAL attributes on require explicit" @@ -208,11 +208,11 @@ # test with HTML parser self.t.pt_edit(text, 'text/html') - self.assertEquals(self.t().strip(), text) + self.assertEqual(self.t().strip(), text) # test with XML parser self.t.pt_edit(text, 'text/xml') - self.assertEquals(self.t().strip(), text) + self.assertEqual(self.t().strip(), text) def test_suite(): return unittest.makeSuite(BasicTemplateTests) diff -Nru zope.pagetemplate-4.0.1/src/zope/pagetemplate/tests/test_engine.py zope.pagetemplate-4.0.4/src/zope/pagetemplate/tests/test_engine.py --- zope.pagetemplate-4.0.1/src/zope/pagetemplate/tests/test_engine.py 2013-01-23 19:44:46.000000000 +0000 +++ zope.pagetemplate-4.0.4/src/zope/pagetemplate/tests/test_engine.py 2013-03-16 00:22:28.000000000 +0000 @@ -13,7 +13,12 @@ ############################################################################## """Doc tests for the pagetemplate's 'engine' module """ +import doctest +import re import unittest +import zope.pagetemplate.engine +from zope.testing.renormalizing import RENormalizing + class DummyNamespace(object): @@ -79,12 +84,24 @@ self.assertRaises(NameError, expr, DummyContext()) + def test_suite(): - from doctest import DocTestSuite + + checker = RENormalizing([ + # Python 3 includes module name in exceptions + (re.compile(r"zope.security.interfaces.ForbiddenAttribute"), + "ForbiddenAttribute"), + (re.compile(r""), + ""), + (re.compile(r""), ""), + ]) + suite = unittest.TestSuite() - suite.addTest(DocTestSuite('zope.pagetemplate.engine')) + suite.addTest(doctest.DocTestSuite('zope.pagetemplate.engine', + checker=checker)) suite.addTest(unittest.makeSuite(EngineTests)) - suite.addTest(unittest.makeSuite(ZopePythonExprTests)) + if zope.pagetemplate.engine.HAVE_UNTRUSTED: + suite.addTest(unittest.makeSuite(ZopePythonExprTests)) return suite diff -Nru zope.pagetemplate-4.0.1/src/zope/pagetemplate/tests/test_ptfile.py zope.pagetemplate-4.0.4/src/zope/pagetemplate/tests/test_ptfile.py --- zope.pagetemplate-4.0.1/src/zope/pagetemplate/tests/test_ptfile.py 2013-01-23 19:44:46.000000000 +0000 +++ zope.pagetemplate-4.0.4/src/zope/pagetemplate/tests/test_ptfile.py 2013-03-16 00:22:28.000000000 +0000 @@ -17,6 +17,7 @@ import tempfile import unittest +import six from zope.pagetemplate.pagetemplatefile import PageTemplateFile @@ -42,78 +43,78 @@ def test_sniffer_xml_ascii(self): self.check_content_type( - "", + b"", "text/xml") self.check_content_type( - "", + b"", "text/xml") def test_sniffer_xml_utf8(self): # w/out byte order mark self.check_content_type( - "", + b"", "text/xml") self.check_content_type( - "", + b"", "text/xml") # with byte order mark self.check_content_type( - "\xef\xbb\xbf", + b"\xef\xbb\xbf", "text/xml") self.check_content_type( - "\xef\xbb\xbf", + b"\xef\xbb\xbf", "text/xml") def test_sniffer_xml_utf16_be(self): # w/out byte order mark self.check_content_type( - "\0<\0?\0x\0m\0l\0 \0v\0e\0r\0s\0i\0o\0n\0=\0'\01\0.\0000\0'" - "\0 \0e\0n\0c\0o\0d\0i\0n\0g\0=\0'\0u\0t\0f\0-\08\0'\0?\0>" - "\0<\0d\0o\0c\0/\0>", + b"\0<\0?\0x\0m\0l\0 \0v\0e\0r\0s\0i\0o\0n\0=\0'\01\0.\0000\0'" + b"\0 \0e\0n\0c\0o\0d\0i\0n\0g\0=\0'\0u\0t\0f\0-\08\0'\0?\0>" + b"\0<\0d\0o\0c\0/\0>", "text/xml") self.check_content_type( - "\0<\0?\0x\0m\0l\0\t\0v\0e\0r\0s\0i\0o\0n\0=\0'\01\0.\0000\0'" - "\0 \0e\0n\0c\0o\0d\0i\0n\0g\0=\0'\0u\0t\0f\0-\08\0'\0?\0>" - "\0<\0d\0o\0c\0/\0>", + b"\0<\0?\0x\0m\0l\0\t\0v\0e\0r\0s\0i\0o\0n\0=\0'\01\0.\0000\0'" + b"\0 \0e\0n\0c\0o\0d\0i\0n\0g\0=\0'\0u\0t\0f\0-\08\0'\0?\0>" + b"\0<\0d\0o\0c\0/\0>", "text/xml") # with byte order mark self.check_content_type( - "\xfe\xff" - "\0<\0?\0x\0m\0l\0 \0v\0e\0r\0s\0i\0o\0n\0=\0'\01\0.\0000\0'" - "\0 \0e\0n\0c\0o\0d\0i\0n\0g\0=\0'\0u\0t\0f\0-\08\0'\0?\0>" - "\0<\0d\0o\0c\0/\0>", + b"\xfe\xff" + b"\0<\0?\0x\0m\0l\0 \0v\0e\0r\0s\0i\0o\0n\0=\0'\01\0.\0000\0'" + b"\0 \0e\0n\0c\0o\0d\0i\0n\0g\0=\0'\0u\0t\0f\0-\08\0'\0?\0>" + b"\0<\0d\0o\0c\0/\0>", "text/xml") self.check_content_type( - "\xfe\xff" - "\0<\0?\0x\0m\0l\0\t\0v\0e\0r\0s\0i\0o\0n\0=\0'\01\0.\0000\0'" - "\0 \0e\0n\0c\0o\0d\0i\0n\0g\0=\0'\0u\0t\0f\0-\08\0'\0?\0>" - "\0<\0d\0o\0c\0/\0>", + b"\xfe\xff" + b"\0<\0?\0x\0m\0l\0\t\0v\0e\0r\0s\0i\0o\0n\0=\0'\01\0.\0000\0'" + b"\0 \0e\0n\0c\0o\0d\0i\0n\0g\0=\0'\0u\0t\0f\0-\08\0'\0?\0>" + b"\0<\0d\0o\0c\0/\0>", "text/xml") def test_sniffer_xml_utf16_le(self): # w/out byte order mark self.check_content_type( - "<\0?\0x\0m\0l\0 \0v\0e\0r\0s\0i\0o\0n\0=\0'\01\0.\0000\0'\0" - " \0e\0n\0c\0o\0d\0i\0n\0g\0=\0'\0u\0t\0f\0-\08\0'\0?\0>\0" - "<\0d\0o\0c\0/\0>\n", + b"<\0?\0x\0m\0l\0 \0v\0e\0r\0s\0i\0o\0n\0=\0'\01\0.\0000\0'\0" + b" \0e\0n\0c\0o\0d\0i\0n\0g\0=\0'\0u\0t\0f\0-\08\0'\0?\0>\0" + b"<\0d\0o\0c\0/\0>\n", "text/xml") self.check_content_type( - "<\0?\0x\0m\0l\0\t\0v\0e\0r\0s\0i\0o\0n\0=\0'\01\0.\0000\0'\0" - " \0e\0n\0c\0o\0d\0i\0n\0g\0=\0'\0u\0t\0f\0-\08\0'\0?\0>\0" - "<\0d\0o\0c\0/\0>\0", + b"<\0?\0x\0m\0l\0\t\0v\0e\0r\0s\0i\0o\0n\0=\0'\01\0.\0000\0'\0" + b" \0e\0n\0c\0o\0d\0i\0n\0g\0=\0'\0u\0t\0f\0-\08\0'\0?\0>\0" + b"<\0d\0o\0c\0/\0>\0", "text/xml") # with byte order mark self.check_content_type( - "\xff\xfe" - "<\0?\0x\0m\0l\0 \0v\0e\0r\0s\0i\0o\0n\0=\0'\01\0.\0000\0'\0" - " \0e\0n\0c\0o\0d\0i\0n\0g\0=\0'\0u\0t\0f\0-\08\0'\0?\0>\0" - "<\0d\0o\0c\0/\0>\0", + b"\xff\xfe" + b"<\0?\0x\0m\0l\0 \0v\0e\0r\0s\0i\0o\0n\0=\0'\01\0.\0000\0'\0" + b" \0e\0n\0c\0o\0d\0i\0n\0g\0=\0'\0u\0t\0f\0-\08\0'\0?\0>\0" + b"<\0d\0o\0c\0/\0>\0", "text/xml") self.check_content_type( - "\xff\xfe" - "<\0?\0x\0m\0l\0\t\0v\0e\0r\0s\0i\0o\0n\0=\0'\01\0.\0000\0'\0" - " \0e\0n\0c\0o\0d\0i\0n\0g\0=\0'\0u\0t\0f\0-\08\0'\0?\0>\0" - "<\0d\0o\0c\0/\0>\0", + b"\xff\xfe" + b"<\0?\0x\0m\0l\0\t\0v\0e\0r\0s\0i\0o\0n\0=\0'\01\0.\0000\0'\0" + b" \0e\0n\0c\0o\0d\0i\0n\0g\0=\0'\0u\0t\0f\0-\08\0'\0?\0>\0" + b"<\0d\0o\0c\0/\0>\0", "text/xml") HTML_PUBLIC_ID = "-//W3C//DTD HTML 4.01 Transitional//EN" @@ -121,11 +122,11 @@ def test_sniffer_html_ascii(self): self.check_content_type( - "" - % self.HTML_SYSTEM_ID, + ("" + % self.HTML_SYSTEM_ID).encode("utf-8"), "text/html") self.check_content_type( - "sample document", + b"sample document", "text/html") # TODO: This reflects a case that simply isn't handled by the @@ -137,43 +138,43 @@ def test_html_default_encoding(self): pt = self.get_pt( - "" + b"<html><head><title>" # 'Test' in russian (utf-8) - "\xd0\xa2\xd0\xb5\xd1\x81\xd1\x82" - "") + b"\xd0\xa2\xd0\xb5\xd1\x81\xd1\x82" + b"") rendered = pt() - self.failUnless(isinstance(rendered, unicode)) - self.failUnlessEqual(rendered.strip(), + self.assertTrue(isinstance(rendered, six.text_type)) + self.assertEqual(rendered.strip(), u"" u"\u0422\u0435\u0441\u0442" u"") def test_html_encoding_by_meta(self): pt = self.get_pt( - "" + b"<html><head><title>" # 'Test' in russian (windows-1251) - "\xd2\xe5\xf1\xf2" - '' - "") + b"\xd2\xe5\xf1\xf2" + b'' + b"") rendered = pt() - self.failUnless(isinstance(rendered, unicode)) - self.failUnlessEqual(rendered.strip(), + self.assertTrue(isinstance(rendered, six.text_type)) + self.assertEqual(rendered.strip(), u"" u"\u0422\u0435\u0441\u0442" u"") def test_xhtml(self): pt = self.get_pt( - "" + b"<html><head><title>" # 'Test' in russian (windows-1251) - "\xd2\xe5\xf1\xf2" - '' - "") + b"\xd2\xe5\xf1\xf2" + b'' + b"") rendered = pt() - self.failUnless(isinstance(rendered, unicode)) - self.failUnlessEqual(rendered.strip(), + self.assertTrue(isinstance(rendered, six.text_type)) + self.assertEqual(rendered.strip(), u"" u"\u0422\u0435\u0441\u0442" u"") diff -Nru zope.pagetemplate-4.0.1/src/zope/pagetemplate/tests/util.py zope.pagetemplate-4.0.4/src/zope/pagetemplate/tests/util.py --- zope.pagetemplate-4.0.1/src/zope/pagetemplate/tests/util.py 2013-01-23 19:44:46.000000000 +0000 +++ zope.pagetemplate-4.0.4/src/zope/pagetemplate/tests/util.py 2013-03-16 00:22:28.000000000 +0000 @@ -13,6 +13,7 @@ ############################################################################## """Utilities """ +from __future__ import print_function import os import re import sys @@ -70,7 +71,7 @@ def dump(tag, x, lo, hi): for i in xrange(lo, hi): - print '%s %s' % (tag, x[i]), + print('%s %s' % (tag, x[i]), end=' ') def check_html(s1, s2): s1 = normalize_html(s1) @@ -102,8 +103,10 @@ def read_input(filename): filename = os.path.join(input_dir, filename) - return open(filename, 'r').read() + with open(filename, 'r') as f: + return f.read() def read_output(filename): filename = os.path.join(output_dir, filename) - return open(filename, 'r').read() + with open(filename, 'r') as f: + return f.read() diff -Nru zope.pagetemplate-4.0.1/src/zope.pagetemplate.egg-info/PKG-INFO zope.pagetemplate-4.0.4/src/zope.pagetemplate.egg-info/PKG-INFO --- zope.pagetemplate-4.0.1/src/zope.pagetemplate.egg-info/PKG-INFO 2013-01-23 19:50:03.000000000 +0000 +++ zope.pagetemplate-4.0.4/src/zope.pagetemplate.egg-info/PKG-INFO 2013-03-16 00:22:32.000000000 +0000 @@ -1,6 +1,6 @@ -Metadata-Version: 1.0 +Metadata-Version: 1.1 Name: zope.pagetemplate -Version: 4.0.1 +Version: 4.0.4 Summary: Zope Page Templates Home-page: http://pypi.python.org/pypi/zope.pagetemplate Author: Zope Foundation and Contributors @@ -117,6 +117,31 @@ CHANGES ======= + 4.0.4 (2013-03-15) + ------------------ + + - Make sure ``ZopePythonExpr`` and ``PythonExpr`` are separate classes even + when ``zope.untrustedpython`` is not available. Fixes a ZCML conflict error + in ``zope.app.pagetemplate``. + + 4.0.3 (2013-02-28) + ------------------ + + - Only allow ``zope.untrustedpython`` to be a dependency in Python 2. + + - Fix buildout to work properly. + + 4.0.2 (2013-02-22) + ------------------ + + - Migrated from ``zope.security.untrustedpython`` to ``zope.untrustedpython``. + + - Made ``zope.untrustedpython`` an extra dependency. Without it, python + expressions are not protected, even though path expressions are still + security wrapped. + + - Added support for Python 3.3. + 4.0.1 (2012-01-23) ------------------ @@ -257,6 +282,8 @@ Classifier: Programming Language :: Python :: 2 Classifier: Programming Language :: Python :: 2.6 Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.3 Classifier: Natural Language :: English Classifier: Operating System :: OS Independent Classifier: Topic :: Internet :: WWW/HTTP diff -Nru zope.pagetemplate-4.0.1/src/zope.pagetemplate.egg-info/requires.txt zope.pagetemplate-4.0.4/src/zope.pagetemplate.egg-info/requires.txt --- zope.pagetemplate-4.0.1/src/zope.pagetemplate.egg-info/requires.txt 2013-01-23 19:50:03.000000000 +0000 +++ zope.pagetemplate-4.0.4/src/zope.pagetemplate.egg-info/requires.txt 2013-03-16 00:22:32.000000000 +0000 @@ -1,7 +1,7 @@ setuptools +six zope.interface zope.component -zope.security [untrustedpython] zope.tales zope.tal zope.i18n @@ -11,4 +11,8 @@ [test] zope.testing zope.proxy -zope.security \ No newline at end of file +zope.security +zope.untrustedpython + +[untrusted] +zope.untrustedpython \ No newline at end of file diff -Nru zope.pagetemplate-4.0.1/tox.ini zope.pagetemplate-4.0.4/tox.ini --- zope.pagetemplate-4.0.1/tox.ini 2013-01-23 19:44:46.000000000 +0000 +++ zope.pagetemplate-4.0.4/tox.ini 2013-03-16 00:22:28.000000000 +0000 @@ -1,11 +1,30 @@ [tox] envlist = - # py32 needs a py3k-compatible zope.security at the very least - py26,py27 + py26,py27,py33 [testenv] deps = zope.pagetemplate[test] -commands = + zope.component + zope.i18n + zope.i18nmessageid + zope.interface + zope.proxy + zope.security + zope.tal + zope.tales + zope.testing + zope.testrunner + zope.traversing +commands = python setup.py test -q +[testenv:py26] +deps = + {[testenv]deps} + zope.untrustedpython + RestrictedPython + +[testenv:py27] +deps = + {[testenv:py26]deps}