66import sys
77import typing
88from functools import cached_property
9- from types import GetSetDescriptorType
9+ from types import GetSetDescriptorType , ModuleType
1010from typing import TYPE_CHECKING , Any , ClassVar
1111
1212from griffe ._internal .enumerations import ObjectKind
@@ -106,7 +106,7 @@ def module(self) -> ObjectNode:
106106 def module_path (self ) -> str | None :
107107 """The object's module path."""
108108 try :
109- return self .obj .__module__
109+ module = self .obj .__module__
110110 except AttributeError :
111111 try :
112112 module = inspect .getmodule (self .obj ) or self .module .obj
@@ -116,6 +116,27 @@ def module_path(self) -> str | None:
116116 return module .__spec__ .name # type: ignore[union-attr]
117117 except AttributeError :
118118 return getattr (module , "__name__" , None )
119+ else :
120+ # Some libraries mistakenly set `__module__` to a module object instead of a string.
121+ # Handle this case specifically, but do not cast any other object to a string.
122+ if isinstance (module , ModuleType ):
123+ logger .debug (
124+ "Object %s has its `__module__` attribute set to a module object: "
125+ "it must be a string instead (the module fully qualified name). "
126+ "Please report to the maintainers of this library." ,
127+ self .path ,
128+ )
129+ return getattr (module , "__qualname__" , getattr (module , "__name__" , None ))
130+ if isinstance (module , str ):
131+ return module
132+ logger .debug (
133+ "Object %s has its `__module__` attribute set to a %s object: "
134+ "it must be a string instead (the module fully qualified name). "
135+ "Please report to the maintainers of this library." ,
136+ self .path ,
137+ getattr (type (module ), "__name__" , str (type (module ))),
138+ )
139+ return None
119140
120141 @property
121142 def kind (self ) -> ObjectKind :
0 commit comments