scanny / python-pptx

Create Open XML PowerPoint documents in Python
MIT License
2.37k stars 513 forks source link

AttributeError: module 'collections' has no attribute 'abc' #762

Closed dejudicibus closed 1 year ago

dejudicibus commented 2 years ago

I just created a simple test.py file

from pptx import Presentation prs = Presentation()

but when I run it I get

`Traceback (most recent call last): File "C:\Python\lib\site-packages\pptx\compat__init__.py", line 10, in 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 "D:\Docs\mycompany\Code\Python\Excel\test.py", line 1, in from pptx import Presentation File "C:\Python\lib\site-packages\pptx__init__.py", line 14, in from pptx.api import Presentation # noqa File "C:\Python\lib\site-packages\pptx\api.py", line 15, in from .package import Package File "C:\Python\lib\site-packages\pptx\package.py", line 6, in from pptx.opc.package import OpcPackage File "C:\Python\lib\site-packages\pptx\opc\package.py", line 11, in from pptx.compat import is_string, Mapping File "C:\Python\lib\site-packages\pptx\compat__init__.py", line 14, in Container = collections.Container AttributeError: module 'collections' has no attribute 'Container'

Process finished with exit code 1`

Any idea why?

scanny commented 2 years ago

What Python version are you running? Also state its provenance, like Anaconda or some other package and its version.

Also, try this from the Python command line (in the same project directory) and let us know what you get:

>>> import collections
>>> collections.__file__
???
>>> OrderedDict = collections.OrderedDict
??? (possibly no output)
>>> Container = collections.abc.Container
???
>>> Container = collections.Container
???
scanny commented 2 years ago

btw, I expect this is Python 3.10 related, so in the meantime if you downgrade to Python 3.9 I expect it will work until we can determine root cause.

innovation-plantation commented 2 years ago

Continued conversation from python-pptx-mini #760

Here's the requested test output:

