Plone 6.1.1 released

Release notes for Plone 6.1.1

If you want to jump straight in, here are some important links:

Highlights

These are the main changes since 6.1.0:

  • Lots of packages: Replace pkg_resources with importlib.metadata/importlib.resources. See the "Distribution not found" section below for why this is important.
  • Zope:
    • Add configuration switch to turn off the built-in XML-RPC support.
      Hardly anyone needs XML-RPC, and it can lead to strange errors when you get malicious and/or spam requests.
    • Add configuration switch for the maximum allowed number of form fields.
      multipart version 1.2.1 introduced a default value of 128, Zope now
      sets it to 1024.
  • plone.recipe.zope2instance: Support for new Zope option enable-xmlrpc.
    Usage: zope-conf-additional = enable-xmlrpc off.
    Setting this is recommended for most sites.
  • plone.autoinclude:
    • If a distribution is not found, try to normalize the name like recent setuptools is doing and try again.
    • Fix importing module when the module name differs from the project name.
      This can easily happen with setuptools 75.8.1, though 75.8.2 fixes most of it.
  • Products.CMFPlone:
    • RegistrationTool: add method principal_id_or_login_name_exists.
      This is factored out from the isMemberIdAllowed method, which now calls this after checking the allowed member id pattern.
    • Fix moving portal actions between categories.
    • Use contentbrowser options for TinyMCE image/link browser. This also fixes the basePath calculation for uploading.
  • collective.recipe.omelette (only relevant if you use Buildout):
    • No longer generate __init__.py files with namespace stanza in parts/omelette.
      I think this was originally done to be able to go to parts/omelette, start a standard Python, and be able to import everything.
      With current Python versions the __init__.py files are not needed for a directory to be importable.
    • Remove products recipe option and special handling of Products namespace.
      Zope 4 and higher no longer have the concept of a products directory.
      You can still use packages = path/to/products_dir Products if you need something similar.
    • Fix handling checkouts of native namespace packages.
  • plone.api:
    • Added the content API helper function api.content.get_path, which gets either the relative or absolute path of an object.
    • Added two new portal API functions:
      • api.portal.get_vocabulary: Get a vocabulary by name.
      • api.portal.get_vocabulary_names: Get a list of all available vocabulary names.
    • Add the api.content.iter_ancestors function for iterating over an object acquisition chain.
    • Implement plone.api.addon module.
  • plone.app.users: Email validation: use new registration tool method principal_id_or_login_name_exists if available.
    This helps in some corner cases when email-as-login is used. The method is in the new Products.CMFPlone release.
  • plone.schema: Fix email validation:
    • allow apostrophes
    • allow accented characters
    • allow ampersand in the user part
    • do not allow spaces.
    • accept TLDs with more than 4 characters
  • plone.staticresources: Update to latest mockup. This improves the new content browser widget (used for uploading images or selecting content).
  • plone.app.caching:
    • Trigger purge on workflow change.
    • Fix purging for deleted content.
  • plone.exportimport:
    • Report object creation during import using the plone-importer cli. Use --quiet to disable it.
    • Do not stop the import if an object parent is missing.
  • plone.restapi:
    • Apply block serialization and deserialization transforms also to JSON fields.
      This includes converting internal URLs to resolveuid URLs.
    • Add a new endpoint, @inherit, for getting values from behaviors inherited from ancestors in the object hierarchy.
    • Add a @userschema/registration endpoint to get the fields for the registration form.
    • Added multilingual feature to @site endpoint.

Volto frontend

The default frontend for new Plone 6 sites is Volto.
Note that this is a JavaScript frontend that you need to run in a separate process with NodeJS.

Plone 6.1 is meant to be used with Volto 18.
Latest release is 18.10.1. See the changelog.

Classic UI

The HTML based and server side rendered UI that was present in Plone 5.2 and earlier major Plone releases is still available and has also been updated and improved upon in Plone 6.0 and 6.1. Our documentation now refers to this frontend as 'Classic UI'.

Python compatibility

This release supports Python 3.10, 3.11, 3.12, and 3.13.

pip, buildout, setuptools

In Plone core we use these versions to install Plone:

packaging==24.2
pip==25.0.1
setuptools==75.8.2
wheel==0.45.1
zc.buildout==4.1.4

In general you are free to use whatever versions work for you, but these worked for us.

Distribution not found

