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

ExifToolHelper Hangs in pytest, in wine #63

Open
OdyX opened this issue Dec 9, 2022 · 3 comments · May be fixed by #64
Open

ExifToolHelper Hangs in pytest, in wine #63

OdyX opened this issue Dec 9, 2022 · 3 comments · May be fixed by #64
Labels
question Further information is requested

Comments

@OdyX
Copy link

OdyX commented Dec 9, 2022

Trying to debug a pyexiftool issue on Windows, to which I don't have access, I'm basically trying to run this, in tobix/pywine:

def test_exiftool_works_on_all_images():
    with ExifToolHelper(executable="./exiftool.exe") as et:
        for d in et.get_metadata("./test.tiff"):
             assert len(d) > 0

    # Also test ExifTool.execute_json
    with ExifTool(executable="./exiftool.exe") as eftl:
        d = eftl.execute_json("./test.tiff")
        assert len(d) > 0

I run this in the following command:

xvfb-run sh -c "wine pytest"

With various prints and pytest options, I can see that the get_metadata call works, and that assert len(d) > 0 passes, but the code never goes past the end of the with block. In other words, it hangs in .terminate(), and never goes to test ExifTool.

Now. If I add a import pdb; pdb.set_trace() as first line in the function, and hit c when prompted, it works. What am I doing wrong?

@sylikc
Copy link
Owner

sylikc commented Dec 17, 2022

Ok. I also have an issue with running in pytest on actual Windows. I think this might be related to the bug I reported to CPython more than a year ago. It's still open... python/cpython#87950

You can try putting print statements in terminate() and see if it happens at self._process.communicate()

@sylikc sylikc added the question Further information is requested label Dec 17, 2022
@OdyX
Copy link
Author

OdyX commented Dec 19, 2022

Let's see if I understand the code in terminate() correctly.

  1. At the end of a with ExifTool(): block, first, __exit__() is called, which calls terminate(_del=False) (_del defaults to False); hence through exiftool.py#L839-L851 I can confirm it blocks at line 850. There, on Windows, this seems it can be rewritten in a simpler way, as we want to kill the process in all cases;
	try:
		self._process.communicate(input=b"-stay_open\nFalse\n", timeout=timeout)  # this is a constant sequence specified by PH's exiftool
	except subprocess.TimeoutExpired:  # this is new in Python 3.3 (for python 2.x, use the PyPI subprocess32 module)
		pass
	# Kill it in all cases
	self._process.kill()
  1. Then self._flag_running_false() runs, unsets self._running, and terminates
  2. Finally, __del__() runs, but as self._running has been unset, doesn't call terminate() at all.

In my tests, with the above simple patch, I see no lurking processes in Linux nor Windows.

OdyX added a commit to liip-forks/pyexiftool that referenced this issue Dec 19, 2022
Also don't get outs nor errs from Popen.communicate()

Fixes sylikc#63
@OdyX OdyX linked a pull request Dec 19, 2022 that will close this issue
@sylikc
Copy link
Owner

sylikc commented Dec 20, 2022

I'll try this next week. But from what I remember, there bug manifests itself during del or something. I had some tests cases that caused PyExifTool to hang. I think they're still in the test code.

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

Successfully merging a pull request may close this issue.

2 participants