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

Program hangs when using get_metadata function on Windows. #69

Closed
llitkr opened this issue Feb 6, 2023 · 14 comments
Closed

Program hangs when using get_metadata function on Windows. #69

llitkr opened this issue Feb 6, 2023 · 14 comments
Labels
question Further information is requested

Comments

@llitkr
Copy link

llitkr commented Feb 6, 2023

Hello.

My program is so simple. I'm just trying basic function of pyexiftool but having problem.

import os
from exiftool import ExifToolHelper

def get_files_in_directory(directory):
    file_list = []
    for filename in os.listdir(directory):
        file_path = os.path.join(directory, filename)
        if os.path.isfile(file_path):
            file_list.append(file_path)
    return file_list

files = get_files_in_directory("directory path")
for i in range(len(files)):
    print(files[i])
    **for d in ExifToolHelper().get_metadata(files[i]):**
        for k, v in d.items():
            print(f"Dict: {k} =- {v}")

My program hangs at bold part.

If I press Ctrl + C in the command window, the metadata of the file is displayed normally with an error. But you can't type Ctrl+C one by one. Why stop there?

@sylikc sylikc added the question Further information is requested label Feb 6, 2023
@sylikc
Copy link
Owner

sylikc commented Feb 6, 2023

Hi, I tested this code on my Windows 10 computer running Python 3.9.6 with exiftool 12.37 and I have no issues

Can you describe your environment? What Python are you using? On what platform? etc

@llitkr
Copy link
Author

llitkr commented Feb 7, 2023

Hi, I tested this code on my Windows 10 computer running Python 3.9.6 with exiftool 12.37 and I have no issues

Can you describe your environment? What Python are you using? On what platform? etc

Hello sylikc. Thanks for reply.

I tested it with exiftool 12.55 and Python 3.10.9.

The Operation System is Windows 11 and Develope environment is VS 2022 community version.

Should I try with 3.9.6 version of Python?

image

Program hans like this and if I press Ctrl + C, it become like below.

image

What's problem do you think?

@sylikc
Copy link
Owner

sylikc commented Feb 7, 2023

Oh, you might be having having probably multiple problems. The directory names are probably one of them

Can you try the suggestion here: #68 (comment) and perhaps using a different -charset parameter?

And you're also encountering likely the Python bug I reported to CPython #63 (comment) ... though that is less likely.

It is showing that line https://github.com/sylikc/pyexiftool/blob/master/exiftool/exiftool.py#L855 is where it's hanging. There's current a PR out #64 ... can you report if that fixes your current issue?

@llitkr
Copy link
Author

llitkr commented Feb 7, 2023

Oh, you might be having having probably multiple problems. The directory names are probably one of them

Can you try the suggestion here: #68 (comment) and perhaps using a different -charset parameter?

And you're also encountering likely the Python bug I reported to CPython #63 (comment) ... though that is less likely.

It is showing that line https://github.com/sylikc/pyexiftool/blob/master/exiftool/exiftool.py#L855 is where it's hanging. There's current a PR out #64 ... can you report if that fixes your current issue?

Thanks for your reply.

I think it's not a problem about directory name.

image

I tried with relative directory and there was no Korean language but also same error occured.

image

Then, I tried .get_metadata() with multi parameters but got an error.

@sylikc
Copy link
Owner

sylikc commented Feb 7, 2023

Hmm, i'm not even sure how to debug this... something really funky is going on. As per your error, it somehow deadlocks in threading.py which is way out of my control... I might need to test on your exact version(s) to see if I can reproduce this problem.

Can you break down the code further to see if it hangs in the same spot?

import os
from exiftool import ExifToolHelper

def get_files_in_directory(directory):
    file_list = []
    for filename in os.listdir(directory):
        file_path = os.path.join(directory, filename)
        if os.path.isfile(file_path):
            file_list.append(file_path)
    return file_list

files = get_files_in_directory("directory path")
for i in range(len(files)):
    f = files[i]
    print(f)
    e = ExifToolHelper()
    m = e.get_metadata(f)
    for d in m:
        for k, v in d.items():
            print(f"Dict: {k} =- {v}")
    # optional, also test if it still hangs if you uncomment this line
    #del e

print("exiting")

@sylikc
Copy link
Owner

sylikc commented Feb 7, 2023

btw, if you don't know about pathlib's Path, there's a cleaner way to do the get_files_in_directory method

@llitkr
Copy link
Author

llitkr commented Feb 7, 2023

Hmm, i'm not even sure how to debug this... something really funky is going on. As per your error, it somehow deadlocks in threading.py which is way out of my control... I might need to test on your exact version(s) to see if I can reproduce this problem.

Can you break down the code further to see if it hangs in the same spot?

import os
from exiftool import ExifToolHelper

def get_files_in_directory(directory):
    file_list = []
    for filename in os.listdir(directory):
        file_path = os.path.join(directory, filename)
        if os.path.isfile(file_path):
            file_list.append(file_path)
    return file_list

files = get_files_in_directory("directory path")
for i in range(len(files)):
    f = files[i]
    print(f)
    e = ExifToolHelper()
    m = e.get_metadata(f)
    for d in m:
        for k, v in d.items():
            print(f"Dict: {k} =- {v}")
    # optional, also test if it still hangs if you uncomment this line
    #del e

