Skip to content

Move setup.py metadata to pyproject.toml#355

Open
gforcada wants to merge 14 commits into2.xfrom
315-move-setup-py-to-pyproject-toml
Open

Move setup.py metadata to pyproject.toml#355
gforcada wants to merge 14 commits into2.xfrom
315-move-setup-py-to-pyproject-toml

Conversation

@gforcada
Copy link
Member

@gforcada gforcada commented Mar 16, 2026

The easy part is done: adapt the zope.meta script to be usable within plone.meta.

We still need to fix what happens after we run again config-package on a repository 😅

Now we have a legal problem 🙃:

On setup.py we used both:

license="GPL",

but also classifiers:

"License :: OSI Approved :: GNU General Public License v2 (GPLv2)",

On pyproject.toml though, we are pressed to use license expressions which mostly boils down to either put a single string from the SPDX license list or a combination of a few of them (though not so much our case).

On license= in setup.py we have a mix of:

BSD
gpl
GPL
GPL v 2
GPL version 2
GPL version 2 or later
GPLv2
LGPL
ZPL 2.1

The last (ZPL 2.1) one seems easy: license = "ZPL-2.1".

What about the GPL or BSD ones? the few ones that mention v2 is GPL-2.0-only or GPL-2.0-or-later ?

Same for BSD, there are so many variations... 😵‍💫 😅

@gforcada gforcada force-pushed the 315-move-setup-py-to-pyproject-toml branch 5 times, most recently from f29320b to 5a4e370 Compare March 17, 2026 14:27
@gforcada gforcada marked this pull request as ready for review March 17, 2026 14:41
@gforcada
Copy link
Member Author

@mauritsvanrees who could the our legal hero for this PR? 🤔 😅 see the first message for the details.

@mauritsvanrees
Copy link
Member

Note: I did not look at the code yet.

@gforcada We could make a mapping from our most used license classifiers to the new license expressions. I see at least these:

License :: OSI Approved :: GNU General Public License v2 (GPLv2)
License :: OSI Approved :: GNU General Public License v2 or later (GPLv2+)
License :: OSI Approved :: Zope Public License
License :: OSI Approved :: BSD License
  • If there is more than one license classifier: stop with an error.
  • If there is a license classifier, but it is not in the list: probably also stop with an error. If the user wants to keep the license, they can always temporarily remove the classifier, run the script, and put their own chosen license expression in pyproject.toml.
  • If there is a license classifier and a license key, and they don't match, stop with an error. If the classifier says GPL v2 (plus maybe 'or later') then I would say it is fine if the license key has "GPL" in it, in whatever spelling.

Maybe @polyester has thoughts here?

You could also ask in the sprint standup tomorrow if anyone there has knowledge about this.

gforcada added 11 commits March 18, 2026 11:25
Move `get_pyproject_toml` inline on the module as in `plone.meta` we
don't have `.shared.packages` module.

`META_HINT` is on our `config_package` module.

Simplify the `OLDEST_PYTHON_VERSION` to a static value (3.10).
Check the license and trove classifiers from `setup.py` against a known
set of licenses and complain in certain scenarios:

- if there is more than one license trove classifier
- if there is license trove classifier out of our known set
- if the license and the license trove classifier disagree

If all works well and there is either none or only one trove classifier
and it matches with the license argument on setup.py, get a valid SPDX
license expression.

This last part is important, otherwise `pyroma`, and probably PyPI when
uploading, will complain and refuse new releases.
Surround `pyproject.toml` `project` table with some special comments
that `config-package` will use to avoid dropping that content whenever
it runs.

Add the `[project.urls]` table on `pyproject.toml` with a few project
related URLs: source, issue tracker and change log.
@mauritsvanrees
Copy link
Member

I am trying it on collective.recipe.backup. See collective/collective.recipe.backup#99

Eyeballing the changes, what stands out is this:

+[project.urls]
+Source = "https://github.com/collective/collective.recipe.backup"
+Issues = "https://github.com/plone/Products.CMFPlone/issues"
+Changelog = "https://github.com/plone/collective.recipe.backup/blob/315-move-setup-py-to-pyproject-toml/CHANGES.rst"
+# END-MARKER-MANUAL-CONFIG
  • Pointing to the CMFPlone issue tracker makes sense for a lot of our packages, but of course not for collective packages. It would be nice to be able to override this with an option. Something like --issues own to use the repo url + /issues. Maybe also --issues https://somewhere.else to pass a literal url.
  • The Changelog url should use the main/master branch (or whatever the branch was that the repo started on).

At the end of the file I see this change:

+
+[tool.setuptools.dynamic]
+readme = {file = ["README.rst", "CHANGES.rst"]}
+
  • It would be nice to avoid the extra line at the end.
  • The setup.py still calculates a long_description as well. This should be either in setup.py or in pyproject.toml, not both. I thought that in tool.setuptools.dynamic it did not quite work to specify more than one file. As far as I know, this is why in zope.meta they decided to only use the readme, and no longer include the CHANGES.rst. Instead, the changelog is linked in project.urls.

Another one:

  • There is a separate commit 'Add news entry'. It would be good to have this in the main commit.
  • The news snippet says "Update configuration files." This should be something like "Move package configuration from setup.py to pyproject.toml.

@mauritsvanrees
Copy link
Member

Rather more importantly, the extras_require is lost. The GitHub Actions give errors like this:

collective.recipe.backup 6.0.0.dev0 does not provide the extra 'test'

@mauritsvanrees
Copy link
Member

  • Pointing to the CMFPlone issue tracker makes sense for a lot of our packages, but of course not for collective packages. It would be nice to be able to override this with an option. Something like --issues own to use the repo url + /issues. Maybe also --issues https://somewhere.else to pass a literal url.

Easier: if the repo url starts with github.com/plone use the CMFPlone tracker, otherwise use the one from the repo itself.
That should do the right thing 99% of the time, and we don't need an option. The user can always edit the url manually later.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants