james-see / iptcinfo3

iptcinfo working for python 3 finally do pip3 install iptcinfo3

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

save() throws traceback with TypeError

mb243 opened this issue · comments

commented

iptcinfo3 throws a traceback on every photo that I've tried it with so far. Even if I make no changes and just load and save the file, an error is thrown:

>>> from iptcinfo3 import IPTCInfo
>>> f = "/Users/mike/Desktop/IMG_1302.jpeg"
>>> i = IPTCInfo(f)
WARNING: problems with charset recognition (b'\x1b')
>>> i.save()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.7/site-packages/iptcinfo3.py", line 626, in save
    return self.save_as(self._filename, options)
  File "/usr/local/lib/python3.7/site-packages/iptcinfo3.py", line 635, in save_as
    jpeg_parts = jpeg_collect_file_parts(fh)
  File "/usr/local/lib/python3.7/site-packages/iptcinfo3.py", line 324, in jpeg_collect_file_parts
    adobeParts = collect_adobe_parts(partdata)
  File "/usr/local/lib/python3.7/site-packages/iptcinfo3.py", line 433, in collect_adobe_parts
    out = [''.join(out)]
TypeError: sequence item 0: expected str instance, bytes found

I'm not discounting that the files I've tried with may have unexpected data in them. If I use exiftool to delete the data in the file, I get another traceback:

$ exiftool -all= IMG_1302.jpeg 
    1 image files updated
>>> i = IPTCInfo(f)
Marker scan hit start of image data
No IPTC data found in /Users/mike/Desktop/IMG_1302.jpeg
>>> i.save()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.7/site-packages/iptcinfo3.py", line 626, in save
    return self.save_as(self._filename, options)
  File "/usr/local/lib/python3.7/site-packages/iptcinfo3.py", line 635, in save_as
    jpeg_parts = jpeg_collect_file_parts(fh)
  File "/usr/local/lib/python3.7/site-packages/iptcinfo3.py", line 264, in jpeg_collect_file_parts
    marker = ord(jpeg_next_marker(fh))
TypeError: ord() expected string of length 1, but NoneType found
>>> i = IPTCInfo(f, force=True)
Marker scan hit start of image data
>>> i.save()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.7/site-packages/iptcinfo3.py", line 626, in save
    return self.save_as(self._filename, options)
  File "/usr/local/lib/python3.7/site-packages/iptcinfo3.py", line 635, in save_as
    jpeg_parts = jpeg_collect_file_parts(fh)
  File "/usr/local/lib/python3.7/site-packages/iptcinfo3.py", line 264, in jpeg_collect_file_parts
    marker = ord(jpeg_next_marker(fh))
TypeError: ord() expected string of length 1, but NoneType found

I'd be happy to share a file to help in debugging.

I am having the same issue.
It seems that if the JPG has any existing metadata it fails, but I am not sure which part of the metadata is causing it to fail.
I have an image that fails every time, if I strip all the metadata then run it through Python again, it saves fine. A sample file can be found at http://crouchers.org/mike-test.jpg

from iptcinfo3 import IPTCInfo
info = IPTCInfo('image.jpg', force=True)
info.save()
WARNING: problems with charset recognition (b'\x1b')
WARNING: problems with charset recognition (b'\x1b')
Traceback (most recent call last):
  File "./searchimages.py", line 123, in <module>
    main(sys.argv[1:])
  File "./searchimages.py", line 119, in main
    find_photos(str(sys.argv[1]))
  File "./searchimages.py", line 46, in find_photos
    write_keywords(image, current_keywords, new_keywords)
  File "./searchimages.py", line 109, in write_keywords
    info.save_as('out.jpg')
  File "/usr/local/lib/python3.7/site-packages/iptcinfo3.py", line 635, in save_as
    jpeg_parts = jpeg_collect_file_parts(fh)
  File "/usr/local/lib/python3.7/site-packages/iptcinfo3.py", line 324, in jpeg_collect_file_parts
    adobeParts = collect_adobe_parts(partdata)
  File "/usr/local/lib/python3.7/site-packages/iptcinfo3.py", line 433, in collect_adobe_parts
    out = [''.join(out)]
TypeError: sequence item 0: expected str instance, bytes found

A quick fix I have found is to comment out line 433 of iptcinfo3.py

out = [''.join(out)]

The function here is trying to combine binary strings with an empty regular string ''
This is causing the exception. The correct code should read as follows -

out = [b''.join(out)]

commented

@jcroucher @mb243 @Xankill3r thanks everyone for point this out, it has been merged and a new release version 2.1.4 pushed to pypi, please upgrade - pip3 install iptcinfo3 -U and the saving works!

commented

Sorry, it took me so long to do this, setting this repo to be in my watchlist now. Glad people are using it!