python-3.xpypdf

module 'PyPDF2' has no attribute 'PdfFileReader'


I am following along the book "Automate Boring Stuff with Python", but I receive the an error when trying to run this simple script.

import PyPDF2

pdfFileObj = open('meetingminutes.pdf', 'rb')
pdfReader = PyPDF2.PdfFileReader(pdfFileObj)

The complete error message was:

runfile('D:/Python files/PyPDF2/PyPDF2.py', wdir='D:/Python files/PyPDF2')
Traceback (most recent call last):

  File "<ipython-input-4-caab1b8716b0>", line 1, in <module>
    runfile('D:/Python files/PyPDF2/PyPDF2.py', wdir='D:/Python files/PyPDF2')

  File "C:\Users\cjwu\AppData\Local\Continuum\anaconda3\lib\site-packages\spyder\utils\site\sitecustomize.py", line 705, in runfile
    execfile(filename, namespace)

  File "C:\Users\cjwu\AppData\Local\Continuum\anaconda3\lib\site-packages\spyder\utils\site\sitecustomize.py", line 102, in execfile
    exec(compile(f.read(), filename, 'exec'), namespace)

  File "D:/Python files/PyPDF2/PyPDF2.py", line 22, in <module>
    import PyPDF2

  File "D:\Python files\PyPDF2\PyPDF2.py", line 25, in <module>
    pdfReader = PyPDF2.PdfFileReader(pdfFileObj)

AttributeError: module 'PyPDF2' has no attribute 'PdfFileReader'

Thank you for your help!


Solution

  • From this:

    runfile('D:/Python files/PyPDF2/PyPDF2.py', wdir='D:/Python files/PyPDF2')

    It seems you named your file as PyPDF2.py, which is the same name as the PyPDF2 package. Do not do this because that will conflict with the imports from the actual PyPDF2 package.

    From the Module Search Path docs:

    When a module named spam is imported, the interpreter first searches for a built-in module with that name. If not found, it then searches for a file named spam.py in a list of directories given by the variable sys.path.
    ...
    The directory containing the script being run is placed at the beginning of the search path, ahead of the standard library path. This means that scripts in that directory will be loaded instead of modules of the same name in the library directory.

    So when you do:

    import PyPDF2
    PyPDF2.PdfFileReader(pdfFileObj)
    

    The import command will look for PdfFileReader from your PyPDF2.py because it imported your PyPDF2.py instead of the actual PyPDF2 package. You can check it by printing PyPDF2.__file__ after importing, which should show the path to the current script.

    Simply name your file to something else.
    Example:

    PyPDF2.py --> mypdfapp.py

    Actually, I would also recommend renaming the parent folder (which is also PyPDF2).
    Example:

    D:/Python files/PyPDF2/PyPDF2.py --> D:/Python files/project01/mypdfapp.py