diff mbox series

[meta-python,scarthgap] python3-pykickstart: fix options parse error

Message ID 20250311085756.1136319-1-kai.kang@windriver.com
State Under Review
Headers show
Series [meta-python,scarthgap] python3-pykickstart: fix options parse error | expand

Commit Message

Kai March 11, 2025, 8:57 a.m. UTC
From: Kai Kang <kai.kang@windriver.com>

Backport a patch for python3-pykickstart to fix option parse error:

    File "/usr/lib64/python3.12/site-packages/pykickstart/options.py", line 185, in _parse_optional
      option = action.option_strings[0]
               ^^^^^^^^^^^^^^^^^^^^^
  AttributeError: 'tuple' object has no attribute 'option_strings'

Signed-off-by: Kai Kang <kai.kang@windriver.com>
---
 ...o-behavior-change-in-upstream-_parse.patch | 71 +++++++++++++++++++
 .../python3-pykickstart_3.48.bb               |  1 +
 2 files changed, 72 insertions(+)
 create mode 100644 meta-python/recipes-extended/python-pykickstart/files/0005-options-adjust-to-behavior-change-in-upstream-_parse.patch

Comments

Khem Raj March 11, 2025, 3:44 p.m. UTC | #1
This is needed on master as well. Please add [master] to the subject
line as well in future, else I might end up ignoring such patches
accidentally thinking they are backports to stable branches.

