From 7d43bb199e52d375339d1bb37ef10bfbdb99c7a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Brunner?= Date: Tue, 10 Feb 2026 10:21:54 +0100 Subject: [PATCH 1/5] Fix linting error --- deform/exception.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deform/exception.py b/deform/exception.py index 8b61915f..862230cf 100644 --- a/deform/exception.py +++ b/deform/exception.py @@ -25,7 +25,7 @@ class ValidationFailure(Exception): """ def __init__(self, field, cstruct, error): - Exception.__init__(self) + super().__init__() self.field = field self.cstruct = cstruct self.error = error From c29475b3cf301bc980931aca72f5f67e28e32c4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Brunner?= Date: Tue, 10 Feb 2026 10:29:33 +0100 Subject: [PATCH 2/5] Convert setup.py and setup.cfg into a pyproject.toml To make it work with the last setuptools version --- RELEASING.txt | 8 +-- pyproject.toml | 134 ++++++++++++++++++++++++++++++++++++++++++++++++- setup.cfg | 37 -------------- setup.py | 125 --------------------------------------------- tox.ini | 23 ++++----- 5 files changed, 145 insertions(+), 182 deletions(-) delete mode 100644 setup.cfg delete mode 100644 setup.py diff --git a/RELEASING.txt b/RELEASING.txt index 4bf3a46e..00610a74 100644 --- a/RELEASING.txt +++ b/RELEASING.txt @@ -19,7 +19,7 @@ Prepare new release branch - Create a new release branch, incrementing the version number. -- Align the release number with deformdemo (setup.py, README.rst, CHANGES.txt). +- Align the release number with deformdemo (pyproject.toml, README.rst, CHANGES.txt). - Do any necessary branch merges (e.g., main to branch, branch to main). @@ -27,10 +27,10 @@ Prepare new release branch git pull -- Make sure your Python has ``setuptools-git``, ``twine``, and ``wheel`` +- Make sure your Python has `twine``, and ``wheel`` installed: - $VENV/bin/pip install setuptools-git twine wheel + $VENV/bin/pip install twine wheel - Do a platform test, run a check with black, ensure the PyPI long description renders, and run check-manifest with the following command. @@ -52,7 +52,7 @@ Prepare new release branch branch, and previously released branch. Also in the previously released branch only, uncomment the sections to enable pylons_sphinx_latesturl. -- Change setup.py version to the release version number. +- Change pyproject.toml version to the release version number. - Build an sdist and a wheel: diff --git a/pyproject.toml b/pyproject.toml index a67f2c57..cf280ff7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,135 @@ -[build-system] -requires = ["setuptools", "wheel"] +[project] +name = "deform" +version = "3.0.0.dev0" +description = "Form library with advanced features like nested forms" +readme = "README.rst" +requires-python = ">=3.10" +license = {text = "BSD-derived"} +authors = [ + {name = "Chris McDonough, Agendaless Consulting", email = "pylons-discuss@googlegroups.com"}, +] +maintainers = [ + {name = "Josip Delić", email = "delijati@gmx.net"}, + {name = "Stéphane Brunner", email = "stephane.brunner@gmail.com"}, +] +keywords = ["web", "forms", "form", "generation", "schema", "validation", "pyramid"] +classifiers = [ + "Intended Audience :: Developers", + "License :: Repoze Public License", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: Implementation :: CPython", + "Programming Language :: Python :: Implementation :: PyPy", +] +dependencies = [ + "Chameleon>=2.5.1", + "colander>=1.0", + "iso8601", + "peppercorn>=0.3", + "translationstring>=1.0", + "zope.deprecation", +] + +[project.optional-dependencies] +lint = [ + "black", + "check-manifest", + "flake8", + "flake8-bugbear", + "flake8-builtins", + "isort", + "rstcheck", + "readme_renderer", +] +testing = [ + "beautifulsoup4", + "coverage", + "flaky", + "pyramid", + "pytest", + "pytest-cov", +] +functional = [ + "beautifulsoup4", + "coverage", + "flaky", + "pyramid", + "pytest", + "pytest-cov", + "pygments", + "waitress", + "lingua", + "selenium>=4.0.0.b4,<4.10.0", +] +docs = [ + "Sphinx>=1.7.4", + "repoze.sphinx.autointerface", + "pylons_sphinx_latesturl", + "pylons-sphinx-themes", +] +dev = [ + "black", + "check-manifest", + "flake8", + "flake8-bugbear", + "flake8-builtins", + "isort", + "rstcheck", + "readme_renderer", + "beautifulsoup4", + "coverage", + "flaky", + "pyramid", + "pytest", + "pytest-cov", + "pygments", + "waitress", + "lingua", + "selenium>=4.0.0.b4,<4.10.0", + "Sphinx>=1.7.4", + "repoze.sphinx.autointerface", + "pylons_sphinx_latesturl", + "pylons-sphinx-themes", +] + +[project.urls] +Homepage = "https://docs.pylonsproject.org/projects/deform/en/latest/" +Documentation = "https://docs.pylonsproject.org/projects/deform/en/3.0-branch/" +Changelog = "https://docs.pylonsproject.org/projects/deform/en/3.0-branch/changes.html" +"Issue Tracker" = "https://github.com/Pylons/deform/issues" + +[tool.pytest.ini_options] +python_files = ["test_*.py"] +testpaths = ["deform/tests"] +addopts = "-W always" + +[tool.check-manifest] +ignore-bad-ideas = ["*.mo"] + +[tool.babel.compile_catalog] +directory = "deform/locale" +domain = "deform" +statistics = true + +[tool.babel.extract_messages] +add_comments = "TRANSLATORS:" +output_file = "deform/locale/deform.pot" +width = 80 + +[tool.babel.init_catalog] +domain = "deform" +input_file = "deform/locale/deform.pot" +output_dir = "deform/locale" + +[tool.babel.update_catalog] +domain = "deform" +input_file = "deform/locale/deform.pot" +output_dir = "deform/locale" +previous = true [tool.black] line-length = 79 diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index 514953a6..00000000 --- a/setup.cfg +++ /dev/null @@ -1,37 +0,0 @@ -[easy_install] -zip_ok = false - -[tool:pytest] -python_files = test_*.py -testpaths = - deform/tests -addopts = -W always - -[aliases] -dev = develop easy_install deform[testing] -docs = develop easy_install deform[docs] - -[compile_catalog] -directory = deform/locale -domain = deform -statistics = true - -[extract_messages] -add_comments = TRANSLATORS: -output_file = deform/locale/deform.pot -width = 80 - -[init_catalog] -domain = deform -input_file = deform/locale/deform.pot -output_dir = deform/locale - -[update_catalog] -domain = deform -input_file = deform/locale/deform.pot -output_dir = deform/locale -previous = true - -[check-manifest] -ignore-bad-ideas = - *.mo diff --git a/setup.py b/setup.py deleted file mode 100644 index 5e604a36..00000000 --- a/setup.py +++ /dev/null @@ -1,125 +0,0 @@ -############################################################################## -# -# Copyright (c) 2011 Agendaless Consulting and Contributors. -# All Rights Reserved. -# -# This software is subject to the provisions of the BSD-like license at -# http://www.repoze.org/LICENSE.txt. A copy of the license should accompany -# this distribution. THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL -# EXPRESS OR IMPLIED WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, -# THE IMPLIED WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND -# FITNESS FOR A PARTICULAR PURPOSE -# -############################################################################## -from setuptools import find_packages -from setuptools import setup - - -def readfile(name): - with open(name) as f: - return f.read() - - -README = readfile("README.rst") -CHANGES = readfile("CHANGES.txt") -VERSION = '3.0.0.dev0' - -requires = [ - "Chameleon>=2.5.1", # Markup class - "colander>=1.0", # cstruct_children/appstruct_children, Set - "iso8601", - "peppercorn>=0.3", # rename operation type - "translationstring>=1.0", # add format mapping with % - "zope.deprecation", -] - -lint_extras = [ - "black", - "check-manifest", - "flake8", - "flake8-bugbear", - "flake8-builtins", - "isort", - "rstcheck", - "readme_renderer", -] - -testing_extras = [ - "beautifulsoup4", - "coverage", - "flaky", - "pyramid", - "pytest", - "pytest-cov", -] - -# Needed to run deformdemo tests -functional_testing_extras = [ - "pygments", - "waitress", - "lingua", -] - -docs_extras = [ - "Sphinx >= 1.7.4", - "repoze.sphinx.autointerface", - "pylons_sphinx_latesturl", - "pylons-sphinx-themes", -] - -functional_testing_extras.extend(["selenium >= 4.0.0.b4, < 4.10.0"]) - -branch_version = ".".join(VERSION.split(".")[:2]) - -# black is refusing to make anything under 80 chars so just splitting it up -docs_fmt = "https://docs.pylonsproject.org/projects/deform/en/{}-branch/" -docs_url = docs_fmt.format(branch_version) - -setup( - name="deform", - version=VERSION, - description="Form library with advanced features like nested forms", - long_description=README + "\n\n" + CHANGES, - classifiers=[ - "Intended Audience :: Developers", - "License :: Repoze Public License", - "Programming Language :: Python", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.11", - "Programming Language :: Python :: 3.12", - "Programming Language :: Python :: 3.13", - "Programming Language :: Python :: Implementation :: CPython", - "Programming Language :: Python :: Implementation :: PyPy", - ], - keywords="web forms form generation schema validation pyramid", - author="Chris McDonough, Agendaless Consulting", - author_email="pylons-discuss@googlegroups.com", - maintainer="Josip Delić, Stéphane Brunner", - maintainer_email="delijati@gmx.net, stephane.brunner@gmail.com", - url="https://docs.pylonsproject.org/projects/deform/en/latest/", - project_urls={ - 'Documentation': docs_url, - 'Changelog': '{}changes.html'.format(docs_url), - 'Issue Tracker': 'https://github.com/Pylons/deform/issues', - }, - license="BSD-derived", - packages=find_packages(), - include_package_data=True, - zip_safe=False, - tests_require=testing_extras, - install_requires=requires, - test_suite="deform.tests", - extras_require={ - "lint": lint_extras, - "testing": testing_extras, - "docs": docs_extras, - "functional": functional_testing_extras, - "dev": ( - lint_extras - + testing_extras - + docs_extras - + functional_testing_extras - ), - }, -) diff --git a/tox.ini b/tox.ini index 238ea1ea..59262299 100644 --- a/tox.ini +++ b/tox.ini @@ -23,12 +23,10 @@ commands = commands = python --version pip freeze - flake8 deform setup.py - isort --check-only --df deform setup.py - black --check --diff deform setup.py - # XXX -r reports now warnings too so we fail - python setup.py check -s -m - rstcheck README.rst CHANGES.txt + flake8 deform + isort --check-only --df deform + black --check --diff deform + rstcheck README.rst CHANGES.txt check-manifest extras = lint @@ -70,8 +68,8 @@ deps = [testenv:format] skip_install = true commands = - isort deform setup.py - black deform setup.py + isort deform + black deform deps = black isort @@ -82,11 +80,8 @@ skip_install = true commands = # clean up build/ and dist/ folders python -c 'import shutil; shutil.rmtree("dist", ignore_errors=True)' - python setup.py clean --all - # build sdist - python setup.py sdist --dist-dir {toxinidir}/dist - # build wheel from sdist - pip wheel -v --no-deps --no-index --no-build-isolation --wheel-dir {toxinidir}/dist --find-links {toxinidir}/dist deform + # build sdist and wheel + python -m build --sdist --wheel --outdir {toxinidir}/dist deps = - setuptools + build wheel From d0189ba393e9a3e948a155cceff9cc0760b18759 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Brunner?= Date: Tue, 10 Feb 2026 10:42:27 +0100 Subject: [PATCH 3/5] fix-style --- deform/exception.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deform/exception.py b/deform/exception.py index 862230cf..7e4a8fd4 100644 --- a/deform/exception.py +++ b/deform/exception.py @@ -25,7 +25,7 @@ class ValidationFailure(Exception): """ def __init__(self, field, cstruct, error): - super().__init__() + super().__init__(field, cstruct, error) self.field = field self.cstruct = cstruct self.error = error From c9dfb513fbda812be1da34a2f6c41e0859c50510 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Brunner?= Date: Tue, 10 Feb 2026 10:47:36 +0100 Subject: [PATCH 4/5] fix-pkg --- RELEASING.txt | 2 +- pyproject.toml | 11 ++++------- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/RELEASING.txt b/RELEASING.txt index 00610a74..56113665 100644 --- a/RELEASING.txt +++ b/RELEASING.txt @@ -27,7 +27,7 @@ Prepare new release branch git pull -- Make sure your Python has `twine``, and ``wheel`` +- Make sure your Python has ``twine`` and ``wheel`` installed: $VENV/bin/pip install twine wheel diff --git a/pyproject.toml b/pyproject.toml index cf280ff7..d8a69c5e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,3 +1,7 @@ +[build-system] +requires = ["setuptools>=61", "wheel"] +build-backend = "setuptools.build_meta" + [project] name = "deform" version = "3.0.0.dev0" @@ -15,7 +19,6 @@ maintainers = [ keywords = ["web", "forms", "form", "generation", "schema", "validation", "pyramid"] classifiers = [ "Intended Audience :: Developers", - "License :: Repoze Public License", "Programming Language :: Python", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.10", @@ -54,12 +57,6 @@ testing = [ "pytest-cov", ] functional = [ - "beautifulsoup4", - "coverage", - "flaky", - "pyramid", - "pytest", - "pytest-cov", "pygments", "waitress", "lingua", From 48a11caf45eea1e3d46e0c5d37a4664e78960f42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Brunner?= Date: Tue, 10 Feb 2026 10:51:34 +0100 Subject: [PATCH 5/5] Don't use deprecated pkg_resources anymore --- deform/template.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/deform/template.py b/deform/template.py index 90ccb5ea..c249ab20 100644 --- a/deform/template.py +++ b/deform/template.py @@ -2,9 +2,9 @@ # Standard Library import os.path +import importlib.resources as resources from chameleon.zpt.loader import TemplateLoader -from pkg_resources import resource_filename from translationstring import ChameleonTranslate from .exception import TemplateError @@ -40,7 +40,15 @@ def __init__(self, *args, **kwargs): def load(self, filename, *args, **kwargs): if ":" in filename: pkg_name, fn = filename.split(":", 1) - filename = resource_filename(pkg_name, fn) + resource = resources.files(pkg_name).joinpath(fn) + try: + with resources.as_file(resource) as resolved: + filename = os.fspath(resolved) + return super(ZPTTemplateLoader, self).load( + filename, *args, **kwargs + ) + except ValueError: + raise TemplateError(filename) else: path, ext = os.path.splitext(filename) if not ext: @@ -123,5 +131,5 @@ def load(self, template_name): return self.loader.load(template_name) -default_dir = resource_filename("deform", "templates/") +default_dir = os.fspath(resources.files("deform").joinpath("templates")) default_renderer = ZPTRendererFactory((default_dir,))