当我importlib_meta从版本升级8.4.08.5.0(昨天刚刚发布,2024 年 9 月 11 日)时,当我开始使用运行开发服务器时出现以下错误python manage.py runserver

   File "/app/manage.py", line 17, in main
     execute_from_command_line(sys.argv)
   File "/usr/local/lib/python3.10/site-packages/django/core/management/__init__.py", line 442, in execute_from_command_line
     utility.execute()
   File "/usr/local/lib/python3.10/site-packages/django/core/management/__init__.py", line 436, in execute
     self.fetch_command(subcommand).run_from_argv(self.argv)
   File "/usr/local/lib/python3.10/site-packages/django/core/management/base.py", line 413, in run_from_argv
     self.execute(*args, **cmd_options)
   File "/usr/local/lib/python3.10/site-packages/django/core/management/commands/runserver.py", line 75, in execute
     super().execute(*args, **options)
   File "/usr/local/lib/python3.10/site-packages/django/core/management/base.py", line 459, in execute
     output = self.handle(*args, **options)
   File "/usr/local/lib/python3.10/site-packages/django/core/management/commands/runserver.py", line 112, in handle
     self.run(**options)
   File "/usr/local/lib/python3.10/site-packages/django/core/management/commands/runserver.py", line 119, in run
     autoreload.run_with_reloader(self.inner_run, **options)
   File "/usr/local/lib/python3.10/site-packages/django/utils/autoreload.py", line 671, in run_with_reloader
     start_django(reloader, main_func, *args, **kwargs)
   File "/usr/local/lib/python3.10/site-packages/django/utils/autoreload.py", line 660, in start_django
     reloader.run(django_main_thread)
   File "/usr/local/lib/python3.10/site-packages/django/utils/autoreload.py", line 344, in run
     self.run_loop()
   File "/usr/local/lib/python3.10/site-packages/django/utils/autoreload.py", line 350, in run_loop
     next(ticker)
   File "/usr/local/lib/python3.10/site-packages/django/utils/autoreload.py", line 390, in tick
     for filepath, mtime in self.snapshot_files():
   File "/usr/local/lib/python3.10/site-packages/django/utils/autoreload.py", line 411, in snapshot_files
     for file in self.watched_files():
   File "/usr/local/lib/python3.10/site-packages/django/utils/autoreload.py", line 304, in watched_files
     yield from iter_all_python_module_files()
   File "/usr/local/lib/python3.10/site-packages/django/utils/autoreload.py", line 120, in iter_all_python_module_files
     return iter_modules_and_files(modules, frozenset(_error_files))
 TypeError: unhashable type: 'types.SimpleNamespace'

我实际上可以将问题缩小到以下提交

当我importlib_meta在有问题的提交之前安装一个提交时,pip install git+https://github.com/python/importlib_metadata@d968f6270d55f27a10491344a22e9e0fd77b5583错误消失了。当我importlib_meta在有问题的提交处安装时,错误开始出现。

我真的无法理解 Traceback 以及问题可能与上述提交的更改有何关联。有人知道是什么原因导致了这个问题或者我该如何调试它吗?


最佳答案
2

zipfile = types.SimpleNamespace(**vars(importlib.import_module('zipfile')))
...
sys.modules[__name__ + '.zipfile'] = zipfile  # type: ignore[assignment]

这是

    modules = tuple(
        m
        for m in map(sys.modules.__getitem__, keys)
        if not isinstance(m, weakref.ProxyTypes)
    )
    # WARNING: `modules` now has `zipfile = types.SimpleNamespace(...)` in it
    return iter_modules_and_files(modules, frozenset(_error_files))


@lru_cache(maxsize=1)
def iter_modules_and_files(modules, extra_files):

来自 Python 文档

由于使用字典来缓存结果,因此函数的位置参数和关键字参数必须是

types.SimpleNamespace()不可哈希:

>>> from types import SimpleNamespace
>>> hash(SimpleNamespace())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'types.SimpleNamespace'

我想说这是一个 django 问题 – django 应该考虑到sys.modules在运行时受 monkeypatching 影响的事实,并且可以保存任意对象(包括不可散列的对象)。

1

  • 太棒了。感谢您清晰地概述了这个问题!


    – 

我只是硬编码

importlib_metadata==8.4.0

放入我的 requirements.txt 文件中,现在它又可以正常工作了。我会一直保持这种状态,直到他们修复该错误。