diff mbox series

parse/ast: avoid AttributeError when built-in fragment variable isn't defined

Message ID 20250924-fix-no-builtin-fragment-v1-1-4d7f734b6d21@bootlin.com
State New
Headers show
Series parse/ast: avoid AttributeError when built-in fragment variable isn't defined | expand

Commit Message

Antonin Godard Sept. 24, 2025, 1:48 p.m. UTC
When adding the following to a configuration file:

  addfragments ${FRAGMENTS_PREFIX} CUSTOM_FRAGMENTS FRAGMENTS_METADATA_VARS CUSTOM_FRAGMENTS_BUILTIN

Bitbake will fail with the following error if CUSTOM_FRAGMENTS_BUILTIN
is not defined yet:

  File ".../bitbake/lib/bb/parse/ast.py", line 374, in eval
    builtin_fragments = {f[0]:f[1] for f in [f.split(':') for f in data.getVar(self.builtin_fragments_variable).split()] }
                                                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  AttributeError: 'NoneType' object has no attribute 'split'

To be safe, check if the value returned by getVar is None.

Signed-off-by: Antonin Godard <antonin.godard@bootlin.com>
---
 lib/bb/parse/ast.py | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)


---
base-commit: 7bd36f6c6d33211bb2a6b6fc6d40bdbd83b8b7c3
change-id: 20250924-fix-no-builtin-fragment-0b82af0b066b

Best regards,
--  
Antonin Godard <antonin.godard@bootlin.com>

Comments

Alexander Kanavin Sept. 24, 2025, 2:22 p.m. UTC | #1
On Wed, 24 Sept 2025 at 15:48, Antonin Godard via
lists.openembedded.org
<antonin.godard=bootlin.com@lists.openembedded.org> wrote:
> -        builtin_fragments = {f[0]:f[1] for f in [f.split(':') for f in data.getVar(self.builtin_fragments_variable).split()] }
> +        builtin_fragments = {}
> +        builtin_fragments_var = data.getVar(self.builtin_fragments_variable)
> +        if builtin_fragments_var is not None:
> +            builtin_fragments = {f[0]:f[1] for f in [f.split(':') for f in builtin_fragments_var.split()]}

I'm not sure setting builtins to empty is the correct behavior.
Perhaps an error should be raised instead?

Also, do other items from addfragments need similar guards?

Alex
Antonin Godard Sept. 25, 2025, 7:12 a.m. UTC | #2
On Wed Sep 24, 2025 at 4:22 PM CEST, Alexander Kanavin wrote:
> On Wed, 24 Sept 2025 at 15:48, Antonin Godard via
> lists.openembedded.org
> <antonin.godard=bootlin.com@lists.openembedded.org> wrote:
>> -        builtin_fragments = {f[0]:f[1] for f in [f.split(':') for f in data.getVar(self.builtin_fragments_variable).split()] }
>> +        builtin_fragments = {}
>> +        builtin_fragments_var = data.getVar(self.builtin_fragments_variable)
>> +        if builtin_fragments_var is not None:
>> +            builtin_fragments = {f[0]:f[1] for f in [f.split(':') for f in builtin_fragments_var.split()]}
>
> I'm not sure setting builtins to empty is the correct behavior.
> Perhaps an error should be raised instead?

I was thinking that there may be a case where you want to use addfragments
without specifying any built-in fragments. In this case you could either set the
built-in fragment variable to an empty string, or not set it at all. The result
is the same with the above code: the dictionary will be empty.

> Also, do other items from addfragments need similar guards?

I don't think I have seen that behavior with "regular" fragments variables. I
haven't tested it thoroughly though.

Antonin
Alexander Kanavin Sept. 25, 2025, 8:09 a.m. UTC | #3
On Thu, 25 Sept 2025 at 09:12, Antonin Godard
<antonin.godard@bootlin.com> wrote:
> I was thinking that there may be a case where you want to use addfragments
> without specifying any built-in fragments. In this case you could either set the
> built-in fragment variable to an empty string, or not set it at all. The result
> is the same with the above code: the dictionary will be empty.

It's better to require that the variable is explicitly set. The
problem is when someone sets it *after* the addfragments directive. In
that case, this magic empty default that the patch adds will take
precedence, and the user will be baffled as to why their variable
doesn't work. Better to give an error and the error should say where
the variable should be.

> > Also, do other items from addfragments need similar guards?
>
> I don't think I have seen that behavior with "regular" fragments variables. I
> haven't tested it thoroughly though.

I think at least flagged_variables should be similarly checked. What
happens when it isn't set?

Alex
diff mbox series

Patch

diff --git a/lib/bb/parse/ast.py b/lib/bb/parse/ast.py
index 49a0788038..317f00d3bd 100644
--- a/lib/bb/parse/ast.py
+++ b/lib/bb/parse/ast.py
@@ -371,7 +371,10 @@  class AddFragmentsNode(AstNode):
         fragments = data.getVar(self.fragments_variable)
         layers = data.getVar('BBLAYERS')
         flagged_variables = data.getVar(self.flagged_variables_list_variable).split()
-        builtin_fragments = {f[0]:f[1] for f in [f.split(':') for f in data.getVar(self.builtin_fragments_variable).split()] }
+        builtin_fragments = {}
+        builtin_fragments_var = data.getVar(self.builtin_fragments_variable)
+        if builtin_fragments_var is not None:
+            builtin_fragments = {f[0]:f[1] for f in [f.split(':') for f in builtin_fragments_var.split()]}
 
         if not fragments:
             return