Fix module names to hide implementation details

E.g. now fbchat.PleaseRefresh.__module__ == 'fbchat'
This commit is contained in:
Mads Marquart
2020-01-15 16:08:59 +01:00
parent 9228ac698d
commit 8b70fe8bfd

View File

@@ -55,3 +55,36 @@ __author__ = "Taehoon Kim; Moreels Pieter-Jan; Mads Marquart"
__email__ = "carpedm20@gmail.com"
__all__ = ("Session", "Client")
# Everything below is taken from the excellent trio project:
def fixup_module_metadata(namespace):
def fix_one(qualname, name, obj):
mod = getattr(obj, "__module__", None)
if mod is not None and mod.startswith("fbchat."):
obj.__module__ = "fbchat"
# Modules, unlike everything else in Python, put fully-qualitied
# names into their __name__ attribute. We check for "." to avoid
# rewriting these.
if hasattr(obj, "__name__") and "." not in obj.__name__:
obj.__name__ = name
obj.__qualname__ = qualname
if isinstance(obj, type):
# Fix methods
for attr_name, attr_value in obj.__dict__.items():
fix_one(objname + "." + attr_name, attr_name, attr_value)
for objname, obj in namespace.items():
if not objname.startswith("_"): # ignore private attributes
fix_one(objname, objname, obj)
# Having the public path in .__module__ attributes is important for:
# - exception names in printed tracebacks
# - sphinx :show-inheritance:
# - deprecation warnings
# - pickle
# - probably other stuff
fixup_module_metadata(globals())
del fixup_module_metadata