Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
dejudicibus opened this issue Nov 9, 2021 · 15 comments
Closed

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

dejudicibus opened this issue Nov 9, 2021 · 15 comments

Comments

@dejudicibus
Copy link

dejudicibus commented Nov 9, 2021

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
Copy link
Owner

scanny commented Nov 9, 2021

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
Copy link
Owner

scanny commented Nov 9, 2021

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
Copy link

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
Copy link

innovation-plantation commented Nov 10, 2021

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
Copy link

innovation-plantation commented Nov 10, 2021

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

  • import collections
  • import collections.abc
A:\>python
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
>>> import collections.abc
>>> collections.abc.__file__
'C:\\Python\\Python310\\lib\\collections\\abc.py'
>>> Container = collections.abc.Container
>>>

@scanny
Copy link
Owner

scanny commented Nov 10, 2021

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
Copy link
Owner

scanny commented Nov 10, 2021

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
Copy link

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
Copy link
Owner

scanny commented Nov 10, 2021

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
Copy link
Author

dejudicibus commented Nov 10, 2021 via email

@scanny
Copy link
Owner

scanny commented Nov 15, 2021

@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
Copy link
Author

dejudicibus commented Nov 15, 2021 via email

@Ace-Of-Snakes
Copy link

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?

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
Copy link

This issue is fixed in python-pptx-fix

@scanny
Copy link
Owner

scanny commented Aug 20, 2023

Fixed in release 0.6.22 circa Aug 20, 2023.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants