2

We are checking whether one of our packages leaves garbage objects in the Python gc and found that collections.OrderedDict objects are not deleted by the ref-count mechanism but are put into the GC, with the following references (when pprint'ing them and tweaking the output a little):

<type 'list'> object at 0x10a876ab8:
[ <Recursive reference to list object at 0x10a876ab8>,
  <Recursive reference to list object at 0x10a876ab8>,
  None]

This seems to be the same issue as the one reported in https://bugs.python.org/issue9825. That issue was fixed in Python 3.2, and indeed, the reference cycle shown above appears on Python 2.7 but not on Python 3.7.

Is there a ref-cycle free alternative to collections.OrderedDict for Python 2.7?

Update:

  1. I found that ordereddict.OrderedDict also has the same reference cycle.

  2. I am fully aware that Python 2.7 is out of support. Nevertheless, we still need to support our package on Python 2.7.

  3. The answer of @Ramsha Siddiqui points to the SortedDict of Django. I verified that in Django 1.7, its SortedDict does not have reference cycles. However, SortedDict was removed from Django (at least in its version 1.11).

Andreas Maier
  • 2,129
  • 1
  • 20
  • 24
  • Does this answer your question? [Python ordered garbage collectible dictionary?](https://stackoverflow.com/questions/12667057/python-ordered-garbage-collectible-dictionary) – Ramsha Siddiqui Feb 09 '20 at 15:26

1 Answers1

-1

You can use sorted() on any dictionary's items like so:

odt = dict(sorted(dt.items()))

UPDATE: Preserving Original Order

If you want to preserve original order, there is a Django libary for that too:

from django.utils.datastructures import SortedDict
d2 = SortedDict()

Let me know if this helps your case.

UPDATE: [Duplicate] Reference: Python ordered garbage collectible dictionary?

del collections.OrderedDict.__del__

This seems to be the solution for gaining the ability to use OrderedDicts in a reference cycle. You will lose having the OrderedDict free all its resources immediately upon deletion.

Ramsha Siddiqui
  • 320
  • 2
  • 18
  • Sorting the items is not the same as preserving their original order, which is what OrderedDict does. – Andreas Maier Feb 09 '20 at 08:24
  • thats true - I didnt think of that before. I updated the answer. – Ramsha Siddiqui Feb 09 '20 at 08:39
  • I tried your suggestion to use the django SortedDict, but it was no longer in the django version I installed (1.11). From https://code.djangoproject.com/wiki/SortedDict: "SortedDict is deprecated as of Django 1.7 and will be removed in Django 1.9. Use ​collections.OrderedDict instead". Thanks for the help, anyway! – Andreas Maier Feb 09 '20 at 09:35
  • Oh and just for the record: The SortedDict from Django 1.7 has no reference cycles according to our garbage object check!! – Andreas Maier Feb 09 '20 at 09:39