markdown: AttributeError: module 'importlib' has no attribute 'util' with python-markdown 3.4 on macOS/Windows

With python3.9 on macOS:

$ python3.9 -m venv venv
$ source venv/bin/activate
$ pip install markdown
Collecting markdown
  Using cached Markdown-3.4-py3-none-any.whl (93 kB)
Collecting importlib-metadata>=4.4; python_version < "3.10"
  Using cached importlib_metadata-4.12.0-py3-none-any.whl (21 kB)
Collecting zipp>=0.5
  Using cached zipp-3.8.1-py3-none-any.whl (5.6 kB)
Installing collected packages: zipp, importlib-metadata, markdown
Successfully installed importlib-metadata-4.12.0 markdown-3.4 zipp-3.8.1
WARNING: You are using pip version 20.2.3; however, version 22.1.2 is available.
You should consider upgrading via the '/Users/mike/tmp/resume.md/venv/bin/python3.9 -m pip install --upgrade pip' command.
$ python
Python 3.9.4 (default, Apr 16 2021, 21:18:07)
[Clang 12.0.0 (clang-1200.0.32.29)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import markdown
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/mike/tmp/resume.md/venv/lib/python3.9/site-packages/markdown/__init__.py", line 22, in <module>
    from .core import Markdown, markdown, markdownFromFile
  File "/Users/mike/tmp/resume.md/venv/lib/python3.9/site-packages/markdown/core.py", line 27, in <module>
    from .preprocessors import build_preprocessors
  File "/Users/mike/tmp/resume.md/venv/lib/python3.9/site-packages/markdown/preprocessors.py", line 29, in <module>
    from .htmlparser import HTMLExtractor
  File "/Users/mike/tmp/resume.md/venv/lib/python3.9/site-packages/markdown/htmlparser.py", line 29, in <module>
    spec = importlib.util.find_spec('html.parser')
AttributeError: module 'importlib' has no attribute 'util'
>>>

With python3.10 on macOS:

$ python3.10 -m venv 3.10
$ source 3.10/bin/activate
$ pip install markdown
Collecting markdown
  Using cached Markdown-3.4-py3-none-any.whl (93 kB)
Installing collected packages: markdown
Successfully installed markdown-3.4
WARNING: You are using pip version 22.0.4; however, version 22.1.2 is available.
You should consider upgrading via the '/Users/mike/tmp/resume.md/3.10/bin/python3.10 -m pip install --upgrade pip' command.
$ python
Python 3.10.3 (main, Mar 25 2022, 22:16:41) [Clang 12.0.5 (clang-1205.0.22.9)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import markdown
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/mike/tmp/resume.md/3.10/lib/python3.10/site-packages/markdown/__init__.py", line 22, in <module>
    from .core import Markdown, markdown, markdownFromFile
  File "/Users/mike/tmp/resume.md/3.10/lib/python3.10/site-packages/markdown/core.py", line 27, in <module>
    from .preprocessors import build_preprocessors
  File "/Users/mike/tmp/resume.md/3.10/lib/python3.10/site-packages/markdown/preprocessors.py", line 29, in <module>
    from .htmlparser import HTMLExtractor
  File "/Users/mike/tmp/resume.md/3.10/lib/python3.10/site-packages/markdown/htmlparser.py", line 29, in <module>
    spec = importlib.util.find_spec('html.parser')
AttributeError: module 'importlib' has no attribute 'util'

pip install "markdown<3.4" works, so this is perhaps a regression in the 3.4 release?

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Comments: 39 (6 by maintainers)

Commits related to this issue

Most upvoted comments

Okay, I can reproduce the error sometimes, but not every time.

>>> import importlib
>>> importlib.util
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: module 'importlib' has no attribute 'util'
>>> from importlib import util
>>> importlib.util
<module 'importlib.util' from 'C:\\Users\\wlimberg\\AppData\\Local\\Programs\\Python\\Python38\\lib\\importlib\\util.py'>

A few things to note:

  1. This is Python 3.8 on Windows. Not one of the reported problem environments (but the only one I have access to at the moment).
  2. I can run Markdown just fine in this environment.
  3. The error only occurs if I do the imports in a certain order. Once util is imported directly, then it can be referenced from importlib.util, but not before.

However, I can do this with no errors:

from importlib.util import find_spec, module_from_spec

@mikepqr I’m wondering if this change will work for you:

diff --git a/markdown/htmlparser.py b/markdown/htmlparser.py
index 7ca858e..cfdc49c 100644
--- a/markdown/htmlparser.py
+++ b/markdown/htmlparser.py
@@ -20,14 +20,14 @@ License: BSD (see LICENSE.md for details).
 """

 import re
-import importlib
 import sys

+from importlib.util import find_spec, module_from_spec

 # Import a copy of the html.parser lib as `htmlparser` so we can monkeypatch it.
 # Users can still do `from html import parser` and get the default behavior.
-spec = importlib.util.find_spec('html.parser')
-htmlparser = importlib.util.module_from_spec(spec)
+spec = find_spec('html.parser')
+htmlparser = module_from_spec(spec)
 spec.loader.exec_module(htmlparser)
 sys.modules['htmlparser'] = htmlparser

It seems to work for me.

I can’t understand why this makes a difference. And weirdly, now I suddenly can’t get Markdown to work without the change when I import it from within a Python session. However, when I call Markdown from the command line (python -m markdown), I get no error.

I understand, but there is something else going on here. I should be able to reproduce this issue on macOS…I’ll have to spend some time this evening and see isolate things in a virtual environment. I should note that I’m on Python 3.10.4. Not sure if that makes a difference either.