'How to fix AttributeError: 'ZipFile' object has no attribute 'seek' in this code?

My task is to take a ZIP file of images and process them, using the PIL, Tesseract, and OpenCV libraries built into Python. The files in the ZIP file are newspaper images. The task is to write Python code which allows one to search through the images looking for the occurrences of keywords and faces. E.g. if you search for "pizza", it will return a contact sheet of all of the faces which were located on the newspaper page which mentions "pizza".

This is my code so far:

#Use zipfile library to open the zipfile
import zipfile
from zipfile import ZipFile
from PIL import Image

small_img = "readonly/small_img.zip"

#Iterate through the objects (newspapers) in zipfile using .infolist()
with ZipFile(small_img, 'r') as zip:
    #printing all the contents of the zip file
    zip.printdir()
  
    #extracting all the files
    print('Extracting all the files now...')
    zip.extractall()
    print('Done!')

#Write a simple routine to go through the zipfile, and print the name of the file
def print_file(archive_name):
    zf = zipfile.ZipFile(archive_name)
    for info in zf.infolist():
        print('File Name:' + info.filename)    
        
print_file(small_img)

#Display the files
def display_newsfile(archive_name):
    with ZipFile(small_img, 'r') as zip:
        zip.extractall()
        zf = zipfile.ZipFile(archive_name)
        for info in zf.infolist():
            image = Image.open(info)
            display(image)
        
display_newsfile(zip)

When I run this I receive the following output with the error listed below:

File Name                                             Modified             Size
a-0.png                                        2019-02-26 22:30:30     21000053
a-1.png                                        2019-02-26 22:30:28     22598429
a-2.png                                        2019-02-26 22:30:28      3650049
a-3.png                                        2019-02-26 22:30:30     18646538
Extracting all the files now...
Done!
File Name:a-0.png
File Name:a-1.png
File Name:a-2.png
File Name:a-3.png
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-38-234780db859a> in <module>
     33             display(image)
     34 
---> 35 display_newsfile(zip)
     36 
     37 

<ipython-input-38-234780db859a> in display_newsfile(archive_name)
     28     with ZipFile(small_img, 'r') as zip:
     29         zip.extractall()
---> 30         zf = zipfile.ZipFile(archive_name)
     31         for info in zf.infolist():
     32             image = Image.open(info)

/opt/conda/lib/python3.7/zipfile.py in __init__(self, file, mode, compression, allowZip64, compresslevel)
   1220         try:
   1221             if mode == 'r':
-> 1222                 self._RealGetContents()
   1223             elif mode in ('w', 'x'):
   1224                 # set the modified flag so central directory gets written

/opt/conda/lib/python3.7/zipfile.py in _RealGetContents(self)
   1283         fp = self.fp
   1284         try:
-> 1285             endrec = _EndRecData(fp)
   1286         except OSError:
   1287             raise BadZipFile("File is not a zip file")

/opt/conda/lib/python3.7/zipfile.py in _EndRecData(fpin)
    257 
    258     # Determine file size
--> 259     fpin.seek(0, 2)
    260     filesize = fpin.tell()
    261 

AttributeError: 'ZipFile' object has no attribute 'seek'

I'm fairly new to coding so I'm not sure why the same block of code would work for the print_file function but not the display_newsfile function. One of the hints included in the assignment states:

'The PIL.Image library can .open() files, and that items in .infolist() in the zipfile each appear to Python just as if they were a file (these are called "file-like" objects).'

Based on that info I feel like the 'display_newsfile' function should be correct with what I have written. Open to any thoughts you might have.



Solution 1:[1]

In the last line

display_newsfile(zip)

zip already is some ZipFile object, namely created in the very beginning:

with ZipFile(small_img, 'r') as zip:

Within display_news, you then – again! – try to open the input using zipfile:

zf = zipfile.ZipFile(archive_name)

That cannot work, since archive_name now basically is zip. So, to fix that, for example, just change the last line to:

display_newsfile(small_img)

After fixing that, you'll encounter another error from:

image = Image.open(info)

You need to change that to:

image = Image.open(info.filename)

Then, your code should be fine – at least runs on my machine then.

----------------------------------------
System information
----------------------------------------
Platform:      Windows-10-10.0.19042-SP0
Python:        3.9.6
PyCharm:       2021.2
Pillow:        8.3.1
----------------------------------------

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 HansHirse