1010import subprocess
1111import types
1212from dataclasses import dataclass , is_dataclass
13+ from enum import Enum
1314from pydoc import locate
1415from typing import Any , Callable , Dict , List , Optional
1516from urllib .parse import quote
6970"""
7071
7172_CLASS_TEMPLATE = """
72- {section} <kbd>class </kbd> `{header}`
73+ {section} <kbd>{kind} </kbd> `{header}`
7374{doc}
7475{init}
7576{variables}
@@ -807,21 +808,43 @@ def class2md(self, cls: Any, depth: int = 2, is_mdx: bool = False) -> str:
807808 return ""
808809
809810 section = "#" * depth
811+ sectionheader = "#" * (depth + 1 )
810812 subsection = "#" * (depth + 2 )
811813 clsname = cls .__name__
812814 modname = cls .__module__
813815 header = clsname
814816 path = self ._get_src_path (cls )
815817 doc = _doc2md (cls )
816818 summary = _get_doc_summary (cls )
819+ variables = []
820+
821+ # Handle different kinds of classes
822+ if issubclass (cls , Enum ):
823+ kind = cls .__base__ .__name__
824+ if kind != "Enum" :
825+ kind = "enum[%s]" % (kind )
826+ else :
827+ kind = kind .lower ()
828+ variables .append (
829+ "%s <kbd>symbols</kbd>\n " % (sectionheader )
830+ )
831+ elif is_dataclass (cls ):
832+ kind = "dataclass"
833+ variables .append (
834+ "%s <kbd>attributes</kbd>\n " % (sectionheader )
835+ )
836+ elif issubclass (cls , Exception ):
837+ kind = "exception"
838+ else :
839+ kind = "class"
817840
818841 self .generated_objects .append (
819842 {
820843 "type" : "class" ,
821844 "name" : header ,
822845 "full_name" : header ,
823846 "module" : modname ,
824- "anchor_tag" : _get_anchor_tag ("class-" + header ),
847+ "anchor_tag" : _get_anchor_tag ("%s-%s" % ( kind , header ) ),
825848 "description" : summary ,
826849 }
827850 )
@@ -839,21 +862,31 @@ def class2md(self, cls: Any, depth: int = 2, is_mdx: bool = False) -> str:
839862 # this happens if __init__ is outside the repo
840863 init = ""
841864
842- variables = []
843865 for name , obj in inspect .getmembers (
844866 cls , lambda a : not (inspect .isroutine (a ) or inspect .ismethod (a ))
845867 ):
846- if not name .startswith ("_" ) and type (obj ) == property :
847- comments = _doc2md (obj ) or inspect .getcomments (obj )
848- comments = "\n \n %s" % comments if comments else ""
849- property_name = f"{ clsname } .{ name } "
868+ if not name .startswith ("_" ):
869+ full_name = f"{ clsname } .{ name } "
850870 if self .remove_package_prefix :
851- property_name = name
852- variables .append (
853- _SEPARATOR
854- + "\n %s <kbd>property</kbd> %s%s\n "
855- % (subsection , property_name , comments )
856- )
871+ full_name = name
872+ if isinstance (obj , property ):
873+ comments = _doc2md (obj ) or inspect .getcomments (obj )
874+ comments = "\n \n %s" % comments if comments else ""
875+ variables .append (
876+ _SEPARATOR
877+ + "\n %s <kbd>property</kbd> %s%s\n "
878+ % (subsection , full_name , comments )
879+ )
880+ elif isinstance (obj , Enum ):
881+ variables .append (
882+ "- **%s** = %s\n " % (full_name , obj .value )
883+ )
884+ elif name == "__dataclass_fields__" :
885+ for name , field in sorted ((obj ).items ()):
886+ variables .append (
887+ "- ```%s``` (%s)\n " % (name ,
888+ field .type .__name__ )
889+ )
857890
858891 handlers = []
859892 for name , obj in inspect .getmembers (cls , inspect .ismethoddescriptor ):
@@ -890,6 +923,7 @@ def class2md(self, cls: Any, depth: int = 2, is_mdx: bool = False) -> str:
890923
891924 markdown = _CLASS_TEMPLATE .format (
892925 section = section ,
926+ kind = kind ,
893927 header = header ,
894928 doc = doc if doc else "" ,
895929 init = init ,
0 commit comments