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

[BUG] Vendoring of importlib_metadata is shadowing actual package #3113

Open
sphuber opened this issue Feb 16, 2022 · 4 comments
Open

[BUG] Vendoring of importlib_metadata is shadowing actual package #3113

sphuber opened this issue Feb 16, 2022 · 4 comments
Assignees
Labels
bug Needs Discussion Issues where the implementation still needs to be discussed.

Comments

@sphuber
Copy link

sphuber commented Feb 16, 2022

setuptools version

setuptools==60.9.1

Python version

Python 3.8 and Python 3.9

OS

Ubuntu 20.04

Additional environment information

No response

Description

Since setuptools started vendoring importlib_metadata it is shadowing the actual package. This means that the type of entry points are no longer the class provided by the original importlib_metadata but the vendored package instead. Example:

Expected behavior

Installing setuptools should not have its vendored library shadow the real one changing the types returned by functions of the importlib_metadata package.

How to Reproduce

  1. Install setuptools>=60.9.0 in Python 3.8 or Python 3.9

Output

Behavior of setuptools==60.8

Python 3.8.10 (default, Nov 26 2021, 20:14:08) 
Type 'copyright', 'credits' or 'license' for more information
IPython 7.31.1 -- An enhanced Interactive Python. Type '?' for help.

In [1]: import setuptools

In [2]: setuptools.__version__
Out[2]: '60.8.0'

In [3]: from importlib_metadata import entry_points

In [4]: ep = entry_points().select(group='aiida.calculations', name='core.arithmetic.add')['core.arithmetic.add']

In [5]: type(ep)
Out[5]: importlib_metadata.EntryPoint

In [6]: str(ep)
Out[6]: "EntryPoint(name='core.arithmetic.add', value='aiida.calculations.arithmetic.add:ArithmeticAddCalculation', group='aiida.calculations')"

Behavior of setuptools>=60.9.0

Python 3.8.10 (default, Nov 26 2021, 20:14:08) 
Type 'copyright', 'credits' or 'license' for more information
IPython 7.31.1 -- An enhanced Interactive Python. Type '?' for help.

In [1]: import setuptools

In [2]: setuptools.__version__
Out[2]: '60.9.1'

In [3]: from importlib_metadata import entry_points

In [4]: ep = entry_points().select(group='aiida.calculations', name='core.arithmetic.add')['core.arithmetic.add']

In [5]: type(ep)
Out[5]: setuptools._vendor.importlib_metadata.EntryPoint

In [6]: str(ep)
Out[6]: "EntryPoint(name='core.arithmetic.add', value='aiida.calculations.arithmetic.add:ArithmeticAddCalculation', group='aiida.calculations')"

Note how the type of the return value of entry_points().select has changed.

@sphuber sphuber added bug Needs Triage Issues that need to be evaluated for severity and status. labels Feb 16, 2022
@jaraco
Copy link
Member

jaraco commented Feb 16, 2022

Since setuptools started vendoring importlib_metadata it is shadowing the actual package.

Are you sure? Setuptools started vendoring importlib_metadata in 6.8.0. It started using it in 6.9.0, and it specifically took precedence over a base install in 6.9.1 due to #3107.

It'd be good to know if 6.9.0 experiences the undesirable behavior you report.

This issue is particularly tricky because:

  • Setuptools can't have real dependencies (Stop vendoring packages #2825).
  • Any copy of importlib_metadata (even vendored) needs to install a hook to make distributions discoverable.
  • That hook needs to honor hooks by a variety of package providers in order to allow Distributions to be discoverable by any number of providers.
  • Older versions of importlib_metadata are incompatible with the version of importlib_metadata vendored by Setuptools.

Can you speak a little more to the impact of this issue? Other than that the entry_point values have unexpected origins, what is the concern (why not just ignore it)?

Have you considered not importing setuptools? I expect Setuptools to be used primarily as a build backend for building packages, where I would not expect the class of EntryPoint to be particularly relevant. What is your usage of setuptools such that it triggers this undesirable behavior?

@jaraco jaraco self-assigned this Feb 16, 2022
@jaraco jaraco added Needs Discussion Issues where the implementation still needs to be discussed. and removed Needs Triage Issues that need to be evaluated for severity and status. labels Feb 16, 2022
@sphuber
Copy link
Author

sphuber commented Feb 17, 2022

Thanks @jaraco for the detailed comment.

Are you sure? Setuptools started vendoring importlib_metadata in 6.8.0. It started using it in 6.9.0, and it specifically took precedence over a base install in 6.9.1 due to #3107.

I am not an expert, so I probably described the exact cause incorrectly. But what I reported as the observed behavior seems to be reproducible. It seems then maybe that when setuptools started using it, the behavior was triggered.

It'd be good to know if 6.9.0 experiences the undesirable behavior you report.

I will do this test later and report back with the results.

Can you speak a little more to the impact of this issue? Other than that the entry_point values have unexpected origins, what is the concern (why not just ignore it)?

We discovered the problem, because in our application we have the following logic:

from importlib_metadata import EntryPoint
if isinstance(some_variable, EntryPoint):
    # Some logic

With setuptools==60.9.1 this conditional was no longer being hit, because setuptools._vendor.importlib_metadata.EntryPoint != importlib_metadata.EntryPoint. We have refactored our code as much as possible to no longer rely on this type check, but it is not always ideal or even fully possible. It is not always desirable to rely fully on duck-typing.

Have you considered not importing setuptools? I expect Setuptools to be used primarily as a build backend for building packages, where I would not expect the class of EntryPoint to be particularly relevant. What is your usage of setuptools such that it triggers this undesirable behavior?

We don't install nor import it in our package, but for the bug to manifest, setuptools nearly needs to be present in the environment. However, we cannot control that setuptools will not be present in the environment where our package is installed. So we have to operate under the assumption that setuptools might be present.

@sphuber
Copy link
Author

sphuber commented Feb 17, 2022

The behavior for 60.9.0 is identical to that of 60.9.1:

Python 3.8.10 (default, Nov 26 2021, 20:14:08) 
Type 'copyright', 'credits' or 'license' for more information
IPython 7.31.1 -- An enhanced Interactive Python. Type '?' for help.

In [1]: import setuptools

In [2]: setuptools.__version__
Out[2]: '60.9.0'

In [3]: from importlib_metadata import entry_points

In [4]: ep = entry_points().select(group='aiida.calculations', name='core.arithmetic.add')['core.arithmetic.add']

In [5]: type(ep)
Out[5]: setuptools._vendor.importlib_metadata.EntryPoint

In [6]: str(ep)
Out[6]: "EntryPoint(name='core.arithmetic.add', value='aiida.calculations.arithmetic.add:ArithmeticAddCalculation', group='aiida.calculations')"

@Avasam
Copy link
Contributor

Avasam commented Oct 27, 2023

If importlib.metadata is part of the stdlib in Python 3.8, and the minimal Python version supported by setuptools is 3.8 . Is there a reason to keep vendored importlib_metadata around?

Edit: I found an instance of importlib_metadata being preferred for 3.8 and 3.9: https://github.com/pypa/setuptools/blob/main/setuptools/_importlib.py#L40

I assume this has to do with python/cpython#88779 ? Not sure. Or more likely python/importlib_metadata#396

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Needs Discussion Issues where the implementation still needs to be discussed.
Projects
None yet
Development

No branches or pull requests

3 participants