diff options
author | Michael Howitz <mh@gocept.com> | 2023-02-07 11:15:48 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-02-07 10:15:48 +0000 |
commit | 8f8ed8f7b603792b48401a64b51e900e86b88a82 (patch) | |
tree | 7fa4ac09d90e57c261ea28bc8281c42d7032d8b3 /src | |
parent | 14ba59c98e12517b9f8abcdb24bc882bb435ed7c (diff) | |
download | zope-pagetemplate-8f8ed8f7b603792b48401a64b51e900e86b88a82.tar.gz |
Multiple changes (#31)
* Add support for Python 3.11.
* Lint the code.
* Improve error handling in test.
* Bumped version for breaking release.
* Drop support for Python 2.7, 3.5, 3.6.
Co-authored-by: Gil Forcada Codinachs <gil.gnome@gmail.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/zope/pagetemplate/engine.py | 47 | ||||
-rw-r--r-- | src/zope/pagetemplate/i18n.py | 2 | ||||
-rw-r--r-- | src/zope/pagetemplate/interfaces.py | 3 | ||||
-rw-r--r-- | src/zope/pagetemplate/pagetemplate.py | 40 | ||||
-rw-r--r-- | src/zope/pagetemplate/pagetemplatefile.py | 5 | ||||
-rw-r--r-- | src/zope/pagetemplate/tests/batch.py | 2 | ||||
-rw-r--r-- | src/zope/pagetemplate/tests/test_basictemplate.py | 20 | ||||
-rw-r--r-- | src/zope/pagetemplate/tests/test_engine.py | 32 | ||||
-rw-r--r-- | src/zope/pagetemplate/tests/test_htmltests.py | 4 | ||||
-rw-r--r-- | src/zope/pagetemplate/tests/test_ptfile.py | 27 | ||||
-rw-r--r-- | src/zope/pagetemplate/tests/util.py | 20 |
11 files changed, 106 insertions, 96 deletions
diff --git a/src/zope/pagetemplate/engine.py b/src/zope/pagetemplate/engine.py index 4eb805d..662dbcd 100644 --- a/src/zope/pagetemplate/engine.py +++ b/src/zope/pagetemplate/engine.py @@ -19,15 +19,19 @@ __docformat__ = 'restructuredtext' import sys -from zope import component +from zope.i18n import translate from zope.interface import implementer from zope.interface.interfaces import ComponentLookupError from zope.proxy import isProxy -from zope.traversing.interfaces import IPathAdapter, ITraversable -from zope.traversing.interfaces import TraversalError +from zope.security.proxy import ProxyFactory +from zope.security.proxy import removeSecurityProxy from zope.traversing.adapters import traversePathElement -from zope.security.proxy import ProxyFactory, removeSecurityProxy -from zope.i18n import translate +from zope.traversing.interfaces import IPathAdapter +from zope.traversing.interfaces import ITraversable +from zope.traversing.interfaces import TraversalError + +from zope import component + try: # pragma: no cover # Until https://github.com/zopefoundation/zope.untrustedpython/issues/2 @@ -48,10 +52,14 @@ if HAVE_UNTRUSTED: # pragma: no cover del rcompile del SafeBuiltins -from zope.tales.expressions import PathExpr, StringExpr, NotExpr, DeferExpr +from zope.tales.expressions import DeferExpr +from zope.tales.expressions import NotExpr +from zope.tales.expressions import PathExpr from zope.tales.expressions import SimpleModuleImporter +from zope.tales.expressions import StringExpr from zope.tales.pythonexpr import PythonExpr -from zope.tales.tales import ExpressionEngine, Context +from zope.tales.tales import Context +from zope.tales.tales import ExpressionEngine from zope.pagetemplate.i18n import ZopeMessageFactory as _ @@ -60,7 +68,7 @@ class InlineCodeError(Exception): pass -class ZopeTraverser(object): +class ZopeTraverser: def __init__(self, proxify=None): if proxify is None: @@ -96,7 +104,7 @@ zopeTraverser = ZopeTraverser(ProxyFactory) class ZopePathExpr(PathExpr): def __init__(self, name, expr, engine): - super(ZopePathExpr, self).__init__(name, expr, engine, zopeTraverser) + super().__init__(name, expr, engine, zopeTraverser) trustedZopeTraverser = ZopeTraverser() @@ -105,8 +113,7 @@ trustedZopeTraverser = ZopeTraverser() class TrustedZopePathExpr(PathExpr): def __init__(self, name, expr, engine): - super(TrustedZopePathExpr, self).__init__(name, expr, engine, - trustedZopeTraverser) + super().__init__(name, expr, engine, trustedZopeTraverser) # Create a version of the restricted built-ins that uses a safe @@ -238,7 +245,7 @@ class TrustedZopeContext(ZopeContextBase): """Evaluation context for trusted programs.""" -class AdapterNamespaces(object): +class AdapterNamespaces: """Simulate tales function namespaces with adapter lookup. When we are asked for a namespace, we return an object that @@ -350,7 +357,7 @@ class ZopeEngine(ZopeBaseEngine): >>> m._getframe Traceback (most recent call last): ... - ForbiddenAttribute: ('_getframe', <module 'sys' (built-in)>) + zope.security.interfaces.ForbiddenAttribute: ('_getframe', <module 'sys' (built-in)>) The results of Python expressions evaluated by this engine are wrapped in security proxies if the 'untrusted' extra is installed:: @@ -394,16 +401,16 @@ class ZopeEngine(ZopeBaseEngine): >>> o1.__name__ 'bar' >>> type(o1) - <type 'zope.security._proxy._Proxy'> + <class 'zope.security._proxy._Proxy'> >>> o2 = context.evaluate('foo/bar/baz') >>> o2.__name__ 'baz' >>> type(o2) - <type 'zope.security._proxy._Proxy'> + <class 'zope.security._proxy._Proxy'> >>> o3 = o2.__parent__ >>> type(o3) - <type 'zope.security._proxy._Proxy'> + <class 'zope.security._proxy._Proxy'> >>> o1 == o3 True @@ -446,12 +453,12 @@ class ZopeEngine(ZopeBaseEngine): >>> tearDown() - """ + """ # noqa: E501 line too long def getFunctionNamespace(self, namespacename): """ Returns the function namespace """ return ProxyFactory( - super(ZopeEngine, self).getFunctionNamespace(namespacename)) + super().getFunctionNamespace(namespacename)) class TrustedZopeEngine(ZopeBaseEngine): @@ -536,13 +543,13 @@ Engine = _Engine() TrustedEngine = _TrustedEngine() -class AppPT(object): +class AppPT: def pt_getEngine(self): return Engine -class TrustedAppPT(object): +class TrustedAppPT: def pt_getEngine(self): return TrustedEngine diff --git a/src/zope/pagetemplate/i18n.py b/src/zope/pagetemplate/i18n.py index fc47f88..0db0317 100644 --- a/src/zope/pagetemplate/i18n.py +++ b/src/zope/pagetemplate/i18n.py @@ -17,4 +17,6 @@ __docformat__ = 'restructuredtext' # import this as _ to create i18n messages in the zope domain from zope.i18nmessageid import MessageFactory + + ZopeMessageFactory = MessageFactory('zope') diff --git a/src/zope/pagetemplate/interfaces.py b/src/zope/pagetemplate/interfaces.py index 0812a83..75ef47f 100644 --- a/src/zope/pagetemplate/interfaces.py +++ b/src/zope/pagetemplate/interfaces.py @@ -13,7 +13,8 @@ ############################################################################## """Interface that describes the 'macros' attribute of a PageTemplate. """ -from zope.interface import Interface, Attribute +from zope.interface import Attribute +from zope.interface import Interface class IPageTemplate(Interface): diff --git a/src/zope/pagetemplate/pagetemplate.py b/src/zope/pagetemplate/pagetemplate.py index bd9eafb..9c875ec 100644 --- a/src/zope/pagetemplate/pagetemplate.py +++ b/src/zope/pagetemplate/pagetemplate.py @@ -16,19 +16,20 @@ HTML- and XML-based template objects using TAL, TALES, and METAL. """ import sys -import six -from zope.tal.talparser import TALParser + +from zope.component import queryUtility +from zope.interface import implementer +from zope.interface import provider from zope.tal.htmltalparser import HTMLTALParser from zope.tal.talgenerator import TALGenerator from zope.tal.talinterpreter import TALInterpreter +from zope.tal.talparser import TALParser from zope.tales.engine import Engine -from zope.component import queryUtility -from zope.pagetemplate.interfaces import IPageTemplateSubclassing from zope.pagetemplate.interfaces import IPageTemplateEngine from zope.pagetemplate.interfaces import IPageTemplateProgram -from zope.interface import implementer -from zope.interface import provider +from zope.pagetemplate.interfaces import IPageTemplateSubclassing + _default_options = {} @@ -43,11 +44,11 @@ class StringIO(list): self.append(value) def getvalue(self): - return u''.join(self) + return ''.join(self) @implementer(IPageTemplateSubclassing) -class PageTemplate(object): +class PageTemplate: """ Page Templates using TAL, TALES, and METAL. @@ -151,16 +152,16 @@ class PageTemplate(object): """Adjust the string type to the type of text""" if isinstance( text, - six.binary_type) and not isinstance( + bytes) and not isinstance( string, - six.binary_type): + bytes): return string.encode('utf-8') if isinstance( text, - six.text_type) and not isinstance( + str) and not isinstance( string, - six.text_type): + str): return string.decode('utf-8') return string @@ -169,7 +170,7 @@ class PageTemplate(object): # 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, (six.string_types, six.binary_type)) + assert isinstance(text, (str, bytes)) def bs(s): """Bytes or str""" @@ -209,9 +210,8 @@ class PageTemplate(object): (self._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 + return bs('{}\n {}\n-->\n{}'.format( + self._error_start, '\n'.join(self._v_errors), self._text)) def pt_source_file(self): """To be overridden.""" @@ -243,7 +243,7 @@ class PageTemplate(object): try: self._v_errors = [ "Compilation failed", - "%s.%s: %s" % (etype.__module__, etype.__name__, e) + "{}.{}: {}".format(etype.__module__, etype.__name__, e) ] finally: del e @@ -258,7 +258,7 @@ class PTRuntimeError(RuntimeError): @implementer(IPageTemplateProgram) @provider(IPageTemplateEngine) -class PageTemplateEngine(object): +class PageTemplateEngine: """ Page template engine that uses the TAL interpreter to render. @@ -270,7 +270,7 @@ class PageTemplateEngine(object): self.program = program def __call__(self, context, macros, **options): - output = StringIO(u'') + output = StringIO('') interpreter = TALInterpreter( self.program, macros, context, stream=output, **options @@ -294,7 +294,7 @@ class PageTemplateEngine(object): # @implementer(ITracebackSupplement) -class PageTemplateTracebackSupplement(object): +class PageTemplateTracebackSupplement: def __init__(self, pt, namespace): self.manageable_object = pt diff --git a/src/zope/pagetemplate/pagetemplatefile.py b/src/zope/pagetemplate/pagetemplatefile.py index abbea81..b5a0a91 100644 --- a/src/zope/pagetemplate/pagetemplatefile.py +++ b/src/zope/pagetemplate/pagetemplatefile.py @@ -18,13 +18,14 @@ Zope object encapsulating a Page Template from the filesystem. __all__ = ("PageTemplateFile",) +import logging import os -import sys import re -import logging +import sys from zope.pagetemplate.pagetemplate import PageTemplate + logger = logging.getLogger(__name__) DEFAULT_ENCODING = "utf-8" diff --git a/src/zope/pagetemplate/tests/batch.py b/src/zope/pagetemplate/tests/batch.py index b6cb872..c63d6b8 100644 --- a/src/zope/pagetemplate/tests/batch.py +++ b/src/zope/pagetemplate/tests/batch.py @@ -15,7 +15,7 @@ """ -class batch(object): +class batch: """Create a sequence batch""" def __init__(self, sequence, size, start=0, end=0, diff --git a/src/zope/pagetemplate/tests/test_basictemplate.py b/src/zope/pagetemplate/tests/test_basictemplate.py index 014dc74..5b421c5 100644 --- a/src/zope/pagetemplate/tests/test_basictemplate.py +++ b/src/zope/pagetemplate/tests/test_basictemplate.py @@ -15,10 +15,11 @@ """ import unittest -from zope.pagetemplate.tests import util -import zope.pagetemplate.pagetemplate import zope.component.testing +import zope.pagetemplate.pagetemplate +from zope.pagetemplate.tests import util + class BasicTemplateTests(unittest.TestCase): @@ -82,17 +83,18 @@ class BasicTemplateTests(unittest.TestCase): output = self.t.pt_render({}) self.assertEqual(output, 'foo') - from zope.pagetemplate.interfaces import IPageTemplateEngine from zope.component import provideUtility - class DummyProgram(object): + from zope.pagetemplate.interfaces import IPageTemplateEngine + + class DummyProgram: def __init__(self, *args): self.args = args def __call__(self, *args, **kwargs): return self.args, (self,) + args, kwargs - class DummyEngine(object): + class DummyEngine: @staticmethod def cook(*args): return DummyProgram(*args), "macros" @@ -204,7 +206,7 @@ class BasicTemplateTests(unittest.TestCase): self.t() def test_unicode_html(self): - text = u'<p>\xe4\xf6\xfc\xdf</p>' + text = '<p>\xe4\xf6\xfc\xdf</p>' # test with HTML parser self.t.pt_edit(text, 'text/html') @@ -230,7 +232,7 @@ class BasicTemplateTests(unittest.TestCase): self.assertEqual(e[0], 'Macro expansion failed') def test_convert(self): - string = u'binary' + string = 'binary' text = b'binary' self.assertEqual(text, self.t._convert(string, text)) @@ -264,7 +266,7 @@ class BasicTemplateTests(unittest.TestCase): class TestPageTemplateTracebackSupplement(unittest.TestCase): def test_errors_old_style(self): - class PT(object): + class PT: def pt_errors(self, ns): return (ns,) @@ -274,7 +276,7 @@ class TestPageTemplateTracebackSupplement(unittest.TestCase): self.assertEqual(pts.warnings, ['ns']) def test_errors_none(self): - class PT(object): + class PT: def pt_errors(self, ns, check_macro_expansion=False): return None diff --git a/src/zope/pagetemplate/tests/test_engine.py b/src/zope/pagetemplate/tests/test_engine.py index 0caeb93..946cfba 100644 --- a/src/zope/pagetemplate/tests/test_engine.py +++ b/src/zope/pagetemplate/tests/test_engine.py @@ -16,9 +16,11 @@ import doctest import re import unittest -import zope.pagetemplate.engine -from zope.testing.renormalizing import RENormalizing + from zope.component.testing import PlacelessSetup +from zope.testing.renormalizing import RENormalizing + +import zope.pagetemplate.engine class EngineTests(PlacelessSetup, @@ -43,13 +45,20 @@ class EngineTests(PlacelessSetup, self.assertEqual(ctx.getValue('context'), 4) -class DummyEngine(object): +class DummyEngine: def getTypes(self): return {} + def getCompilerError(self): + # This is only here to get meaningful errors if RestrictedPython denies + # execution of some code. + def get_error(text): # pragma: no cover + raise RuntimeError(text) # pragma: no cover + return get_error # pragma: no cover -class DummyContext(object): + +class DummyContext: _engine = DummyEngine() @@ -73,8 +82,9 @@ class ZopePythonExprTests(unittest.TestCase): @unittest.skipUnless(zope.pagetemplate.engine.HAVE_UNTRUSTED, "Needs untrusted") def test_forbidden_module_name(self): - from zope.pagetemplate.engine import ZopePythonExpr from zope.security.interfaces import Forbidden + + from zope.pagetemplate.engine import ZopePythonExpr expr = ZopePythonExpr('python', '__import__("sys").exit', DummyEngine()) self.assertRaises(Forbidden, expr, DummyContext()) @@ -139,8 +149,8 @@ class TestZopeContext(PlacelessSetup, def test_evaluate_interpreter_found(self): get = zope.pagetemplate.engine._get_iinterpreter - from zope import interface from zope import component + from zope import interface class IInterpreter(interface.Interface): pass @@ -149,7 +159,7 @@ class TestZopeContext(PlacelessSetup, return IInterpreter @interface.implementer(IInterpreter) - class Interpreter(object): + class Interpreter: def evaluateRawCode(self, code, globs): globs['new'] = code return 42 @@ -198,15 +208,9 @@ class TestAppPT(unittest.TestCase): def test_suite(): checker = RENormalizing([ - # Python 3 includes module name in exceptions - (re.compile(r"zope.security.interfaces.ForbiddenAttribute"), - "ForbiddenAttribute"), - (re.compile(r"<class 'zope.security._proxy._Proxy'>"), - "<type 'zope.security._proxy._Proxy'>"), - (re.compile(r"<class 'list'>"), "<type 'list'>"), # PyPy/pure-Python implementation (re.compile(r"<class 'zope.security.proxy.ProxyPy'>"), - "<type 'zope.security._proxy._Proxy'>"), + "<class 'zope.security._proxy._Proxy'>"), ]) suite = unittest.defaultTestLoader.loadTestsFromName(__name__) diff --git a/src/zope/pagetemplate/tests/test_htmltests.py b/src/zope/pagetemplate/tests/test_htmltests.py index 80f6c0b..de08f17 100644 --- a/src/zope/pagetemplate/tests/test_htmltests.py +++ b/src/zope/pagetemplate/tests/test_htmltests.py @@ -15,11 +15,11 @@ """ import unittest -from zope.pagetemplate.tests import util from zope.pagetemplate.pagetemplate import PageTemplate +from zope.pagetemplate.tests import util -class Folder(object): +class Folder: context = property(lambda self: self) diff --git a/src/zope/pagetemplate/tests/test_ptfile.py b/src/zope/pagetemplate/tests/test_ptfile.py index ee7fd0d..7e62111 100644 --- a/src/zope/pagetemplate/tests/test_ptfile.py +++ b/src/zope/pagetemplate/tests/test_ptfile.py @@ -17,11 +17,10 @@ import os import tempfile import unittest -import six from zope.pagetemplate.pagetemplatefile import PageTemplateFile -class AbstractPTCase(object): +class AbstractPTCase: def get_pt(self, text=b'<html />'): with tempfile.NamedTemporaryFile(mode='wb', delete=False) as f: @@ -142,11 +141,11 @@ class TypeSniffingTestCase(AbstractPTCase, b"\xd0\xa2\xd0\xb5\xd1\x81\xd1\x82" b"</title></head></html>") rendered = pt() - self.assertTrue(isinstance(rendered, six.text_type)) + self.assertTrue(isinstance(rendered, str)) self.assertEqual(rendered.strip(), - (u"<html><head><title>" - u"\u0422\u0435\u0441\u0442" - u"</title></head></html>")) + ("<html><head><title>" + "\u0422\u0435\u0441\u0442" + "</title></head></html>")) def test_html_encoding_by_meta(self): pt = self.get_pt( @@ -157,11 +156,11 @@ class TypeSniffingTestCase(AbstractPTCase, b' content="text/html; charset=windows-1251">' b"</head></html>") rendered = pt() - self.assertTrue(isinstance(rendered, six.text_type)) + self.assertTrue(isinstance(rendered, str)) self.assertEqual(rendered.strip(), - (u"<html><head><title>" - u"\u0422\u0435\u0441\u0442" - u"</title></head></html>")) + ("<html><head><title>" + "\u0422\u0435\u0441\u0442" + "</title></head></html>")) def test_xhtml(self): pt = self.get_pt( @@ -172,11 +171,11 @@ class TypeSniffingTestCase(AbstractPTCase, b' content="text/html; charset=windows-1251"/>' b"</head></html>") rendered = pt() - self.assertTrue(isinstance(rendered, six.text_type)) + self.assertTrue(isinstance(rendered, str)) self.assertEqual(rendered.strip(), - (u"<html><head><title>" - u"\u0422\u0435\u0441\u0442" - u"</title></head></html>")) + ("<html><head><title>" + "\u0422\u0435\u0441\u0442" + "</title></head></html>")) class TestPageTemplateFile(AbstractPTCase, diff --git a/src/zope/pagetemplate/tests/util.py b/src/zope/pagetemplate/tests/util.py index 55dbebd..1e18d23 100644 --- a/src/zope/pagetemplate/tests/util.py +++ b/src/zope/pagetemplate/tests/util.py @@ -13,15 +13,16 @@ ############################################################################## """Utilities """ -from __future__ import print_function + import os import re import sys import unittest + import zope.pagetemplate.tests -class arg(object): +class arg: __allow_access_to_unprotected_subobjects__ = 1 def __init__(self, nn, aa): @@ -31,7 +32,7 @@ class arg(object): return str(self.arg) -class argv(object): +class argv: __allow_access_to_unprotected_subobjects__ = 1 def __init__(self, argv=None): @@ -43,14 +44,7 @@ class argv(object): context = property(lambda self: self) -class _Test(unittest.TestCase): - - def runTest(self): # pragma: no cover 2.7 compatibility - return - - -_assertEqual = _Test().assertEqual -del _Test +_assertEqual = unittest.TestCase().assertEqual def check_html(s1, s2): @@ -85,11 +79,11 @@ output_dir = os.path.join(here, 'output') def read_input(filename): filename = os.path.join(input_dir, filename) - with open(filename, 'r') as f: + with open(filename) as f: return f.read() def read_output(filename): filename = os.path.join(output_dir, filename) - with open(filename, 'r') as f: + with open(filename) as f: return f.read() |