summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Howitz <mh@gocept.com>2023-02-07 11:15:48 +0100
committerGitHub <noreply@github.com>2023-02-07 10:15:48 +0000
commit8f8ed8f7b603792b48401a64b51e900e86b88a82 (patch)
tree7fa4ac09d90e57c261ea28bc8281c42d7032d8b3
parent14ba59c98e12517b9f8abcdb24bc882bb435ed7c (diff)
downloadzope-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>
-rw-r--r--.github/workflows/tests.yml20
-rw-r--r--.gitignore1
-rw-r--r--.meta.toml4
-rw-r--r--CHANGES.rst8
-rw-r--r--CONTRIBUTING.md23
-rw-r--r--MANIFEST.in1
-rw-r--r--setup.cfg13
-rw-r--r--setup.py21
-rw-r--r--src/zope/pagetemplate/engine.py47
-rw-r--r--src/zope/pagetemplate/i18n.py2
-rw-r--r--src/zope/pagetemplate/interfaces.py3
-rw-r--r--src/zope/pagetemplate/pagetemplate.py40
-rw-r--r--src/zope/pagetemplate/pagetemplatefile.py5
-rw-r--r--src/zope/pagetemplate/tests/batch.py2
-rw-r--r--src/zope/pagetemplate/tests/test_basictemplate.py20
-rw-r--r--src/zope/pagetemplate/tests/test_engine.py32
-rw-r--r--src/zope/pagetemplate/tests/test_htmltests.py4
-rw-r--r--src/zope/pagetemplate/tests/test_ptfile.py27
-rw-r--r--src/zope/pagetemplate/tests/util.py20
-rw-r--r--tox.ini32
20 files changed, 185 insertions, 140 deletions
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index d31f648..d8889f3 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -17,32 +17,30 @@ jobs:
fail-fast: false
matrix:
os:
- - ubuntu
+ - ["ubuntu", "ubuntu-20.04"]
config:
# [Python version, tox env]
- ["3.9", "lint"]
- - ["2.7", "py27"]
- - ["3.5", "py35"]
- - ["3.6", "py36"]
- ["3.7", "py37"]
- ["3.8", "py38"]
- ["3.9", "py39"]
- ["3.10", "py310"]
- - ["pypy2", "pypy"]
- - ["pypy3", "pypy3"]
+ - ["3.11", "py311"]
+ - ["pypy-3.9", "pypy3"]
- ["3.9", "docs"]
- ["3.9", "coverage"]
- runs-on: ${{ matrix.os }}-latest
+ runs-on: ${{ matrix.os[1] }}
+ if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name
name: ${{ matrix.config[1] }}
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v3
- name: Set up Python
- uses: actions/setup-python@v2
+ uses: actions/setup-python@v4
with:
python-version: ${{ matrix.config[0] }}
- name: Pip cache
- uses: actions/cache@v2
+ uses: actions/cache@v3
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ matrix.config[0] }}-${{ hashFiles('setup.*', 'tox.ini') }}
@@ -58,7 +56,7 @@ jobs:
- name: Coverage
if: matrix.config[1] == 'coverage'
run: |
- pip install coveralls coverage-python-version
+ pip install coveralls
coveralls --service=github
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.gitignore b/.gitignore
index c724a76..1f321f5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -28,4 +28,5 @@ lib64
log/
parts/
pyvenv.cfg
+testing.log
var/
diff --git a/.meta.toml b/.meta.toml
index 7bb3250..f0ea76b 100644
--- a/.meta.toml
+++ b/.meta.toml
@@ -2,15 +2,15 @@
# https://github.com/zopefoundation/meta/tree/master/config/pure-python
[meta]
template = "pure-python"
-commit-id = "7788b0c785ec23246369c0df9c6010e0047d8645"
+commit-id = "638bf910"
[python]
with-pypy = true
-with-legacy-python = true
with-docs = true
with-sphinx-doctests = true
with-windows = false
with-future-python = false
+with-macos = false
[tox]
use-flake8 = true
diff --git a/CHANGES.rst b/CHANGES.rst
index 5f7a0ac..937553f 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -2,10 +2,12 @@
Changes
=========
-4.6.1 (unreleased)
-==================
+5.0 (unreleased)
+================
+
+- Add support for Python 3.11.
-- Nothing changed yet.
+- Drop support for Python 2.7, 3.5, 3.6.
4.6.0 (2021-11-04)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..31d95f0
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,23 @@
+<!--
+Generated from:
+https://github.com/zopefoundation/meta/tree/master/config/pure-python
+-->
+# Contributing to zopefoundation projects
+
+The projects under the zopefoundation GitHub organization are open source and
+welcome contributions in different forms:
+
+* bug reports
+* code improvements and bug fixes
+* documentation improvements
+* pull request reviews
+
+For any changes in the repository besides trivial typo fixes you are required
+to sign the contributor agreement. See
+https://www.zope.dev/developer/becoming-a-committer.html for details.
+
+Please visit our [Developer
+Guidelines](https://www.zope.dev/developer/guidelines.html) if you'd like to
+contribute code changes and our [guidelines for reporting
+bugs](https://www.zope.dev/developer/reporting-bugs.html) if you want to file a
+bug report.
diff --git a/MANIFEST.in b/MANIFEST.in
index 8a3cd9b..52dc2ad 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -1,5 +1,6 @@
# Generated from:
# https://github.com/zopefoundation/meta/tree/master/config/pure-python
+include *.md
include *.rst
include *.txt
include buildout.cfg
diff --git a/setup.cfg b/setup.cfg
index 8b04203..544de16 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,7 +1,7 @@
# Generated from:
# https://github.com/zopefoundation/meta/tree/master/config/pure-python
[bdist_wheel]
-universal = 1
+universal = 0
[flake8]
doctests = 1
@@ -12,3 +12,14 @@ ignore =
.meta.toml
docs/_build/html/_sources/*
docs/_build/doctest/*
+
+[isort]
+force_single_line = True
+combine_as_imports = True
+sections = FUTURE,STDLIB,THIRDPARTY,ZOPE,FIRSTPARTY,LOCALFOLDER
+known_third_party = six, docutils, pkg_resources, pytz
+known_zope =
+known_first_party =
+default_section = ZOPE
+line_length = 79
+lines_after_imports = 2
diff --git a/setup.py b/setup.py
index e46e60c..4b2fb6d 100644
--- a/setup.py
+++ b/setup.py
@@ -19,7 +19,9 @@
"""Setup for zope.pagetemplate package
"""
import os
-from setuptools import setup, find_packages
+
+from setuptools import find_packages
+from setuptools import setup
def read(*rnames):
@@ -36,9 +38,9 @@ TESTS_REQUIRE = [
setup(name='zope.pagetemplate',
- version='4.6.1.dev0',
+ version='5.0.dev0',
author='Zope Foundation and Contributors',
- author_email='zope-dev@zope.org',
+ author_email='zope-dev@zope.dev',
description='Zope Page Templates',
long_description=(
read('README.rst')
@@ -51,15 +53,12 @@ setup(name='zope.pagetemplate',
'Intended Audience :: Developers',
'License :: OSI Approved :: Zope Public License',
'Programming Language :: Python',
- 'Programming Language :: Python :: 2',
- 'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
- 'Programming Language :: Python :: 3.5',
- 'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.8',
'Programming Language :: Python :: 3.9',
'Programming Language :: Python :: 3.10',
+ 'Programming Language :: Python :: 3.11',
'Programming Language :: Python :: Implementation :: CPython',
'Programming Language :: Python :: Implementation :: PyPy',
'Natural Language :: English',
@@ -72,16 +71,11 @@ setup(name='zope.pagetemplate',
packages=find_packages('src'),
package_dir={'': 'src'},
namespace_packages=['zope'],
+ python_requires='>=3.7',
extras_require={
'test': TESTS_REQUIRE,
- 'test:python_version == "2.7"': [
- 'zope.untrustedpython',
- ],
'untrusted': [
],
- 'untrusted:python_version == "2.7"': [
- 'zope.untrustedpython',
- ],
'docs': [
'Sphinx',
'repoze.sphinx.autointerface',
@@ -89,7 +83,6 @@ setup(name='zope.pagetemplate',
},
install_requires=[
'setuptools',
- 'six',
'zope.interface',
'zope.component',
'zope.tales',
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()
diff --git a/tox.ini b/tox.ini
index 77c9b01..9f935b5 100644
--- a/tox.ini
+++ b/tox.ini
@@ -4,14 +4,11 @@
minversion = 3.18
envlist =
lint
- py27
- py35
- py36
py37
py38
py39
py310
- pypy
+ py311
pypy3
docs
coverage
@@ -21,7 +18,7 @@ usedevelop = true
deps =
commands =
zope-testrunner --test-path=src {posargs:-vc}
- !py27-!pypy: sphinx-build -b doctest -d {envdir}/.cache/doctrees docs {envdir}/.cache/doctest
+ sphinx-build -b doctest -d {envdir}/.cache/doctrees docs {envdir}/.cache/doctest
extras =
test
docs
@@ -29,15 +26,26 @@ extras =
[testenv:lint]
basepython = python3
skip_install = true
+commands =
+ isort --check-only --diff {toxinidir}/src {toxinidir}/setup.py
+ flake8 src setup.py
+ check-manifest
+ check-python-versions
deps =
- flake8
check-manifest
check-python-versions >= 0.19.1
wheel
+ flake8
+ isort
+
+[testenv:isort-apply]
+basepython = python3
+skip_install = true
+commands_pre =
+deps =
+ isort
commands =
- flake8 src setup.py
- check-manifest
- check-python-versions
+ isort {toxinidir}/src {toxinidir}/setup.py []
[testenv:docs]
basepython = python3
@@ -53,17 +61,15 @@ allowlist_externals =
mkdir
deps =
coverage
- coverage-python-version
commands =
mkdir -p {toxinidir}/parts/htmlcov
coverage run -m zope.testrunner --test-path=src {posargs:-vc}
coverage run -a -m sphinx -b doctest -d {envdir}/.cache/doctrees docs {envdir}/.cache/doctest
- coverage html
- coverage report -m --fail-under=97
+ coverage html --ignore-errors
+ coverage report --ignore-errors --show-missing --fail-under=97
[coverage:run]
branch = True
-plugins = coverage_python_version
source = zope.pagetemplate
[coverage:report]