From ff8c5ad26b5dc3ede3c62c61ac46256cec5434ab Mon Sep 17 00:00:00 2001 From: Mikel Larreategi Date: Mon, 9 Feb 2026 18:39:46 +0100 Subject: [PATCH 01/11] require setuptools <82.0.0 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index ffc46f6..a65d39b 100644 --- a/setup.py +++ b/setup.py @@ -20,7 +20,7 @@ include_package_data=True, python_requires=">=3.6", install_requires=[ - "setuptools", + "setuptools<82.0.0", "Click>=7.0", "click-aliases", "mr.bob", From a5e97bf9c3087fd785609ee292bbb9f93083d87d Mon Sep 17 00:00:00 2001 From: Mikel Larreategi Date: Mon, 9 Feb 2026 18:59:03 +0100 Subject: [PATCH 02/11] changelog --- CHANGES.rst | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 52c41db..4efcc0b 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,7 +4,11 @@ History 2.6 (unreleased) ---------------- -- Nothing changed yet. +- Support only python 3.11 - 3.14 + [erral] + +- Require setuptools < 82.0.0 + [erral] 2.5 (2022-11-03) From 19e3436776a3492cfee12725276c7981d21ab5cf Mon Sep 17 00:00:00 2001 From: Mikel Larreategi Date: Mon, 9 Feb 2026 18:59:12 +0100 Subject: [PATCH 03/11] test with newer versions of python --- setup.cfg | 10 ++++------ tox.ini | 21 ++++++++++----------- 2 files changed, 14 insertions(+), 17 deletions(-) diff --git a/setup.cfg b/setup.cfg index 3daf56d..e8f91d4 100644 --- a/setup.cfg +++ b/setup.cfg @@ -21,12 +21,10 @@ classifiers = Framework :: Plone Framework :: Plone :: 6.0 Intended Audience :: Developers - Programming Language :: Python :: 3 - 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 :: 3.12 + Programming Language :: Python :: 3.13 + Programming Language :: Python :: 3.14 [bumpversion] current_version = 0.1.1 diff --git a/tox.ini b/tox.ini index c4cc48b..0d52f23 100644 --- a/tox.ini +++ b/tox.ini @@ -1,17 +1,17 @@ [tox] envlist = - {py37,py38,py39,py310}, - {lint-py37,lint-py38,lint-py39,lint-py310}, + {py311,py312,py313,py314}, + {lint-py311,lint-py312,lint-py313,lint-py314}, coverage-report, skip_missing_interpreters = True [travis] python = - 3.7: py37 - 3.8: py38 - 3.9: py39 - 3.10: py310 + 3.11: py311 + 3.12: py312 + 3.13: py313 + 3.14: py314 [testenv] @@ -20,11 +20,10 @@ extras = test basepython: - py36: python3.6 - py37: python3.7 - py38: python3.8 - py39: python3.8 - py310: python3.10 + py311: python3.11 + py312: python3.12 + py313: python3.13 + py314: python3.14 # pypy: pypy commands = From 69662cf199118f1df20cb196c288ff94f5ed3676 Mon Sep 17 00:00:00 2001 From: Mikel Larreategi Date: Mon, 9 Feb 2026 19:02:23 +0100 Subject: [PATCH 04/11] test in newer versions of python --- .github/workflows/python-package.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index 5de4ccb..ea39f95 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -15,7 +15,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: [3.7, 3.8, 3.9, '3.10'] + python-version: ["3.11", "3.12", "3.13", "3.14"] steps: - uses: actions/checkout@v2 From 6be5e857595ef3246722d96e230f67f1cfc418f2 Mon Sep 17 00:00:00 2001 From: Mikel Larreategi Date: Mon, 9 Feb 2026 19:04:51 +0100 Subject: [PATCH 05/11] remove comment from flake8 config --- setup.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.cfg b/setup.cfg index e8f91d4..cc763b0 100644 --- a/setup.cfg +++ b/setup.cfg @@ -40,7 +40,7 @@ universal = 1 [flake8] exclude = docs,tmp,tmpdist,local,lib,build,bin,dist,include,man -ignore = W503, C812, E501, T001 # E203, E266 +ignore = W503, C812, E501, T001 max-line-length = 88 max-complexity = 18 select = B,C,E,F,W,T4,B From 55c31e4e009e2e1ad965cb3aa6e6142ab1429341 Mon Sep 17 00:00:00 2001 From: Mikel Larreategi Date: Mon, 9 Feb 2026 19:14:55 +0100 Subject: [PATCH 06/11] feat: replace usage of pkg_resources with importlib.metadata --- plonecli/__init__.py | 4 ++-- plonecli/cli.py | 10 +++++----- plonecli/registry.py | 6 +++--- setup.py | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/plonecli/__init__.py b/plonecli/__init__.py index fe5c492..986726c 100644 --- a/plonecli/__init__.py +++ b/plonecli/__init__.py @@ -1,9 +1,9 @@ # -*- coding: utf-8 -*- """Top-level package for Plone CLI.""" -import pkg_resources +import importlib.metadata __author__ = """Maik Derstappen""" __email__ = "md@derico.de" -__version__ = pkg_resources.require("plonecli")[0].version +__version__ = importlib.metadata.version("plonecli") diff --git a/plonecli/cli.py b/plonecli/cli.py index 42db8ed..7c851dd 100644 --- a/plonecli/cli.py +++ b/plonecli/cli.py @@ -3,9 +3,11 @@ from __future__ import absolute_import +import importlib.metadata + from click_aliases import ClickAliasedGroup from mrbob.cli import main as mrbobmain -from pkg_resources import WorkingSet + from plonecli.configure_mrbob import is_venv_disabled from plonecli.exceptions import NoSuchValue from plonecli.exceptions import NotInPackageError @@ -58,10 +60,8 @@ def cli(context, list_templates, versions): if list_templates: click.echo(reg.list_templates()) if versions: - ws = WorkingSet() - bobtemplates_dist = ws.by_key["bobtemplates.plone"] - bobtemplates_version = bobtemplates_dist.version - plonecli_version = ws.by_key["plonecli"].version + bobtemplates_version = importlib.metadata.version("bobtemplates.plone") + plonecli_version = importlib.metadata.version("plonecli") version_str = """Available packages:\n plonecli : {0}\n bobtemplates.plone: {1}\n""".format( diff --git a/plonecli/registry.py b/plonecli/registry.py index 065a74b..7c829e3 100644 --- a/plonecli/registry.py +++ b/plonecli/registry.py @@ -2,9 +2,8 @@ from __future__ import print_function +import importlib.metadata import os -import pkg_resources - try: from six.moves.configparser import ConfigParser @@ -76,7 +75,8 @@ def __init__(self, cur_dir=None): self.bob_config = read_bob_config(self.root_folder) self.templates = {} self.template_infos = {} - for entry_point in pkg_resources.iter_entry_points("mrbob_templates"): + + for entry_point in importlib.metadata.entry_points(group="mrbob_templates"): template_info_method = entry_point.load() self.template_infos[entry_point.name] = template_info_method() diff --git a/setup.py b/setup.py index a65d39b..ffc46f6 100644 --- a/setup.py +++ b/setup.py @@ -20,7 +20,7 @@ include_package_data=True, python_requires=">=3.6", install_requires=[ - "setuptools<82.0.0", + "setuptools", "Click>=7.0", "click-aliases", "mr.bob", From a00e960e9507bd2a7e1caa835a9bef3d0781fad0 Mon Sep 17 00:00:00 2001 From: Mikel Larreategi Date: Mon, 9 Feb 2026 19:16:27 +0100 Subject: [PATCH 07/11] require setuptools<82.0.0, as bobtemplates.plone is not fixed yet --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index ffc46f6..a65d39b 100644 --- a/setup.py +++ b/setup.py @@ -20,7 +20,7 @@ include_package_data=True, python_requires=">=3.6", install_requires=[ - "setuptools", + "setuptools<82.0.0", "Click>=7.0", "click-aliases", "mr.bob", From 6cade729629d75c41af940ec94d23fb8bd22b271 Mon Sep 17 00:00:00 2001 From: Mikel Larreategi Date: Tue, 10 Feb 2026 08:36:13 +0100 Subject: [PATCH 08/11] remove python2 tests --- plonecli/configure_mrbob.py | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/plonecli/configure_mrbob.py b/plonecli/configure_mrbob.py index f9e9d9d..01c5202 100644 --- a/plonecli/configure_mrbob.py +++ b/plonecli/configure_mrbob.py @@ -52,17 +52,17 @@ def configoverride_warning_post_question(configurator, question, answer): def mrbob_config_exists(configurator, answer): target_directory = home_path - file_name = u".mrbob" + file_name = ".mrbob" file_list = os.listdir(target_directory) if file_name not in file_list: raise SkipQuestion( - u"No existing mrbob config file found, so we skip this question." + "No existing mrbob config file found, so we skip this question." ) def check_git_disabled(configurator, answer): if configurator.variables["configure_mrbob.package.git.disabled"]: - raise SkipQuestion(u"GIT is disabled, so we skip git related questions.") + raise SkipQuestion("GIT is disabled, so we skip git related questions.") def get_mrbob_config_variable(varname, dirname): @@ -73,7 +73,7 @@ def get_mrbob_config_variable(varname, dirname): file_list = os.listdir(dirname) if file_name not in file_list: return - config.readfp(codecs.open(config_path, "r", "utf-8")) + config.read_file(codecs.open(config_path, "r", "utf-8")) if not config.sections(): return if config.has_option("variables", varname): @@ -145,7 +145,7 @@ def is_venv_disabled(): def generate_mrbob_ini(configurator, directory_path, answers): - file_name = u".mrbob" + file_name = ".mrbob" file_path = directory_path + "/" + file_name template = """[mr.bob] verbose = False @@ -166,11 +166,14 @@ def generate_mrbob_ini(configurator, directory_path, answers): safe_string(answers["package.git.disabled"]), ) if not configurator.variables["configure_mrbob.package.git.disabled"]: - template = template + """package.git.init = {0} + template = ( + template + + """package.git.init = {0} package.git.autocommit = {1} """.format( - safe_string(answers["package.git.init"]), - safe_string(answers["package.git.autocommit"]), + safe_string(answers["package.git.init"]), + safe_string(answers["package.git.autocommit"]), + ) ) template = ( template @@ -225,6 +228,6 @@ def post_render(configurator, target_directory=None): target_directory = configurator.target_directory generate_mrbob_ini(configurator, target_directory, mrbob_config) echo( - u"\nMrbob's settings have been saved to {0}/.mrbob\n".format(target_directory), + "\nMrbob's settings have been saved to {0}/.mrbob\n".format(target_directory), msg_type="info", ) From 9322d85b6fe76474774c5b2ce3101124fc5a6093 Mon Sep 17 00:00:00 2001 From: Mikel Larreategi Date: Tue, 10 Feb 2026 08:37:20 +0100 Subject: [PATCH 09/11] remove python2 tests --- tests/test_plonecli.py | 29 ----------------------------- 1 file changed, 29 deletions(-) diff --git a/tests/test_plonecli.py b/tests/test_plonecli.py index f1818c8..a9a679b 100644 --- a/tests/test_plonecli.py +++ b/tests/test_plonecli.py @@ -203,32 +203,3 @@ def test_plonecli_build_py_conf(tmpdir, plonecli_bin): result = subprocess.check_output([plonecli_bin, "build"], cwd=target_path) assert "\nRUN: python3 -m venv venv" in result.decode() - - -@pytest.mark.skipif(sys.version_info < (3, 0), reason="requires python3") -def test_plonecli_build_target_py27(tmpdir, plonecli_bin): - target_path = tmpdir.strpath - os.chdir(target_path) - template = """ -setuptools==40.8.0 -zc.buildout==2.13.1 -""" - with open("requirements.txt", "w") as f: - f.write(template) - - template = """[buildout] -parts = -""" - with open("buildout.cfg", "w") as f: - f.write(template) - - template = """[main] -version = 5.2.2 -template = plone_addon -python = python2.7 -""" - with open("bobtemplate.cfg", "w") as f: - f.write(template) - - result = subprocess.check_output([plonecli_bin, "build"], cwd=target_path) - assert "\nRUN: virtualenv -p python2.7 venv" in result.decode() From cce61a289bd60f61d3204e8e494d12ef1c49bf5d Mon Sep 17 00:00:00 2001 From: Mikel Larreategi Date: Tue, 10 Feb 2026 08:37:36 +0100 Subject: [PATCH 10/11] modify testing configuration --- tox.ini | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/tox.ini b/tox.ini index 0d52f23..81692dc 100644 --- a/tox.ini +++ b/tox.ini @@ -48,12 +48,12 @@ deps = pytest-mock pytest-html -whitelist_externals = +allowlist_externals = mkdir [testenv:coverage-report] usedevelop = True -basepython = python3.9 +basepython = python3.13 deps = coverage @@ -70,7 +70,7 @@ commands = coverage xml [testenv:isort-apply] -basepython = python3.9 +basepython = python3.13 deps = isort @@ -78,7 +78,7 @@ commands = isort {toxinidir}/plonecli setup.py tests [testenv:autopep8] -basepython = python3.9 +basepython = python3.13 skip_install = true deps = autopep8 @@ -119,29 +119,29 @@ commands = whitelist_externals = mkdir -[testenv:lint-py37] -basepython = python3.7 +[testenv:lint-py311] +basepython = python3.11 skip_install = true deps = {[lint]deps} commands = {[lint]commands} whitelist_externals = {[lint]whitelist_externals} -[testenv:lint-py38] -basepython = python3.8 +[testenv:lint-py312] +basepython = python3.12 skip_install = true deps = {[lint]deps} commands = {[lint]commands} whitelist_externals = {[lint]whitelist_externals} -[testenv:lint-py39] -basepython = python3.9 +[testenv:lint-py313] +basepython = python3.13 skip_install = true deps = {[lint]deps} commands = {[lint]commands} whitelist_externals = {[lint]whitelist_externals} -[testenv:lint-py310] -basepython = python3.10 +[testenv:lint-py314] +basepython = python3.14 skip_install = true deps = {[lint]deps} commands = {[lint]commands} From 1838b2daceeef5f968ceb957a4b6000d12d50451 Mon Sep 17 00:00:00 2001 From: Mikel Larreategi Date: Tue, 10 Feb 2026 08:37:49 +0100 Subject: [PATCH 11/11] run black --- tests/test_plonecli.py | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/tests/test_plonecli.py b/tests/test_plonecli.py index a9a679b..e461e7a 100644 --- a/tests/test_plonecli.py +++ b/tests/test_plonecli.py @@ -70,9 +70,11 @@ def test_plonecli_test(): context.obj["target_dir"] = os.path.dirname(os.path.abspath("bobtemplate.cfg")) test_command_result_a = runner.invoke( - cli.run_test, args=["--all"], obj=context.obj, + cli.run_test, + args=["--all"], + obj=context.obj, ) - assert u"\nRUN: ./bin/test --all" in test_command_result_a.output + assert "\nRUN: ./bin/test --all" in test_command_result_a.output test_command_result_t_a = runner.invoke( cli.run_test, @@ -80,15 +82,17 @@ def test_plonecli_test(): obj=context.obj, ) assert ( - u"./bin/test --test src/collective/todo/tests/test_robot.py --all" + "./bin/test --test src/collective/todo/tests/test_robot.py --all" in test_command_result_t_a.output ) # NOQA: E501 test_command_result_s_a = runner.invoke( - cli.run_test, args=["-s collective.todo", "-a"], obj=context.obj, + cli.run_test, + args=["-s collective.todo", "-a"], + obj=context.obj, ) assert ( - u"./bin/test --package collective.todo --all" + "./bin/test --package collective.todo --all" in test_command_result_s_a.output ) # NOQA: E501 @@ -98,7 +102,7 @@ def test_plonecli_test(): obj=context.obj, ) assert ( - u"./bin/test --test src/collective/todo/tests/test_robot.py --package collective.todo" + "./bin/test --test src/collective/todo/tests/test_robot.py --package collective.todo" in test_command_result_t_s.output ) # NOQA: E501 @@ -112,7 +116,7 @@ def test_plonecli_test(): obj=context.obj, ) assert ( - u"./bin/test --test src/collective/todo/tests/test_robot.py --package collective.todo --all" + "./bin/test --test src/collective/todo/tests/test_robot.py --package collective.todo --all" in test_command_result.output ) # NOQA: E501 @@ -142,7 +146,7 @@ def test_plonecli_build_default_py(tmpdir, plonecli_bin): with open("bobtemplate.cfg", "w") as f: f.write(template) result = subprocess.check_output([plonecli_bin, "build"], cwd=target_path) - assert u"\nRUN: python3 -m venv venv" in result.decode() + assert "\nRUN: python3 -m venv venv" in result.decode() @pytest.mark.skipif(sys.version_info < (3, 7), reason="requires explicitly python3.7") @@ -171,9 +175,10 @@ def test_plonecli_build_py_option(tmpdir, plonecli_bin): f.write(template) result = subprocess.check_output( - [plonecli_bin, "build", "-p", "python3"], cwd=target_path, + [plonecli_bin, "build", "-p", "python3"], + cwd=target_path, ) - assert u"\nRUN: python3 -m venv venv" in result.decode() + assert "\nRUN: python3 -m venv venv" in result.decode() @pytest.mark.skipif(sys.version_info < (3, 0), reason="requires python3")