-
-
Notifications
You must be signed in to change notification settings - Fork 208
Closed
Milestone
Description
Responsible Persons
Proposer: Maurits van Rees
Seconder: Gil Forcada Codinachs
Abstract
Move from setuptools/pkg_resources namespaces to native namespaces.
This is a breaking change that we need for Plone 6.2, because setuptools plans to drop its pkg_resources module near the end of 2025.
Motivation
Use of pkg_resources from setuptools is deprecated. Native namespaces have been available since Python 3.3 and are now the recommended and most easy way to define namespaces.
Assumptions
- Zope wants to make the same move.
Since it is best to move all packages within one namespace at the same time, we need to coordinate with Zope for theProductsnamespace. - Support for non-native namespaces is slowly being removed from
pipandsetuptoolsand other packaging related software. Bugs may be less likely to get a fix. - We want to be less dependent on
setuptools. There are other ways to handle packaging and distribution nowadays. - Theoretically you can combine native namespaces and
pkg_resourcesnamespaces within the same namespace, but this depends on the tools that you use, and whether you make a development checkout of a package. A combination that works today, might fail tomorrow with a newersetuptoolsorpipversion. It is best to move over all packages from a single namespace at the same time. - Note that there should be no problem combining different namespace variants in different namespaces: if all
zope.*packages have moved to non-native namespaces, allplone.*packages could still use the oldpkg_resources-style namespaces.
Proposal & Implementation
- In Plone 6.2, all repositories in the GitHub
ploneorganisation that are used by thePlonepackage should move to native namespaces. Others too where possible, and where we have control. - In the upgrade guide, give add-on authors the advice to do the same. This goes especially for the
collectivenamespace. - The main changes per package:
- Make a maintenance branch for this package on Plone 6.1. We want to leave room for new features in Plone 6.1, so the branch should be something like
3.x, not3.0.x. - Remove
__init__.pyfrom the namespace packages. InProducts.CMFPlonewe would removeProducts/__init__.py. - Make sure all packages (directories) in the package are found, and are included when creating a distribution. This includes for example the
browser,profiles, andtestsdirectories. There are multiple ways to do this, but I propose we use asrc-layoutas this is supposed to make everything automatic. For example moveProductstosrc/Products. See discussion here. This is optional, but seems best. It avoids problems like this when movingzest.releaserover to using native namespaces. It will make some QA code easier, for example inplone/meta, because all code will be insrc, instead of in any of{src, plone, Products, etc}. - It is fine to still have a
setup.py: this PLIP is not about getting rid ofsetuptools. We must then declare setuptools as build backend inpyproject.toml, which we are already starting to do in Plone 6.1. - Remove any Plone 6.1 and earlier PyPI classifiers and add the Plone 6.2 classifier.
- Increase the major version of the package, because this is a breaking change.
- Make a quick alpha release on PyPI with only these changes (and any other breaking changes that may have already been added).
- Compare the number of tests before and after: there are various ways for tests to get lost (tests directory not included in the distribution), or not be discovered (the tests directory is there, but the test runner can't find it).
- Make a maintenance branch for this package on Plone 6.1. We want to leave room for new features in Plone 6.1, so the branch should be something like
- We would have an early Plone 6.2.0a1 that is not much different from the latest Plone 6.1, except for the namespace implementation.
- The order does not matter too much, but this would be one way:
- First get a Zope 6 alpha release with all those packages moved to native namespaces. This includes the
Productsnamespace. The pure Zope community can use help from the wider Plone community in this. - Do the Plone part of the
Productsnamespace. plone.*, includingplone.app.*.- Others, like
collective,plonetheme,borg,zc,z3c,repoze,five. - We could also start with small namespaces. We have two namespaces that only have one package in core Plone:
plonetheme.barcelonetaandborg.localrole.
- First get a Zope 6 alpha release with all those packages moved to native namespaces. This includes the
- If we do this during a sprint, we may need to temporarily disable Jenkins for Plone 6.2, to avoid complete overload.
Deliverables
- For each package, the main/master branch needs to be for Plone 6.2 only. Each package needs an alpha release on PyPI.
- Update on scaffolding generators to use native namespaces.
- A full Plone 6.2.0a1 release.
- Documentation:
- Document what/why/how we did this.
- Include links to several pull requests as example.
- Advise add-on authors to do the same for their packages, especially in the
collectivenamespace.
Risks
- Core Plone development will likely be broken for a while, until an entire namespace has been taken care of. Using
zc.buildout5 will help, and alsohorse-with-no-namespaceforpip. - We may temporarily lose some tests in a package if we are not careful. We may only notice this later, and then find they have been broken in the meantime.
- Some tooling may need updates.
zope.testrunnerwas already updated, andz3c.dependencycheckeras well.
Participants
- Maurits van Rees, Release Manager. I will need to do a lot of releases. :-) I can do some packages too, but it would be good if others did most of them. A group of people can do a lot in a day of sprinting or on a Plone TuneUp day.
Links:
- Similar Zope issue: Switch to PEP 420 (Implicit namespace packages) zopefoundation/meta#194
- The Python Packaging Guide:
- packaging namespace packages
- src-layout versus flat-layout
- Is
setup.pydeprecated? Short answer: no.
- Setuptools:
- The PyPA sample namespace packages repo has sample namespace packages for each of the three possible namespace variants. The readme has remarks on staggered migrations, including a table. Relevant to us in the table are the lines with
cross_pep420_pkg_resources(orcross_pkg_resources_pep420but that is basically duplicate data). The takeaway from that table, is that currently you can install a pep420 (native) and apkg_resourcespackage within the same namespace under some conditions:- both installed normally: works
- both installed in editable mode: works (this surprises me a bit)
- native installed in editable mode, pkg_resources normal: works
- native installed normally, pkg_resources in editable mode: does NOT work.
Distributions
The list of distributions that need to be migrated to native namespace are:
- borg.localrole (needs
srclayout first) Pep 420 native namespace borg.localrole#40 - collective.monkeypatcher
- collective.recipe.omelette
- plone.alterego PEP 420 native namespace plone.alterego#35
- plone.api PEP 420 native namespace plone.api#588
- plone.app.caching PEP 420 native namespace plone.app.caching#153
- plone.app.content PEP 420 native namespace plone.app.content#315
- plone.app.contentlisting PEP 420 native namespace plone.app.contentlisting#80
- plone.app.contentmenu PEP 420 native namespace plone.app.contentmenu#83
- plone.app.contentrules PEP 420 native namespace plone.app.contentrules#118
- plone.app.contenttypes PEP 420 native namespace plone.app.contenttypes#732
- plone.app.customerize PEP 420 native namespace plone.app.customerize#47
- plone.app.dexterity PEP 420 native namespace plone.app.dexterity#415
- plone.app.discussion PEP 420 native namespace plone.app.discussion#291
- plone.app.event PEP 420 native namespace plone.app.event#428
- plone.app.i18n PEP 420 native namespace plone.app.i18n#38
- plone.app.intid PEP 420 native namespace plone.app.intid#36
- plone.app.iterate PEP 420 native namespace plone.app.iterate#151
- plone.app.layout PEP 420 native namespace plone.app.layout#418
- plone.app.linkintegrity PEP 420 native namespace plone.app.linkintegrity#112
- plone.app.locales PEP 420 native namespace collective/plone.app.locales#567
- plone.app.lockingbehavior PEP 420 native namespace plone.app.lockingbehavior#14
- plone.app.multilingual PEP 420 native namespace plone.app.multilingual#516
- plone.app.portlets PEP 420 native namespace plone.app.portlets#208
- plone.app.querystring PEP 420 native namespace plone.app.querystring#170
- plone.app.redirector PEP 420 native namespace plone.app.redirector#59
- plone.app.registry PEP 420 native namespace plone.app.registry#103
- plone.app.relationfield PEP 420 native namespace plone.app.relationfield#73
- plone.app.robotframework PEP 420 native namespace plone.app.robotframework#177
- plone.app.testing PEP 420 native namespace plone.app.testing#114
- plone.app.textfield PEP 420 native namespace plone.app.textfield#79
- plone.app.theming PEP 420 native namespace plone.app.theming#268
- plone.app.upgrade PEP 420 native namespace plone.app.upgrade#353
- plone.app.users PEP 420 native namespace plone.app.users#143
- plone.app.uuid PEP 420 native namespace plone.app.uuid#48
- plone.app.versioningbehavior PEP 420 native namespace plone.app.versioningbehavior#100
- plone.app.viewletmanager PEP 420 native namespace plone.app.viewletmanager#68
- plone.app.vocabularies PEP 420 native namespace plone.app.vocabularies#112
- plone.app.widgets PEP 420 native namespace plone.app.widgets#227
- plone.app.workflow PEP 420 native namespace plone.app.workflow#66
- plone.app.z3cform PEP 420 native namespace plone.app.z3cform#246
- plone.autoform PEP 420 native namespace plone.autoform#72
- plone.autoinclude PEP 420 native namespace plone.autoinclude#39
- plone.base PEP 420 native namespace plone.base#99
- plone.batching PEP 420 native namespace plone.batching#96
- plone.behavior PEP 420 native namespace plone.behavior#53
- plone.browserlayer PEP 420 native namespace plone.browserlayer#39
- plone.cachepurging PEP 420 native namespace plone.cachepurging#60
- plone.caching PEP 420 native namespace plone.caching#35
- plone.classicui PEP 420 native namespace plone.classicui#24
- plone.contentrules PEP 420 native namespace plone.contentrules#41
- plone.dexterity PEP 420 native namespace plone.dexterity#216
- plone.distribution PEP 420 native namespace plone.distribution#130
- plone.event PEP 420 native namespace plone.event#46
- plone.exportimport PEP 420 native namespace plone.exportimport#82
- plone.folder PEP 420 native namespace plone.folder#43
- plone.formwidget.namedfile PEP 420 native namespace plone.formwidget.namedfile#86
- plone.formwidget.recurrence PEP 420 native namespace plone.formwidget.recurrence#65
- plone.i18n PEP 420 native namespace plone.i18n#82
- plone.indexer PEP 420 native namespace plone.indexer#37
- plone.intelligenttext PEP 420 native namespace plone.intelligenttext#38
- plone.keyring PEP 420 native namespace plone.keyring#44
- plone.locking Pep 420 native namespace plone.locking#51
- plone.memoize PEP 420 native namespace plone.memoize#63
- plone.meta Pep 420 native namespace meta#305
- plone.namedfile PEP 420 native namespace plone.namedfile#190
- plone.outputfilters PEP 420 native namespace plone.outputfilters#93
- plone.portlet.collection PEP 420 native namespace plone.portlet.collection#48
- plone.portlets PEP 420 native namespace plone.portlets#37
- plone.portlet.static PEP 420 native namespace plone.portlet.static#56
- plone.protect Pep 420 native namespace plone.protect#138
- plone.recipe.zeoserver
- plone.recipe.zope2instance
- plone.registry PEP 420 native namespace plone.registry#56
- plone.releaser PEP 420 native namespace plone.releaser#88
- plone.reload PEP 420 native namespace plone.reload#20
- plone.resource PEP 420 native namespace plone.resource#61
- plone.resourceeditor PEP 420 native namespace plone.resourceeditor#58
- plone.rest PEP 420 native namespace plone.rest#194
- plone.restapi Pep 420 native namespace plone.restapi#1959
- plone.rfc822 PEP 420 native namespace plone.rfc822#37
- plone.scale PEP 420 native namespace plone.scale#127
- plone.schema PEP 420 native namespace plone.schema#48
- plone.schemaeditor PEP 420 native namespace plone.schemaeditor#146
- plone.session PEP 420 native namespace plone.session#69
- plone.staticresources PEP 420 native namespace plone.staticresources#399
- plone.stringinterp PEP 420 native namespace plone.stringinterp#45
- plone.subrequest PEP 420 native namespace plone.subrequest#59
- plone.supermodel PEP 420 native namespace plone.supermodel#77
- plone.testing PEP 420 native namespace plone.testing#118
- plone.theme PEP 420 native namespace plone.theme#38
- plonetheme.barceloneta PEP 420 native namespace plonetheme.barceloneta#419
- plone.tiles PEP 420 native namespace plone.tiles#42
- plone.transformchain PEP 420 native namespace plone.transformchain#40
- plone.uuid PEP 420 native namespace plone.uuid#35
- plone.versioncheck Modernize to Python 3.10+ with async HTTP and improved tooling plone.versioncheck#58
- plone.volto PEP 420 native namespace plone.volto#203
- plone.z3cform PEP 420 native namespace plone.z3cform#31
- repoze.xmliter Switch to PEP 420 (Implicit namespace packages) repoze/repoze.xmliter#21
- Products.CMFDiffTool PEP 420 native namespace Products.CMFDiffTool#72
- Products.CMFDynamicViewFTI PEP 420 native namespace Products.CMFDynamicViewFTI#51
- Products.CMFEditions PEP 420 native namespace Products.CMFEditions#129
- Products.CMFPlacefulWorkflow PEP 420 native namespace Products.CMFPlacefulWorkflow#78
- Products.CMFPlone PEP 420 native namespace #4239
- Products.DateRecurringIndex PEP 420 native namespace collective/Products.DateRecurringIndex#11
- Products.ExtendedPathIndex PEP 420 native namespace Products.ExtendedPathIndex#23
- Products.MimetypesRegistry PEP 420 native namespace Products.MimetypesRegistry#52
- Products.PlonePAS PEP 420 native namespace Products.PlonePAS#106
- Products.PortalTransforms PEP 420 native namespace Products.PortalTransforms#83
- Products.isurlinportal PEP 420 native namespace Products.isurlinportal#43
- Products.statusmessages PEP 420 native namespace Products.statusmessages#36
Reactions are currently unavailable
Metadata
Metadata
Assignees
Type
Projects
Status
Done
Status
Closed