On February 25, setuptools 75.8.1 was released. This had an innocent sounding change: "Fix wheel file naming to follow binary distribution specification." The consequences were large. Any namespace packages that are released using this or a later version, have a slightly different "binary wheel" name, for example plone_autoinclude-2.0.2.whl with an underscore instead of plone.autoinclude-2.0.2.whl with a dot. Result is that you can easily get a "distribution not found" error when starting Plone, or even during install.

This new Plone 6.1.1 should fix all problems. If you run into problems with this Plone version or an older one, the following observations may help.

  • setuptools 75.8.2 fixes some of the problems: it tries to find a distribution by multiple names, for example plone.autoinclude, plone-autoinclude, plone_autoinclude. So use this version or a higher one.
  • Buildout had more problems than pip, but that should be fixed with zc.buildout 4.1.4.
  • In pip-based projects I had more problems on Python 3.9 than on newer versions. (Plone 6.1 cannot use 3.9, so no problem there.) I had slightly more problems on 3.13 than on 3.11 and 3.12. So if all else fails, switching the Python version may help.
  • plone.autoinclude was the package that needed the most changes, because this uses entry points and here we quickly ran into problems in finding a distribution. Latest 2.0.3 has all the fixes that we found necessary. It needs Python 3.9 minimum.
  • A lot of Plone packages where using the pkg_resources part of setuptools to check for the existence of a distribution, or do other tasks related to Python packages. This is deprecated, and can mostly be replaced by switching to importlib.metadata, which is a library available in standard Python since version 3.8. We made the switch for most packages. See CMFPlone issue 4126 for a big list of packages with changes. This also contains examples of changes that needed to be made.
  • You may be using add-ons or have own code that uses pkg_resources. You should probably replace that, getting inspiration from the previous link. You can leave declare_namespace lines untouched; that is something for another time.
  • If you have a namespace package that you want to support in projects that cannot switch to the latest setuptools or zc.buildout (which both require Python 3.9 minimum), you can restrict which setuptools version is used while building the binary wheel. You need as maximum 75.8.0. We did this for plone.restapi and plone.autoinclude. To do this, the package needs a pyproject.toml file with contents like this:
[build-system]
requires = ["setuptools>=68.2,<=75.8.0"]

or this:

[build-system]
requires = ["setuptools==75.8.0"]

This needs zest.releaser 9.5.0, if you are using this for releasing your packages to PyPI. See its changelog for this and other recent changes, also relates to the new setuptools versions.

Note that on March 19, setuptools 77 was released with initial support for so called "license expressions" (PEP 639). This gave errors when I tried making releases to PyPI: "twine.exceptions.InvalidDistribution: Metadata is missing required fields: Name, Version." . So this may need some changes in setup.py/cfg or pyproject.toml. So if you try to upload to PyPI and get a similar error, you may indeed want to restrict the setuptools version to something less than 77.

Installation

For installation instructions, see the documentation.

Issues

If you find any issues, please report them in the main issue tracker.

5 Likes

I was looking over the upgrade page, specifically about distributions Upgrade Plone 6.0 to 6.1 — Plone Documentation v6

That is quite a confusing section.

  • Do you want to use the Products.CMFPlone package (no distributions), either plone.volto or plone.classicui (one distribution), or Plone (two distributions)?

I guess I can understand not wanting to do anything with distributions or needing Volto or Classic, but what does "Plone (two distributions)" mean?

That's just one example of my confusion...

@tkimnguyen If you install the Plone Python package, it also installs both plone.volto and plone.classicui as dependencies, and you can choose between these 2 distributions when you create a new Plone site in the Zope instance. (See Add a Plone site — Plone Documentation v6)

1 Like

This might help to understand the backgrounds Architecture: packages and dependencies — Plone Documentation v6

1 Like

I updated a customized site (member site Tiroler Fischereiverband) without problems, except that my tests are broken on Python 3.13. I need to investigate here.

So I am using Python 3.12 for now and everything works fine and is in production now.

We will release too smaller sites on 6.1.1 in a few days (freshly migrated from Plone 5)...no issues at all.

I had a problem in a buildout project that includes a package which uses hatchling instead of setuptools. Problem description is here: Installing a dependency that uses hatchling messes up dependency packages · Issue #695 · buildout/buildout · GitHub. Basically: some eggs may get the wrong name (products_cmfplone).

Workaround: for any eggs that end up with the wrong name, add them explicitly in the eggs section. (and remove the broken eggs first)

For clarity: this is only a problem when using buildout. I did not try a pip-based install here, but I expect that will work fine.

2 Likes

