-
-
Notifications
You must be signed in to change notification settings - Fork 189
Description
Hi,
So if there is a module test_module/__init__.py:
from .test import *
and then in test_module/test.py there is:
def test():
pass
def test_function():
pass
Then if you import test_module then the name test_module.test goes to the function test_module.test() instead of the submodule test_module.test.
If we then try to (dill) pickle either one of the functions it will raise an error:
import dill
import tempfile
import test_module
file = tempfile.TemporaryFile()
dill._dill.StockPickler(file).save(test_module.test_function)
# OR
dill._dill.StockPickler(file).save(test_module.test)
# OR
import pickle
pickle._Pickler(file).save(test_module.test_function)
Any of the above 3 will throw an error:
Traceback (most recent call last):
File "C:\code\test_bug3.py", line 5, in <module>
dill._dill.StockPickler(file).save(test_module.test_function)
File "C:\...\AppData\Local\Programs\Python\Python311\Lib\pickle.py", line 560, in save
f(self, obj) # Call unbound method with explicit self
^^^^^^^^^^^^
File "C:\...\.venv\Lib\site-packages\dill\_dill.py", line 1940, in save_function
for stack_element in _postproc:
TypeError: 'NoneType' object is not iterable
This is using dill==0.3.7 and Python 3.11 and on the master branch too f66ed3b, and a repo to reproduce it is: https://github.com/kelvinburke/dill-issue
I think this is because the function _import_module() returns the function test_module.test instead of the submodule of the same name.
I think this can be easily fixed with a check that the getattr(__import__(module, None, None, [obj]), obj) returns the right type
See commit: kelvinburke@228a700
Note I think this is the same problem causing #604 but this a slightly different error and simpler to reproduce.
I will open a PR soon that I think will fix both.