Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
1408592
chore: verbatim copy from zope.meta
gforcada Mar 16, 2026
f0a5522
chore: run tox -e lint
gforcada Mar 16, 2026
c30a63a
chore(setup-to-pyproject): simplify
gforcada Mar 18, 2026
3f84373
chore(setup-to-pyproject): simplify argparser
gforcada Mar 18, 2026
fc5aac9
chore(setup-to-pyproject): move functions around
gforcada Mar 18, 2026
3e6c977
chore(setup-to-pyproject): simplify the global operations
gforcada Mar 18, 2026
317dcd2
feat(setup-to-pyproject): classifiers and license
gforcada Mar 18, 2026
3771f4b
feat(setup-to-pyproject): add guard marks and url table
gforcada Mar 18, 2026
a01e20d
fix(setup-to-pyproject): handle issues and changelog URLs
gforcada Mar 18, 2026
9a0213a
fix(setp-to-pyproject): handle broken extras
gforcada Mar 20, 2026
f5c16e9
feat(setup-to-pyproject): adjust maintainers
gforcada Mar 20, 2026
a237335
fix(setup-to-pyproject): handle md files as well
gforcada Mar 20, 2026
b85a474
chore: update coverage
gforcada Mar 16, 2026
f245656
feat(docs): explain how to run setup-to-pyproject
gforcada Mar 17, 2026
e358940
Add news entry
gforcada Mar 18, 2026
ba853b4
Update src/plone/meta/setup_to_pyproject.py
gforcada Mar 27, 2026
df9f12b
Update src/plone/meta/setup_to_pyproject.py
gforcada Mar 27, 2026
504b64d
Update src/plone/meta/setup_to_pyproject.py
gforcada Mar 27, 2026
434b818
check-python-versions: do not check setup.py when it is not used.
mauritsvanrees Apr 10, 2026
063aa3e
Rewriting pyproject.toml: keep only one empty line at the end.
mauritsvanrees Apr 10, 2026
edb5206
setup_to_pyproject: let tool.setuptools end up before the end marker.
mauritsvanrees Apr 10, 2026
7043f21
parse_setup_function: handle ast.Call.
mauritsvanrees Apr 10, 2026
34d4a2a
Removed temporary raising of ValueError for testing.
mauritsvanrees Apr 10, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions docs/sources/how-to/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,13 @@ Set up CI jobs, Python version matrices, OS dependencies, and environment variab
Set up CI pipelines for GitLab-hosted repositories, including custom Docker images and OS dependencies.
:::

:::{grid-item-card} Convert `setup.py` metadata to `pyproject.toml`
:link: setup-to-pyproject
:link-type: doc

Convert the metadata in `setup.py` to `pyproject.toml`
:::

:::{grid-item-card} Re-enable GitHub Actions
:link: re-enable-actions
:link-type: doc
Expand Down
71 changes: 71 additions & 0 deletions docs/sources/how-to/setup-to-pyproject.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# Convert setup.py metadata to pyproject.toml

`pyproject.toml`'s `[project]` metadata is the standard place to find a project metadata.

Historically this was on `setup.py`, but it had plenty of problems.

