[v3] setuptools3.bbclass: add check for pyproject.toml

Message ID 20220225234317.668778-1-tim.orling@konsulko.com
State New
Headers show
Series [v3] setuptools3.bbclass: add check for pyproject.toml | expand

Commit Message

Tim Orling Feb. 25, 2022, 11:43 p.m. UTC
From: Tim Orling <ticotimo@gmail.com>

With help from Peter Kjellerstedt <peter.kjellerstedt@axis.com> via IRC.

Add a check for pyproject.toml in ${S} and if so check if it has a
[build-system] build-backend. Give the user a helpful warning that
the recipe should be changed to one of the PEP-517 classes (instead of
setuptools3.bbclass).

Add SETUPTOOLS_SKIP_BUILD_BACKEND_CHECK variable to skip this check (and
avoid the warning). This is needed for e.g.
python3-setuptools-rust-native which does not build cleanly with
setuptools_build_meta.bbclass

Because some sources have a pyproject.toml but no [build-sytem] or no
properly defined (or accurate) build-backend, add a try: except: clause
to avoid KeyError.

[YOCTO #14736]

Signed-off-by: Tim Orling <tim.orling@konsulko.com>
---
 meta/classes/setuptools3.bbclass | 41 ++++++++++++++++++++++++++++++++
 1 file changed, 41 insertions(+)

Comments

Richard Purdie Feb. 26, 2022, 7:27 a.m. UTC | #1
On Fri, 2022-02-25 at 15:43 -0800, Tim Orling wrote:
> From: Tim Orling <ticotimo@gmail.com>
> 
> With help from Peter Kjellerstedt <peter.kjellerstedt@axis.com> via IRC.
> 
> Add a check for pyproject.toml in ${S} and if so check if it has a
> [build-system] build-backend. Give the user a helpful warning that
> the recipe should be changed to one of the PEP-517 classes (instead of
> setuptools3.bbclass).
> 
> Add SETUPTOOLS_SKIP_BUILD_BACKEND_CHECK variable to skip this check (and
> avoid the warning). This is needed for e.g.
> python3-setuptools-rust-native which does not build cleanly with
> setuptools_build_meta.bbclass
> 
> Because some sources have a pyproject.toml but no [build-sytem] or no
> properly defined (or accurate) build-backend, add a try: except: clause
> to avoid KeyError.
> 
> [YOCTO #14736]
> 
> Signed-off-by: Tim Orling <tim.orling@konsulko.com>
> ---
>  meta/classes/setuptools3.bbclass | 41 ++++++++++++++++++++++++++++++++
>  1 file changed, 41 insertions(+)
> 
> diff --git a/meta/classes/setuptools3.bbclass b/meta/classes/setuptools3.bbclass
> index 12561340b07..d80a91d3296 100644
> --- a/meta/classes/setuptools3.bbclass
> +++ b/meta/classes/setuptools3.bbclass
> @@ -18,6 +18,47 @@ setuptools3_do_configure() {
>      :
>  }
>  
> +SETUPTOOLS_SKIP_BUILD_BACKEND_CHECK ?= "0"
> +
> +python check_for_pyprojecttoml_build_backend() {
> +    import os
> +    import tomli

https://autobuilder.yoctoproject.org/typhoon/#/builders/65/builds/4833/steps/12/logs/stdio

Exception: ModuleNotFoundError: No module named 'tomli'

Cheers,

Richard

> +    from pathlib import Path
> +
> +    if d.getVar('SETUPTOOLS_SKIP_BUILD_BACKEND_CHECK') == "1":
> +        bb.debug(3, "Skipping check for build-backend in pyproject.toml")
> +        return 0
> +    warn_string = "The source has a pyproject.toml which declares '%s' as a build backend, please consider 'inherit %s' instead of inheriting setuptools3."
> +    warn_layer_string = "The source has a pyproject.toml which declares '%s' as a build backend, please consider 'inherit %s' from %s instead of inheriting setuptools3."
> +    pyprojecttoml_file = Path(d.getVar('S'), 'pyproject.toml')
> +    if pyprojecttoml_file.exists():
> +        bb.debug(3, "pyproject.toml found: %s" % pyprojecttoml_file)
> +        with open(pyprojecttoml_file, "rb") as f:
> +            pyprojecttoml_dict = tomli.load(f)
> +            try:
> +                build_system = pyprojecttoml_dict["build-system"]
> +                if build_system:
> +                    bb.debug(3, "[build-system] found in pyproject.toml")
> +                    backend = build_system.get('build-backend')
> +                    if backend:
> +                        bb.debug(3, "build-backend found: %s" % backend)
> +                    if backend == "flit_core.buildapi":
> +                        bb.warn(warn_string % ('flit_core.buildapi', 
> +                                               'flit_core'))
> +                    elif backend == "setuptools.build_meta":
> +                        bb.warn(warn_string % ('setuptools.build_meta',
> +                                              'setuptools_build_meta'))
> +                    elif backend == "poetry.core.masonry.api":
> +                        bb.warn(warn_layer_string % ('poetry.core.masonry.api',
> +                                                     'poetry_core', 'meta-python'))
> +                    else:
> +                        bb.warn("The source has a pyproject.toml which declares '%s' as a build backend, but this is not currently supported in oe-core." % backend)
> +            except KeyError:
> +                bb.warn("The source has a pyproject.toml, but either no [build-system] or it is malformed. If the recipe is still buildable with setuptools3, you can skip this check with:\nSETUPTOOLS_SKIP_BUILD_BACKEND_CHECK= \"1\"")
> +                pass
> +}
> +do_configure[prefuncs] += "check_for_pyprojecttoml_build_backend"
> +
>  setuptools3_do_compile() {
>          cd ${SETUPTOOLS_SETUP_PATH}
>          NO_FETCH_BUILD=1 \
> -=-=-=-=-=-=-=-=-=-=-=-
> Links: You receive all messages sent to this group.
> View/Reply Online (#162414): https://lists.openembedded.org/g/openembedded-core/message/162414
> Mute This Topic: https://lists.openembedded.org/mt/89401217/1686473
> Group Owner: openembedded-core+owner@lists.openembedded.org
> Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub [richard.purdie@linuxfoundation.org]
> -=-=-=-=-=-=-=-=-=-=-=-
>
Tim Orling Feb. 26, 2022, 6:37 p.m. UTC | #2
On Fri, Feb 25, 2022 at 11:27 PM Richard Purdie <
richard.purdie@linuxfoundation.org> wrote:

> On Fri, 2022-02-25 at 15:43 -0800, Tim Orling wrote:
> > From: Tim Orling <ticotimo@gmail.com>
> >
> > With help from Peter Kjellerstedt <peter.kjellerstedt@axis.com> via IRC.
> >
> > Add a check for pyproject.toml in ${S} and if so check if it has a
> > [build-system] build-backend. Give the user a helpful warning that
> > the recipe should be changed to one of the PEP-517 classes (instead of
> > setuptools3.bbclass).
> >
> > Add SETUPTOOLS_SKIP_BUILD_BACKEND_CHECK variable to skip this check (and
> > avoid the warning). This is needed for e.g.
> > python3-setuptools-rust-native which does not build cleanly with
> > setuptools_build_meta.bbclass
> >
> > Because some sources have a pyproject.toml but no [build-sytem] or no
> > properly defined (or accurate) build-backend, add a try: except: clause
> > to avoid KeyError.
> >
> > [YOCTO #14736]
> >
> > Signed-off-by: Tim Orling <tim.orling@konsulko.com>
> > ---
> >  meta/classes/setuptools3.bbclass | 41 ++++++++++++++++++++++++++++++++
> >  1 file changed, 41 insertions(+)
> >
> > diff --git a/meta/classes/setuptools3.bbclass
> b/meta/classes/setuptools3.bbclass
> > index 12561340b07..d80a91d3296 100644
> > --- a/meta/classes/setuptools3.bbclass
> > +++ b/meta/classes/setuptools3.bbclass
> > @@ -18,6 +18,47 @@ setuptools3_do_configure() {
> >      :
> >  }
> >
> > +SETUPTOOLS_SKIP_BUILD_BACKEND_CHECK ?= "0"
> > +
> > +python check_for_pyprojecttoml_build_backend() {
> > +    import os
> > +    import tomli
>
>
> https://autobuilder.yoctoproject.org/typhoon/#/builders/65/builds/4833/steps/12/logs/stdio
>
> Exception: ModuleNotFoundError: No module named 'tomli'
>

Ah. Right. This is the chicken and egg problem of needing a TOML parser.
I really wish upstream had added one to the standard libs.


>
> Cheers,
>
> Richard
>
> > +    from pathlib import Path
> > +
> > +    if d.getVar('SETUPTOOLS_SKIP_BUILD_BACKEND_CHECK') == "1":
> > +        bb.debug(3, "Skipping check for build-backend in
> pyproject.toml")
> > +        return 0
> > +    warn_string = "The source has a pyproject.toml which declares '%s'
> as a build backend, please consider 'inherit %s' instead of inheriting
> setuptools3."
> > +    warn_layer_string = "The source has a pyproject.toml which declares
> '%s' as a build backend, please consider 'inherit %s' from %s instead of
> inheriting setuptools3."
> > +    pyprojecttoml_file = Path(d.getVar('S'), 'pyproject.toml')
> > +    if pyprojecttoml_file.exists():
> > +        bb.debug(3, "pyproject.toml found: %s" % pyprojecttoml_file)
> > +        with open(pyprojecttoml_file, "rb") as f:
> > +            pyprojecttoml_dict = tomli.load(f)
> > +            try:
> > +                build_system = pyprojecttoml_dict["build-system"]
> > +                if build_system:
> > +                    bb.debug(3, "[build-system] found in
> pyproject.toml")
> > +                    backend = build_system.get('build-backend')
> > +                    if backend:
> > +                        bb.debug(3, "build-backend found: %s" % backend)
> > +                    if backend == "flit_core.buildapi":
> > +                        bb.warn(warn_string % ('flit_core.buildapi',
> > +                                               'flit_core'))
> > +                    elif backend == "setuptools.build_meta":
> > +                        bb.warn(warn_string % ('setuptools.build_meta',
> > +                                              'setuptools_build_meta'))
> > +                    elif backend == "poetry.core.masonry.api":
> > +                        bb.warn(warn_layer_string %
> ('poetry.core.masonry.api',
> > +                                                     'poetry_core',
> 'meta-python'))
> > +                    else:
> > +                        bb.warn("The source has a pyproject.toml which
> declares '%s' as a build backend, but this is not currently supported in
> oe-core." % backend)
> > +            except KeyError:
> > +                bb.warn("The source has a pyproject.toml, but either no
> [build-system] or it is malformed. If the recipe is still buildable with
> setuptools3, you can skip this check
> with:\nSETUPTOOLS_SKIP_BUILD_BACKEND_CHECK= \"1\"")
> > +                pass
> > +}
> > +do_configure[prefuncs] += "check_for_pyprojecttoml_build_backend"
> > +
> >  setuptools3_do_compile() {
> >          cd ${SETUPTOOLS_SETUP_PATH}
> >          NO_FETCH_BUILD=1 \
> > -=-=-=-=-=-=-=-=-=-=-=-
> > Links: You receive all messages sent to this group.
> > View/Reply Online (#162414):
> https://lists.openembedded.org/g/openembedded-core/message/162414
> > Mute This Topic: https://lists.openembedded.org/mt/89401217/1686473
> > Group Owner: openembedded-core+owner@lists.openembedded.org
> > Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub [
> richard.purdie@linuxfoundation.org]
> > -=-=-=-=-=-=-=-=-=-=-=-
> >
>
>
>

Patch

diff --git a/meta/classes/setuptools3.bbclass b/meta/classes/setuptools3.bbclass
index 12561340b07..d80a91d3296 100644
--- a/meta/classes/setuptools3.bbclass
+++ b/meta/classes/setuptools3.bbclass
@@ -18,6 +18,47 @@  setuptools3_do_configure() {
     :
 }
 
+SETUPTOOLS_SKIP_BUILD_BACKEND_CHECK ?= "0"
+
+python check_for_pyprojecttoml_build_backend() {
+    import os
+    import tomli
+    from pathlib import Path
+
+    if d.getVar('SETUPTOOLS_SKIP_BUILD_BACKEND_CHECK') == "1":
+        bb.debug(3, "Skipping check for build-backend in pyproject.toml")
+        return 0
+    warn_string = "The source has a pyproject.toml which declares '%s' as a build backend, please consider 'inherit %s' instead of inheriting setuptools3."
+    warn_layer_string = "The source has a pyproject.toml which declares '%s' as a build backend, please consider 'inherit %s' from %s instead of inheriting setuptools3."
+    pyprojecttoml_file = Path(d.getVar('S'), 'pyproject.toml')
+    if pyprojecttoml_file.exists():
+        bb.debug(3, "pyproject.toml found: %s" % pyprojecttoml_file)
+        with open(pyprojecttoml_file, "rb") as f:
+            pyprojecttoml_dict = tomli.load(f)
+            try:
+                build_system = pyprojecttoml_dict["build-system"]
+                if build_system:
+                    bb.debug(3, "[build-system] found in pyproject.toml")
+                    backend = build_system.get('build-backend')
+                    if backend:
+                        bb.debug(3, "build-backend found: %s" % backend)
+                    if backend == "flit_core.buildapi":
+                        bb.warn(warn_string % ('flit_core.buildapi', 
+                                               'flit_core'))
+                    elif backend == "setuptools.build_meta":
+                        bb.warn(warn_string % ('setuptools.build_meta',
+                                              'setuptools_build_meta'))
+                    elif backend == "poetry.core.masonry.api":
+                        bb.warn(warn_layer_string % ('poetry.core.masonry.api',
+                                                     'poetry_core', 'meta-python'))
+                    else:
+                        bb.warn("The source has a pyproject.toml which declares '%s' as a build backend, but this is not currently supported in oe-core." % backend)
+            except KeyError:
+                bb.warn("The source has a pyproject.toml, but either no [build-system] or it is malformed. If the recipe is still buildable with setuptools3, you can skip this check with:\nSETUPTOOLS_SKIP_BUILD_BACKEND_CHECK= \"1\"")
+                pass
+}
+do_configure[prefuncs] += "check_for_pyprojecttoml_build_backend"
+
 setuptools3_do_compile() {
         cd ${SETUPTOOLS_SETUP_PATH}
         NO_FETCH_BUILD=1 \