print("exiting")

Thanks again for reply. I tested it and "del e" seems something matter.
image

When I try with your code, It successes to get metadata and print it once. Then it seems hang on second try.(After print second file's name)

image

However, if I try with "del e" code, it also sucess to get metadata and print for first one but hang on second try. Difference is it cannot reach to print second file's name. It means maybe "del e" makes program stop. By the way, I don't know why It success once because it looks same with my code before.

@sylikc
Copy link
Owner

sylikc commented Feb 7, 2023

It makes no sense lol.

Let's try it one more time... I'm guessing this "should" work. Btw, where did you download exiftool? from official exiftool.org?

import os
from exiftool import ExifToolHelper

def get_files_in_directory(directory):
    file_list = []
    for filename in os.listdir(directory):
        file_path = os.path.join(directory, filename)
        if os.path.isfile(file_path):
            file_list.append(file_path)
    return file_list

files = get_files_in_directory("directory path")
for i in range(len(files)):
    f = files[i]
    print(f)
    e = ExifToolHelper()
    m = e.get_metadata(f)
    for d in m:
        for k, v in d.items():
            print(f"Dict: {k} =- {v}")
    e.terminate()

print("exiting")

@sylikc
Copy link
Owner

sylikc commented Feb 7, 2023

Btw, your usage is not the most efficient way to use PyExifTool, since each invocation of ExifToolHelper() causes a new object to be created... if I optimized your code to use PyExifTool most effectively, (and use pathlib) it looks like this:

from exiftool import ExifToolHelper
from pathlib import Path

def get_files_in_directory(directory):
    file_list = []
    for filename in directory.iterdir():
        if filename.is_file():
            file_list.append(directory / filename)
    return file_list

files = get_files_in_directory(Path("directory path"))
e = ExifToolHelper()
for i in range(len(files)):
    f = files[i]
    print(f)
    for d in e.get_metadata(f):
        for k, v in d.items():
            print(f"Dict: {k} =- {v}")

e.terminate()
print("exiting")

This code will run much faster btw, just because ExifToolHelper() is left running. It'll likely get rid of your hanging problem (although why it hangs with the normal code doesn't make sense either)

@llitkr
Copy link
Author

llitkr commented Feb 8, 2023

image

Wow. It worked with your new code but it hanged with moff file. maybe exiftool doesn't support the file type like this.(This is Sony Action Cam's GPS moving data file) Maybe I can handle it with try-except.

@llitkr
Copy link
Author

llitkr commented Feb 8, 2023

Btw, your usage is not the most efficient way to use PyExifTool, since each invocation of ExifToolHelper() causes a new object to be created... if I optimized your code to use PyExifTool most effectively, (and use pathlib) it looks like this:

from exiftool import ExifToolHelper
from pathlib import Path

def get_files_in_directory(directory):
    file_list = []
    for filename in directory.iterdir():
        if filename.is_file():
            file_list.append(directory / filename)
    return file_list

files = get_files_in_directory(Path("directory path"))
e = ExifToolHelper()
for i in range(len(files)):
    f = files[i]
    print(f)
    for d in e.get_metadata(f):
        for k, v in d.items():
            print(f"Dict: {k} =- {v}")

e.terminate()
print("exiting")

This code will run much faster btw, just because ExifToolHelper() is left running. It'll likely get rid of your hanging problem (although why it hangs with the normal code doesn't make sense either)

image
image

By the way, I don't know why it makes exception at first try if I use Path library and there is no exception if I use os library.

@sylikc
Copy link
Owner

sylikc commented Feb 8, 2023

Not really sure... but... anyways you shouldn't terminate() every time.

Leave the ExifToolHelper object running for the life of the program... that's the fastest way.

from exiftool import ExifToolHelper, ExifToolExecuteError
from pathlib import Path

def get_files_in_directory(directory):
    file_list = []
    for filename in directory.iterdir():
        if filename.is_file():
            file_list.append(filename)
    return file_list

files = get_files_in_directory(Path("directory path"))
e = ExifToolHelper()
for i in range(len(files)):
    f = files[i]
    print(f)
    try:
        e.get_metadata(f)
    except ExifToolExecuteError:
        continue
    for d in m:
        for k, v in d.items():
            print(f"Dict: {k} =- {v}")

e.terminate()
print("exiting")

You could also turn off error checking https://sylikc.github.io/pyexiftool/reference/2-helper.html#exiftool.ExifToolHelper.check_execute but I advise against it...

Anyways, the error you're getting is coming back from exiftool, but in my experience, it means that that particular file has no metadata.

Try the code above...

@llitkr
Copy link
Author

llitkr commented Feb 8, 2023

Thanks a lot for help me.
image
I modified code little bit and it worked perfect like what I expected.

@sylikc
Copy link
Owner

sylikc commented Feb 8, 2023

You're welcome. Feel free to reopen this issue if you encounter further problems.

While the hanging in the initial example "shouldn't happen", this new code is a workaround. I don't really know why that initial code hangs for you... I'll test Python 3.10's windows bug another time... but I think it's related to the same CPython bug I reported 2 years ago

@sylikc sylikc closed this as completed Feb 8, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants