python / importlib_metadata

Library to access metadata for Python packages
https://importlib-metadata.readthedocs.io
Apache License 2.0
123 stars 80 forks source link

ReadTheDocs broken by a bug in `importlib_metadata` since release of `pygment v2.13.0` #403

Closed kif closed 1 year ago

kif commented 2 years ago

This affects only Python3.7, and not all version of Python3.7, but especially the one used for ReadTheDocs. RTD relies on pygment for syntax highlighting, and the latest version uses importlib.metadata, a backup of which is provided by this package for Py3.7.

To reproduce the bug, on a debian10 running Python3.7, create a virtual-env with just this package and perform:

import importlib_metadata
importlib_metadata.entry_points()

It is possible that the bug comes from something else, but that's where my investigation lead for now.

Related issues: https://github.com/silx-kit/pyFAI/issues/1726 https://github.com/pygments/pygments/issues/2218

kif commented 2 years ago

The bug is likely in RTD itself. Sorry for the noise.

kif commented 2 years ago

Diving into this bug, it comes down to importlib_metadata.entry_points() raising an exception when a package was installed using python setup.py install. While we all agree that this method is deprecated and should be replaced by pip install ., it has widely been used and still is. Since importlib_metadata is a compatibility library, it should accommodate for this old way of working.

Here is the complete stack-trace: it is a bunch of generator called function, not simple to follow:

Traceback (most recent call last):
  File "debug.py", line 3, in <module>
    importlib_metadata.entry_points()
  File "/tmp/rtd/py37/lib/python3.7/site-packages/importlib_metadata/__init__.py", line 1047, in entry_points
    return SelectableGroups.load(eps).select(**params)
  File "/tmp/rtd/py37/lib/python3.7/site-packages/importlib_metadata/__init__.py", line 477, in load
    ordered = sorted(eps, key=by_group)
  File "/tmp/rtd/py37/lib/python3.7/site-packages/importlib_metadata/__init__.py", line 1045, in <genexpr>
    dist.entry_points for dist in _unique(distributions())
  File "/tmp/rtd/py37/lib/python3.7/site-packages/importlib_metadata/_itertools.py", line 16, in unique_everseen
    k = key(element)
  File "/tmp/rtd/py37/lib/python3.7/site-packages/importlib_metadata/__init__.py", line 961, in _normalized_name
    or super()._normalized_name
  File "/tmp/rtd/py37/lib/python3.7/site-packages/importlib_metadata/__init__.py", line 628, in _normalized_name
    return Prepared.normalize(self.name)
  File "/tmp/rtd/py37/lib/python3.7/site-packages/importlib_metadata/__init__.py", line 883, in normalize
    return re.sub(r"[-_.]+", "-", name).lower().replace('-', '_')
  File "/usr/lib/python3.7/re.py", line 192, in sub
    return _compile(pattern, flags).sub(repl, string, count)
TypeError: expected string or bytes-like object
kif commented 2 years ago

The error was already present in importlib-metadata==4.11.0

jaraco commented 1 year ago

This issue doesn't occur for me:

 draft $ docker run -it jaraco/multipy-tox bash -c 'py -3.7 -m venv .venv; py -m pip install -q -U pip pygments importlib_metadata; py -c "import importlib_metadata as md; print(md.entry_points().groups)"'
{'console_scripts', 'setuptools.installation', 'distutils.commands', 'distutils.setup_keywords', 'egg_info.writers', 'setuptools.finalize_distribution_options'}

Of course, I'm not using debian10, I'm instead using Ubuntu 22.04, so that may be a factor. Also, I found I had to replace pygment with pygments to get the install to work.

Of course, you also mentioned setup.py install - I'm not sure what is installed that way.

Can you put together some repro steps that will help someone replicate the error?

jaraco commented 1 year ago

I tried replicating the issue by installing pygments using setup.py install, but still the issue doesn't replicate. I'll be happy to revisit if repro steps can be provided.