Open theNewFlesh opened 4 years ago
Does:
header['foo'] = b'bar'
work?
Yes, but I get None when I read it back in.
and you're using Python 3, correct?
3.7
OK, I have added test case test_header_bytes
to exercise this path:
https://github.com/jamesbowman/openexrpython/blob/master/test-exr.py#L362-L391
Please can you run test_exr.py
- maybe this will clear up why you're seeing None
for these attributes?
Also added a case in the implementation's header parser to give a more helpful error message when encountering a Unicode string in a header. test_header_string
confirms the Exception.
It passes, but others fail.
The none makes sense if the macro isn't loading.
I am running a docker env (Ubuntu 20.04) with blender inside of it, blender comes packaged with its own python3.7. I have install OpenEXR there. I run test.py using Blender's python, which is just a normal python plus Blender libraries.
I have 2 test scripts:
test.py
import Imath as imath
import numpy as np
import OpenEXR
ctype = imath.Channel(imath.PixelType(imath.PixelType.HALF))
target = '/tmp/test.exr'
data = {}
chans = {}
channels = list('RGBA')
for c in channels:
chan = c.upper()
data[chan] = np.zeros((5, 10), dtype=np.float16).tobytes()
chans[chan] = ctype
header = OpenEXR.Header(10, 5)
header['channels'] = chans
header['foo'] = 'bar'.encode('utf-8')
# ALSO-FAIL-------------------------------
# header['foo'] = 'bar'.encode('ascii')
# header['foo'] = 'bar'.encode('utf-8')
# Segmentation fault
# header['foo'] = list('bar'.encode('utf-8'))
# header['foo'] = [bytes([x]) for x in list('bar')]
# ------------------------------------------
file_ = OpenEXR.OutputFile(target, header)
file_.writePixels(data)
and
result.py
import OpenEXR
target = '/tmp/test.exr'
h = OpenEXR.InputFile(target).header()
print(h['foo'])
I can't run them as one file because I get this:
OSError: Cannot read image file "/tmp/test_exr.exr". Early end of file: read 0 out of 4 requested bytes.
When I run:
rm -rf /tmp/test.exr; python3.7 test.py; python3.7 result.py
I get:
b'bar'
When I run this:
rm -rf /tmp/test.exr; /root/blender/blender --background test.py; /root/blender/blender --background result.py
I get:
None
Pretty sure this tells me that blender's python thinks INCLUDED_IMF_STRINGVECTOR_ATTRIBUTE_H is undefined. I have deliberately added stuff to my system path to fix this but to no avail. Not sure if I need to put the include/OpenEXR dir in my PYTHONPATH variable.
pip install OpenEXR doesn't include the C++ file reference by INCLUDED_IMF_STRINGVECTOR_ATTRIBUTE_H I'm guessing. but apt install libopenexr-dev
probably puts it in place, so python3.7 can see it, but not blender's python.
I have tried dumping the OpenEXR C++ files and SOs many places and modifying my sys.path, but to no avail. Can you recommend something?
Or alternatively.... Is it possible to package OpenEXR with all its C/C++ dependencies, so that when one installs pip installs OpenEXR they get a fully functioning OpenEXR implementation? Having pip packaged pyOpenVDB, I realize C++ introduces a number of complexities to the process, not found with pure python, but the normal expectation of pip packages is complete installation and functionality.
In case it's useful, OpenTimelineIO has a setup.py that facilitates building the C++ portions as part of the pip install. You can see it in the root of the OpenTimelineIO repo.
When I run this:
I get this:
Inside of my pytest environment I get a segmentation fault. This was not the case a few months ago, when I last ran them.
I'm guessing the problem is that PyList_Check(val) returns false when it shouldn't. I looked at PyType_FastSubclass, which PyList_Check uses, inside /usr/include/python3.7m/object.h but it seems impenetrable.