On Tue, Mar 11, 2025 at 1:58 AM Kai Kang via lists.openembedded.org
<kai.kang=windriver.com@lists.openembedded.org> wrote:
>
> From: Kai Kang <kai.kang@windriver.com>
>
> Backport a patch for python3-pykickstart to fix option parse error:
>
>     File "/usr/lib64/python3.12/site-packages/pykickstart/options.py", line 185, in _parse_optional
>       option = action.option_strings[0]
>                ^^^^^^^^^^^^^^^^^^^^^
>   AttributeError: 'tuple' object has no attribute 'option_strings'
>
> Signed-off-by: Kai Kang <kai.kang@windriver.com>
> ---
>  ...o-behavior-change-in-upstream-_parse.patch | 71 +++++++++++++++++++
>  .../python3-pykickstart_3.48.bb               |  1 +
>  2 files changed, 72 insertions(+)
>  create mode 100644 meta-python/recipes-extended/python-pykickstart/files/0005-options-adjust-to-behavior-change-in-upstream-_parse.patch
>
> diff --git a/meta-python/recipes-extended/python-pykickstart/files/0005-options-adjust-to-behavior-change-in-upstream-_parse.patch b/meta-python/recipes-extended/python-pykickstart/files/0005-options-adjust-to-behavior-change-in-upstream-_parse.patch
> new file mode 100644
> index 0000000000..e2b34ab937
> --- /dev/null
> +++ b/meta-python/recipes-extended/python-pykickstart/files/0005-options-adjust-to-behavior-change-in-upstream-_parse.patch
> @@ -0,0 +1,71 @@
> +From f753d4d6ad1f4846d14735beb3d1b157b9914b51 Mon Sep 17 00:00:00 2001
> +From: Adam Williamson <awilliam@redhat.com>
> +Date: Wed, 2 Oct 2024 09:48:39 -0700
> +Subject: [PATCH] options: adjust to behavior change in upstream
> + _parse_optional
> +
> +In Python 3.13 and 3.12.7, the behavior of _parse_optional has
> +changed. It used to raise an error on multiple matching actions
> +itself, and only ever return None or an option tuple. Now the
> +"raise error on multiple matching actions" code was moved out
> +into consume_optional, and _parse_optional returns either None
> +or a *list* of option tuples, which contains more than one if
> +multiple actions match. See:
> +
> +https://github.com/python/cpython/pull/124631
> +https://github.com/python/cpython/issues/58573
> +
> +This adapts to the change in a way that should work on both older
> +and newer Pythons.
> +
> +Signed-off-by: Adam Williamson <awilliam@redhat.com>
> +
> +Upstream-Status: Backport [https://github.com/pykickstart/pykickstart/commit/f753d4d]
> +
> +Signed-off-by: Kai Kang <kai.kang@windriver.com>
> +---
> + pykickstart/options.py | 20 +++++++++++++++++---
> + 1 file changed, 17 insertions(+), 3 deletions(-)
> +
> +diff --git a/pykickstart/options.py b/pykickstart/options.py
> +index 2e3a0721..ca0e18af 100644
> +--- a/pykickstart/options.py
> ++++ b/pykickstart/options.py
> +@@ -177,9 +177,23 @@ class KSOptionParser(ArgumentParser):
> +         self.lineno = None
> +
> +     def _parse_optional(self, arg_string):
> +-        option_tuple = ArgumentParser._parse_optional(self, arg_string)
> ++        # Before 3.13 and 3.12.7, this returned None or a single
> ++        # option tuple. From 3.13 / 3.12.7 onwards it returns None
> ++        # or a *list* of option tuples
> ++        option_tuple_or_tuples = ArgumentParser._parse_optional(self, arg_string)
> ++        # all we want to do here is a custom warning if the action is
> ++        # deprecated. we can only safely do this if there's exactly
> ++        # one matching action
> ++        if isinstance(option_tuple_or_tuples, list):
> ++            if len(option_tuple_or_tuples) == 1:
> ++                option_tuple = option_tuple_or_tuples[0]
> ++            else:
> ++                return option_tuple_or_tuples
> ++        else:
> ++            option_tuple = option_tuple_or_tuples
> ++
> +         if option_tuple is None or option_tuple[0] is None:
> +-            return option_tuple
> ++            return option_tuple_or_tuples
> +
> +         action = option_tuple[0]
> +         option = action.option_strings[0]
> +@@ -191,7 +205,7 @@ class KSOptionParser(ArgumentParser):
> +                             "kickstart. Please modify your kickstart file to remove this option.")
> +                           % {"lineno": self.lineno, "option": option}, KickstartDeprecationWarning)
> +
> +-        return option_tuple
> ++        return option_tuple_or_tuples
> +
> +     def add_argument(self, *args, **kwargs):
> +         if "introduced" in kwargs:
> +--
> +2.47.1
> +
> diff --git a/meta-python/recipes-extended/python-pykickstart/python3-pykickstart_3.48.bb b/meta-python/recipes-extended/python-pykickstart/python3-pykickstart_3.48.bb
> index 953068f7c3..657d0df539 100644
> --- a/meta-python/recipes-extended/python-pykickstart/python3-pykickstart_3.48.bb
> +++ b/meta-python/recipes-extended/python-pykickstart/python3-pykickstart_3.48.bb
> @@ -17,6 +17,7 @@ SRC_URI = "git://github.com/rhinstaller/pykickstart.git;protocol=https;branch=ma
>             file://0002-pykickstart-parser.py-add-lock-for-readKickstart-and.patch \
>             file://0003-comment-out-sections-shutdown-and-environment-in-gen.patch \
>             file://0004-load.py-retry-to-invoke-request-with-timeout.patch \
> +           file://0005-options-adjust-to-behavior-change-in-upstream-_parse.patch \
>             "
>  SRCREV = "fa6c80c0e5c6bee29d089899a10d26e6f7f8afd8"
>
> --
> 2.34.1
>
>
> -=-=-=-=-=-=-=-=-=-=-=-
> Links: You receive all messages sent to this group.
> View/Reply Online (#115888): https://lists.openembedded.org/g/openembedded-devel/message/115888
> Mute This Topic: https://lists.openembedded.org/mt/111636553/1997914
> Group Owner: openembedded-devel+owner@lists.openembedded.org
> Unsubscribe: https://lists.openembedded.org/g/openembedded-devel/unsub [raj.khem@gmail.com]
> -=-=-=-=-=-=-=-=-=-=-=-
>
Kai March 12, 2025, 1:41 a.m. UTC | #2
On 3/11/25 23:44, Khem Raj wrote:
> This is needed on master as well. Please add [master] to the subject
> line as well in future, else I might end up ignoring such patches
> accidentally thinking they are backports to stable branches.

I didn't verify this patch on master since I planned to upgrade it on 
master. And I'll consider master first next time.

Sorry for inconvenience.

Kai

>
> On Tue, Mar 11, 2025 at 1:58 AM Kai Kang via lists.openembedded.org
> <kai.kang=windriver.com@lists.openembedded.org> wrote:
>> From: Kai Kang <kai.kang@windriver.com>
>>
>> Backport a patch for python3-pykickstart to fix option parse error:
>>
>>      File "/usr/lib64/python3.12/site-packages/pykickstart/options.py", line 185, in _parse_optional
>>        option = action.option_strings[0]
>>                 ^^^^^^^^^^^^^^^^^^^^^
>>    AttributeError: 'tuple' object has no attribute 'option_strings'
>>
>> Signed-off-by: Kai Kang <kai.kang@windriver.com>
>> ---
>>   ...o-behavior-change-in-upstream-_parse.patch | 71 +++++++++++++++++++
>>   .../python3-pykickstart_3.48.bb               |  1 +
>>   2 files changed, 72 insertions(+)
>>   create mode 100644 meta-python/recipes-extended/python-pykickstart/files/0005-options-adjust-to-behavior-change-in-upstream-_parse.patch
>>
>> diff --git a/meta-python/recipes-extended/python-pykickstart/files/0005-options-adjust-to-behavior-change-in-upstream-_parse.patch b/meta-python/recipes-extended/python-pykickstart/files/0005-options-adjust-to-behavior-change-in-upstream-_parse.patch
>> new file mode 100644
>> index 0000000000..e2b34ab937
>> --- /dev/null
>> +++ b/meta-python/recipes-extended/python-pykickstart/files/0005-options-adjust-to-behavior-change-in-upstream-_parse.patch
>> @@ -0,0 +1,71 @@
>> +From f753d4d6ad1f4846d14735beb3d1b157b9914b51 Mon Sep 17 00:00:00 2001
>> +From: Adam Williamson <awilliam@redhat.com>
>> +Date: Wed, 2 Oct 2024 09:48:39 -0700
>> +Subject: [PATCH] options: adjust to behavior change in upstream
>> + _parse_optional
>> +
>> +In Python 3.13 and 3.12.7, the behavior of _parse_optional has
>> +changed. It used to raise an error on multiple matching actions
>> +itself, and only ever return None or an option tuple. Now the
>> +"raise error on multiple matching actions" code was moved out
>> +into consume_optional, and _parse_optional returns either None
>> +or a *list* of option tuples, which contains more than one if
>> +multiple actions match. See:
>> +
>> +https://github.com/python/cpython/pull/124631
>> +https://github.com/python/cpython/issues/58573
>> +
>> +This adapts to the change in a way that should work on both older
>> +and newer Pythons.
>> +
>> +Signed-off-by: Adam Williamson <awilliam@redhat.com>
>> +
>> +Upstream-Status: Backport [https://github.com/pykickstart/pykickstart/commit/f753d4d]
>> +
>> +Signed-off-by: Kai Kang <kai.kang@windriver.com>
>> +---
>> + pykickstart/options.py | 20 +++++++++++++++++---
>> + 1 file changed, 17 insertions(+), 3 deletions(-)
>> +
>> +diff --git a/pykickstart/options.py b/pykickstart/options.py
>> +index 2e3a0721..ca0e18af 100644
>> +--- a/pykickstart/options.py
>> ++++ b/pykickstart/options.py
>> +@@ -177,9 +177,23 @@ class KSOptionParser(ArgumentParser):
>> +         self.lineno = None
>> +
>> +     def _parse_optional(self, arg_string):
>> +-        option_tuple = ArgumentParser._parse_optional(self, arg_string)
>> ++        # Before 3.13 and 3.12.7, this returned None or a single
>> ++        # option tuple. From 3.13 / 3.12.7 onwards it returns None
>> ++        # or a *list* of option tuples
>> ++        option_tuple_or_tuples = ArgumentParser._parse_optional(self, arg_string)
>> ++        # all we want to do here is a custom warning if the action is
>> ++        # deprecated. we can only safely do this if there's exactly
>> ++        # one matching action
>> ++        if isinstance(option_tuple_or_tuples, list):
>> ++            if len(option_tuple_or_tuples) == 1:
>> ++                option_tuple = option_tuple_or_tuples[0]
>> ++            else:
>> ++                return option_tuple_or_tuples
>> ++        else:
>> ++            option_tuple = option_tuple_or_tuples
>> ++
>> +         if option_tuple is None or option_tuple[0] is None:
>> +-            return option_tuple
>> ++            return option_tuple_or_tuples
>> +
>> +         action = option_tuple[0]
>> +         option = action.option_strings[0]
>> +@@ -191,7 +205,7 @@ class KSOptionParser(ArgumentParser):
>> +                             "kickstart. Please modify your kickstart file to remove this option.")
>> +                           % {"lineno": self.lineno, "option": option}, KickstartDeprecationWarning)
>> +
>> +-        return option_tuple
>> ++        return option_tuple_or_tuples
>> +
>> +     def add_argument(self, *args, **kwargs):
>> +         if "introduced" in kwargs:
>> +--
>> +2.47.1
>> +
>> diff --git a/meta-python/recipes-extended/python-pykickstart/python3-pykickstart_3.48.bb b/meta-python/recipes-extended/python-pykickstart/python3-pykickstart_3.48.bb
>> index 953068f7c3..657d0df539 100644
>> --- a/meta-python/recipes-extended/python-pykickstart/python3-pykickstart_3.48.bb
>> +++ b/meta-python/recipes-extended/python-pykickstart/python3-pykickstart_3.48.bb
>> @@ -17,6 +17,7 @@ SRC_URI = "git://github.com/rhinstaller/pykickstart.git;protocol=https;branch=ma
>>              file://0002-pykickstart-parser.py-add-lock-for-readKickstart-and.patch \
>>              file://0003-comment-out-sections-shutdown-and-environment-in-gen.patch \
>>              file://0004-load.py-retry-to-invoke-request-with-timeout.patch \
>> +           file://0005-options-adjust-to-behavior-change-in-upstream-_parse.patch \
>>              "
>>   SRCREV = "fa6c80c0e5c6bee29d089899a10d26e6f7f8afd8"
>>
>> --
>> 2.34.1
>>
>>
>> -=-=-=-=-=-=-=-=-=-=-=-
>> Links: You receive all messages sent to this group.
>> View/Reply Online (#115888): https://lists.openembedded.org/g/openembedded-devel/message/115888
>> Mute This Topic: https://lists.openembedded.org/mt/111636553/1997914
>> Group Owner: openembedded-devel+owner@lists.openembedded.org
>> Unsubscribe: https://lists.openembedded.org/g/openembedded-devel/unsub [raj.khem@gmail.com]
>> -=-=-=-=-=-=-=-=-=-=-=-
>>
diff mbox series

Patch

diff --git a/meta-python/recipes-extended/python-pykickstart/files/0005-options-adjust-to-behavior-change-in-upstream-_parse.patch b/meta-python/recipes-extended/python-pykickstart/files/0005-options-adjust-to-behavior-change-in-upstream-_parse.patch
new file mode 100644
index 0000000000..e2b34ab937
--- /dev/null
+++ b/meta-python/recipes-extended/python-pykickstart/files/0005-options-adjust-to-behavior-change-in-upstream-_parse.patch
@@ -0,0 +1,71 @@ 
+From f753d4d6ad1f4846d14735beb3d1b157b9914b51 Mon Sep 17 00:00:00 2001
+From: Adam Williamson <awilliam@redhat.com>
+Date: Wed, 2 Oct 2024 09:48:39 -0700
+Subject: [PATCH] options: adjust to behavior change in upstream
+ _parse_optional
+
+In Python 3.13 and 3.12.7, the behavior of _parse_optional has
+changed. It used to raise an error on multiple matching actions
+itself, and only ever return None or an option tuple. Now the
+"raise error on multiple matching actions" code was moved out
+into consume_optional, and _parse_optional returns either None
+or a *list* of option tuples, which contains more than one if
+multiple actions match. See:
+
+https://github.com/python/cpython/pull/124631
+https://github.com/python/cpython/issues/58573
+
+This adapts to the change in a way that should work on both older
+and newer Pythons.
+
+Signed-off-by: Adam Williamson <awilliam@redhat.com>
+
+Upstream-Status: Backport [https://github.com/pykickstart/pykickstart/commit/f753d4d]
+
+Signed-off-by: Kai Kang <kai.kang@windriver.com>
+---
+ pykickstart/options.py | 20 +++++++++++++++++---
+ 1 file changed, 17 insertions(+), 3 deletions(-)
+
+diff --git a/pykickstart/options.py b/pykickstart/options.py
+index 2e3a0721..ca0e18af 100644
+--- a/pykickstart/options.py
++++ b/pykickstart/options.py
+@@ -177,9 +177,23 @@ class KSOptionParser(ArgumentParser):
+         self.lineno = None
+ 
+     def _parse_optional(self, arg_string):
+-        option_tuple = ArgumentParser._parse_optional(self, arg_string)
++        # Before 3.13 and 3.12.7, this returned None or a single
++        # option tuple. From 3.13 / 3.12.7 onwards it returns None
++        # or a *list* of option tuples
++        option_tuple_or_tuples = ArgumentParser._parse_optional(self, arg_string)
++        # all we want to do here is a custom warning if the action is
++        # deprecated. we can only safely do this if there's exactly
++        # one matching action
++        if isinstance(option_tuple_or_tuples, list):
++            if len(option_tuple_or_tuples) == 1:
++                option_tuple = option_tuple_or_tuples[0]
++            else:
++                return option_tuple_or_tuples
++        else:
++            option_tuple = option_tuple_or_tuples
++
+         if option_tuple is None or option_tuple[0] is None:
+-            return option_tuple
++            return option_tuple_or_tuples
+ 
+         action = option_tuple[0]
+         option = action.option_strings[0]
+@@ -191,7 +205,7 @@ class KSOptionParser(ArgumentParser):
+                             "kickstart. Please modify your kickstart file to remove this option.")
+                           % {"lineno": self.lineno, "option": option}, KickstartDeprecationWarning)
+ 
+-        return option_tuple
++        return option_tuple_or_tuples
+ 
+     def add_argument(self, *args, **kwargs):
+         if "introduced" in kwargs:
+-- 
+2.47.1
+
diff --git a/meta-python/recipes-extended/python-pykickstart/python3-pykickstart_3.48.bb b/meta-python/recipes-extended/python-pykickstart/python3-pykickstart_3.48.bb
index 953068f7c3..657d0df539 100644
--- a/meta-python/recipes-extended/python-pykickstart/python3-pykickstart_3.48.bb
+++ b/meta-python/recipes-extended/python-pykickstart/python3-pykickstart_3.48.bb
@@ -17,6 +17,7 @@  SRC_URI = "git://github.com/rhinstaller/pykickstart.git;protocol=https;branch=ma
            file://0002-pykickstart-parser.py-add-lock-for-readKickstart-and.patch \
            file://0003-comment-out-sections-shutdown-and-environment-in-gen.patch \
            file://0004-load.py-retry-to-invoke-request-with-timeout.patch \
+           file://0005-options-adjust-to-behavior-change-in-upstream-_parse.patch \
            "
 SRCREV = "fa6c80c0e5c6bee29d089899a10d26e6f7f8afd8"