What happens when a function's __qualname__ is changed in python?

Viewed 132

In order to be able to pickle a nested function (for multiprocessing), I decorated the nested function with the decorator:

def globalize_one(func):
    def wrapper_one(*args,**kwargs):
        return func(*args,**kwargs)
    setattr(modules['__main__'],'sdfsdf',wrapper_one)
    return wrapper_one

However, this decorator does not work, when I ran this

def test_one():
    @globalize_one
    def inside_one():
        return 1

    try:
        pickle.dumps(inside_one)
    except Exception as e:
        print(e)

test_one()

I received the exception Can't pickle local object 'globalize_one.<locals>.wrapper_one'

To make the decorator work, all I need is to change the __qualname__ of wrapper_one to sdfsdf in globalize_one right before the line setattr(modules['__main__'],'sdfsdf',wrapper_one).

def globalize_two(func):
    def wrapper_two(*args,**kwargs):
        return func(*args,**kwargs)

    # the single extra line as compared to globalize_one
    wrapper_two.__qualname__ = 'sdfsdf'

    setattr(modules['__main__'],'sdfsdf',wrapper_two)
    return wrapper_two

def test_two():
    @globalize_two
    def inside_two():
        return 1

    try:
        pickle.dumps(inside_two)
    except Exception as e:
        print(e)

As you can see by running the code, the nested function inside_two can be pickled now.

My confusion is, why by changing the __qualname__, the decorator will work properly? I thought changing the name of a function have no real effect.

0 Answers
Related