From patchwork Thu Jul 9 02:03:33 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Woolley, Rob" X-Patchwork-Id: 92062 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1A5D1C44501 for ; Thu, 9 Jul 2026 02:03:56 +0000 (UTC) Received: from mx0b-0064b401.pphosted.com (mx0b-0064b401.pphosted.com [205.220.178.238]) by mx.groups.io with SMTP id smtpd.msgproc01-g2.404.1783562630728256954 for ; Wed, 08 Jul 2026 19:03:52 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@windriver.com header.s=PPS06212021 header.b=RlVfNZz+; spf=permerror, err=parse error for token &{10 18 %{ir}.%{v}.%{d}.spf.has.pphosted.com}: invalid domain name (domain: windriver.com, ip: 205.220.178.238, mailfrom: prvs=1650fcb189=rob.woolley@windriver.com) Received: from pps.filterd (m0250812.ppops.net [127.0.0.1]) by mx0a-0064b401.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 6691gLph1094724 for ; Thu, 9 Jul 2026 02:03:49 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=windriver.com; h=cc:content-transfer-encoding:content-type:date:from :in-reply-to:message-id:mime-version:references:subject:to; s= PPS06212021; bh=Rd0uScq6RhcuIqqNnuSE0D90xGjr+2/VIkBK7T0O2MU=; b= RlVfNZz+oWvW9CYGOui/W/LSauZxqJPVvEWlAaeld6Kvfciw4I2FzzsoLsjnepr2 ara0/IHKyPwAQnjpyqHqcOAxmxGGgq7BPk9Dr3DDB+cTWBxLIdUgIwMhzNqfXpEi xeDH75H2DflynYhLHgdVLkW7p7+zMOC9dNduCIBLjsFgyJReiiDIFlOeUIdSWlHC ykoIYTRRs22YWpCk2Dp/8LPyfeQkYDQiexknYgO0srl9kxdpsm8GQZim2EgAMMVi XcXI16EnZAjud2vLplDl3Ao0kZtoYRe22lFDYiUl81CmXDLID1Qq8+swhG5bb6DE GblBqDuFy1fRTN564iphzQ== Received: from ala-exchng02.corp.ad.wrs.com (ala-exchng02.wrs.com [128.224.246.37]) by mx0a-0064b401.pphosted.com (PPS) with ESMTPS id 4fa1h202nm-2 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT) for ; Thu, 09 Jul 2026 02:03:49 +0000 (GMT) Received: from ala-exchng01.corp.ad.wrs.com (10.11.224.121) by ALA-EXCHNG02.corp.ad.wrs.com (10.11.224.122) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.61; Wed, 8 Jul 2026 19:03:47 -0700 Received: from ala-lpggp3.wrs.com (10.11.232.110) by ala-exchng01.corp.ad.wrs.com (10.11.224.121) with Microsoft SMTP Server id 15.1.2507.61 via Frontend Transport; Wed, 8 Jul 2026 19:03:47 -0700 From: Rob Woolley Date: Wed, 8 Jul 2026 19:03:33 -0700 Subject: [PATCH v5 1/9] bitbake-setup: Add version option MIME-Version: 1.0 Message-ID: <20260708-add-pypi-v10-v5-1-7d5f457f4b9c@windriver.com> References: <20260708-add-pypi-v10-v5-0-7d5f457f4b9c@windriver.com> In-Reply-To: <20260708-add-pypi-v10-v5-0-7d5f457f4b9c@windriver.com> To: CC: Rob Woolley X-Mailer: b4 0.15.2 X-Authority-Analysis: v=2.4 cv=LbIMLDfi c=1 sm=1 tr=0 ts=6a4f0185 cx=c_pps a=Lg6ja3A245NiLSnFpY5YKQ==:117 a=Lg6ja3A245NiLSnFpY5YKQ==:17 a=IkcTkHD0fZMA:10 a=RAioF0-LDSMA:10 a=VkNPw1HP01LnGYTKEx00:22 a=bi6dqmuHe4P4UrxVR6um:22 a=fTW__CHxibyLmBMfj2wP:22 a=t7CeM3EgAAAA:8 a=3MZ2cW2_6ngPcrpQ0mEA:9 a=QEXdDO2ut3YA:10 a=FdTzh2GWekK77mhwV6Dw:22 X-Proofpoint-Spam-Info: AW1haW4tMjYwNzA5MDAxNiBTYWx0ZWRfX4vHxC7LzRSRk nNs6h80yaK0CyE9ksOb2RrRKSJ39ebvT5VRmotjWtJuB55MNKFjcvEy0Oq7cl4lswXbvzENerc/ AdamGINVJrKcnWYHPcEUi+Xc3QZmPqBEZVZB4vUby+//UyB1AU6U X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNzA5MDAxNiBTYWx0ZWRfXzWCqP33IuvHZ UrUM5lIxbVTcJqk4fAf4VG9VbLS0oFehmcQTTVtXxdcpFV9wHM/+hm8htI+RiEQoeSEersiT2CK qxH4MI4tL7zccqaRTPcD8hTM2S1EUOUng0kH4HqNttFmFa+BwdrlnpXtd//QIOmoqtOMxEsI7P6 P4zwZXWP/9rB2rzEbfAmfpieehcJKWRCZobb4clH+KxLco/um8RGcQSQBAlH03OV2hRIh3lleF4 85kdfqDzMqKvKaBRp5QvmHnQE9j2/J6jMY5zEj0nJhcQp6pApmMkNxEzY0iD5p8kI19KyXOFQDh WuRrEzGXau/JTZFF7OhEN9XdfqsrmeFt2xadHCGPQjKYH34yx6uDkzKbxhijnVzOuf0NPA4i+oq I7NaXxo2tplPTFcPPIEYjh4BoVVWknVZgpJ5eIHJUO6lvqMDkwWKMSWvUShWoAmI37H9UNNWoJH 9u+pU/N9gg/lgO44dxw== X-Proofpoint-ORIG-GUID: nmqJ2QCJZ1hM3hw62iA_Uk5CCkImRi-Q X-Proofpoint-GUID: nmqJ2QCJZ1hM3hw62iA_Uk5CCkImRi-Q X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-07-08_05,2026-07-08_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 adultscore=0 phishscore=0 priorityscore=1501 malwarescore=0 clxscore=1015 lowpriorityscore=0 bulkscore=0 suspectscore=0 spamscore=0 impostorscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2607090016 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Thu, 09 Jul 2026 02:03:56 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/bitbake-devel/message/19827 This adds the long-form version option to match bitbake. Signed-off-by: Rob Woolley --- bin/bitbake-setup | 1 + 1 file changed, 1 insertion(+) diff --git a/bin/bitbake-setup b/bin/bitbake-setup index b81d3ad11..d105fb43d 100755 --- a/bin/bitbake-setup +++ b/bin/bitbake-setup @@ -1250,6 +1250,7 @@ def main(): ) parser.add_argument('-d', '--debug', help='Enable debug output', action='store_true') parser.add_argument('-q', '--quiet', help='Print only errors', action='store_true') + parser.add_argument('--version', action='version', version='%(prog)s ' + __version__) parser.add_argument('--color', choices=['auto', 'always', 'never'], default='auto', help='Colorize output (where %(metavar)s is %(choices)s)', metavar='COLOR') parser.add_argument('--no-network', action='store_true', help='Do not check whether configuration repositories and layer repositories have been updated; use only the local cache.') parser.add_argument('--global-settings', action='store', metavar='PATH', help='Path to the global settings file.') From patchwork Thu Jul 9 02:03:34 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Woolley, Rob" X-Patchwork-Id: 92064 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 64609C44507 for ; Thu, 9 Jul 2026 02:03:56 +0000 (UTC) Received: from mx0b-0064b401.pphosted.com (mx0b-0064b401.pphosted.com [205.220.178.238]) by mx.groups.io with SMTP id smtpd.msgproc01-g2.405.1783562631461175374 for ; Wed, 08 Jul 2026 19:03:52 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@windriver.com header.s=PPS06212021 header.b=sVhlmeLL; spf=permerror, err=parse error for token &{10 18 %{ir}.%{v}.%{d}.spf.has.pphosted.com}: invalid domain name (domain: windriver.com, ip: 205.220.178.238, mailfrom: prvs=1650fcb189=rob.woolley@windriver.com) Received: from pps.filterd (m0250812.ppops.net [127.0.0.1]) by mx0a-0064b401.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 6691gLpi1094724 for ; Thu, 9 Jul 2026 02:03:50 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=windriver.com; h=cc:content-transfer-encoding:content-type:date:from :in-reply-to:message-id:mime-version:references:subject:to; s= PPS06212021; bh=AVKIln7rlaUXjgXV871p8bcP5HNkoZOa8GDcPwsVf+8=; b= sVhlmeLLGEtRySZufQUTaizxw+IS/W8kTkbnsudYWkzHxLYACcsJeZuDXYOccd7i sWk61u+Z8/0sDvTO0fdWreJEeDieH4pCu/eoria19EAEMOjmyxo06KUkqjAOuZ2U d0jIB/a7t5UMKgOjnQ+VxS1ROnsdIWHBqqwd9A15Hdv2zE9NWexkJYCt4lwk730b ocb3Vm9mo9StGtQb04paw2e2eD8xbp819GkAUoqRh7SdkQfooIUpXqlCI0G0TSIC yS6czdiUpZ7T/MPu/dIp6aP+YzwCnQ5nFZ6wzCyHqyNlk8Va+LPlLDneAnhBqn53 9qYwI44bkZ6pz6+ZHD26Pw== Received: from ala-exchng02.corp.ad.wrs.com (ala-exchng02.wrs.com [128.224.246.37]) by mx0a-0064b401.pphosted.com (PPS) with ESMTPS id 4fa1h202nm-3 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT) for ; Thu, 09 Jul 2026 02:03:50 +0000 (GMT) Received: from ala-exchng01.corp.ad.wrs.com (10.11.224.121) by ALA-EXCHNG02.corp.ad.wrs.com (10.11.224.122) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.61; Wed, 8 Jul 2026 19:03:48 -0700 Received: from ala-lpggp3.wrs.com (10.11.232.110) by ala-exchng01.corp.ad.wrs.com (10.11.224.121) with Microsoft SMTP Server id 15.1.2507.61 via Frontend Transport; Wed, 8 Jul 2026 19:03:48 -0700 From: Rob Woolley Date: Wed, 8 Jul 2026 19:03:34 -0700 Subject: [PATCH v5 2/9] pypi: Add PyPI packaging for bitbake-setup MIME-Version: 1.0 Message-ID: <20260708-add-pypi-v10-v5-2-7d5f457f4b9c@windriver.com> References: <20260708-add-pypi-v10-v5-0-7d5f457f4b9c@windriver.com> In-Reply-To: <20260708-add-pypi-v10-v5-0-7d5f457f4b9c@windriver.com> To: CC: Rob Woolley X-Mailer: b4 0.15.2 X-Authority-Analysis: v=2.4 cv=LbIMLDfi c=1 sm=1 tr=0 ts=6a4f0186 cx=c_pps a=Lg6ja3A245NiLSnFpY5YKQ==:117 a=Lg6ja3A245NiLSnFpY5YKQ==:17 a=IkcTkHD0fZMA:10 a=RAioF0-LDSMA:10 a=VkNPw1HP01LnGYTKEx00:22 a=bi6dqmuHe4P4UrxVR6um:22 a=fTW__CHxibyLmBMfj2wP:22 a=24AZYWMyAAAA:8 a=iGHA9ds3AAAA:8 a=Q4-j1AaZAAAA:8 a=t7CeM3EgAAAA:8 a=qV09NasGAAAA:8 a=V5MqrhjLj9XmrIPkEmEA:9 a=QEXdDO2ut3YA:10 a=bG88sKzkDEFeXWNnvthB:22 a=nM-MV4yxpKKO9kiQg6Ot:22 a=9H3Qd4_ONW2Ztcrla5EB:22 a=FdTzh2GWekK77mhwV6Dw:22 a=GlicbclHOgpI_Rq0ze_Y:22 X-Proofpoint-Spam-Info: AW1haW4tMjYwNzA5MDAxNiBTYWx0ZWRfX1QOvI1Nctepb CNghr8P6tTgIgpHdHkKFUNDqSvLCCSfeTpIH3C8IjlnywsvB57AJAKmoljMvkiBqdYCI/N8Xfwu pn8Vk1/9a+uy0ZGOOx6MriXvNvq4ZiIfuyOs5Xy6wQ36f2m7bnlN X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNzA5MDAxNiBTYWx0ZWRfX5eL8WAfir1u+ l27I7FyQEcITSW+gms8LzkyYEqE7D2htVbGkgl9xSU1Qr2wrK5FVVeLIEwRbLTXazhBJfvmbz7q gOHzsz/3/gHn9IV+MFt1IDgA1H2cpFl6w5+L+1ZG3fLBn2FRJGRuygoNHXCdEr70459L2g+9I6l +Szl5i7l7UBSMTmjGIz0lphJHtMEFa/Rla399XnoKFDYwFEEZ3MttQ5SoOIfDtN5AIXJy6y7Cyg NAweDnAmAwiBlKR+TvTJhA11UKEDi0ZVMzOLdpoluACN1QuUk02vC22iYl7Bai/UOKBHThbemrY pFrVxpRKgPwjdbECKF6im3bXx/UBq51KKwxkripbq/fzkpgNUa3igd60v70Vq03DOSQ2EhAY90u iLFeqftO3nK3n0qx+e69NDc0FkSW6UJ3gMj4YzEi/TokEpNfqi+gFMwHbv2N9snHTW6oIHxStVj hirDVP5L+a1BR6vKBmQ== X-Proofpoint-ORIG-GUID: 6dbOkI4ukFfKRt3c2L3KEVCzHzlqchAX X-Proofpoint-GUID: 6dbOkI4ukFfKRt3c2L3KEVCzHzlqchAX X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-07-08_05,2026-07-08_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 adultscore=0 phishscore=0 priorityscore=1501 malwarescore=0 clxscore=1015 lowpriorityscore=0 bulkscore=0 suspectscore=0 spamscore=0 impostorscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2607090016 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Thu, 09 Jul 2026 02:03:56 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/bitbake-devel/message/19828 We wish to publish bitbake-setup to PyPI to improve the workflow for new users that are familiar with pip install. In order to publish bitbake-setup as a standalone package, we must create a staging directory for Python to build the package. The package-bitbake-setup.py automates the staging of the necessary files. You may supply your desired directory as the first argument, but packaging-workspace in the root of the git repository is chosen by default. The packaging process and related tests have also been included as part of bitbake-selftest and lib/bb/tests/setup.py. These tests use package-bitbake-setup.py. The tests include: * Verify bitbake-setup --help runs successfully. * Verify bitbake-setup list runs successfully. * Verify console script entry points are correctly defined. * Verify all expected modules can be imported from installed package. * Verify package metadata is correctly set. * Verify version is set correctly (not fallback 0.0.0 unless expected). * Verify wheel METADATA file contains required fields. The pyproject.toml, LICENSE, and README.md files are used to create the package and provide information for PyPI. Assisted-by: Claude:claude-4.6-opus Signed-off-by: Rob Woolley --- bin/bitbake-selftest | 2 + lib/bb/tests/setup.py | 289 ++++++++++++++++++++- packaging-pypi/bitbake-setup/LICENSE | 23 ++ packaging-pypi/bitbake-setup/README.md | 42 +++ .../bitbake-setup/package-bitbake-setup.py | 79 ++++++ packaging-pypi/bitbake-setup/pyproject.toml | 92 +++++++ 6 files changed, 526 insertions(+), 1 deletion(-) diff --git a/bin/bitbake-selftest b/bin/bitbake-selftest index 7f6a64438..8ac0aeb5f 100755 --- a/bin/bitbake-selftest +++ b/bin/bitbake-selftest @@ -72,6 +72,8 @@ ENV_HELP = """\ Environment variables: BB_SKIP_NETTESTS set to 'yes' in order to skip tests using network connection + BB_SKIP_PYPI_TESTS set to 'no' to run PyPI packaging tests + (default: yes/skip) BB_TMPDIR_NOCLEAN set to 'yes' to preserve test tmp directories """ diff --git a/lib/bb/tests/setup.py b/lib/bb/tests/setup.py index 5592e8196..de0ccef28 100644 --- a/lib/bb/tests/setup.py +++ b/lib/bb/tests/setup.py @@ -11,7 +11,14 @@ import glob import hashlib import json import os +import shutil import stat +import subprocess +import sys +import tempfile +import unittest +import venv +import zipfile from bb.tests.support.httpserver import HTTPService class BitbakeSetupTest(FetcherTest): @@ -92,7 +99,11 @@ print("BBPATH is {{}}".format(os.environ["BBPATH"])) def runbbsetup(self, cmd): bbsetup = os.path.abspath(os.path.dirname(__file__) + "/../../../bin/bitbake-setup") - return bb.process.run([bbsetup, '--global-settings', os.path.join(self.tempdir, 'global-config')] + cmd) + # Set PYTHONPATH so subprocess can find bb module instead of relying on the current directory + env = os.environ.copy() + libdir = os.path.abspath(os.path.dirname(__file__) + "/../..") + env["PYTHONPATH"] = libdir + ":" + env.get("PYTHONPATH", "") + return bb.process.run([bbsetup, '--global-settings', os.path.join(self.tempdir, 'global-config')] + cmd, env=env, cwd=self.tempdir) def _add_json_config_to_registry_helper(self, name, sources): @@ -735,3 +746,279 @@ print("BBPATH is {{}}".format(os.environ["BBPATH"])) self.assertEqual(f.read(), 'conflicting-upstream\n', "re-cloned layer must contain the upstream content after conflict backup") del os.environ['BBPATH'] + +@unittest.skipIf(os.environ.get("BB_SKIP_PYPI_TESTS", "yes") != "no", + "PyPI packaging test (set BB_SKIP_PYPI_TESTS=no to run)") +class PyPIPackagingTest(unittest.TestCase): + """Tests for PyPI packaging of bitbake-setup. + + These tests build a wheel from source, install it in an isolated venv, + and verify the package works correctly. Skipped by default unless + BB_SKIP_PYPI_TESTS=no is set. + """ + + wheel_path = None + build_tempdir = None + workspace_dir = None + + @classmethod + def setUpClass(cls): + """Build wheel once for all tests in this class.""" + # Locate packaging-pypi/bitbake-setup directory + cls.pypi_dir = os.path.abspath( + os.path.join(os.path.dirname(__file__), '..', '..', '..', 'packaging-pypi', 'bitbake-setup') + ) + + # Check for required build tools + cls._check_build_tools() + + # Create temporary directory for packaging workspace + cls.build_tempdir = tempfile.mkdtemp(prefix="bitbake-pypi-build-") + + # Run package-bitbake-setup.py to create packaging workspace + cls._create_packaging_workspace() + + # Build the wheel + cls._build_wheel() + + @classmethod + def _check_build_tools(cls): + """Verify build tools are available, skip if not.""" + try: + result = subprocess.run( + [sys.executable, "-m", "build", "--version"], + capture_output=True, check=True + ) + except (subprocess.CalledProcessError, FileNotFoundError): + raise unittest.SkipTest("'build' package not installed (pip install build)") + + @classmethod + def _create_packaging_workspace(cls): + """Create packaging workspace using package-bitbake-setup.py.""" + script = os.path.join(cls.pypi_dir, 'package-bitbake-setup.py') + cls.workspace_dir = os.path.join(cls.build_tempdir, 'workspace') + result = subprocess.run( + [sys.executable, script, '-d', cls.workspace_dir], + capture_output=True, text=True + ) + if result.returncode != 0: + raise unittest.SkipTest(f"Packaging workspace creation failed: {result.stderr}") + + @classmethod + def _build_wheel(cls): + """Build the wheel in the packaging workspace.""" + result = subprocess.run( + [sys.executable, "-m", "build", "--wheel"], + cwd=cls.workspace_dir, + capture_output=True, text=True + ) + if result.returncode != 0: + raise unittest.SkipTest(f"Wheel build failed: {result.stderr}") + + # Find the built wheel + dist_dir = os.path.join(cls.workspace_dir, 'dist') + wheels = glob.glob(os.path.join(dist_dir, '*.whl')) + if not wheels: + raise unittest.SkipTest("No wheel file found after build") + cls.wheel_path = wheels[0] + + @classmethod + def tearDownClass(cls): + """Clean up the shared wheel build artifacts.""" + if cls.build_tempdir and os.environ.get("BB_TMPDIR_NOCLEAN") != "yes": + shutil.rmtree(cls.build_tempdir, ignore_errors=True) + elif cls.build_tempdir: + print(f"Not cleaning up {cls.build_tempdir}. Please remove manually.") + + def setUp(self): + """Create isolated venv for testing the installed package.""" + self.venv_dir = tempfile.mkdtemp(prefix="bitbake-pypi-venv-") + + # Create venv without pip (faster, no network needed) + venv.create(self.venv_dir, with_pip=False, symlinks=True) + + # Get paths to venv python and bin directory + if sys.platform == 'win32': + self.venv_python = os.path.join(self.venv_dir, 'Scripts', 'python.exe') + self.venv_bin = os.path.join(self.venv_dir, 'Scripts') + else: + self.venv_python = os.path.join(self.venv_dir, 'bin', 'python') + self.venv_bin = os.path.join(self.venv_dir, 'bin') + + # Install wheel using pip from the outer environment (offline, no-deps) + site_packages = self._get_site_packages() + result = subprocess.run( + [sys.executable, "-m", "pip", "install", + "--target", site_packages, + "--no-deps", "--no-index", + self.wheel_path], + capture_output=True, text=True + ) + if result.returncode != 0: + self.fail(f"Failed to install wheel: {result.stderr}") + + # Install console script entry point manually + self._install_console_script() + + def _get_site_packages(self): + """Get the site-packages directory in the venv.""" + lib_dir = os.path.join(self.venv_dir, 'lib') + # Find python version directory + for d in os.listdir(lib_dir): + if d.startswith('python'): + return os.path.join(lib_dir, d, 'site-packages') + raise RuntimeError("Could not find site-packages in venv") + + def _install_console_script(self): + """Create console script wrapper in venv bin directory.""" + site_packages = self._get_site_packages() + script_path = os.path.join(self.venv_bin, 'bitbake-setup') + script_content = f'''#!{self.venv_python} +import sys +sys.path.insert(0, "{site_packages}") +from bitbake_setup.__main__ import main +sys.exit(main()) +''' + with open(script_path, 'w') as f: + f.write(script_content) + os.chmod(script_path, 0o755) + + def tearDown(self): + """Remove venv after test.""" + if os.environ.get("BB_TMPDIR_NOCLEAN") != "yes": + shutil.rmtree(self.venv_dir, ignore_errors=True) + else: + print(f"Not cleaning up {self.venv_dir}. Please remove manually.") + + def test_imports(self): + """Verify all expected modules can be imported from installed package.""" + + site_packages = self._get_site_packages() + imports = ['bb', 'bitbake_setup'] + for module in imports: + result = subprocess.run( + [self.venv_python, '-c', f'import sys; sys.path.insert(0, "{site_packages}"); import {module}'], + capture_output=True, text=True + ) + self.assertEqual(result.returncode, 0, + f"Failed to import {module}: {result.stderr}") + + def test_console_script_help(self): + """Verify bitbake-setup --help runs successfully.""" + script = os.path.join(self.venv_bin, 'bitbake-setup') + result = subprocess.run( + [script, '--help'], + capture_output=True, text=True + ) + self.assertEqual(result.returncode, 0, + f"bitbake-setup --help failed: {result.stderr}") + self.assertIn('usage:', result.stdout.lower()) + + def test_console_script_list(self): + """Verify bitbake-setup list runs successfully.""" + script = os.path.join(self.venv_bin, 'bitbake-setup') + result = subprocess.run( + [script, 'list'], + capture_output=True, text=True + ) + # List may return 0 even with no configurations + self.assertEqual(result.returncode, 0, + f"bitbake-setup list failed: {result.stderr}") + + def test_package_metadata(self): + """Verify package metadata is correctly set.""" + site_packages = self._get_site_packages() + code = ''' +import json +import sys +sys.path.insert(0, "{}") +from importlib.metadata import metadata +m = metadata("bitbake-setup") +print(json.dumps({{ + "name": m["Name"], + "version": m["Version"], + "requires_python": m.get("Requires-Python", ""), + "license": m.get("License", ""), +}})) +'''.format(site_packages) + result = subprocess.run( + [self.venv_python, '-c', code], + capture_output=True, text=True + ) + self.assertEqual(result.returncode, 0, + f"Failed to get metadata: {result.stderr}") + + meta = json.loads(result.stdout) + self.assertEqual(meta['name'], 'bitbake-setup') + self.assertIn('>=3.9', meta['requires_python']) + + def test_vendored_dependencies(self): + """Verify vendored dependencies (bs4, ply, progressbar, simplediff) are not bundled in package.""" + # Check that vendored packages do not exist in root of wheel + with zipfile.ZipFile(self.wheel_path, 'r') as whl: + names = whl.namelist() + + # Check for expected package directories + expected = ['bs4/', 'ply/', 'progressbar/', 'simplediff/'] + for pkg in expected: + found = any(n.startswith(pkg) for n in names) + self.assertFalse(found, + f"Unexpected vendored package '{pkg}' found in wheel") + + def test_version_from_wheel(self): + """Verify version is set correctly (not fallback 0.0.0 unless expected).""" + import re + # Extract version from wheel filename + wheel_name = os.path.basename(self.wheel_path) + # Wheel format: {name}-{version}(-{build})?-{python}-{abi}-{platform}.whl + parts = wheel_name.split('-') + version = parts[1] + + # Check version format (should be semver-like or contain git info) + version_pattern = r'^\d+\.\d+\.\d+.*$' + self.assertTrue(re.match(version_pattern, version), + f"Version '{version}' doesn't match expected pattern") + + print(f"Extracted version from wheel: {version}") + + self.assertNotEqual(version, '0.0.0', + "Version is fallback 0.0.0 - no git tags found") + + def test_wheel_metadata_file(self): + """Verify wheel METADATA file contains required fields.""" + with zipfile.ZipFile(self.wheel_path, 'r') as whl: + # Find METADATA file in dist-info + metadata_path = None + for name in whl.namelist(): + if name.endswith('.dist-info/METADATA'): + metadata_path = name + break + + self.assertIsNotNone(metadata_path, "METADATA file not found in wheel") + + # Parse metadata + metadata_content = whl.read(metadata_path).decode('utf-8') + + # Check required fields + self.assertIn('Metadata-Version:', metadata_content) + self.assertIn('Name: bitbake-setup', metadata_content) + self.assertIn('Version:', metadata_content) + self.assertIn('Requires-Python:', metadata_content) + + def test_entry_points(self): + """Verify console script entry points are correctly defined.""" + with zipfile.ZipFile(self.wheel_path, 'r') as whl: + # Find entry_points.txt in dist-info + entry_points_path = None + for name in whl.namelist(): + if name.endswith('.dist-info/entry_points.txt'): + entry_points_path = name + break + + self.assertIsNotNone(entry_points_path, + "entry_points.txt not found in wheel") + + content = whl.read(entry_points_path).decode('utf-8') + self.assertIn('[console_scripts]', content) + self.assertIn('bitbake-setup', content) + self.assertIn('bitbake_setup.__main__:main', content) diff --git a/packaging-pypi/bitbake-setup/LICENSE b/packaging-pypi/bitbake-setup/LICENSE new file mode 100644 index 000000000..4b4c73672 --- /dev/null +++ b/packaging-pypi/bitbake-setup/LICENSE @@ -0,0 +1,23 @@ +bitbake-setup is licensed under the GNU General Public License version 2.0. See +LICENSE.GPL-2.0-only for further details. + +Individual files contain the following style tags instead of the full license text: + + SPDX-License-Identifier: GPL-2.0-only + +This enables machine processing of license information based on the SPDX +License Identifiers that are here available: http://spdx.org/licenses/ + +The bitbake-setup package vendorizes the following modules: + +beautifulsoup4 + SPDX-License-Identifier: MIT + +typing_extensions + SPDX-License-Identifier: PSF-2.0 + +progressbar: + SPDX-License-Identifier: LGPL-2.1-or-later OR BSD-3-Clause-Clear + +simplediff: + SPDX-License-Identifier: Zlib diff --git a/packaging-pypi/bitbake-setup/README.md b/packaging-pypi/bitbake-setup/README.md new file mode 100644 index 000000000..aaa702783 --- /dev/null +++ b/packaging-pypi/bitbake-setup/README.md @@ -0,0 +1,42 @@ +# bitbake-setup + +This package provides the `bitbake-setup` command and the Python modules +required to support BitBake setup and configuration. + +## Usage + +Instructions on uses of bitbake-setup can be found in +[Setting Up the Environment With bitbake-setup](https://docs.yoctoproject.org/bitbake/dev/bitbake-user-manual/bitbake-user-manual-environment-setup.html) from the Yocto Project manual. + +List the available configurations; +```bash +bitbake-setup list +``` + +Show the help for the bitbake-setup init subcommand: +```bash +bitbake-setup init --help +usage: bitbake-setup init [-h] [--non-interactive] [--source-overrides SOURCE_OVERRIDES] [--setup-dir-name SETUP_DIR_NAME] [--skip-selection SKIP_SELECTION] [-L SOURCE_NAME PATH] + [config ...] + +positional arguments: + config path/URL/id to a configuration file (use 'list' command to get available ids), followed by configuration options. Bitbake-setup will ask to choose from available + choices if command line doesn't completely specify them. + +options: + -h, --help show this help message and exit + --non-interactive Do not ask to interactively choose from available options; if bitbake-setup cannot make a decision it will stop with a failure. + --source-overrides SOURCE_OVERRIDES + Override sources information (repositories/revisions) with values from a local json file. + --setup-dir-name SETUP_DIR_NAME + A custom setup directory name under the top directory. + --skip-selection SKIP_SELECTION + Do not select and set an option/fragment from available choices; the resulting bitbake configuration may be incomplete. + -L SOURCE_NAME PATH, --use-local-source SOURCE_NAME PATH + Symlink local source into a build, instead of getting it as prescribed by a configuration (useful for local development). +``` + +To initialize a workspace for the Poky reference distro using the development branch (ie. "master") of OpenEmbedded: +```bash +bitbake-setup init poky-master +``` \ No newline at end of file diff --git a/packaging-pypi/bitbake-setup/package-bitbake-setup.py b/packaging-pypi/bitbake-setup/package-bitbake-setup.py new file mode 100755 index 000000000..f5468dc47 --- /dev/null +++ b/packaging-pypi/bitbake-setup/package-bitbake-setup.py @@ -0,0 +1,79 @@ +#!/usr/bin/env python3 + +import argparse +import logging +import shutil +from pathlib import Path + + +def create_packaging_workspace(directory): + # Create the directory for packaging workspace + if len(directory or "") > 0: + workspace_dir = Path(directory) + else: + # This script is located in packaging-pypi/bitbake-setup/package-bitbake-setup.py + workspace_dir = Path(__file__).parents[2] / "packaging-workspace" + + if not workspace_dir.exists(): + logging.debug(f"Created packaging workspace at: {workspace_dir}") + workspace_dir.mkdir(exist_ok=True) + else: + logging.debug(f"Packaging workspace already exists at: {workspace_dir}") + + # Copy packaging files to the workspace + files_to_copy = [ + "packaging-pypi/bitbake-setup/pyproject.toml", + "packaging-pypi/bitbake-setup/README.md", + "packaging-pypi/bitbake-setup/LICENSE", + "LICENSE.MIT", + "LICENSE.GPL-2.0-only" + ] + + for file in files_to_copy: + src_path = Path(__file__).parents[2] / file + dest_path = workspace_dir / Path(file).name + + if src_path.is_dir(): + shutil.copytree(src_path, dest_path, dirs_exist_ok=True) + logging.debug(f"Copied directory: {src_path} to {dest_path}") + else: + shutil.copy2(src_path, dest_path) + logging.debug(f"Copied file: {src_path} to {dest_path}") + + + # Copy necessary modules to the workspace + modules_to_bundle = [ + "lib/bb", + ] + + for module in modules_to_bundle: + src_path = Path(__file__).parents[2] / module + dest_path = workspace_dir / "src" / Path(module).name + + if src_path.is_dir(): + shutil.copytree(src_path, dest_path, dirs_exist_ok=True) + logging.debug(f"Bundled module directory: {src_path} to {dest_path}") + else: + shutil.copy2(src_path, dest_path) + logging.debug(f"Bundled module file: {src_path} to {dest_path}") + + # Create bitbake_setup module + bitbake_setup_dir = Path(workspace_dir / "src" / "bitbake_setup") + bitbake_setup_dir.mkdir(exist_ok=True) + Path(bitbake_setup_dir / "__init__.py").touch() + shutil.copy2(Path(__file__).parents[2] / "bin" / "bitbake-setup", str(bitbake_setup_dir / "__main__.py")) + + +if __name__ == "__main__": + logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') + + parser = argparse.ArgumentParser(description='Package bitbake-setup for PyPI') + parser.add_argument('-v', '--verbose', action='store_true', help='increase output verbosity.') + parser.add_argument('-d', '--directory', type=str, help='specify the directory to create the packaging workspace in.') + + args = parser.parse_args() + + if args.verbose: + logging.getLogger().setLevel(logging.DEBUG) + + create_packaging_workspace(args.directory) diff --git a/packaging-pypi/bitbake-setup/pyproject.toml b/packaging-pypi/bitbake-setup/pyproject.toml new file mode 100644 index 000000000..90ed1ffb9 --- /dev/null +++ b/packaging-pypi/bitbake-setup/pyproject.toml @@ -0,0 +1,92 @@ +[build-system] +requires = [ + "setuptools>=64", +] +build-backend = "setuptools.build_meta" + +[project] +name = "bitbake-setup" +dynamic = ["version"] +description = "bitbake-setup" +readme = "README.md" +requires-python = ">=3.9" +license = "GPL-2.0-only AND MIT AND PSF-2.0 AND Zlib AND LGPL-2.1-or-later OR BSD-3-Clause-Clear" +authors = [ + { name = "OpenEmbedded BitBake Developers", email = "bitbake-devel@lists.openembedded.org" } +] +classifiers = [ + "Programming Language :: Python :: 3", + "Operating System :: POSIX :: Linux", +] + +dependencies = [ + # bitbake-setup is mostly self-contained +] + +[project.optional-dependencies] +test = [ + "pytest>=7", +] + +lint = [ + "ruff>=0.3", + "mypy>=1.8", +] + +dev = [ + "pytest>=7", + "ruff>=0.3", + "mypy>=1.8", + "build", + "twine", +] + +[project.scripts] +bitbake-setup = "bitbake_setup.__main__:main" + +[project.urls] +Homepage = "https://git.openembedded.org/bitbake/" +Documentation = "https://docs.yoctoproject.org/bitbake/bitbake-user-manual/bitbake-user-manual-environment-setup.html" +Repository = "https://git.openembedded.org/bitbake/" + +[tool.mypy] +python_version = "3.9" +warn_unused_configs = true +ignore_missing_imports = true +no_implicit_optional = true +check_untyped_defs = false + +[tool.ruff] +target-version = "py39" +line-length = 88 +src = ["src"] + +[tool.ruff.lint] +select = [ + "E", # pycodestyle + "F", # pyflakes + "B", # flake8-bugbear + "I", # import sorting +] +ignore = [ + "E501", # line length (handled by formatter) +] + +[tool.ruff.format] +quote-style = "double" +indent-style = "space" + +[tool.setuptools] +package-dir = { "" = "src" } +zip-safe = false +include-package-data = true + +[tool.setuptools.dynamic] +version = {attr = "bb.__version__"} + +[tool.setuptools.packages.find] +where = ["src"] +include = [ + "bb*", + "bitbake_setup" +] From patchwork Thu Jul 9 02:03:35 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Woolley, Rob" X-Patchwork-Id: 92065 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id C9214C44509 for ; Thu, 9 Jul 2026 02:03:56 +0000 (UTC) Received: from mx0b-0064b401.pphosted.com (mx0b-0064b401.pphosted.com [205.220.178.238]) by mx.groups.io with SMTP id smtpd.msgproc02-g2.400.1783562631873754580 for ; Wed, 08 Jul 2026 19:03:52 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@windriver.com header.s=PPS06212021 header.b=qb/LrBzw; spf=permerror, err=parse error for token &{10 18 %{ir}.%{v}.%{d}.spf.has.pphosted.com}: invalid domain name (domain: windriver.com, ip: 205.220.178.238, mailfrom: prvs=1650fcb189=rob.woolley@windriver.com) Received: from pps.filterd (m0250812.ppops.net [127.0.0.1]) by mx0a-0064b401.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 6691gLpj1094724 for ; Thu, 9 Jul 2026 02:03:50 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=windriver.com; h=cc:content-transfer-encoding:content-type:date:from :in-reply-to:message-id:mime-version:references:subject:to; s= PPS06212021; bh=RuqHvYKVT8QcNCoUqneF9Nb2cb8hPdet73hbaRJyUG4=; b= qb/LrBzwx+rW0hUK8JfcSlxkDNRLbX3FSbP3fRoIYjR6vvZeTez0d+/BdgMsBxLJ dYUkw02seid6UARydtXHadAtzB3R/zAl4UTTIaHaj5K1N6d9PvgRnWzjHbXko+TV eU1M2GhmfXKuWKrA0R/cYaVYrrncLM4ZMEmWWRZAOUG8oo7tftNYZeCFaSryKuuj bcRjLATHYgl9pOGCBekPWFNnU8WiPoebJPeiGmr5n+ofVwx+1wk4cCvDCMvslyU5 cC05uedDUDRYJa4+vVy+O5L87z0qxFLQR1U7ZGI0ROz8wTbNqvtzbLKQXIowC9w4 KQ4mbv7jufBXkHdikVy/nw== Received: from ala-exchng02.corp.ad.wrs.com (ala-exchng02.wrs.com [128.224.246.37]) by mx0a-0064b401.pphosted.com (PPS) with ESMTPS id 4fa1h202nm-4 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT) for ; Thu, 09 Jul 2026 02:03:50 +0000 (GMT) Received: from ala-exchng01.corp.ad.wrs.com (10.11.224.121) by ALA-EXCHNG02.corp.ad.wrs.com (10.11.224.122) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.61; Wed, 8 Jul 2026 19:03:48 -0700 Received: from ala-lpggp3.wrs.com (10.11.232.110) by ala-exchng01.corp.ad.wrs.com (10.11.224.121) with Microsoft SMTP Server id 15.1.2507.61 via Frontend Transport; Wed, 8 Jul 2026 19:03:48 -0700 From: Rob Woolley Date: Wed, 8 Jul 2026 19:03:35 -0700 Subject: [PATCH v5 3/9] pypi: Add packaging documentation for developers MIME-Version: 1.0 Message-ID: <20260708-add-pypi-v10-v5-3-7d5f457f4b9c@windriver.com> References: <20260708-add-pypi-v10-v5-0-7d5f457f4b9c@windriver.com> In-Reply-To: <20260708-add-pypi-v10-v5-0-7d5f457f4b9c@windriver.com> To: CC: Rob Woolley X-Mailer: b4 0.15.2 X-Authority-Analysis: v=2.4 cv=LbIMLDfi c=1 sm=1 tr=0 ts=6a4f0186 cx=c_pps a=Lg6ja3A245NiLSnFpY5YKQ==:117 a=Lg6ja3A245NiLSnFpY5YKQ==:17 a=IkcTkHD0fZMA:10 a=RAioF0-LDSMA:10 a=VkNPw1HP01LnGYTKEx00:22 a=bi6dqmuHe4P4UrxVR6um:22 a=fTW__CHxibyLmBMfj2wP:22 a=t7CeM3EgAAAA:8 a=IFS6wosHp3F-r_7qPvIA:9 a=QEXdDO2ut3YA:10 a=FdTzh2GWekK77mhwV6Dw:22 X-Proofpoint-Spam-Info: AW1haW4tMjYwNzA5MDAxNiBTYWx0ZWRfXwd9N5ppkXNLR hDgo5R7CpB/bTJeRGqaAAac083ZEANHqWp9+6aZK92jgNxm9lgwKO6gRPcyc0+CVeT9Mp6bzS8T 7Xxpt7+iBzjxkBF4esYbPsZKaF3rJdxKKK0Bvh/QsYvMrruW8Iyp X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNzA5MDAxNiBTYWx0ZWRfXyLyU8p9Hgw51 BFpq2MbnI6Uxx4qmB1KkrLT25wENzeY8Aj88AuLUHbsGXLmKqrxB3bbQpMQkuSBiIke1c1F5Exn ODUj1Kb3dW+l+GpbXjFhJRlVyuIINHqWD1soFt7GU5uz/9yTZOVQp5V930VLUq3+gHo3LyZT1Pl pLsgVw7PVEEL+/XPPD7yBJsgFUrKKoJ/3LTQJmCJA1WWJ8tW5SleOUAFcQ+xDO8Ajk8n6WqLiuo tWB47PMLbkH44E57S03q0nObO7eeVcbe5ECX0BaONwKzAaUBgRq0bqjK9YRa3AlNeEYalw+0zLJ IF9ITTBZIaA7pyj1SNv10pI42+1RcUFYZkyOyzuq7WXZ2xtG04HsaRMXX0FRuGILo4QOTnJb+DB ky4Ee9KvgEHSgdB6EP0OYHRKJh5syw7iLUrNuuxRTgsdNODHowLhS5aO4bMtkulo7J4tXuwsEme 7RUxSTZITOBDa43lnGg== X-Proofpoint-ORIG-GUID: hnAX8qSy0iEyvD5o8H98YU2WgyGf99wX X-Proofpoint-GUID: hnAX8qSy0iEyvD5o8H98YU2WgyGf99wX X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-07-08_05,2026-07-08_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 adultscore=0 phishscore=0 priorityscore=1501 malwarescore=0 clxscore=1015 lowpriorityscore=0 bulkscore=0 suspectscore=0 spamscore=0 impostorscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2607090016 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Thu, 09 Jul 2026 02:03:56 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/bitbake-devel/message/19824 Signed-off-by: Rob Woolley --- packaging-pypi/bitbake-setup/BUILD.md | 67 +++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/packaging-pypi/bitbake-setup/BUILD.md b/packaging-pypi/bitbake-setup/BUILD.md new file mode 100644 index 000000000..adb8d1839 --- /dev/null +++ b/packaging-pypi/bitbake-setup/BUILD.md @@ -0,0 +1,67 @@ +# Development Instructions + +## Requirements + +- Python >= 3.9 +- pip >= 19 (for installation) + +## Testing + +To lint the `bitbake-setup` pypi packaging, run the ruff tool. +```bash +ruff check bin/bitbake-setup packaging-pypi/bitbake-setup +``` + +The steps to build and test the `bitbake-setup` pypi packaging have been automated with the `bitbake-selftest` tool. This tool automatically creates a Python virtual environment for you. + +Run the bitbake-selftest +```bash +BB_SKIP_PYPI_TESTS=no bin/bitbake-selftest -v bb.tests.setup.PyPIPackagingTest +``` + +## Packaging + +### Create the development sandbox + +To create the development sandbox run: +```bash +packaging-pypi/bitbake-setup/package-bitbake-setup.py +cd packaging-workspace +``` + +### Updating the vendored modules + +You may use the Python vendoring module to update the vendored modules. Its configuration can be found in the pyproject.toml under the tool.vendoring section. + +This information includes: +- the destination directory where the vendored modules are stored (e.g. lib/bb/_vendor) +- the module names and versions to vendor are found in the requirements file vendor.txt +- the namespace to place the modules in (eg. bb._vendor) +- the patches to apply to the pristine source code (eg. vendor/patches) + +To run the tool you may install it from pypi and run it from the top-level directory. + +```bash +python3 -m pip install vendoring +vendoring sync . +``` + +### Building the package + +To install the development tools manually run: +```bash +python3 -m pip install -e '.[dev]' +``` + +To build a wheel (.whl) then use: +```bash +python3 -m build +``` + +This produces a wheel (.whl) file in the dist directory. This may be installed using pip. + +### Installing the package + +```bash +python3 -m pip install dist/bitbake_setup-*-py3-none-any.whl +``` From patchwork Thu Jul 9 02:03:36 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Woolley, Rob" X-Patchwork-Id: 92066 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3FABAC43458 for ; Thu, 9 Jul 2026 02:03:57 +0000 (UTC) Received: from mx0b-0064b401.pphosted.com (mx0b-0064b401.pphosted.com [205.220.178.238]) by mx.groups.io with SMTP id smtpd.msgproc02-g2.401.1783562632367635953 for ; Wed, 08 Jul 2026 19:03:52 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@windriver.com header.s=PPS06212021 header.b=ice31Q5u; spf=permerror, err=parse error for token &{10 18 %{ir}.%{v}.%{d}.spf.has.pphosted.com}: invalid domain name (domain: windriver.com, ip: 205.220.178.238, mailfrom: prvs=1650fcb189=rob.woolley@windriver.com) Received: from pps.filterd (m0250812.ppops.net [127.0.0.1]) by mx0a-0064b401.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 6691gLpk1094724 for ; Thu, 9 Jul 2026 02:03:51 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=windriver.com; h=cc:content-transfer-encoding:content-type:date:from :in-reply-to:message-id:mime-version:references:subject:to; s= PPS06212021; bh=AZTiky86Z+eBzZm0o308JQTYJsvZJg8zjjs4nNOyU6Y=; b= ice31Q5umIruDsHQqd0DDgcONg289o6bYlzaiEYo4/zT11QlC6VqFMLr/4Bwqs9V mxlJ/FhkjCUjmFBkfVGaZ3xq0fHr7Tpt50E69k1KqKiFOvLlCUnS4IcT3Vy8k/xq +MOf6sRQDVfkEspiqRHQKkWpSBeWi32hyT9BJWbg0O1Wx7vFyk0vUvOZNTMnaXnC yHY4BoCHvxXkuW7H6XaGxVHDWU7vmPTSgaYHe9QqBjAU7inkdpxvwgmcXHbm42Cz Szl2xELL5lbTRPTdVOWtwPyc8xaDg8zvFIXkDm9etxAJK4PhXgyKZoIPlREPat84 rN9yoTnIX2KYx/q9fmIH0w== Received: from ala-exchng02.corp.ad.wrs.com (ala-exchng02.wrs.com [128.224.246.37]) by mx0a-0064b401.pphosted.com (PPS) with ESMTPS id 4fa1h202nm-5 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT) for ; Thu, 09 Jul 2026 02:03:51 +0000 (GMT) Received: from ala-exchng01.corp.ad.wrs.com (10.11.224.121) by ALA-EXCHNG02.corp.ad.wrs.com (10.11.224.122) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.61; Wed, 8 Jul 2026 19:03:48 -0700 Received: from ala-lpggp3.wrs.com (10.11.232.110) by ala-exchng01.corp.ad.wrs.com (10.11.224.121) with Microsoft SMTP Server id 15.1.2507.61 via Frontend Transport; Wed, 8 Jul 2026 19:03:48 -0700 From: Rob Woolley Date: Wed, 8 Jul 2026 19:03:36 -0700 Subject: [PATCH v5 4/9] gitignore: Ignore temporary staging directory MIME-Version: 1.0 Message-ID: <20260708-add-pypi-v10-v5-4-7d5f457f4b9c@windriver.com> References: <20260708-add-pypi-v10-v5-0-7d5f457f4b9c@windriver.com> In-Reply-To: <20260708-add-pypi-v10-v5-0-7d5f457f4b9c@windriver.com> To: CC: Rob Woolley X-Mailer: b4 0.15.2 X-Authority-Analysis: v=2.4 cv=LbIMLDfi c=1 sm=1 tr=0 ts=6a4f0187 cx=c_pps a=Lg6ja3A245NiLSnFpY5YKQ==:117 a=Lg6ja3A245NiLSnFpY5YKQ==:17 a=IkcTkHD0fZMA:10 a=RAioF0-LDSMA:10 a=VkNPw1HP01LnGYTKEx00:22 a=bi6dqmuHe4P4UrxVR6um:22 a=fTW__CHxibyLmBMfj2wP:22 a=t7CeM3EgAAAA:8 a=kZMSq-wbSamDtaQhZQkA:9 a=QEXdDO2ut3YA:10 a=FdTzh2GWekK77mhwV6Dw:22 X-Proofpoint-Spam-Info: AW1haW4tMjYwNzA5MDAxNiBTYWx0ZWRfX8o48IdOaVYpm CM98KTjOimBo/7x8Le5u7gXnMiU5gbQ4VXGVig6YtWvoqiM64GmUm1NSQLon06X4eEMUwqDpBxJ mLnd3NIBVNUpi+9bJQJG1UxSMCyxCwLtH5dtYN+4dhxZ85blQEG8 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNzA5MDAxNiBTYWx0ZWRfX1JN5NRfbknJs UbyH/e0gDiO2lKBgWPeA1AwNMa/6ma5rTIJQgzyzYJWqvtfHaVW/iVbYUYaWVc8l2kvxdeJlJiu 2AWTscBSMQa5Lc7P4p3PjpR3yJDkAwwT7rcK5/j2IgICfBc5yF6Ra78Aptf5eJBq7YKVpJ8jFKQ G/MJNjPf/W0Z3npDIIsJgJVah/+Hx+KYXMH4maD0FlUOY9uKZwde3u9xQmb2LoaFAPCydbQDrSG 6mwoUG9eOqZVgzy6fQYYLHUSO6Uuier/HTtcHuvgRbSEYm1H4Uucca/6GZrEQPlqI2FHHFujw76 rDuG2FhNjV4WHbvuGQkNckssLVbfl/9R8522tKSJZf0hNOzBicCqbWpvYP0kFk2XHU6HBB983pW /kO5KuyYEW2qp6aviDaOqZFHbo8jbWUhKnMJcaugiyw8qav3yFVcLzs5j5F6+VXnvv94niQKBES uDU+S7rbc3tGIAX7IpA== X-Proofpoint-ORIG-GUID: vv4MHS5ytFFY-D6Djd8C2462GEM9eiV_ X-Proofpoint-GUID: vv4MHS5ytFFY-D6Djd8C2462GEM9eiV_ X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-07-08_05,2026-07-08_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 adultscore=0 phishscore=0 priorityscore=1501 malwarescore=0 clxscore=1015 lowpriorityscore=0 bulkscore=0 suspectscore=0 spamscore=0 impostorscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2607090016 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Thu, 09 Jul 2026 02:03:57 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/bitbake-devel/message/19825 This directory gets created automatically by package-bitbake-setup.py when packaging bitbake-setup for PyPI. It is a temporary staging directory and should not be added to git. Signed-off-by: Rob Woolley --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index a6a256b2c..23cb96881 100644 --- a/.gitignore +++ b/.gitignore @@ -17,3 +17,4 @@ lib/toaster/contrib/tts/backlog.txt lib/toaster/contrib/tts/log/* lib/toaster/contrib/tts/.cache/* lib/bb/tests/runqueue-tests/bitbake-cookerdaemon.log +packaging-workspace/ From patchwork Thu Jul 9 02:03:37 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Woolley, Rob" X-Patchwork-Id: 92063 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7476CC44508 for ; Thu, 9 Jul 2026 02:03:56 +0000 (UTC) Received: from mx0b-0064b401.pphosted.com (mx0b-0064b401.pphosted.com [205.220.178.238]) by mx.groups.io with SMTP id smtpd.msgproc02-g2.402.1783562632864076159 for ; Wed, 08 Jul 2026 19:03:53 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@windriver.com header.s=PPS06212021 header.b=nQPopu+C; spf=permerror, err=parse error for token &{10 18 %{ir}.%{v}.%{d}.spf.has.pphosted.com}: invalid domain name (domain: windriver.com, ip: 205.220.178.238, mailfrom: prvs=1650fcb189=rob.woolley@windriver.com) Received: from pps.filterd (m0250812.ppops.net [127.0.0.1]) by mx0a-0064b401.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 6691gLpl1094724 for ; Thu, 9 Jul 2026 02:03:51 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=windriver.com; h=cc:content-transfer-encoding:content-type:date:from :in-reply-to:message-id:mime-version:references:subject:to; s= PPS06212021; bh=oDv9X9weBwQUpIx/I9WQodEEmFSBZ+IFbGQOmzBlkWQ=; b= nQPopu+CtsYNgJOHso1i3jFusOcW5JObTzJ6etoUEfhHJ2TY2ZJU+bFQ47WMLZcn DxNysGEOFgjocw4Eukm4dErvJ4XxxV78HHjMX6wB95aC9pCndZEoVzBIZrU7oOMu rMlVDq0DySxy2w0Ew7jEXrdMh2el3pyKHGx3oKPeBXV5+Eq4xSon9Oa2aNprLOx8 voGmoaFTPH/ytNPVAWbBsuKrmqq/SWhektgOZBIwajIshoWuyU2GmGjeXAicrwsY 34i04VeS3OCj+Hv7vOcPd2W6K290DB9Qc8L5kVpaV8ZKQdoiYaPzYHWB/m733lOi ZWje9P+RB86hzrkGr1uuIA== Received: from ala-exchng02.corp.ad.wrs.com (ala-exchng02.wrs.com [128.224.246.37]) by mx0a-0064b401.pphosted.com (PPS) with ESMTPS id 4fa1h202nm-6 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT) for ; Thu, 09 Jul 2026 02:03:51 +0000 (GMT) Received: from ala-exchng01.corp.ad.wrs.com (10.11.224.121) by ALA-EXCHNG02.corp.ad.wrs.com (10.11.224.122) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.61; Wed, 8 Jul 2026 19:03:48 -0700 Received: from ala-lpggp3.wrs.com (10.11.232.110) by ala-exchng01.corp.ad.wrs.com (10.11.224.121) with Microsoft SMTP Server id 15.1.2507.61 via Frontend Transport; Wed, 8 Jul 2026 19:03:48 -0700 From: Rob Woolley Date: Wed, 8 Jul 2026 19:03:37 -0700 Subject: [PATCH v5 5/9] Add pyproject.toml and vendor.txt for vendoring MIME-Version: 1.0 Message-ID: <20260708-add-pypi-v10-v5-5-7d5f457f4b9c@windriver.com> References: <20260708-add-pypi-v10-v5-0-7d5f457f4b9c@windriver.com> In-Reply-To: <20260708-add-pypi-v10-v5-0-7d5f457f4b9c@windriver.com> To: CC: Rob Woolley X-Mailer: b4 0.15.2 X-Authority-Analysis: v=2.4 cv=LbIMLDfi c=1 sm=1 tr=0 ts=6a4f0187 cx=c_pps a=Lg6ja3A245NiLSnFpY5YKQ==:117 a=Lg6ja3A245NiLSnFpY5YKQ==:17 a=IkcTkHD0fZMA:10 a=RAioF0-LDSMA:10 a=VkNPw1HP01LnGYTKEx00:22 a=bi6dqmuHe4P4UrxVR6um:22 a=fTW__CHxibyLmBMfj2wP:22 a=-SJoDt46AAAA:20 a=t7CeM3EgAAAA:8 a=adcO8tCN0-mKZzeWj3YA:9 a=QEXdDO2ut3YA:10 a=FdTzh2GWekK77mhwV6Dw:22 a=bA3UWDv6hWIuX7UZL3qL:22 X-Proofpoint-Spam-Info: AW1haW4tMjYwNzA5MDAxNiBTYWx0ZWRfX3GrhGa2RxhvY AXfoA/4NhBXJGnye5LP4B0om3mrJGR3X0S3MmeS+eXsflTFpEhNJngBlcAfc69UP3REEtWmNWcV dM6A2ETVUJvrWn1qHktX99/xzAsoFHRdKRKxpe4X9DRJt9C4cIQL X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNzA5MDAxNiBTYWx0ZWRfXyKFuDAOJ6X6O tiyUtrM+nP2mRy6xBfb9AVxemuwxyYZRuQHkNdjbygsvohThDj84pzQnsuoXnfcNPtwgD+1P8D6 0bEiLtEoUASaVPrE0aTXNy7DilaRVDeollyZ0vta5Ln/byf7YQaJTCb0kfDCP1KZUtNtvp7ejf9 fFzP11NZyeUm5wp9tg4QBzEDwcL+dCUg99AafkRtES2sAVTqSR7afhbo+jOhklXIp/W9oxnNESP x0dscGQl7wwUEWnhtDTbAy4CYQ1+liQqAqErcq2AyqeoiQYlNyw0hCTvpJ38WGzOvPry/9FMLMs M1U1i14tnvt2Bfc4gPowuBPtES+i6X0MZH+ajPSWXQI5fi+0FW3PLccpCec9OfO/70w2Dvv1TRp sM+ht1uUI17e2OH27lMSvv4e+TCVXvC/Rh2GVb11fvUv7fMOs/iy2wgzn0xL5I6MHVKy4Q2l9v6 sFqJnJHBCg2qF7M41VQ== X-Proofpoint-ORIG-GUID: qScmYz1tNXGnF4ab2KntZ4dlAjAHhaI_ X-Proofpoint-GUID: qScmYz1tNXGnF4ab2KntZ4dlAjAHhaI_ X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-07-08_05,2026-07-08_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 adultscore=0 phishscore=0 priorityscore=1501 malwarescore=0 clxscore=1015 lowpriorityscore=0 bulkscore=0 suspectscore=0 spamscore=0 impostorscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2607090016 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Thu, 09 Jul 2026 02:03:56 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/bitbake-devel/message/19829 Used for updateing the vendorized modules with: vendoring sync . Signed-off-by: Rob Woolley --- pyproject.toml | 19 +++++++++++++++++++ vendor.txt | 4 ++++ 2 files changed, 23 insertions(+) diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 000000000..93508d92e --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,19 @@ +[build-system] +requires = [] +build-backend = "setuptools.build_meta" + +[project] +name = "bitbake" +version = "2.19.0" + +[tool.vendoring] +destination = "lib/bb/_vendor" +requirements = "vendor.txt" +namespace = "bb._vendor" +patches-dir = "vendor/patches" + +[tool.vendoring.license.directories] +ply = "vendor/licenses/ply/LICENSE" + +[tool.vendoring.license.fallback-urls] +ply = "https://raw.githubusercontent.com/dabeaz/ply/refs/heads/master/src/ply/lex.py" diff --git a/vendor.txt b/vendor.txt new file mode 100644 index 000000000..c60d43092 --- /dev/null +++ b/vendor.txt @@ -0,0 +1,4 @@ +beautifulsoup4==4.15.0 +ply==3.10 +progressbar==2.5 +simplediff==1.1 From patchwork Thu Jul 9 02:03:38 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: "Woolley, Rob" X-Patchwork-Id: 92067 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 91F33C4450A for ; Thu, 9 Jul 2026 02:03:56 +0000 (UTC) Received: from mx0b-0064b401.pphosted.com (mx0b-0064b401.pphosted.com [205.220.178.238]) by mx.groups.io with SMTP id smtpd.msgproc01-g2.407.1783562633438268658 for ; Wed, 08 Jul 2026 19:03:53 -0700 Authentication-Results: mx.groups.io; dkim=fail reason="dkim: body hash did not verify" header.i=@windriver.com header.s=PPS06212021 header.b=oWpGI/NF; spf=permerror, err=parse error for token &{10 18 %{ir}.%{v}.%{d}.spf.has.pphosted.com}: invalid domain name (domain: windriver.com, ip: 205.220.178.238, mailfrom: prvs=1650fcb189=rob.woolley@windriver.com) Received: from pps.filterd (m0250812.ppops.net [127.0.0.1]) by mx0a-0064b401.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 6691gLpm1094724 for ; Thu, 9 Jul 2026 02:03:52 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=windriver.com; h=cc:content-transfer-encoding:content-type:date:from :in-reply-to:message-id:mime-version:references:subject:to; s= PPS06212021; bh=zNSEpSOGEHGU4oOTZ385vZogRsZ7nok/kLf4+FSncvI=; b= oWpGI/NF/2/Dc8weL9QMLoPQY0110M5qnDG6/1LdLCMWj6HeWAX+d8RBsacDPIoO 31WyvnzRJRtKZaXw+4/Dhzz06wuXY36N2P/DAHsoGBM0Kz4IzNGgYxzpTMuygmxV 2l9Ea1xupnOPUArYx1LqapYK+ZlVJLRsi6jH+Rta2Z8nZ74WHoezDpjW7/1h7X35 OySZmJr2PBGFC/VPv2zfeHSc07zXYeq+cx+NdoWDRZnhveKM/yB5p0GwHXrTPV2N ojfaw95hCUJ21pS/1kDnUAf5Hwlog93v3f2t1AUoflNZ5G3NvD/vQbxacsXTXTb2 HLJlVpYV9XfmGvZLvxHE9g== Received: from ala-exchng02.corp.ad.wrs.com (ala-exchng02.wrs.com [128.224.246.37]) by mx0a-0064b401.pphosted.com (PPS) with ESMTPS id 4fa1h202nm-7 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT) for ; Thu, 09 Jul 2026 02:03:52 +0000 (GMT) Received: from ala-exchng01.corp.ad.wrs.com (10.11.224.121) by ALA-EXCHNG02.corp.ad.wrs.com (10.11.224.122) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.61; Wed, 8 Jul 2026 19:03:48 -0700 Received: from ala-lpggp3.wrs.com (10.11.232.110) by ala-exchng01.corp.ad.wrs.com (10.11.224.121) with Microsoft SMTP Server id 15.1.2507.61 via Frontend Transport; Wed, 8 Jul 2026 19:03:48 -0700 From: Rob Woolley Date: Wed, 8 Jul 2026 19:03:38 -0700 Subject: [PATCH v5 6/9] Add vendor patches MIME-Version: 1.0 Message-ID: <20260708-add-pypi-v10-v5-6-7d5f457f4b9c@windriver.com> References: <20260708-add-pypi-v10-v5-0-7d5f457f4b9c@windriver.com> In-Reply-To: <20260708-add-pypi-v10-v5-0-7d5f457f4b9c@windriver.com> To: CC: Rob Woolley X-Mailer: b4 0.15.2 X-Authority-Analysis: v=2.4 cv=LbIMLDfi c=1 sm=1 tr=0 ts=6a4f0188 cx=c_pps a=Lg6ja3A245NiLSnFpY5YKQ==:117 a=Lg6ja3A245NiLSnFpY5YKQ==:17 a=IkcTkHD0fZMA:10 a=RAioF0-LDSMA:10 a=VkNPw1HP01LnGYTKEx00:22 a=bi6dqmuHe4P4UrxVR6um:22 a=fTW__CHxibyLmBMfj2wP:22 a=t7CeM3EgAAAA:8 a=ag1SF4gXAAAA:8 a=QyXUC8HyAAAA:8 a=aRxQL1JOAAAA:8 a=P-IC7800AAAA:8 a=3-RhneuVAAAA:8 a=uvxgbxF22WCvZ4Xt2W0A:9 a=3ZKOabzyN94A:10 a=QEXdDO2ut3YA:10 a=FdTzh2GWekK77mhwV6Dw:22 a=Yupwre4RP9_Eg_Bd0iYG:22 a=lBRdisTmIr2YKkuu8atg:22 a=d3PnA9EDa4IxuAV0gXij:22 a=VLVLkjT_5ZicWzSuYqSo:22 X-Proofpoint-Spam-Info: AW1haW4tMjYwNzA5MDAxNiBTYWx0ZWRfX9PqCbEVF1rzb pmOGq8Vznljy4gRQunIzBbRRooLk2gFuqPjz71BKizkh3Jr1qiys6cm+5NFUj962Ltk9atnq8ta rxZI9pNfzjoBzL6RyIBQLEcqg9vpJGNwme0bSFI0rVZgWtbXFGyb X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNzA5MDAxNiBTYWx0ZWRfX27l0lY2ddj8n PpgdD/PF7iEKYP9fiVjplW2aJFiOhVvP2I22AUAc+ePon8hCxnYfnsaT6hDLnli1te2/9mZRTcE 1WzAThdU4aGOj9HpYaJ6+7NErgzvB5Aphld/FbuCbWopfaFYXEEqJx2KkZGiQNVb0Bn3xumZlEU SiJEFLNVFxM6h5EcutHemi2dshDSxbtNGFHR5ilFBg9iOPTKRWaYGG6HHv1AVYBOv13gtBIaSkr 4eSzuRadCrUSCTQeWl4y8gd5DsMX4pgEdYkQ43uZeHLJM6QqCzuFOX+6kDl+hRQIK0vO5FT+1el X92vUlsvZ4uBXiqJFz4NPv1oBEt1AUCFU23HDKGdp1XDQ8DyUzolYEyXN1FMKaYvVMkytjqx4o8 lONWU/SqDCBcmOnH7LFjxbWaSAQoaF7BFuAhokaTW/5xGtgxeONq+OqfEaHvu8l7VaEnP2EtIkO FFipRwMvBFXj93EzmGQ== X-Proofpoint-ORIG-GUID: s61xHsBpux-QWvjXsnwM5-BK5BWgnwXC X-Proofpoint-GUID: s61xHsBpux-QWvjXsnwM5-BK5BWgnwXC X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-07-08_05,2026-07-08_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 adultscore=0 phishscore=0 priorityscore=1501 malwarescore=0 clxscore=1015 lowpriorityscore=0 bulkscore=0 suspectscore=0 spamscore=0 impostorscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2607090016 X-MIME-Autoconverted: from 8bit to quoted-printable by mx0a-0064b401.pphosted.com id 6691gLpm1094724 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Thu, 09 Jul 2026 02:03:56 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/bitbake-devel/message/19830 Signed-off-by: Rob Woolley --- vendor/licenses/ply/LICENSE | 32 ++++++ .../bs4-0010-lib-bs4-Avoid-soupsieve-warning.patch | 40 +++++++ vendor/patches/bs4-remove-double-imports.patch | 23 ++++ ...lib-implement-basic-task-progress-support.patch | 125 +++++++++++++++++++++ ...-initial-pass-of-SPDX-license-headers-to-.patch | 79 +++++++++++++ ...gressbar-accept-value-over-initial-maxval.patch | 54 +++++++++ ...-Add-self._fd_console-to-use-for-self._ha.patch | 53 +++++++++ ...ar-Make-bars-show-correctly-with-maxval-0.patch | 31 +++++ ...-knotty-Allow-mixing-log-messages-and-pro.patch | 31 +++++ 9 files changed, 468 insertions(+) diff --git a/vendor/licenses/ply/LICENSE b/vendor/licenses/ply/LICENSE new file mode 100644 index 000000000..d050b2ef9 --- /dev/null +++ b/vendor/licenses/ply/LICENSE @@ -0,0 +1,32 @@ +# ----------------------------------------------------------------------------- +# ply +# +# Copyright (C) 2001-2018 +# David M. Beazley (Dabeaz LLC) +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# * Neither the name of the David Beazley or Dabeaz LLC may be used to +# endorse or promote products derived from this software without +# specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# ----------------------------------------------------------------------------- diff --git a/vendor/patches/bs4-0010-lib-bs4-Avoid-soupsieve-warning.patch b/vendor/patches/bs4-0010-lib-bs4-Avoid-soupsieve-warning.patch new file mode 100644 index 000000000..e352473e8 --- /dev/null +++ b/vendor/patches/bs4-0010-lib-bs4-Avoid-soupsieve-warning.patch @@ -0,0 +1,40 @@ +From 8e444cd9913d1ee0672b5583e263e5927c3221df Mon Sep 17 00:00:00 2001 +From: Richard Purdie +Date: Fri, 31 May 2024 13:09:44 +0100 +Subject: [PATCH 10/11] lib/bs4: Avoid soupsieve warning + +Signed-off-by: Richard Purdie +--- + lib/bs4/css.py | 10 ++-------- + 1 file changed, 2 insertions(+), 8 deletions(-) + +diff --git a/lib/bb/_vendor/bs4/css.py b/lib/bb/_vendor/bs4/css.py +index 245ac6010..cd1fd2df8 100644 +--- a/lib/bb/_vendor/bs4/css.py ++++ b/lib/bb/_vendor/bs4/css.py +@@ -24,23 +24,14 @@ + Optional, + TYPE_CHECKING, + ) +-import warnings + from bs4._typing import _NamespaceMapping + + if TYPE_CHECKING: +- from soupsieve import SoupSieve + from bs4 import element + from bs4.element import ResultSet, Tag + +-soupsieve: Optional[ModuleType] +-try: +- import soupsieve +-except ImportError: +- soupsieve = None +- warnings.warn( +- "The soupsieve package is not installed. CSS selectors cannot be used." +- ) +- ++# We don't use soupsieve ++soupsieve = None + + class CSS(object): + """A proxy object against the ``soupsieve`` library, to simplify its diff --git a/vendor/patches/bs4-remove-double-imports.patch b/vendor/patches/bs4-remove-double-imports.patch new file mode 100644 index 000000000..2bbfa9373 --- /dev/null +++ b/vendor/patches/bs4-remove-double-imports.patch @@ -0,0 +1,23 @@ +commit 741db6719efca5aa9ef2c15e60cdd624e4aa1a8d +Author: Michael Estner +Date: Tue Feb 25 19:34:25 2025 +0100 + + lib: Remove double imports + + * Remove double imports mentioned by pylint + + Signed-off-by: Michael Estner + Signed-off-by: Richard Purdie + +diff --git a/lib/bb/_vendor/bs4/__init__.py b/lib/bb/_vendor/bs4/__init__.py +index d8ad5e1dc..725203d94 100644 +--- a/lib/bb/_vendor/bs4/__init__.py ++++ b/lib/bb/_vendor/bs4/__init__.py +@@ -1173,7 +1173,5 @@ + + # If this file is run as a script, act as an HTML pretty-printer. + if __name__ == "__main__": +- import sys +- + soup = BeautifulSoup(sys.stdin) + print((soup.prettify())) diff --git a/vendor/patches/progressbar-0001-lib-implement-basic-task-progress-support.patch b/vendor/patches/progressbar-0001-lib-implement-basic-task-progress-support.patch new file mode 100644 index 000000000..97dd5ca97 --- /dev/null +++ b/vendor/patches/progressbar-0001-lib-implement-basic-task-progress-support.patch @@ -0,0 +1,125 @@ +From 0d275fc5b6531957a6189069b04074065bb718a0 Mon Sep 17 00:00:00 2001 +From: Paul Eggleton +Date: Thu, 23 Jun 2016 22:59:05 +1200 +Subject: [PATCH 1/6] lib: implement basic task progress support + +For long-running tasks where we have some output from the task that +gives us some idea of the progress of the task (such as a percentage +complete), provide the means to scrape the output for that progress +information and show it to the user in the default knotty terminal +output in the form of a progress bar. This is implemented using a new +TaskProgress event as well as some code we can insert to do output +scanning/filtering. + +Any task can fire TaskProgress events; however, if you have a shell task +whose output you wish to scan for progress information, you just need to +set the "progress" varflag on the task. This can be set to: + * "percent" to just look for a number followed by a % sign + * "percent:" to specify your own regex matching a percentage + value (must have a single group which matches the percentage number) + * "outof:" to look for the specified regex matching x out of y + items completed (must have two groups - first group needs to be x, + second y). +We can potentially extend this in future but this should be a good +start. + +Part of the implementation for [YOCTO #5383]. + +Signed-off-by: Paul Eggleton +Signed-off-by: Richard Purdie +--- + lib/progressbar/progressbar.py | 16 +++++++++++---- + lib/progressbar/widgets.py | 36 ++++++++++++++++++++++++++++++++++ + 2 files changed, 48 insertions(+), 4 deletions(-) + +diff --git a/lib/bb/_vendor/progressbar/progressbar.py b/lib/bb/_vendor/progressbar/progressbar.py +index 0b9dcf763..2873ad6ca 100644 +--- a/lib/bb/_vendor/progressbar/progressbar.py ++++ b/lib/bb/_vendor/progressbar/progressbar.py +@@ -3,6 +3,8 @@ + # progressbar - Text progress bar library for Python. + # Copyright (c) 2005 Nilton Volpato + # ++# (With some small changes after importing into BitBake) ++# + # This library is free software; you can redistribute it and/or + # modify it under the terms of the GNU Lesser General Public + # License as published by the Free Software Foundation; either +@@ -261,12 +263,14 @@ class ProgressBar(object): + now = time.time() + self.seconds_elapsed = now - self.start_time + self.next_update = self.currval + self.update_interval +- self.fd.write(self._format_line() + '\r') ++ output = self._format_line() ++ self.fd.write(output + '\r') + self.fd.flush() + self.last_update_time = now ++ return output + + +- def start(self): ++ def start(self, update=True): + """Starts measuring time, and prints the bar at 0%. + + It returns self so you can use it like this: +@@ -289,8 +293,12 @@ class ProgressBar(object): + self.update_interval = self.maxval / self.num_intervals + + +- self.start_time = self.last_update_time = time.time() +- self.update(0) ++ self.start_time = time.time() ++ if update: ++ self.last_update_time = self.start_time ++ self.update(0) ++ else: ++ self.last_update_time = 0 + + return self + +diff --git a/lib/bb/_vendor/progressbar/widgets.py b/lib/bb/_vendor/progressbar/widgets.py +index 6434ad559..77285ca7a 100644 +--- a/lib/bb/_vendor/progressbar/widgets.py ++++ b/lib/bb/_vendor/progressbar/widgets.py +@@ -353,3 +353,39 @@ class BouncingBar(Bar): + if not self.fill_left: rpad, lpad = lpad, rpad + + return '%s%s%s%s%s' % (left, lpad, marker, rpad, right) ++ ++ ++class BouncingSlider(Bar): ++ """ ++ A slider that bounces back and forth in response to update() calls ++ without reference to the actual value. Based on a combination of ++ BouncingBar from a newer version of this module and RotatingMarker. ++ """ ++ def __init__(self, marker='<=>'): ++ self.curmark = -1 ++ self.forward = True ++ Bar.__init__(self, marker=marker) ++ def update(self, pbar, width): ++ left, marker, right = (format_updatable(i, pbar) for i in ++ (self.left, self.marker, self.right)) ++ ++ width -= len(left) + len(right) ++ if width < 0: ++ return '' ++ ++ if pbar.finished: return '%s%s%s' % (left, width * '=', right) ++ ++ self.curmark = self.curmark + 1 ++ position = int(self.curmark % (width * 2 - 1)) ++ if position + len(marker) > width: ++ self.forward = not self.forward ++ self.curmark = 1 ++ position = 1 ++ lpad = ' ' * (position - 1) ++ rpad = ' ' * (width - len(marker) - len(lpad)) ++ ++ if not self.forward: ++ temp = lpad ++ lpad = rpad ++ rpad = temp ++ return '%s%s%s%s%s' % (left, lpad, marker, rpad, right) +-- +2.49.0 diff --git a/vendor/patches/progressbar-0002-bitbake-Add-initial-pass-of-SPDX-license-headers-to-.patch b/vendor/patches/progressbar-0002-bitbake-Add-initial-pass-of-SPDX-license-headers-to-.patch new file mode 100644 index 000000000..fd8ccaa39 --- /dev/null +++ b/vendor/patches/progressbar-0002-bitbake-Add-initial-pass-of-SPDX-license-headers-to-.patch @@ -0,0 +1,79 @@ +From ff237c33337f4da2ca06c3a2c49699bc26608a6b Mon Sep 17 00:00:00 2001 +From: Richard Purdie +Date: Tue, 30 Apr 2019 11:05:26 +0100 +Subject: [PATCH 2/6] bitbake: Add initial pass of SPDX license headers to + source code + +This adds the SPDX-License-Identifier license headers to the majority of +our source files to make it clearer exactly which license files are under. + +The bulk of the files are under GPL v2.0 with one found to be under V2.0 +or later, some under MIT and some have dual license. There are some files +which are potentially harder to classify where we've imported upstream code +and those can be handled specifically in later commits. + +The COPYING file is replaced with LICENSE.X files which contain the full +license texts. + +Signed-off-by: Richard Purdie +--- + lib/progressbar/__init__.py | 2 ++ + lib/progressbar/compat.py | 2 ++ + lib/progressbar/progressbar.py | 2 ++ + lib/progressbar/widgets.py | 2 ++ + 4 files changed, 8 insertions(+) + +diff --git a/lib/bb/_vendor/progressbar/__init__.py b/lib/bb/_vendor/progressbar/__init__.py +index fbab744ee..c545a6275 100644 +--- a/lib/bb/_vendor/progressbar/__init__.py ++++ b/lib/bb/_vendor/progressbar/__init__.py +@@ -4,6 +4,8 @@ + # progressbar - Text progress bar library for Python. + # Copyright (c) 2005 Nilton Volpato + # ++# SPDX-License-Identifier: LGPL-2.1-or-later OR BSD-3-Clause-Clear ++# + # This library is free software; you can redistribute it and/or + # modify it under the terms of the GNU Lesser General Public + # License as published by the Free Software Foundation; either +diff --git a/lib/bb/_vendor/progressbar/compat.py b/lib/bb/_vendor/progressbar/compat.py +index a39f4a1f4..9804e0b51 100644 +--- a/lib/bb/_vendor/progressbar/compat.py ++++ b/lib/bb/_vendor/progressbar/compat.py +@@ -3,6 +3,8 @@ + # progressbar - Text progress bar library for Python. + # Copyright (c) 2005 Nilton Volpato + # ++# SPDX-License-Identifier: LGPL-2.1-or-later OR BSD-3-Clause-Clear ++# + # This library is free software; you can redistribute it and/or + # modify it under the terms of the GNU Lesser General Public + # License as published by the Free Software Foundation; either +diff --git a/lib/bb/_vendor/progressbar/progressbar.py b/lib/bb/_vendor/progressbar/progressbar.py +index 2873ad6ca..e2b6ba108 100644 +--- a/lib/bb/_vendor/progressbar/progressbar.py ++++ b/lib/bb/_vendor/progressbar/progressbar.py +@@ -5,6 +5,8 @@ + # + # (With some small changes after importing into BitBake) + # ++# SPDX-License-Identifier: LGPL-2.1-or-later OR BSD-3-Clause-Clear ++# + # This library is free software; you can redistribute it and/or + # modify it under the terms of the GNU Lesser General Public + # License as published by the Free Software Foundation; either +diff --git a/lib/bb/_vendor/progressbar/widgets.py b/lib/bb/_vendor/progressbar/widgets.py +index 77285ca7a..0772aa536 100644 +--- a/lib/bb/_vendor/progressbar/widgets.py ++++ b/lib/bb/_vendor/progressbar/widgets.py +@@ -3,6 +3,8 @@ + # progressbar - Text progress bar library for Python. + # Copyright (c) 2005 Nilton Volpato + # ++# SPDX-License-Identifier: LGPL-2.1-or-later OR BSD-3-Clause-Clear ++# + # This library is free software; you can redistribute it and/or + # modify it under the terms of the GNU Lesser General Public + # License as published by the Free Software Foundation; either +-- +2.49.0 diff --git a/vendor/patches/progressbar-0003-bitbake-progressbar-accept-value-over-initial-maxval.patch b/vendor/patches/progressbar-0003-bitbake-progressbar-accept-value-over-initial-maxval.patch new file mode 100644 index 000000000..aca9e0edf --- /dev/null +++ b/vendor/patches/progressbar-0003-bitbake-progressbar-accept-value-over-initial-maxval.patch @@ -0,0 +1,54 @@ +From 7cea7f7a87da041fc1ad370c5c3d15aabad3a0d4 Mon Sep 17 00:00:00 2001 +From: Enguerrand de Ribaucourt +Date: Thu, 22 Feb 2024 16:21:53 +0100 +Subject: [PATCH 3/6] bitbake: progressbar: accept value over initial maxval + +There is a very rare case where the maxval is improperly computed +initially for cache loading progress, and the value will go over. + +Explanation from bitbake/lib/bb/cache.py:736 in MulticonfigCache:__init__:progress() + # we might have calculated incorrect total size because a file + # might've been written out just after we checked its size + +In that case, progressbar will receive a value over the initial maxval. +This results in a ValueError stack trace as well as bitbake returning 1. + Traceback (most recent call last): + File ".../poky/bitbake/lib/bb/ui/knotty.py", line 736, in main + cacheprogress.update(event.current) + File ".../poky/bitbake/lib/progressbar/progressbar.py", line 256, in update + raise ValueError('Value out of range') + ValueError: Value out of range + +This fix mirrors the behavior of MulticonfigCache and accepts the new +value as the new maxval. This is also what the percentage printout +is doing in bitbake/lib/progressbar/progressbar.py:191 in ProgressBar:percentage() + +I encountered this issue randomly while working on a project with +VSCode saving files while commands where fired. + +Note: This file is a fork from python-progressbar. It hasn't been +refreshed in 8 years. We did only two commits, 5 years ago with minor +modifications. This new change is also not how the upstream project is +behaving. + +Signed-off-by: Enguerrand de Ribaucourt +Signed-off-by: Richard Purdie +--- + lib/progressbar/progressbar.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/lib/bb/_vendor/progressbar/progressbar.py b/lib/bb/_vendor/progressbar/progressbar.py +index e2b6ba108..d4da10ab7 100644 +--- a/lib/bb/_vendor/progressbar/progressbar.py ++++ b/lib/bb/_vendor/progressbar/progressbar.py +@@ -253,7 +253,7 @@ class ProgressBar(object): + if (self.maxval is not widgets.UnknownLength + and not 0 <= value <= self.maxval): + +- raise ValueError('Value out of range') ++ self.maxval = value + + self.currval = value + +-- +2.49.0 diff --git a/vendor/patches/progressbar-0004-progressbar-Add-self._fd_console-to-use-for-self._ha.patch b/vendor/patches/progressbar-0004-progressbar-Add-self._fd_console-to-use-for-self._ha.patch new file mode 100644 index 000000000..1bf0718f0 --- /dev/null +++ b/vendor/patches/progressbar-0004-progressbar-Add-self._fd_console-to-use-for-self._ha.patch @@ -0,0 +1,53 @@ +From f8c76eb89d52b1c28407f0b52dfe4318faa47cd2 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Benjamin=20Sz=C5=91ke?= +Date: Sat, 25 Jan 2025 13:27:49 +0100 +Subject: [PATCH 4/6] progressbar: Add self._fd_console to use for + self._handle_resize() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Introduce self._fd_console as a dedicated attribute of self._handle_resize(). + +Signed-off-by: Benjamin Szőke +Signed-off-by: Mathieu Dubois-Briand +--- + lib/progressbar/progressbar.py | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +diff --git a/lib/bb/_vendor/progressbar/progressbar.py b/lib/bb/_vendor/progressbar/progressbar.py +index d4da10ab7..eccc45849 100644 +--- a/lib/bb/_vendor/progressbar/progressbar.py ++++ b/lib/bb/_vendor/progressbar/progressbar.py +@@ -110,12 +110,20 @@ class ProgressBar(object): + self.widgets = widgets + self.fd = fd if fd is not None else sys.stderr + self.left_justify = left_justify ++ self._fd_console = None + + self.signal_set = False + if term_width is not None: + self.term_width = term_width + else: + try: ++ # Check if given file descriptor is resizable for example belong ++ # to a terminal/console as STDOUT or STDERR. If file descriptor ++ # is resizable, let's allow to use for self._handle_resize() ++ # in a dedicated self._fd_console in order to be able to set ++ # temporarily/permanently self.fd to any StringIO or other ++ # file descriptor later. ++ self._fd_console = fd + self._handle_resize() + signal.signal(signal.SIGWINCH, self._handle_resize) + self.signal_set = True +@@ -182,7 +189,7 @@ class ProgressBar(object): + def _handle_resize(self, signum=None, frame=None): + """Tries to catch resize signals sent from the terminal.""" + +- h, w = array('h', ioctl(self.fd, termios.TIOCGWINSZ, '\0' * 8))[:2] ++ h, w = array('h', ioctl(self._fd_console, termios.TIOCGWINSZ, '\0' * 8))[:2] + self.term_width = w + + +-- +2.49.0 diff --git a/vendor/patches/progressbar-0005-progressbar-Make-bars-show-correctly-with-maxval-0.patch b/vendor/patches/progressbar-0005-progressbar-Make-bars-show-correctly-with-maxval-0.patch new file mode 100644 index 000000000..c8592355b --- /dev/null +++ b/vendor/patches/progressbar-0005-progressbar-Make-bars-show-correctly-with-maxval-0.patch @@ -0,0 +1,31 @@ +From 736b5b33a5d656a6d5cb6a3180ab529832f77b16 Mon Sep 17 00:00:00 2001 +From: Peter Kjellerstedt +Date: Sat, 11 Oct 2025 06:23:10 +0200 +Subject: [PATCH 5/6] progressbar: Make bars show correctly with maxval == 0 + +While it can be argued how useful a progressbar created with 0 as +maximum value is, it should still show two states, started (empty) and +finished (full). Setting the maxval to _DEFAULT_MAXVAL instead will +accomplish this. + +Signed-off-by: Peter Kjellerstedt +Signed-off-by: Mathieu Dubois-Briand +--- + lib/progressbar/progressbar.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/lib/bb/_vendor/progressbar/progressbar.py b/lib/bb/_vendor/progressbar/progressbar.py +index eccc45849..a8e2dc09c 100644 +--- a/lib/bb/_vendor/progressbar/progressbar.py ++++ b/lib/bb/_vendor/progressbar/progressbar.py +@@ -106,7 +106,7 @@ class ProgressBar(object): + if widgets is None: + widgets = list(self._DEFAULT_WIDGETS) + +- self.maxval = maxval ++ self.maxval = maxval if maxval != 0 else self._DEFAULT_MAXVAL + self.widgets = widgets + self.fd = fd if fd is not None else sys.stderr + self.left_justify = left_justify +-- +2.49.0 diff --git a/vendor/patches/progressbar-0006-progressbar-knotty-Allow-mixing-log-messages-and-pro.patch b/vendor/patches/progressbar-0006-progressbar-knotty-Allow-mixing-log-messages-and-pro.patch new file mode 100644 index 000000000..96868c76f --- /dev/null +++ b/vendor/patches/progressbar-0006-progressbar-knotty-Allow-mixing-log-messages-and-pro.patch @@ -0,0 +1,31 @@ +From e827db50d8f61f0d04c9bd0753c05aeb1ed0715f Mon Sep 17 00:00:00 2001 +From: Richard Purdie +Date: Tue, 24 Mar 2026 21:37:25 +0000 +Subject: [PATCH 6/6] progressbar/knotty: Allow mixing log messages and + progress bars + +If we try and print a log message in the middle of progress bar, the display +can be corrupted. Add a clear() method to progress bars allowing them to be +removed for the log message, then reprinted using update(). + +Signed-off-by: Richard Purdie +--- + lib/progressbar/progressbar.py | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/lib/bb/_vendor/progressbar/progressbar.py b/lib/bb/_vendor/progressbar/progressbar.py +index a8e2dc09c..1562774ba 100644 +--- a/lib/bb/_vendor/progressbar/progressbar.py ++++ b/lib/bb/_vendor/progressbar/progressbar.py +@@ -278,6 +278,9 @@ class ProgressBar(object): + self.last_update_time = now + return output + ++ def clear(self): ++ self.fd.write(" " * self.term_width + '\r') ++ self.fd.flush() + + def start(self, update=True): + """Starts measuring time, and prints the bar at 0%. +-- +2.49.0 From patchwork Thu Jul 9 02:03:39 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: "Woolley, Rob" X-Patchwork-Id: 94546 Return-Path: Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id C04C5C4450C for ; Thu, 9 Jul 2026 02:03:57 +0000 (UTC) Received: from mx0b-0064b401.pphosted.com (mx0b-0064b401.pphosted.com [205.220.178.238]) by mx.groups.io with SMTP id smtpd.msgproc02-g2.403.1783562635797634896 for ; Wed, 08 Jul 2026 19:03:56 -0700 Authentication-Results: mx.groups.io; dkim=fail reason="dkim: body hash did not verify" header.i=@windriver.com header.s=PPS06212021 header.b=YRgfuwKS; spf=permerror, err=parse error for token &{10 18 %{ir}.%{v}.%{d}.spf.has.pphosted.com}: invalid domain name (domain: windriver.com, ip: 205.220.178.238, mailfrom: prvs=1650fcb189=rob.woolley@windriver.com) Received: from pps.filterd (m0250812.ppops.net [127.0.0.1]) by mx0a-0064b401.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 6691gLpo1094724 for ; Thu, 9 Jul 2026 02:03:54 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=windriver.com; h=cc:content-transfer-encoding:content-type:date:from :in-reply-to:message-id:mime-version:references:subject:to; s= PPS06212021; bh=Yp4PteAFp2SMk7uUB2DoCl855qSVUxHdH0b9/yTEcQU=; b= YRgfuwKSDfHHvnh0ft76o1k2usnFpENpXKfDyqrfywlUQE8Gn9hZuyTL6t8jNbLt 8U5+rOTXVNHENotOnzBEAXYgwe2vpPqjaPQI504Os01h3DfEvZOV6lHzjOS0UfTc kV3zB3l7IxwQzBv1xssi4LF/v7ddIxJyApUQObemuWzhJXGxPsVIPd+Gax/lnzCu 5ewuXxA/0/+uLJpUJrwvqPwouI+ief4RdOvQU+8CpCFaZihMwnqqDximjHsf17nI Tf6dlUfi67F5ySTRvzt2KDR/h/KZScOiBsT990iV92faxalfai3rwSIWjS5lxZnl LdemmnV1+p8NMtVP2gjwYg== Received: from ala-exchng02.corp.ad.wrs.com (ala-exchng02.wrs.com [128.224.246.37]) by mx0a-0064b401.pphosted.com (PPS) with ESMTPS id 4fa1h202nm-9 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT) for ; Thu, 09 Jul 2026 02:03:53 +0000 (GMT) Received: from ala-exchng01.corp.ad.wrs.com (10.11.224.121) by ALA-EXCHNG02.corp.ad.wrs.com (10.11.224.122) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.61; Wed, 8 Jul 2026 19:03:49 -0700 Received: from ala-lpggp3.wrs.com (10.11.232.110) by ala-exchng01.corp.ad.wrs.com (10.11.224.121) with Microsoft SMTP Server id 15.1.2507.61 via Frontend Transport; Wed, 8 Jul 2026 19:03:48 -0700 From: Rob Woolley Date: Wed, 8 Jul 2026 19:03:39 -0700 Subject: [PATCH v5 7/9] Update vendorized modules MIME-Version: 1.0 Message-ID: <20260708-add-pypi-v10-v5-7-7d5f457f4b9c@windriver.com> References: <20260708-add-pypi-v10-v5-0-7d5f457f4b9c@windriver.com> In-Reply-To: <20260708-add-pypi-v10-v5-0-7d5f457f4b9c@windriver.com> To: CC: Rob Woolley X-Mailer: b4 0.15.2 X-Authority-Analysis: v=2.4 cv=LbIMLDfi c=1 sm=1 tr=0 ts=6a4f0189 cx=c_pps a=Lg6ja3A245NiLSnFpY5YKQ==:117 a=Lg6ja3A245NiLSnFpY5YKQ==:17 a=IkcTkHD0fZMA:10 a=RAioF0-LDSMA:10 a=VkNPw1HP01LnGYTKEx00:22 a=bi6dqmuHe4P4UrxVR6um:22 a=fTW__CHxibyLmBMfj2wP:22 a=CckQENj0AAAA:8 a=danhDmx_AAAA:8 a=NEAV23lmAAAA:8 a=ekYV4lpRAAAA:8 a=48Kcd2OYAAAA:8 a=SSmOFEACAAAA:8 a=0x2vhHYrAAAA:8 a=8AHkEIZyAAAA:8 a=IZVGuq1iAAAA:8 a=mDV3o1hIAAAA:8 a=t7CeM3EgAAAA:8 a=bo08yYyjAAAA:8 a=HxmDso_oAAAA:8 a=LZ1EdHRVAAAA:8 a=WP5zsaevAAAA:8 a=pGLkceISAAAA:8 a=K7ZyPv_3mASGp8tg8XoA:9 a=qcg49hLlgF0N60+LroqrWnV/Vu4=:19 a=fTTRyY75f2tJ7nP0:21 a=L03L2QfmqWoA:10 a=lqcHg5cX4UMA:10 a=3ZKOabzyN94A:10 a=QEXdDO2ut3YA:10 a=O8hF6Hzn-FEA:10 a=ImwWUX5h3JJ3gRE9moBe:22 a=mrCxpU6zTNQDHnudu_9Q:22 a=SDE4kRAlhdREaT3mAHa9:22 a=jKTDQKFe_9NOjXLEHhtL:22 a=qnRFykaDRnJ3NeEHDCy2:22 a=FdTzh2GWekK77mhwV6Dw:22 a=sJLr6QBoMFAj2pSMC3bB:22 a=wVk_OTPmZRE1ccVI5G2I:22 a=8WfeQlEPN7eFB_yiPD7s:22 a=t8Kx07QrZZTALmIZmm-o:22 a=5VJXQO18lHU1uJw8Rqww:22 X-Proofpoint-Spam-Info: AW1haW4tMjYwNzA5MDAxNiBTYWx0ZWRfXxulymXa4vzzc zNlo2q9JXhH5fXsxw1Fac1SNrfDOMBX1x1SLFCcnge2UkqWmGYbTm7JOScPTrx7iOiz3yGRLD9F SoqIQ1ffqO4iZqbw9ts07Mghl1kB3KddgG9sHO/7U6QlDrivVa9j X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNzA5MDAxNiBTYWx0ZWRfX2Xjv7CV9bW+3 qw7O+ahldskMIORnwy3gnB9HDnWlAznWyYChtFhjPHjcVOLUqfjkoReoJsW8aI8Nxg5F6aNS8Wm dW2o1KAhNLU5GkuUOEf8W3hCVnIlNtmeMmc8xgePpu4UIy7Tyd9bY+adYRouzTcSxBt4U2LYKN2 /osE4oXBVumXBycXVm5S4rin63pSaPKUEjt+Kl83assUlKfkgLp3YhUNdLjCRUzWuErJ5bnDZTt L2N61S50LjdqeBCFPKdRLP34TZMWNFkWhOwcR0Nu1yLDqtRG9g2JENvu41hUmVnn4PJUmFQt8I2 M7DOGqCG7+a6yl/iz5kcZtAQ2javJdpUz2iLGec0tV4aHn8lZt4+20UPdtM30QjH2ZpDDpFO1Cs I7AEUbYTLHIJHUwRq9eRnq5cUJkJtojd1A+5upoz7FvrBYtT8nisSDhqeMJnqNSP76Tc69XE6be RZ/tL7ZhMciGlXrpn0g== X-Proofpoint-ORIG-GUID: CIs5QK3lHXKSyhmzUc2DMTGF0-Isrvgt X-Proofpoint-GUID: CIs5QK3lHXKSyhmzUc2DMTGF0-Isrvgt X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-07-08_05,2026-07-08_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 adultscore=0 phishscore=0 priorityscore=1501 malwarescore=0 clxscore=1015 lowpriorityscore=0 bulkscore=0 suspectscore=0 spamscore=0 impostorscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2607090016 X-MIME-Autoconverted: from 8bit to quoted-printable by mx0a-0064b401.pphosted.com id 6691gLpo1094724 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Thu, 09 Jul 2026 02:03:57 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/bitbake-devel/message/19832 This was automated with "vendoring sync .". Signed-off-by: Rob Woolley --- lib/bb/_vendor/__init__.py | 18 - .../{bs4/LICENSE => beautifulsoup4.LICENSE} | 0 lib/bb/_vendor/bs4/AUTHORS | 49 - lib/bb/_vendor/bs4/CHANGELOG | 1839 ----------- lib/bb/_vendor/bs4/__init__.py | 856 +++-- lib/bb/_vendor/bs4/_deprecation.py | 80 + lib/bb/_vendor/bs4/_typing.py | 205 ++ lib/bb/_vendor/bs4/_warnings.py | 98 + lib/bb/_vendor/bs4/builder/__init__.py | 828 +++-- lib/bb/_vendor/bs4/builder/_html5lib.py | 592 ++-- lib/bb/_vendor/bs4/builder/_htmlparser.py | 426 ++- lib/bb/_vendor/bs4/builder/_lxml.py | 387 ++- lib/bb/_vendor/bs4/css.py | 268 +- lib/bb/_vendor/bs4/dammit.py | 1622 +++++---- lib/bb/_vendor/bs4/diagnose.py | 169 +- lib/bb/_vendor/bs4/element.py | 3494 +++++++++++++------- lib/bb/_vendor/bs4/exceptions.py | 28 + lib/bb/_vendor/bs4/filter.py | 764 +++++ lib/bb/_vendor/bs4/formatter.py | 211 +- lib/bb/_vendor/bs4/py.typed | 0 lib/bb/_vendor/ply.pyi | 1 + lib/bb/_vendor/ply/__init__.py | 1 + lib/bb/_vendor/ply/cpp.py | 918 +++++ lib/bb/_vendor/ply/ctokens.py | 133 + lib/bb/_vendor/ply/lex.py | 845 ++--- lib/bb/_vendor/ply/yacc.py | 2231 +++++++------ lib/bb/_vendor/ply/ygen.py | 74 + lib/bb/_vendor/progressbar.pyi | 1 + lib/bb/_vendor/progressbar/__init__.py | 4 +- lib/bb/_vendor/progressbar/progressbar.py | 21 +- lib/bb/_vendor/progressbar/widgets.py | 14 +- lib/bb/_vendor/simplediff.pyi | 1 + lib/bb/_vendor/simplediff/__init__.py | 2 +- 33 files changed, 9570 insertions(+), 6610 deletions(-) diff --git a/lib/bb/_vendor/__init__.py b/lib/bb/_vendor/__init__.py deleted file mode 100644 index 3c054dc32..000000000 --- a/lib/bb/_vendor/__init__.py +++ /dev/null @@ -1,18 +0,0 @@ -# -# Copyright BitBake Contributors -# -# SPDX-License-Identifier: GPL-2.0-only -# - -""" -Vendored third-party libraries for BitBake. - -These libraries have been modified from their upstream versions and are -bundled here to avoid conflicts with system-installed packages. - -Vendored packages: - - bs4 (BeautifulSoup4) - - ply - - progressbar - - simplediff -""" diff --git a/lib/bb/_vendor/bs4/LICENSE b/lib/bb/_vendor/beautifulsoup4.LICENSE similarity index 100% rename from lib/bb/_vendor/bs4/LICENSE rename to lib/bb/_vendor/beautifulsoup4.LICENSE diff --git a/lib/bb/_vendor/bs4/AUTHORS b/lib/bb/_vendor/bs4/AUTHORS deleted file mode 100644 index 1f14fe07d..000000000 --- a/lib/bb/_vendor/bs4/AUTHORS +++ /dev/null @@ -1,49 +0,0 @@ -Behold, mortal, the origins of Beautiful Soup... -================================================ - -Leonard Richardson is the primary maintainer. - -Aaron DeVore and Isaac Muse have made significant contributions to the -code base. - -Mark Pilgrim provided the encoding detection code that forms the base -of UnicodeDammit. - -Thomas Kluyver and Ezio Melotti finished the work of getting Beautiful -Soup 4 working under Python 3. - -Simon Willison wrote soupselect, which was used to make Beautiful Soup -support CSS selectors. Isaac Muse wrote SoupSieve, which made it -possible to _remove_ the CSS selector code from Beautiful Soup. - -Sam Ruby helped with a lot of edge cases. - -Jonathan Ellis was awarded the prestigious Beau Potage D'Or for his -work in solving the nestable tags conundrum. - -An incomplete list of people have contributed patches to Beautiful -Soup: - - Istvan Albert, Andrew Lin, Anthony Baxter, Oliver Beattie, Andrew -Boyko, Tony Chang, Francisco Canas, "Delong", Zephyr Fang, Fuzzy, -Roman Gaufman, Yoni Gilad, Richie Hindle, Toshihiro Kamiya, Peteris -Krumins, Kent Johnson, Marek Kapolka, Andreas Kostyrka, Roel Kramer, -Ben Last, Robert Leftwich, Stefaan Lippens, "liquider", Staffan -Malmgren, Ksenia Marasanova, JP Moins, Adam Monsen, John Nagle, "Jon", -Ed Oskiewicz, Martijn Peters, Greg Phillips, Giles Radford, Stefano -Revera, Arthur Rudolph, Marko Samastur, James Salter, Jouni Sepp�nen, -Alexander Schmolck, Tim Shirley, Geoffrey Sneddon, Ville Skytt�, -"Vikas", Jens Svalgaard, Andy Theyers, Eric Weiser, Glyn Webster, John -Wiseman, Paul Wright, Danny Yoo - -An incomplete list of people who made suggestions or found bugs or -found ways to break Beautiful Soup: - - Hanno B�ck, Matteo Bertini, Chris Curvey, Simon Cusack, Bruce Eckel, - Matt Ernst, Michael Foord, Tom Harris, Bill de hOra, Donald Howes, - Matt Patterson, Scott Roberts, Steve Strassmann, Mike Williams, - warchild at redho dot com, Sami Kuisma, Carlos Rocha, Bob Hutchison, - Joren Mc, Michal Migurski, John Kleven, Tim Heaney, Tripp Lilley, Ed - Summers, Dennis Sutch, Chris Smith, Aaron Swartz, Stuart - Turner, Greg Edwards, Kevin J Kalupson, Nikos Kouremenos, Artur de - Sousa Rocha, Yichun Wei, Per Vognsen diff --git a/lib/bb/_vendor/bs4/CHANGELOG b/lib/bb/_vendor/bs4/CHANGELOG deleted file mode 100644 index 2701446a6..000000000 --- a/lib/bb/_vendor/bs4/CHANGELOG +++ /dev/null @@ -1,1839 +0,0 @@ -= 4.12.3 (20240117) - -* The Beautiful Soup documentation now has a Spanish translation, thanks - to Carlos Romero. Delong Wang's Chinese translation has been updated - to cover Beautiful Soup 4.12.0. - -* Fixed a regression such that if you set .hidden on a tag, the tag - becomes invisible but its contents are still visible. User manipulation - of .hidden is not a documented or supported feature, so don't do this, - but it wasn't too difficult to keep the old behavior working. - -* Fixed a case found by Mengyuhan where html.parser giving up on - markup would result in an AssertionError instead of a - ParserRejectedMarkup exception. - -* Added the correct stacklevel to instances of the XMLParsedAsHTMLWarning. - [bug=2034451] - -* Corrected the syntax of the license definition in pyproject.toml. Patch - by Louis Maddox. [bug=2032848] - -* Corrected a typo in a test that was causing test failures when run against - libxml2 2.12.1. [bug=2045481] - -= 4.12.2 (20230407) - -* Fixed an unhandled exception in BeautifulSoup.decode_contents - and methods that call it. [bug=2015545] - -= 4.12.1 (20230405) - -NOTE: the following things are likely to be dropped in the next -feature release of Beautiful Soup: - - Official support for Python 3.6. - Inclusion of unit tests and test data in the wheel file. - Two scripts: demonstrate_parser_differences.py and test-all-versions. - -Changes: - -* This version of Beautiful Soup replaces setup.py and setup.cfg - with pyproject.toml. Beautiful Soup now uses tox as its test backend - and hatch to do builds. - -* The main functional improvement in this version is a nonrecursive technique - for regenerating a tree. This technique is used to avoid situations where, - in previous versions, doing something to a very deeply nested tree - would overflow the Python interpreter stack: - - 1. Outputting a tree as a string, e.g. with - BeautifulSoup.encode() [bug=1471755] - - 2. Making copies of trees (copy.copy() and - copy.deepcopy() from the Python standard library). [bug=1709837] - - 3. Pickling a BeautifulSoup object. (Note that pickling a Tag - object can still cause an overflow.) - -* Making a copy of a BeautifulSoup object no longer parses the - document again, which should improve performance significantly. - -* When a BeautifulSoup object is unpickled, Beautiful Soup now - tries to associate an appropriate TreeBuilder object with it. - -* Tag.prettify() will now consistently end prettified markup with - a newline. - -* Added unit tests for fuzz test cases created by third - parties. Some of these tests are skipped since they point - to problems outside of Beautiful Soup, but this change - puts them all in one convenient place. - -* PageElement now implements the known_xml attribute. (This was technically - a bug, but it shouldn't be an issue in normal use.) [bug=2007895] - -* The demonstrate_parser_differences.py script was still written in - Python 2. I've converted it to Python 3, but since no one has - mentioned this over the years, it's a sign that no one uses this - script and it's not serving its purpose. - -= 4.12.0 (20230320) - -* Introduced the .css property, which centralizes all access to - the Soup Sieve API. This allows Beautiful Soup to give direct - access to as much of Soup Sieve that makes sense, without cluttering - the BeautifulSoup and Tag classes with a lot of new methods. - - This does mean one addition to the BeautifulSoup and Tag classes - (the .css property itself), so this might be a breaking change if you - happen to use Beautiful Soup to parse XML that includes a tag called - . In particular, code like this will stop working in 4.12.0: - - soup.css['id'] - - Code like this will work just as before: - - soup.find_one('css')['id'] - - The Soup Sieve methods supported through the .css property are - select(), select_one(), iselect(), closest(), match(), filter(), - escape(), and compile(). The BeautifulSoup and Tag classes still - support the select() and select_one() methods; they have not been - deprecated, but they have been demoted to convenience methods. - - [bug=2003677] - -* When the html.parser parser decides it can't parse a document, Beautiful - Soup now consistently propagates this fact by raising a - ParserRejectedMarkup error. [bug=2007343] - -* Removed some error checking code from diagnose(), which is redundant with - similar (but more Pythonic) code in the BeautifulSoup constructor. - [bug=2007344] - -* Added intersphinx references to the documentation so that other - projects have a target to point to when they reference Beautiful - Soup classes. [bug=1453370] - -= 4.11.2 (20230131) - -* Fixed test failures caused by nondeterministic behavior of - UnicodeDammit's character detection, depending on the platform setup. - [bug=1973072] - -* Fixed another crash when overriding multi_valued_attributes and using the - html5lib parser. [bug=1948488] - -* The HTMLFormatter and XMLFormatter constructors no longer return a - value. [bug=1992693] - -* Tag.interesting_string_types is now propagated when a tag is - copied. [bug=1990400] - -* Warnings now do their best to provide an appropriate stacklevel, - improving the usefulness of the message. [bug=1978744] - -* Passing a Tag's .contents into PageElement.extend() now works the - same way as passing the Tag itself. - -* Soup Sieve tests will be skipped if the library is not installed. - -= 4.11.1 (20220408) - -This release was done to ensure that the unit tests are packaged along -with the released source. There are no functionality changes in this -release, but there are a few other packaging changes: - -* The Japanese and Korean translations of the documentation are included. -* The changelog is now packaged as CHANGELOG, and the license file is - packaged as LICENSE. NEWS.txt and COPYING.txt are still present, - but may be removed in the future. -* TODO.txt is no longer packaged, since a TODO is not relevant for released - code. - -= 4.11.0 (20220407) - -* Ported unit tests to use pytest. - -* Added special string classes, RubyParenthesisString and RubyTextString, - to make it possible to treat ruby text specially in get_text() calls. - [bug=1941980] - -* It's now possible to customize the way output is indented by - providing a value for the 'indent' argument to the Formatter - constructor. The 'indent' argument works very similarly to the - argument of the same name in the Python standard library's - json.dump() function. [bug=1955497] - -* If the charset-normalizer Python module - (https://pypi.org/project/charset-normalizer/) is installed, Beautiful - Soup will use it to detect the character sets of incoming documents. - This is also the module used by newer versions of the Requests library. - For the sake of backwards compatibility, chardet and cchardet both take - precedence if installed. [bug=1955346] - -* Added a workaround for an lxml bug - (https://bugs.launchpad.net/lxml/+bug/1948551) that causes - problems when parsing a Unicode string beginning with BYTE ORDER MARK. - [bug=1947768] - -* Issue a warning when an HTML parser is used to parse a document that - looks like XML but not XHTML. [bug=1939121] - -* Do a better job of keeping track of namespaces as an XML document is - parsed, so that CSS selectors that use namespaces will do the right - thing more often. [bug=1946243] - -* Some time ago, the misleadingly named "text" argument to find-type - methods was renamed to the more accurate "string." But this supposed - "renaming" didn't make it into important places like the method - signatures or the docstrings. That's corrected in this - version. "text" still works, but will give a DeprecationWarning. - [bug=1947038] - -* Fixed a crash when pickling a BeautifulSoup object that has no - tree builder. [bug=1934003] - -* Fixed a crash when overriding multi_valued_attributes and using the - html5lib parser. [bug=1948488] - -* Standardized the wording of the MarkupResemblesLocatorWarning - warnings to omit untrusted input and make the warnings less - judgmental about what you ought to be doing. [bug=1955450] - -* Removed support for the iconv_codec library, which doesn't seem - to exist anymore and was never put up on PyPI. (The closest - replacement on PyPI, iconv_codecs, is GPL-licensed, so we can't use - it--it's also quite old.) - -= 4.10.0 (20210907) - -* This is the first release of Beautiful Soup to only support Python - 3. I dropped Python 2 support to maintain support for newer versions - (58 and up) of setuptools. See: - https://github.com/pypa/setuptools/issues/2769 [bug=1942919] - -* The behavior of methods like .get_text() and .strings now differs - depending on the type of tag. The change is visible with HTML tags - like