plone / Products.CMFPlone

The core of the Plone content management system
https://plone.org
GNU General Public License v2.0
249 stars 188 forks source link

Switch to PEP 420 (Implicit namespace packages) #3928

Open mauritsvanrees opened 6 months ago

mauritsvanrees commented 6 months ago

Responsible Persons

Proposer: Maurits van Rees

Seconder:

Abstract

Move from setuptools/pkg_resources namespaces to native namespaces. This is a breaking change, so is for Plone 7.

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

Proposal & Implementation

Deliverables

Risks

Participants

Links:

gforcada commented 6 months ago

With some scripts and the GitHub CLI tool it might be easy to distribute the effort... we can create preparatory branches to switch, so the window of brokenness will not be that big...

One last item that might be a good idea to also add in this massive breakage would be to also rename master to main as default branches 🀞🏾

I will have some days off next week (and without kids!) so I will try to work on it.

I already ported our internal packages at work to native namespaces, and before it bitrots I can re-apply the steps there πŸ‘πŸΎ

mauritsvanrees commented 6 months ago

@gforcada Trying things out, preparing, making tooling, that would be great. But for clarity: please do not yet make the actual move to native namespaces on any package. That is really for Plone 7, so next year.

I guess for a small namespace like borg it would be fine in a Plone 6 minor version already: only borg.localrole exists in this namespace as far as I know. I wanted to add plonetheme there, but I see lots of plonetheme packages on PyPI, so that would be for Plone 7 as well.

I already had a problem after moving zest.releaser to native namespaces, because there is also a zest.pocompile package that I usually install in the same venv or buildout, and this no longer worked until I moved that one over as well.

Indeed we could create a native branch on each package, do the changes there, and on coredev have a PLIP config and on Jenkins a PLIP job to checkouts those branches, before doing anything on a coredev 7.0 branch.

Going from master to main on all Plone repos could be good, but I would make that a separate PLIP. It is something that can be tackled one repo at a time. But: if this makes tooling for the current PLIP easier, then sure, let's combine the work.

gforcada commented 6 months ago

Sure, I was not planning on merging anything πŸ˜„ but as you say, tooling needed some love as both zope.testrunner and z3c.dependencychecker were not capable of working with native namespaced distributions.

Fortunately that is fixed now, but there might be other tooling (zc.buildout ?) that might need some help as well, or a transition plan.

The idea of creating a main branch with only those changes (src layout and native namespaces) sounds good, specially if we tie it with periodic (monthly?) rebases and some CI (Jenkins) jobs that ensure things keep working.

Otherwise, if we wait until we want to open the door for Plone 7 changes, and things are not ready, nor tried already (on CI), we might face a stressful point where we stall development while waiting for tooling to get fixed.

See this funny issue in tox: https://github.com/tox-dev/tox/issues/3247 I'm a bit surprised that I was the first one to notice and report it actually, given how widespread is tox and collective.* packages πŸ˜…

Anyway: there is a draft PR for borg.localrole and I have a 7.0 branch on buildout.coredev still to be pushed, that just updates borg.localrole branch from master to main πŸ’₯ I will push it in the next few days.

Then we will need a Jenkins job to ensure it does work πŸ€–

davisagli commented 6 months ago

@mauritsvanrees @gforcada In order to avoid the need for new major releases of all packages at the same time, could we do something like this to switch between namespace package implementations based on the Python major version?

(in __init__.py)

import sys
if sys.version_info < (13,):
    __import__("pkg_resources").declare_namespace(__name__)

Ah, no, of course we cannot, because native namespace packages require NOT having __init__.py at all.

yurj commented 6 months ago

https://peps.python.org/pep-0420/#migrating-from-legacy-namespace-packages

mauritsvanrees commented 6 months ago

https://peps.python.org/pep-0420/#migrating-from-legacy-namespace-packages

That is for pkgutil namespaces, which is yet another namespace implementation. This is not used in core Zope and Plone.

gforcada commented 5 months ago

Not sure how much is worth it, but an idea came across:

If we keep this releases parallel to the production ones, we don't have to wait until Plone 7 is open, for then to notice that, oops X and Y tooling/packages/dependencies are broken.

I still need to add the jenkins job to run tests with the borg.localrole PR I made some weeks ago... I'm a bit overwhelmed right now πŸ˜΅β€πŸ’« πŸ˜“ maybe this weekend I find some time πŸ€

mauritsvanrees commented 5 months ago

Not sure how much is worth it, but an idea came across:

  • create branches for all distributions of a given namespace with only the PEP 420 changes
  • make alpha releases of them all

The problem with doing this now, is that this gets in the way of other changes that require a major version bump and that we want to include in Plone 6.x.

Take for example plone.app.event:

If we imagine it really happens this way, it can still be fixed, but it will be confusing:

So: I think best not do this.

Crazy idea of my own:

mauritsvanrees commented 5 months ago

Sample PR of moving to a src-layout and the changes needed then: https://github.com/plone/plone.app.event/pull/384 I close that one because it is old and outdated, but as example it works.