Python 3.10.0 (tags/v3.10.0:b494f59, Oct  4 2021, 19:00:18) [MSC v.1929 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import collections
>>> collections.__file__
'C:\\Python\\Python310\\lib\\collections\\__init__.py'
>>> OrderedDict = collections.OrderedDict
>>> Container = collections.abc.Container
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: module 'collections' has no attribute 'abc'
>>> Container = collections.Container
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: module 'collections' has no attribute 'Container'
>>>
innovation-plantation commented 2 years ago

Under 3.9.6: Note the deprecation warning.

Python 3.9.6 (tags/v3.9.6:db3ff76, Jun 28 2021, 15:26:21) [MSC v.1929 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license()" for more information.
>>> import collections
>>> collections.__file__
'C:\\Users\\...\\AppData\\Local\\Programs\\Python\\Python39\\lib\\collections\\__init__.py'
>>> OrderedDict = collections.OrderedDict
>>> Container = collections.abc.Container
>>> Container = collections.Container

Warning (from warnings module):
  File "<pyshell#5>", line 1
DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated since Python 3.3, and in 3.10 it will stop working
>>> 
innovation-plantation commented 2 years ago

It looks like Python 3.10 is happy if you do both imports

scanny commented 2 years ago

Okay, I think this gives us what we need to know.

My diagnosis is that Python 3.10 on Windows for some reason does not allow the collections.abc subpackage to be referenced from the collections module. It actually works fine on MacOS and Linux, so I expect this is unintended, a bug folks might say. You could confirm this with the following at a fresh Python prompt:

>>> import collections
>>> "abc" in dir(collections)
True or False

I expect you'll see False, which would explain why collections.abc raises AttributeError. That snippet returns True on my MacOS box running Python 3.10.

It's possible there is an open bug report for this on the Python issue tracker so it may go away in the next 3.10 subversion. In the meantime, especially since 3.10 is so new (only 3.10.0 is available on my machine), unless you have a compelling reason to be on the very latest Python version, I recommend using 3.9 or 3.8.

Barring that, this monkey patch may work if applied before any from pptx import Presentation line (or import pptx):

import collections
import collections.abc
c = collections
c.abc = collections.abc

from pptx import Presentation
...

Meanwhile, I'll shortlist this issue, but I don't have any other reason to cut a new release so I don't have any immediate plans to do so and it may be a while before I do.

In any case, please try the monkeypatch and let me know if it works so we can use it as a workaround for others who encounter this. I don't have a Windows box at my disposal.

scanny commented 2 years ago

I couldn't find a bug report for this on the Python bug tracker so I added one. We'll see what they have to say in a few days I expect. https://bugs.python.org/issue45776

innovation-plantation commented 2 years ago

It's a bit obscure, but I think it's intentional after more carefully reading the deprecation warning from Python3.9

DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated since Python 3.3, and in 3.10 it will stop working

This is exactly importing the abc's from collections instead of collections.abc That is exactly what it says will stop working in 3.10, and it did on Windows. I wouldn't be too surprised if the resolution is to also break it on other platforms for consistency. In any case a new release to comply will help pretty much every windows user who tries to install python-pptx for Python3, and now that Python2 is losing support, it may be about all Windows users or evaluators thinking of using it.

I'll see if I get a chance to work on it tomorrow. For a workaround I resorted to VBA in a pptm file and that's working.

scanny commented 2 years ago

I can see why you might say that, but this isn't using or importing an ABC from collections, it's using the abc submodule from collections. An ABC would be like Mapping or Container. Also, if it was intentional, why would it work on MacOS (and I expect Linux)?

Also, the intent here was to segregate the abstract base classes (ABCs) into their own module, not to make it less convenient to access that module. So I'll be surprised if they "break" it for other platforms for "equity's" sake :). I think the more plausible explanation was that the maintainer accidentally removed an import collections.abc as abc line from the Windows version or whatever when they were in there removing the import collections.abc.Sequence as Sequence lines that effected the "works either way" behavior during the deprecation period.

Be that as it may, it doesn't matter much to me either way. Whether the Python team "fixes" it or not, I'll still do the import in the "safe" way next time I'm in the code, and that way it will work on any version on any OS, including 3.10.0 under Windows.

dejudicibus commented 2 years ago

OK, I made a test. If I create test.py as

from pptx import Presentation

I get

Traceback (most recent call last): File "C:\Python\lib\site-packages\pptx\compat__init__.py", line 10, in

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 "D:\Docs\#Accompany\Code\Python\Excel\test.py", line 2, in from pptx import Presentation File "C:\Python\lib\site-packages\pptx\__init__.py", line 14, in from pptx.api import Presentation # noqa File "C:\Python\lib\site-packages\pptx\api.py", line 15, in from .package import Package File "C:\Python\lib\site-packages\pptx\package.py", line 6, in from pptx.opc.package import OpcPackage File "C:\Python\lib\site-packages\pptx\opc\package.py", line 11, in from pptx.compat import is_string, Mapping File "C:\Python\lib\site-packages\pptx\compat\__init__.py", line 14, in Container = collections.Container AttributeError: module 'collections' has no attribute 'Container' Process finished with exit code 1 but I get no error if test.py is from collections.abc import Container from pptx import Presentation On Wed, Nov 10, 2021 at 8:52 AM innovation-plantation < ***@***.***> wrote: > It's a bit obscure, but I think it's intentional after more carefully > reading the deprecation warning from Python3.9 > > DeprecationWarning: Using or importing the ABCs from 'collections' instead > of from 'collections.abc' is deprecated since Python 3.3, and in 3.10 it > will stop working > > This is exactly importing the abc's from collections instead of > collections.abc > That is exactly what it says will stop working in 3.10, and it did on > Windows. > I wouldn't be too surprised if the resolution is to also break it on other > platforms for consistency. > In any case a new release to comply will help pretty much every windows > user who tries to > install python-pptx for Python3, and now that Python2 is losing support, > it may be about all > Windows users or evaluators thinking of using it. > > I'll see if I get a chance to work on it tomorrow. For a workaround I > resorted to VBA > in a pptm file and that's working. > > — > You are receiving this because you authored the thread. > Reply to this email directly, view it on GitHub > , > or unsubscribe > > . > Triage notifications on the go with GitHub Mobile for iOS > > or Android > . > > -- Dario de Judicibus, Rome, Italy (EU) Site: https://www.dejudicibus.it, https://genealogia.dejudicibus.it Blog: https://www.lindipendente.eu Book: https://www.lalamanera.it, https://www.lasorgentedeimondi.it
scanny commented 2 years ago

@dejudicibus yes, I think that's the right workaround until we fix this, to import collections.abc before pptx

import collections.abc

from pptx import Presentation

After import collections.abc, the collections module will have a .abc attribute and the Python2/3 machinery in python-pptx should work properly.

dejudicibus commented 2 years ago

yes, it works

On Mon, Nov 15, 2021 at 9:08 PM Steve Canny @.***> wrote:

@dejudicibus https://github.com/dejudicibus yes, I think that's the right workaround until we fix this, to import collections.abc before pptx

import collections.abc from pptx import Presentation

After import collections.abc, the collections module will have a .abc attribute and the Python2/3 machinery in python-pptx should work properly.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/scanny/python-pptx/issues/762#issuecomment-969276336, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAK5PECUY5G53CPUNMQ62ZLUMFSDBANCNFSM5HVBEPDA . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

-- Dario de Judicibus, Rome, Italy (EU) Site: https://www.dejudicibus.it, https://genealogia.dejudicibus.it Blog: https://www.lindipendente.eu Book: https://www.lalamanera.it, https://www.lasorgentedeimondi.it

Ace-Of-Snakes commented 1 year ago

I just created a simple test.py file

from pptx import Presentation prs = Presentation()

but when I run it I get

`Traceback (most recent call last): File "C:\Python\lib\site-packages\pptx\compatinit.py", line 10, in 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 "D:\Docs\mycompany\Code\Python\Excel\test.py", line 1, in from pptx import Presentation File "C:\Python\lib\site-packages\pptxinit.py", line 14, in from pptx.api import Presentation # noqa File "C:\Python\lib\site-packages\pptx\api.py", line 15, in from .package import Package File "C:\Python\lib\site-packages\pptx\package.py", line 6, in from pptx.opc.package import OpcPackage File "C:\Python\lib\site-packages\pptx\opc\package.py", line 11, in from pptx.compat import is_string, Mapping File "C:\Python\lib\site-packages\pptx\compatinit.py", line 14, in Container = collections.Container AttributeError: module 'collections' has no attribute 'Container'

Process finished with exit code 1`

Any idea why?

So the solution for this which I found works for me is:

  1. go into the file where the container is defined
  2. instead of import collections write import _collections_abs as collections
  3. bing bang boom for me that solves all
kascodeo commented 1 year ago

This issue is fixed in python-pptx-fix

scanny commented 1 year ago

Fixed in release 0.6.22 circa Aug 20, 2023.