Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions requirements/dev-requirements.in
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ pytest-env
pytest-xdist
pytest-timeout
pyftpdlib
setuptools
1 change: 1 addition & 0 deletions requirements/dev-requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ pytest-env==1.1.5
pytest-xdist==3.6.1
pytest-timeout==2.3.1
pyftpdlib==2.0.1
setuptools==75.6.0
## The following requirements were added by pip freeze:
astroid==3.3.5
dill==0.3.9
Expand Down
3 changes: 2 additions & 1 deletion requirements/requirements.in
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
Click >= 7.0
grpcio
Jinja2 >= 2.10
importlib_metadata >= 3.6; python_version < "3.10"
packaging
pluginbase
protobuf >= 3.19
psutil
ruamel.yaml >= 0.16.7
ruamel.yaml.clib >= 0.1.2
setuptools
pyroaring
ujson
2 changes: 1 addition & 1 deletion requirements/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
click==8.1.7
grpcio==1.68.0
Jinja2==3.1.4
packaging==24.2
pluginbase==1.0.1
protobuf==5.28.3
psutil==6.1.0
ruamel.yaml==0.18.6
ruamel.yaml.clib==0.2.12
setuptools==75.6.0
pyroaring==1.0.0
ujson==5.10.0
## The following requirements were added by pip freeze:
Expand Down
68 changes: 30 additions & 38 deletions src/buildstream/_pluginfactory/pluginoriginpip.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
# limitations under the License.
#
import os
import sys

from .._exceptions import PluginError

Expand All @@ -32,14 +33,12 @@ def __init__(self):

def get_plugin_paths(self, kind, plugin_type):

import pkg_resources
from packaging.requirements import Requirement, InvalidRequirement

try:
# For setuptools >= 70
import packaging
except ImportError:
# For setuptools < 70
from pkg_resources.extern import packaging
if sys.version_info >= (3, 10):
from importlib.metadata import distribution, PackageNotFoundError
else:
from importlib_metadata import distribution, PackageNotFoundError

# Sources and elements are looked up in separate
# entrypoint groups from the same package.
Expand All @@ -53,63 +52,56 @@ def get_plugin_paths(self, kind, plugin_type):
else:
assert False, "unreachable"

# key by a tuple to avoid collision
try:
package = pkg_resources.get_entry_info(self._package_name, entrypoint_group, kind)
except pkg_resources.DistributionNotFound as e:
package = Requirement(self._package_name)
except InvalidRequirement as e:
raise PluginError(
"{}: Malformed package-name '{}' encountered: {}".format(
self.provenance_node.get_provenance(), self._package_name, e
),
reason="package-malformed-requirement",
) from e

try:
dist = distribution(package.name)
except PackageNotFoundError as e:
raise PluginError(
"{}: Failed to load {} plugin '{}': {}".format(
self.provenance_node.get_provenance(), plugin_type, kind, e
),
reason="package-not-found",
) from e
except pkg_resources.VersionConflict as e:

if dist.version not in package.specifier:
raise PluginError(
"{}: Version conflict encountered while loading {} plugin '{}'".format(
self.provenance_node.get_provenance(), plugin_type, kind
),
detail=e.report(),
detail="{} {} is installed but {} is required".format(dist.name, dist.version, package),
reason="package-version-conflict",
) from e
except (
# For setuptools < 49.0.0
pkg_resources.RequirementParseError,
# For setuptools >= 49.0.0
packaging.requirements.InvalidRequirement,
) as e:
raise PluginError(
"{}: Malformed package-name '{}' encountered: {}".format(
self.provenance_node.get_provenance(), self._package_name, e
),
reason="package-malformed-requirement",
) from e
)

if package is None:
try:
entrypoint = dist.entry_points.select(group=entrypoint_group)[kind]
except KeyError as e:
raise PluginError(
"{}: Pip package {} does not contain a {} plugin named '{}'".format(
self.provenance_node.get_provenance(), self._package_name, plugin_type, kind
),
reason="plugin-not-found",
)

location = package.dist.get_resource_filename(
pkg_resources._manager, package.module_name.replace(".", os.sep) + ".py"
)
location = dist.locate_file(entrypoint.module.replace(".", os.sep) + ".py")
defaults = dist.locate_file(entrypoint.module.replace(".", os.sep) + ".yaml")

# Also load the defaults - required since setuptools
# may need to extract the file.
try:
defaults = package.dist.get_resource_filename(
pkg_resources._manager, package.module_name.replace(".", os.sep) + ".yaml"
)
except KeyError:
if not defaults.exists():
# The plugin didn't have an accompanying YAML file
defaults = None

return (
os.path.dirname(location),
defaults,
"python package '{}' at: {}".format(package.dist, package.dist.location),
str(defaults),
"python package '{}' at: {}".format(dist, dist.locate_file("")),
)

def load_config(self, origin_node):
Expand Down
Loading