Now, you can write all of a project's metadata in `pyproject.toml`,
[see the specification](https://packaging.python.org/en/latest/specifications/pyproject-toml/).

All plone and collective python distributions are using `setup.py` to keep each project's metadata.

[`zope.meta`](https://pypi.org/project/zope.meta) created a script to move the metadata from `setup.py` to `pyproject.toml`.

In `plone.meta` this script from `zope.meta` has been adapted to suit the needs of the Plone ecosystem.

## Conversion

To convert the metadata do the following:

```bash
cd $REPOSITORY
uvx --from plone.meta setup-to-pyproject .
```

i.e. go to your repository and run the `setup-to-pyproject` script from `plone.meta`.

This will automatically create a commit on your repository with the changes.

:::{note}
Please review them carefully to ensure that the conversion was done properly.
:::

Ideally `setup.py` should look like this:

```python
from setuptools import setup

# See pyproject.toml for package metadata
setup()
```

### Issues link

`setup-to-pyproject` accepts an optional argument: `--issues`.

This option is to customize the issues link displayed on PyPI related to the project.

It accepts the following options:

- `own`: use the repository itself as the issue tracker
- _URL_: provide a custom URL that will be used verbatim
- _None_: if no value is provided `Products.CMFPlone` issue tracker is used

## Clean up

Run some tooling `tox run -e test` to ensure that the conversion worked.

:::{note}
It might be that the license field in `project.license` within `pyproject.toml` is broken.

Please have a look at valid [license expressions](https://packaging.python.org/en/latest/specifications/license-expression/) to solve it.
:::

Re-configure the repository with `plone.meta` to ensure that the project metadata is kept:

```bash
cd $REPOSITORY
uvx --from plone.meta config-package branch=current .
```

Make sure to review the commit generated by `config-package`.
1 change: 1 addition & 0 deletions news/315.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add `setup-to-pyproject` script to move `setup.py` metadata into `pyproject.toml` @gforcada
2 changes: 2 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ config-package = "plone.meta.config_package:main"
multi-call = "plone.meta.multi_call:main"
re-enable-actions = "plone.meta.re_enable_actions:main"
switch-to-pep420 = "plone.meta.pep_420:main"
setup-to-pyproject = "plone.meta.setup_to_pyproject:main"

[tool.towncrier]
directory = "news/"
Expand Down Expand Up @@ -119,4 +120,5 @@ omit = [
"src/plone/meta/re_enable_actions.py",
"src/plone/meta/pep_420.py",
"src/plone/meta/multi_call.py",
"src/plone/meta/setup_to_pyproject.py",
]
42 changes: 42 additions & 0 deletions src/plone/meta/config_package.py
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,45 @@ def _setuptools_upper_bound(self):
return "82"
return "83"

def _detect_setup_py_for_package_config(self):
"""Dynamically find out if setup.py is used for package configuration.

If `pyproject.toml` contains some specific content, we assume that this
file is used for package configuration, and `setup.py` is basically empty.
Main reason: in that case `check-python-versions` fails if we ask it to
check `setup.py`.
"""
if not (self.path / "setup.py").exists():
# If the file does not even exist, it is definitely not used. ;-)
return False
pyproject = self.path / "pyproject.toml"
if not pyproject.exists():
# Should not happen. But if this file does not exist, then
# `setup.py` will be used.
return True
text = pyproject.read_text()
# If any of these markers do NOT exist in the `pyproject.toml` file,
# we conclude that `setup.py` is still used.
markers = [
"START-MARKER-MANUAL-CONFIG",
"[project]",
"Programming Language :: Python",
"requires-python",
]
return any([marker not in text for marker in markers])

def _check_python_versions_files(self, using_setup_py):
"""Which files should be checked by check-python-versions?

This is for inclusion in the pre-commit config:

id: check-python-versions
args: ['--only', 'setup.py,pyproject.toml']
"""
if using_setup_py:
return "setup.py,tox.ini"
return "pyproject.toml,tox.ini"

def pre_commit_config(self):
options = self._get_options_for(
"pre_commit",
Expand All @@ -370,6 +409,9 @@ def pre_commit_config(self):

python_version = self._minimal_python_version()
options["minimal_python_version"] = self._no_dot_python_version(python_version)
options["check_python_versions_files"] = self._check_python_versions_files(
self._detect_setup_py_for_package_config()
)

return self.copy_with_meta(
"pre-commit-config.yaml.j2",
Expand Down
2 changes: 1 addition & 1 deletion src/plone/meta/default/pre-commit-config.yaml.j2
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ repos:
rev: "0.24.0"
hooks:
- id: check-python-versions
args: ['--only', 'setup.py,pyproject.toml']
args: ['--only', '%(check_python_versions_files)s']
- repo: https://github.com/collective/i18ndude
rev: "6.3.0"
hooks:
Expand Down
Loading