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 | |
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>
-rw-r--r-- | .github/workflows/tests.yml | 20 | ||||
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | .meta.toml | 4 | ||||
-rw-r--r-- | CHANGES.rst | 8 | ||||
-rw-r--r-- | CONTRIBUTING.md | 23 | ||||
-rw-r--r-- | MANIFEST.in | 1 | ||||
-rw-r--r-- | setup.cfg | 13 | ||||
-rw-r--r-- | setup.py | 21 | ||||
-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 | ||||
-rw-r--r-- | tox.ini | 32 |
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 }} @@ -28,4 +28,5 @@ lib64 log/ parts/ pyvenv.cfg +testing.log var/ @@ -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 @@ -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 @@ -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() @@ -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] |