Search code examples
pythongarbage-collectiondill

dill.detect.at Cannot reference object at '0x1023d2600'


More digging into dill. Specifically the detect.at method which is a call to:

def _locate_object(address, module=None):
    """get object located at the given memory address (inverse of id(obj))"""
    special = [None, True, False] #XXX: more...?
    for obj in special:
        if address == id(obj): return obj
    if module:
        if PY3:
            objects = iter(module.__dict__.values())
        else:
            objects = module.__dict__.itervalues()
    else: objects = iter(gc.get_objects())
    for obj in objects:
        if address == id(obj): return obj
    # all bad below... nothing found so throw ReferenceError or TypeError
    from weakref import ReferenceError
    try: address = hex(address)
    except TypeError:
        raise TypeError("'%s' is not a valid memory address" % str(address))
    raise ReferenceError("Cannot reference object at '%s'" % address)

Why am I not able to "get" the string object which appears to be at the address: 4332529152?

>>> class Parent():
...     name="Big Papa"
...     def get_hitched(partner):
...             return name + "+" + partner + "TLFE"
... 
>>> johnny = Parent()
    >>> johnny = Parent()
>>> johnny.get_hitched("Mary")
'Big Papa + Mary TLFE'
>>> billy = johnny.get_hitched
>>> billy("Junebug")
'Big Papa + Junebug TLFE'
>>> dill.detect.reference(billy)
4299844816
>>> dill.detect.reference(johnny.get_hitched)
4299844816
>>> dill.detect.reference(johnny)
4299844816
>>> dill.detect.reference(johnny.name)
4332529152
>>> dill.detect.reference(Parent)
4332953328
>>> dill.detect.at(4332529152)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/mikekilmer/Envs/GLITCH/lib/python2.7/site-packages/dill/dill.py", line 738, in _locate_object
    raise ReferenceError("Cannot reference object at '%s'" % address)
ReferenceError: Cannot reference object at '0x1023d2600'
>>> 0x1023d2600
4332529152
>>> id(johnny.name)
4332529152
>>> type(johnny.name)
<type 'str'>

Solution

  • Detect.at() takes a reference number and, if it is a reference number that would be handle by the garbage collect module, returns the object that it is associated with. Otherwise returns ReferenceError: and the hex value of the reference number.

    For example, instance attributes are not managed by GC because they will be destroyed when the objects they are linked to are destroyed.

    As roippi says in comment:

    All they're doing here is searching through gc.get_objects() and comparing objects by id - which is exactly how you're supposed to use id. The actual reason you can't dereference johnny.name is that class/instance attributes are not directly tracked by the garbage collector - there's no need to, since you can just destroy them when you destroy the objects they're linked to.

    And the hex number is simply the result of calling the hex() method on the reference number input to dill.detect.at().