Reputation: 55
I'm looking for an optimization of my code to avoid the following error and make my program more fast.
maximum recursion depth exceeded while calling a Python object
I'm looking to execute this code in a docker container. It works perfectly locally on my machine.
I'm looking for a way to reduce the number of loops.
def reidentify(self):
try:
# Check if file is re-identify
self.check_if_dicom_is_reidentify()
LOGGER.info(f"Anonymization in progress for {self.dirpath_output}")
# Get patient data
json_data = json.loads(self.get_patient_data().decode('utf-8'))
# Re-identification
archive = zipfile.ZipFile(self.download.dirpath_download, 'r')
for file in archive.namelist():
# Check if the file is a dicom
if not file.endswith('.dcm'):
continue
# Reading dicom file
dicom_data = io.BytesIO(archive.read(file))
ds = pydicom.dcmread(dicom_data)
# Edit Dicom general fields
for key in json_data['tags']:
ds.data_element(key).value = json_data['tags'][key]
# Edit Dicom series field
for key in json_data['series']:
if key['obfuscated_uid'] != ds.data_element('SeriesInstanceUID').value:
continue
for tag in key['tags']:
ds.data_element(tag).value = key['tags'][tag]
# Save re-identify dicom
ds.save_as(f'{self.dirpath_tmp}/{os.path.basename(file)}')
except Exception as e:
LOGGER.error(e)
This code give the expected result, but I think it's not an optimized method and it's very slow.
EDIT : This is the stack trace
reidentify_1 | 2019-10-17 11:29:53,001] With tag (0010, 1030) got exception: maximum recursion depth exceeded while calling a Python object
reidentify_1 | Traceback (most recent call last):
reidentify_1 | File "/usr/local/lib/python3.8/site-packages/pydicom/tag.py", line 30, in tag_in_exception
reidentify_1 | yield
reidentify_1 | File "/usr/local/lib/python3.8/site-packages/pydicom/filewriter.py", line 541, in write_dataset
reidentify_1 | write_data_element(fp, dataset.get_item(tag), dataset_encoding)
reidentify_1 | File "/usr/local/lib/python3.8/site-packages/pydicom/filewriter.py", line 485, in write_data_element
reidentify_1 | writer_function(buffer, data_element)
reidentify_1 | File "/usr/local/lib/python3.8/site-packages/pydicom/filewriter.py", line 338, in write_number_string
reidentify_1 | val = str(val)
reidentify_1 | File "/usr/local/lib/python3.8/site-packages/pydicom/valuerep.py", line 344, in __str__
reidentify_1 | return super(DSfloat, self).__str__()
reidentify_1 | File "/usr/local/lib/python3.8/site-packages/pydicom/valuerep.py", line 347, in __repr__
reidentify_1 | return "\"" + str(self) + "\""
Thank you very much for your help.
Upvotes: 1
Views: 174
Reputation: 2029
It seems to be fixed but there is no pypi package built with that fix.
The origin of this bug is described as follows:
Python 3.8 removes str() from int and float which instead now call object.str() which itself defaults to object.repr().
DSfloat.str(), DSfloat.repr() and IS.repr() all call the parent class' str() which calls the subclass' repr() method and so on, which causes a recursion error.
This PR:
Fixes DSfloat.__str__() by creating a calling repr() instead and removing the " marks. Fixes DSfloat.__repr__() by calling the parent class' __repr__() instead of str() Fixes IS.__repr__() by implementing IS.__str__() in a similar manner to DSfloat.__str__() and making IS.__repr__() symmetric with
DSfloat.repr()
You can try to install it from the git repo directly:
pip uninstall pydicom
pip install git+https://github.com/pydicom/pydicom.git
Upvotes: 1