From: Rob Woolley <rob.woolley@windriver.com>
To: <bitbake-devel@lists.openembedded.org>
Cc: <alex.kanavin@gmail.com>
Subject: [PATCH v2 12/13] lib: Vendorize bundled third-party libraries under bb._vendor
Date: Tue, 31 Mar 2026 09:07:02 -0700 [thread overview]
Message-ID: <20260331160703.3137930-13-rob.woolley@windriver.com> (raw)
In-Reply-To: <20260331160703.3137930-1-rob.woolley@windriver.com>
Move ply, progressbar, simplediff, and bs4 from lib/ into
lib/bb/_vendor/ to avoid conflicts with system-installed versions
and to support proper packaging. These libraries contain local
modifications from their upstream versions.
- Create lib/bb/_vendor/__init__.py
- Move ply/, progressbar/, simplediff/, bs4/ into bb/_vendor/
- Convert absolute self-references to relative imports within
ply (yacc.py) and bs4 (20 import sites across 8 files)
- Update all external import sites to use bb._vendor prefix:
bb/pysh/pyshlex.py, bb/pysh/pyshyacc.py, bb/ui/knotty.py,
bb/siggen.py, bb/fetch2/wget.py, toaster/tests/views/test_views.py
Assisted-by: Claude:claude-4.6-opus
Signed-off-by: Rob Woolley <rob.woolley@windriver.com>
---
lib/bb/_vendor/__init__.py | 18 ++++++++++++++++++
lib/{ => bb/_vendor}/bs4/AUTHORS | 0
lib/{ => bb/_vendor}/bs4/CHANGELOG | 0
lib/{ => bb/_vendor}/bs4/LICENSE | 0
lib/{ => bb/_vendor}/bs4/__init__.py | 0
lib/{ => bb/_vendor}/bs4/builder/__init__.py | 2 +-
lib/{ => bb/_vendor}/bs4/builder/_html5lib.py | 12 ++++++------
.../_vendor}/bs4/builder/_htmlparser.py | 6 +++---
lib/{ => bb/_vendor}/bs4/builder/_lxml.py | 6 +++---
lib/{ => bb/_vendor}/bs4/css.py | 2 +-
lib/{ => bb/_vendor}/bs4/dammit.py | 0
lib/{ => bb/_vendor}/bs4/diagnose.py | 9 ++++-----
lib/{ => bb/_vendor}/bs4/element.py | 6 +++---
lib/{ => bb/_vendor}/bs4/formatter.py | 2 +-
lib/{ => bb/_vendor}/ply/__init__.py | 0
lib/{ => bb/_vendor}/ply/lex.py | 0
lib/{ => bb/_vendor}/ply/yacc.py | 6 +-----
lib/{ => bb/_vendor}/progressbar/LICENSE.txt | 0
lib/{ => bb/_vendor}/progressbar/__init__.py | 0
lib/{ => bb/_vendor}/progressbar/compat.py | 0
.../_vendor}/progressbar/progressbar.py | 0
lib/{ => bb/_vendor}/progressbar/widgets.py | 0
lib/{ => bb/_vendor}/simplediff/LICENSE | 0
lib/{ => bb/_vendor}/simplediff/__init__.py | 0
lib/bb/fetch2/wget.py | 4 ++--
lib/bb/pysh/pyshlex.py | 2 +-
lib/bb/pysh/pyshyacc.py | 2 +-
lib/bb/siggen.py | 2 +-
lib/bb/ui/knotty.py | 2 +-
lib/toaster/tests/views/test_views.py | 2 +-
30 files changed, 48 insertions(+), 35 deletions(-)
create mode 100644 lib/bb/_vendor/__init__.py
rename lib/{ => bb/_vendor}/bs4/AUTHORS (100%)
rename lib/{ => bb/_vendor}/bs4/CHANGELOG (100%)
rename lib/{ => bb/_vendor}/bs4/LICENSE (100%)
rename lib/{ => bb/_vendor}/bs4/__init__.py (100%)
rename lib/{ => bb/_vendor}/bs4/builder/__init__.py (99%)
rename lib/{ => bb/_vendor}/bs4/builder/_html5lib.py (98%)
rename lib/{ => bb/_vendor}/bs4/builder/_htmlparser.py (99%)
rename lib/{ => bb/_vendor}/bs4/builder/_lxml.py (99%)
rename lib/{ => bb/_vendor}/bs4/css.py (99%)
rename lib/{ => bb/_vendor}/bs4/dammit.py (100%)
rename lib/{ => bb/_vendor}/bs4/diagnose.py (96%)
rename lib/{ => bb/_vendor}/bs4/element.py (99%)
rename lib/{ => bb/_vendor}/bs4/formatter.py (99%)
rename lib/{ => bb/_vendor}/ply/__init__.py (100%)
rename lib/{ => bb/_vendor}/ply/lex.py (100%)
rename lib/{ => bb/_vendor}/ply/yacc.py (99%)
rename lib/{ => bb/_vendor}/progressbar/LICENSE.txt (100%)
rename lib/{ => bb/_vendor}/progressbar/__init__.py (100%)
rename lib/{ => bb/_vendor}/progressbar/compat.py (100%)
rename lib/{ => bb/_vendor}/progressbar/progressbar.py (100%)
rename lib/{ => bb/_vendor}/progressbar/widgets.py (100%)
rename lib/{ => bb/_vendor}/simplediff/LICENSE (100%)
rename lib/{ => bb/_vendor}/simplediff/__init__.py (100%)
diff --git a/lib/bb/_vendor/__init__.py b/lib/bb/_vendor/__init__.py
new file mode 100644
index 000000000..3c054dc32
--- /dev/null
+++ b/lib/bb/_vendor/__init__.py
@@ -0,0 +1,18 @@
+#
+# 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/bs4/AUTHORS b/lib/bb/_vendor/bs4/AUTHORS
similarity index 100%
rename from lib/bs4/AUTHORS
rename to lib/bb/_vendor/bs4/AUTHORS
diff --git a/lib/bs4/CHANGELOG b/lib/bb/_vendor/bs4/CHANGELOG
similarity index 100%
rename from lib/bs4/CHANGELOG
rename to lib/bb/_vendor/bs4/CHANGELOG
diff --git a/lib/bs4/LICENSE b/lib/bb/_vendor/bs4/LICENSE
similarity index 100%
rename from lib/bs4/LICENSE
rename to lib/bb/_vendor/bs4/LICENSE
diff --git a/lib/bs4/__init__.py b/lib/bb/_vendor/bs4/__init__.py
similarity index 100%
rename from lib/bs4/__init__.py
rename to lib/bb/_vendor/bs4/__init__.py
diff --git a/lib/bs4/builder/__init__.py b/lib/bb/_vendor/bs4/builder/__init__.py
similarity index 99%
rename from lib/bs4/builder/__init__.py
rename to lib/bb/_vendor/bs4/builder/__init__.py
index ffb31fc25..d60a9a672 100644
--- a/lib/bs4/builder/__init__.py
+++ b/lib/bb/_vendor/bs4/builder/__init__.py
@@ -6,7 +6,7 @@ import itertools
import re
import warnings
import sys
-from bs4.element import (
+from ..element import (
CharsetMetaAttributeValue,
ContentMetaAttributeValue,
RubyParenthesisString,
diff --git a/lib/bs4/builder/_html5lib.py b/lib/bb/_vendor/bs4/builder/_html5lib.py
similarity index 98%
rename from lib/bs4/builder/_html5lib.py
rename to lib/bb/_vendor/bs4/builder/_html5lib.py
index 7c46a8511..8ca19fec6 100644
--- a/lib/bs4/builder/_html5lib.py
+++ b/lib/bb/_vendor/bs4/builder/_html5lib.py
@@ -7,14 +7,14 @@ __all__ = [
import warnings
import re
-from bs4.builder import (
+from . import (
DetectsXMLParsedAsHTML,
PERMISSIVE,
HTML,
HTML_5,
HTMLTreeBuilder,
)
-from bs4.element import (
+from ..element import (
NamespacedAttribute,
nonwhitespace_re,
)
@@ -23,7 +23,7 @@ from html5lib.constants import (
namespaces,
prefixes,
)
-from bs4.element import (
+from ..element import (
Comment,
Doctype,
NavigableString,
@@ -134,7 +134,7 @@ class TreeBuilderForHtml5lib(treebuilder_base.TreeBuilder):
if soup:
self.soup = soup
else:
- from bs4 import BeautifulSoup
+ from .. import BeautifulSoup
# TODO: Why is the parser 'html.parser' here? To avoid an
# infinite loop?
self.soup = BeautifulSoup(
@@ -180,7 +180,7 @@ class TreeBuilderForHtml5lib(treebuilder_base.TreeBuilder):
return TextNode(Comment(data), self.soup)
def fragmentClass(self):
- from bs4 import BeautifulSoup
+ from .. import BeautifulSoup
# TODO: Why is the parser 'html.parser' here? To avoid an
# infinite loop?
self.soup = BeautifulSoup("", "html.parser")
@@ -198,7 +198,7 @@ class TreeBuilderForHtml5lib(treebuilder_base.TreeBuilder):
return treebuilder_base.TreeBuilder.getFragment(self).element
def testSerializer(self, element):
- from bs4 import BeautifulSoup
+ from .. import BeautifulSoup
rv = []
doctype_re = re.compile(r'^(.*?)(?: PUBLIC "(.*?)"(?: "(.*?)")?| SYSTEM "(.*?)")?$')
diff --git a/lib/bs4/builder/_htmlparser.py b/lib/bb/_vendor/bs4/builder/_htmlparser.py
similarity index 99%
rename from lib/bs4/builder/_htmlparser.py
rename to lib/bb/_vendor/bs4/builder/_htmlparser.py
index 3cc187f89..f55cbadf6 100644
--- a/lib/bs4/builder/_htmlparser.py
+++ b/lib/bb/_vendor/bs4/builder/_htmlparser.py
@@ -13,16 +13,16 @@ from html.parser import HTMLParser
import sys
import warnings
-from bs4.element import (
+from ..element import (
CData,
Comment,
Declaration,
Doctype,
ProcessingInstruction,
)
-from bs4.dammit import EntitySubstitution, UnicodeDammit
+from ..dammit import EntitySubstitution, UnicodeDammit
-from bs4.builder import (
+from . import (
DetectsXMLParsedAsHTML,
ParserRejectedMarkup,
HTML,
diff --git a/lib/bs4/builder/_lxml.py b/lib/bb/_vendor/bs4/builder/_lxml.py
similarity index 99%
rename from lib/bs4/builder/_lxml.py
rename to lib/bb/_vendor/bs4/builder/_lxml.py
index 4f7cf7468..fc80133b2 100644
--- a/lib/bs4/builder/_lxml.py
+++ b/lib/bb/_vendor/bs4/builder/_lxml.py
@@ -14,14 +14,14 @@ except ImportError as e:
from io import BytesIO
from io import StringIO
from lxml import etree
-from bs4.element import (
+from ..element import (
Comment,
Doctype,
NamespacedAttribute,
ProcessingInstruction,
XMLProcessingInstruction,
)
-from bs4.builder import (
+from . import (
DetectsXMLParsedAsHTML,
FAST,
HTML,
@@ -30,7 +30,7 @@ from bs4.builder import (
ParserRejectedMarkup,
TreeBuilder,
XML)
-from bs4.dammit import EncodingDetector
+from ..dammit import EncodingDetector
LXML = 'lxml'
diff --git a/lib/bs4/css.py b/lib/bb/_vendor/bs4/css.py
similarity index 99%
rename from lib/bs4/css.py
rename to lib/bb/_vendor/bs4/css.py
index cd1fd2df8..7cbeb83c1 100644
--- a/lib/bs4/css.py
+++ b/lib/bb/_vendor/bs4/css.py
@@ -68,7 +68,7 @@ class CSS(object):
result (a common mistake).
"""
# Import here to avoid circular import
- from bs4.element import ResultSet
+ from .element import ResultSet
return ResultSet(None, results)
def compile(self, select, namespaces=None, flags=0, **kwargs):
diff --git a/lib/bs4/dammit.py b/lib/bb/_vendor/bs4/dammit.py
similarity index 100%
rename from lib/bs4/dammit.py
rename to lib/bb/_vendor/bs4/dammit.py
diff --git a/lib/bs4/diagnose.py b/lib/bb/_vendor/bs4/diagnose.py
similarity index 96%
rename from lib/bs4/diagnose.py
rename to lib/bb/_vendor/bs4/diagnose.py
index 469279534..76d0be8f1 100644
--- a/lib/bs4/diagnose.py
+++ b/lib/bb/_vendor/bs4/diagnose.py
@@ -6,9 +6,8 @@ __license__ = "MIT"
import cProfile
from io import BytesIO
from html.parser import HTMLParser
-import bs4
-from bs4 import BeautifulSoup, __version__
-from bs4.builder import builder_registry
+from . import BeautifulSoup, __version__
+from .builder import builder_registry
import os
import pstats
@@ -219,8 +218,8 @@ def profile(num_elements=100000, parser="lxml"):
filename = filehandle.name
data = rdoc(num_elements)
- vars = dict(bs4=bs4, data=data, parser=parser)
- cProfile.runctx('bs4.BeautifulSoup(data, parser)' , vars, vars, filename)
+ vars = dict(BeautifulSoup=BeautifulSoup, data=data, parser=parser)
+ cProfile.runctx('BeautifulSoup(data, parser)' , vars, vars, filename)
stats = pstats.Stats(filename)
# stats.strip_dirs()
diff --git a/lib/bs4/element.py b/lib/bb/_vendor/bs4/element.py
similarity index 99%
rename from lib/bs4/element.py
rename to lib/bb/_vendor/bs4/element.py
index 0aefe734b..38ca2dc27 100644
--- a/lib/bs4/element.py
+++ b/lib/bb/_vendor/bs4/element.py
@@ -9,8 +9,8 @@ import re
import sys
import warnings
-from bs4.css import CSS
-from bs4.formatter import (
+from .css import CSS
+from .formatter import (
Formatter,
HTMLFormatter,
XMLFormatter,
@@ -420,7 +420,7 @@ class PageElement(object):
and not isinstance(new_child, NavigableString)):
new_child = NavigableString(new_child)
- from bs4 import BeautifulSoup
+ from . import BeautifulSoup
if isinstance(new_child, BeautifulSoup):
# We don't want to end up with a situation where one BeautifulSoup
# object contains another. Insert the children one at a time.
diff --git a/lib/bs4/formatter.py b/lib/bb/_vendor/bs4/formatter.py
similarity index 99%
rename from lib/bs4/formatter.py
rename to lib/bb/_vendor/bs4/formatter.py
index 9fa1b57cb..50f775aee 100644
--- a/lib/bs4/formatter.py
+++ b/lib/bb/_vendor/bs4/formatter.py
@@ -1,4 +1,4 @@
-from bs4.dammit import EntitySubstitution
+from .dammit import EntitySubstitution
class Formatter(EntitySubstitution):
"""Describes a strategy to use when outputting a parse tree to a string.
diff --git a/lib/ply/__init__.py b/lib/bb/_vendor/ply/__init__.py
similarity index 100%
rename from lib/ply/__init__.py
rename to lib/bb/_vendor/ply/__init__.py
diff --git a/lib/ply/lex.py b/lib/bb/_vendor/ply/lex.py
similarity index 100%
rename from lib/ply/lex.py
rename to lib/bb/_vendor/ply/lex.py
diff --git a/lib/ply/yacc.py b/lib/bb/_vendor/ply/yacc.py
similarity index 99%
rename from lib/ply/yacc.py
rename to lib/bb/_vendor/ply/yacc.py
index 529f85b08..0cd9b522b 100644
--- a/lib/ply/yacc.py
+++ b/lib/bb/_vendor/ply/yacc.py
@@ -100,12 +100,8 @@ try:
except AttributeError:
MAXINT = sys.maxsize
-# Python 2.x/3.0 compatibility.
def load_ply_lex():
- if sys.version_info[0] < 3:
- import lex
- else:
- import ply.lex as lex
+ from . import lex
return lex
# This object is a stand-in for a logging object created by the
diff --git a/lib/progressbar/LICENSE.txt b/lib/bb/_vendor/progressbar/LICENSE.txt
similarity index 100%
rename from lib/progressbar/LICENSE.txt
rename to lib/bb/_vendor/progressbar/LICENSE.txt
diff --git a/lib/progressbar/__init__.py b/lib/bb/_vendor/progressbar/__init__.py
similarity index 100%
rename from lib/progressbar/__init__.py
rename to lib/bb/_vendor/progressbar/__init__.py
diff --git a/lib/progressbar/compat.py b/lib/bb/_vendor/progressbar/compat.py
similarity index 100%
rename from lib/progressbar/compat.py
rename to lib/bb/_vendor/progressbar/compat.py
diff --git a/lib/progressbar/progressbar.py b/lib/bb/_vendor/progressbar/progressbar.py
similarity index 100%
rename from lib/progressbar/progressbar.py
rename to lib/bb/_vendor/progressbar/progressbar.py
diff --git a/lib/progressbar/widgets.py b/lib/bb/_vendor/progressbar/widgets.py
similarity index 100%
rename from lib/progressbar/widgets.py
rename to lib/bb/_vendor/progressbar/widgets.py
diff --git a/lib/simplediff/LICENSE b/lib/bb/_vendor/simplediff/LICENSE
similarity index 100%
rename from lib/simplediff/LICENSE
rename to lib/bb/_vendor/simplediff/LICENSE
diff --git a/lib/simplediff/__init__.py b/lib/bb/_vendor/simplediff/__init__.py
similarity index 100%
rename from lib/simplediff/__init__.py
rename to lib/bb/_vendor/simplediff/__init__.py
diff --git a/lib/bb/fetch2/wget.py b/lib/bb/fetch2/wget.py
index ca4959ab5..aaa5027f3 100644
--- a/lib/bb/fetch2/wget.py
+++ b/lib/bb/fetch2/wget.py
@@ -27,8 +27,8 @@ from bb.fetch2 import FetchMethod
from bb.fetch2 import FetchError
from bb.fetch2 import logger
from bb.fetch2 import runfetchcmd
-from bs4 import BeautifulSoup
-from bs4 import SoupStrainer
+from bb._vendor.bs4 import BeautifulSoup
+from bb._vendor.bs4 import SoupStrainer
class WgetProgressHandler(bb.progress.LineFilterProgressHandler):
"""
diff --git a/lib/bb/pysh/pyshlex.py b/lib/bb/pysh/pyshlex.py
index a42c29446..3f99cd1bd 100644
--- a/lib/bb/pysh/pyshlex.py
+++ b/lib/bb/pysh/pyshlex.py
@@ -14,7 +14,7 @@
# that hard to enable pull mode.
import re
-from ply import lex
+from bb._vendor.ply import lex
from bb.pysh.sherrors import *
class NeedMore(Exception):
diff --git a/lib/bb/pysh/pyshyacc.py b/lib/bb/pysh/pyshyacc.py
index 924860a6f..67e22c96e 100644
--- a/lib/bb/pysh/pyshyacc.py
+++ b/lib/bb/pysh/pyshyacc.py
@@ -13,7 +13,7 @@ import sys
import bb.pysh.pyshlex as pyshlex
tokens = pyshlex.tokens
-from ply import yacc
+from bb._vendor.ply import yacc
import bb.pysh.sherrors as sherrors
class IORedirect:
diff --git a/lib/bb/siggen.py b/lib/bb/siggen.py
index 985fa7e4c..4d0aa4ac3 100644
--- a/lib/bb/siggen.py
+++ b/lib/bb/siggen.py
@@ -12,7 +12,7 @@ import tempfile
import pickle
import bb.data
import difflib
-import simplediff
+from bb._vendor import simplediff
import json
import types
from contextlib import contextmanager
diff --git a/lib/bb/ui/knotty.py b/lib/bb/ui/knotty.py
index 82531ef8f..15025e8dd 100644
--- a/lib/bb/ui/knotty.py
+++ b/lib/bb/ui/knotty.py
@@ -14,7 +14,7 @@ import io
import os
import sys
import logging
-import progressbar
+from bb._vendor import progressbar
import signal
import bb.msg
import time
diff --git a/lib/toaster/tests/views/test_views.py b/lib/toaster/tests/views/test_views.py
index e1adfcf86..5e64e8192 100644
--- a/lib/toaster/tests/views/test_views.py
+++ b/lib/toaster/tests/views/test_views.py
@@ -27,7 +27,7 @@ import toastergui
from toastergui.tables import SoftwareRecipesTable
import json
-from bs4 import BeautifulSoup
+from bb._vendor.bs4 import BeautifulSoup
import string
PROJECT_NAME = "test project"
--
2.49.0
next prev parent reply other threads:[~2026-03-31 16:07 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-31 16:06 [PATCH v2 00/13] bitbake-setup PyPI Packaging Rob Woolley
2026-03-31 16:06 ` [PATCH v2 01/13] bitbake-setup: Resolve unused loop control variables Rob Woolley
2026-04-01 21:44 ` [bitbake-devel] " Richard Purdie
2026-03-31 16:06 ` [PATCH v2 02/13] bitbake-setup: Fix ambiguous variable names Rob Woolley
2026-03-31 16:06 ` [PATCH v2 03/13] bitbake-setup: Set function default to None Rob Woolley
2026-04-01 21:43 ` [bitbake-devel] " Richard Purdie
2026-03-31 16:06 ` [PATCH v2 04/13] bitbake-setup: Add checks for version information Rob Woolley
2026-03-31 16:06 ` [PATCH v2 05/13] bitbake-setup: Add version option Rob Woolley
2026-03-31 16:06 ` [PATCH v2 06/13] bitbake-setup: Add the conditional script stanza Rob Woolley
2026-03-31 16:06 ` [PATCH v2 07/13] bitbake-setup: Add version check and catch exceptions Rob Woolley
2026-03-31 16:06 ` [PATCH v2 08/13] bitbake: Add checks for importing bb module Rob Woolley
2026-03-31 16:06 ` [PATCH v2 09/13] pypi: Add PyPI packaging for bitbake-setup Rob Woolley
2026-03-31 16:07 ` [PATCH v2 10/13] pypi: Add packaging documentation for developers Rob Woolley
2026-03-31 16:07 ` [PATCH v2 11/13] gitignore: Ignore temporary staging directory Rob Woolley
2026-03-31 16:07 ` Rob Woolley [this message]
2026-03-31 16:07 ` [PATCH v2 13/13] bb: Move codegen.py inside module Rob Woolley
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260331160703.3137930-13-rob.woolley@windriver.com \
--to=rob.woolley@windriver.com \
--cc=alex.kanavin@gmail.com \
--cc=bitbake-devel@lists.openembedded.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox