Provide __module__ attributes for functions defined in C and Python.
__module__ is the string name of the module the function was defined
in, just like __module__ of classes. In some cases, particularly for
C functions, the __module__ may be None.
Change PyCFunction_New() from a function to a macro, but keep an
unused copy of the function around so that we don't change the binary
API.
Change pickle's save_global() to use whichmodule() if __module__ is
None, but add the __module__ logic to whichmodule() since it might be
used outside of pickle.
diff --git a/Lib/pickle.py b/Lib/pickle.py
index ec19e24..e365bd1 100644
--- a/Lib/pickle.py
+++ b/Lib/pickle.py
@@ -787,9 +787,8 @@
if name is None:
name = obj.__name__
- try:
- module = obj.__module__
- except AttributeError:
+ module = getattr(obj, "__module__", None)
+ if module is None:
module = whichmodule(obj, name)
try:
@@ -876,6 +875,10 @@
Return a module name.
If the function cannot be found, return "__main__".
"""
+ # Python functions should always get an __module__ from their globals.
+ mod = getattr(func, "__module__", None)
+ if mod is not None:
+ return mod
if func in classmap:
return classmap[func]