I guess it would be better to not mention anything else than plone.volto and plone.classicui in the first place. The packages Products.CMFPlone and Plone have more historical important's and/or are for dev's who want to go deeper into Plone dependencies. Products.CMFPlone is the very core and the package Plone is a meta package which use to be the one to go with. But this pulls in quite some packages, which not everyone might need or want. This is what distributions are for now, so the need of that package is more or less gone.

I have some sites on 6.0.14 that have been around since Plone 3 or 4. I'm getting warnings on @@plone-upgrade that there is a history of package versions for packages that no longer exist in the venv. This is true, but I can verify that they are not listed as installed. Is this warning relevant? I have not been able to convert one of these sites without errors, but it's early in my testing and I can't tell if this is a factor or its a problem with my hatchling/setuptools.

I'm not using buildout but namespace packages got really tricky when I started changing some packages in my own ims.* namespace from setuptools to hatchling. I don't fully understand it, but it seems to be even more of a problem when also moving to uv. This doesn't appear to be a problem with uv/hatchling per se - python insists that the normalized name of ims.foobar be ims_foobar and they are merely complying, so I'd rather not try to put this off. My current plan is to not switch to uv until ALL packages in that namespace are converted to using hatchling. I'd love to hear what Plone core/collective developers are doing as I'm sure the problems would be the same there.

Here's a snippet of my pyproject.toml (FYI I don't have a "src" directory, root level is "ims")


[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

...

[tool.hatch.version]
path = "ims/foobar/__init__.py"

[tool.hatch.build]
strict-naming = false
packages = ["ims"]

Any other settings that might be useful?

Theoretically this could indeed be a hatchling/setuptools problem: if @@plone-upgrade sees that plone.app.discussion was marked as installed, and it can't find it in the Python packages because only plone_app_discussion is there

But most likely the package really is not there, in any spelling. Whether that is a problem, is hard to say. You may have previously had a package pulled in automatically as a dependency of a different package, and now this is no longer the case. It is up to you to decide if you want to stop the upgrade and first add the missing package or not.

For reference, the code that determines the reported list is created by the missing_packages method.

When you switch to uv and hatchling, you avoid some possible problems in buildout, but you may get other problems instead.

The plan for core Plone, is that Plone 6.2 will have native (implicit) namespaces, instead of the current pkg_resources style from setuptools. But I am 98 percent sure that the core packages will still have a setup.py. In Plone 7 this may change.

uv is optionally used in core Plone development, and that will most likely increase, but our use of it needs to be improved still. The automated test suite that we run on jenkins.plone.org is still using Buildout, and it would take major effort to move that to uv or pip.

But Buildout is having problems the past months with all the breaking changes in setuptools (usually in bug fix releases...). I have been fixing things left and right, but setuptools 80 is a no go at this point, for multiple reasons. I can probably fix that as well, but I don't know when, and it takes time away from working on making uv/pip a real alternative for Buildout for core Plone development.

Thank you @mauritsvanrees there is some great info there.

Yes I am 100% positive the package is really not there. I do not expect it to be, and believed it to be uninstalled from portal_setup. I also made the assumption that having a history of the last version was distinct from knowing whether the profile is currently installed, but this is probably not true. Profiles that had an installation but no metadata.xml with versions seem to be tricky, at the least.

I believe it, but if there are any particular incidents you could point me to I would appreciate it.

Interesting post, particularly " The goal of the Makefile is to offer a pip-based alternative for what Buildout has offered so far.". This is completely understandable but seems to offer the same promise as cookiecutter does. This is a bit of an aside, but are these not in contention? When I dropped buildout I had the same thought - it was both a python package manager and a configuration manager. venv/uv is great for the python package management, and I've got a lot of use out of cookiecutter for creating config files/etc for the latter. As someone who develops in both Windows and Linux/MacOS I appreciate cookiecutter being OS agnostic. Makefile isn't usable outside of WSL and using WSL has posed a problem for my org. Government driven policies that require granting the least amount of privilege to any developer on a project make it very attractive to disable this. It is perhaps more of a political issue than a tech issue perhaps, but requiring WSL to run Plone is arguably bad UX.

Wouldn't it simplify the change log and documentation if there was simply two releases? Plone Volto 6.1.1 and Plone Classic 6.1.1? Trying to understand which parts apply to your circumstances even when deep in plone is hard let alone someone coming in new. Even if they were exactly the same code with different defaults on setup I think it would be less confusing.

FTR: hatch new --init takes a setup.py&cfg and converts it to a pyproject.yaml. The only problem there I found is that the version handling was broken. I used it already to convert a bunch of collective.* packages and a whole bunch of packages in a customer codebase.