Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Switch plugin system from pkg_resources to importlib #562

Merged
merged 2 commits into from
Aug 17, 2023

Conversation

cottsay
Copy link
Member

@cottsay cottsay commented Jul 6, 2023

There are two commits in this change. The first introduces a replacement API for the existing entry_point module. The latter is coupled to pkg_resources by returning classes defined there. Rather than try to mimic that API, I decided to replace it with one that uses only basic types to return the information we need.

The second change replaces the implementation behind the new extension_point API from pkg_resources to importlib.metadata.

Downstream consumers of entry_point will start getting a deprecation warning in addition to the existing pkg_resources deprecation warning, and will need to update to use the new extension_point functions. I've been prototyping those changes in colcon-devtools, which has the most complex uses of the API right now.

@cottsay cottsay self-assigned this Jul 6, 2023
Copy link
Contributor

@nuclearsandwich nuclearsandwich left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Several comments are mere jubilation. The others, including suggestions are entirely discretionary / informational and don't block approval.

This is a large change but I'm impressed that the majority of the changes are the update of the module name / class names to the new API and more importantly. It does not seem like the new API is as dependent on external libraries. Thanks for tackling this!

colcon_core/entry_point.py Show resolved Hide resolved
test/test_extension_point.py Show resolved Hide resolved
colcon_core/extension_point.py Show resolved Hide resolved
entry_map = dist.get_entry_map()
for group_name in entry_map.keys():
seen = set()
for dist in distributions():
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The iterator for value dist was sorted(working_set) previously. Do we need to sort distributions() as well?

Suggested change
for dist in distributions():
for dist in sorted(distributions()):

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as I understand, this no longer works as expected in the current code due to pypa/setuptools#3791, and the importlib-based class isn't inherently sort-able. We'd have to implement our own sort routine, which would involve parsing the version numbers for comparison. It has the potential to be pretty expensive.

From what I've gathered, it's not a well-supported scenario by any tooling to have multiple versions of a distribution installed in the same prefix anyway.

Also worth questioning is whether this was the right thing to do to begin with. Assuming the working set contained all of the distributions across all of the discoverable prefixes, sorting it like that would always prefer the newest version of a distribution, where an import would prefer the one(s) discoverable soonest in the prefix list.

If I'm not mistaken, the existing code wouldn't allow you to (for example) build an older version of a package in a colcon workspace than the one installed on your system and source that workspace, because this code would always prefer the newer version even though an import statement would not.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I dug into this a little more.

In pkg_resources, it appears that the path ordering was respected and you were never given multiple distributions with the same "key", so if there are multiple dists in the same path directory, it's a matter of luck which one you get.

In importlib.metadata, the dists are not de-duplicated, so you will likely encounter multiple with the same key. If we sorted them, you might get "inferior" or shadowed versions showing up with higher precedence because they have a higher version number.

Since multiple versions in the same path really isn't supported well anywhere, I don't think there's any harm in skipping the sort for performance reasons. I'll say that the one remaining benefit is that it makes the duplicate entry point definition error more deterministic.

colcon_core/extension_point.py Outdated Show resolved Hide resolved
setup.cfg Outdated Show resolved Hide resolved
test/test_extension_point.py Show resolved Hide resolved
@cottsay cottsay force-pushed the cottsay/extension-point branch 4 times, most recently from 1ef4676 to b3440ff Compare July 11, 2023 21:28
@codecov
Copy link

codecov bot commented Jul 11, 2023

Codecov Report

Patch coverage: 89.87% and project coverage change: +0.16% 🎉

Comparison is base (7b70e61) 81.88% compared to head (dab8cad) 82.04%.

Additional details and impacted files
@@            Coverage Diff             @@
##           master     #562      +/-   ##
==========================================
+ Coverage   81.88%   82.04%   +0.16%     
==========================================
  Files          62       63       +1     
  Lines        3648     3721      +73     
  Branches      705      718      +13     
==========================================
+ Hits         2987     3053      +66     
- Misses        609      613       +4     
- Partials       52       55       +3     
Files Changed Coverage Δ
colcon_core/task/python/test/__init__.py 32.71% <50.00%> (ø)
colcon_core/extension_point.py 90.27% <90.27%> (ø)
colcon_core/command.py 86.20% <100.00%> (ø)
colcon_core/entry_point.py 83.33% <100.00%> (+0.21%) ⬆️
colcon_core/plugin_system.py 98.68% <100.00%> (ø)

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@cottsay cottsay force-pushed the cottsay/extension-point branch 2 times, most recently from 966c32d to f8ee3a4 Compare July 11, 2023 23:28
@cottsay cottsay marked this pull request as ready for review July 11, 2023 23:44
@cottsay cottsay force-pushed the cottsay/extension-point branch 2 times, most recently from 3acbd4c to efc8d8d Compare August 8, 2023 20:26
@cottsay cottsay mentioned this pull request Aug 11, 2023
This change deprecates the critical entry_point module in colcon-core in
favor of a new module called 'extension_point' which is not coupled to
the pkg_resources module of setuptools like its predecessor.
@cottsay cottsay merged commit 5f9f5ff into master Aug 17, 2023
35 checks passed
cottsay added a commit that referenced this pull request Aug 17, 2023
This change deprecates the critical entry_point module in colcon-core in
favor of a new module called 'extension_point' which is not coupled to
the pkg_resources module of setuptools like its predecessor.
@delete-merged-branch delete-merged-branch bot deleted the cottsay/extension-point branch August 17, 2023 22:15
@cottsay cottsay added this to the 0.13.0 milestone Sep 22, 2023
@cottsay cottsay added the enhancement New feature or request label Sep 22, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Development

Successfully merging this pull request may close these issues.

2 participants