kakakakakku blog

Weekly Tech Blog: Keep on Learning!

暫定対応 : Python 3.10 で python-pptx を使おうとすると collections で AttributeError が出てしまう

「python-pptx」は Python で Microsoft PowerPoint ファイルを操作できるライブラリでよく使っている❗️

github.com

最近 Python 3.10(今回の環境だと 3.10.8)で python-pptx を使おうと思ったら,以下のように AttributeError: module 'collections' has no attribute 'abc'AttributeError: module 'collections' has no attribute 'Container' というエラーが出てしまった🔥暫定対応をまとめておく.

$ python --version
Python 3.10.8

$ python ~/python-pptx.py
Traceback (most recent call last):
  File "/usr/local/lib/python3.10/site-packages/pptx/compat/__init__.py", line 10, in <module>
    Container = collections.abc.Container
AttributeError: module 'collections' has no attribute 'abc'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/kakakakakku/python-pptx.py", line 1, in <module>
    from pptx import Presentation
  File "/usr/local/lib/python3.10/site-packages/pptx/__init__.py", line 14, in <module>
    from pptx.api import Presentation  # noqa
  File "/usr/local/lib/python3.10/site-packages/pptx/api.py", line 15, in <module>
    from .package import Package
  File "/usr/local/lib/python3.10/site-packages/pptx/package.py", line 6, in <module>
    from pptx.opc.package import OpcPackage
  File "/usr/local/lib/python3.10/site-packages/pptx/opc/package.py", line 11, in <module>
    from pptx.compat import is_string, Mapping
  File "/usr/local/lib/python3.10/site-packages/pptx/compat/__init__.py", line 14, in <module>
    Container = collections.Container
AttributeError: module 'collections' has no attribute 'Container'

理由としては collections は Python 3.3 で非推奨になって,Python 3.9 までは使えるようになっていた.しかし Python 3.10 ではサポートされず,collections.abc を使う必要がある.python-pptx では collections に依存する箇所があって Python 3.10 で動かなくなっている.

Deprecated since version 3.3, will be removed in version 3.10: Moved Collections Abstract Base Classes to the collections.abc module. For backwards compatibility, they continue to be visible in this module through Python 3.9.
collections — Container datatypes — Python 3.9.14 documentation

暫定対応

現時点(2022年11月末)でリリースされている python-pptx の最新バージョン 0.6.21 では Python 3.10 に対応してなく,暫定対応(ワークアラウンド)としてコードを直接修正する必要がある.以下のように pip show コマンドを使ってコードディレクトリを探して,pptx/compat/__init__.py を修正する.今回は /usr/local/lib/python3.10/site-packages/pptx/compat/__init__.py にあった.

$ pip show python-pptx | grep Location
Location: /usr/local/lib/python3.10/site-packages

そして pptx/compat/__init__.py の前半を以下のように修正する.

import sys

try:
    import collections.abc
    Container = collections.abc.Container
    Mapping = collections.abc.Mapping
    Sequence = collections.abc.Sequence
except ImportError:
    import collections
    Container = collections.Container
    Mapping = collections.Mapping
    Sequence = collections.Sequence

実際に python-pptx にプルリクエストも出ているし,Approved も付いているし,merge されるとイイなぁー❗️

github.com

もしくは pptx/compat/__init__.py は修正せずに,以下のように Python コードに直接 import collections.abc を書いてしまう案もある.その場合には順番に注意すること👀

import collections.abc
from pptx import Presentation

関連 issue