@@ -519,14 +519,7 @@ def _fetch_schema(self, fetchSchemaParam: _FetchSchemaParam = None) -> None:
519519 )
520520 schema_str = json .dumps (schemas_for_preprocessing [0 ])
521521
522- schema = json .loads (
523- schema_str .replace ("$ref" , "dollarref" ).replace (
524- # '$' is a special char for root object in jsonpath
525- '"allOf": [' ,
526- '"allOf": [{},' ,
527- )
528- # fix https://github.com/koxudaxi/datamodel-code-generator/issues/1910
529- )
522+ schema = json .loads (schema_str .replace ("$ref" , "dollarref" ))
530523
531524 jsonpath_expr = parse ("$..dollarref" )
532525 for match in jsonpath_expr .find (schema ):
@@ -725,6 +718,71 @@ def _fetch_schema(self, fetchSchemaParam: _FetchSchemaParam = None) -> None:
725718 # are not v1 compatible mainly by using update_model()
726719 content = re .sub (r"(,?\s*unique_items=True\s*)" , "" , content )
727720
721+ # Detect empty subclasses, replaces their occurrences with base classes,
722+ # and removes the empty class definitions.
723+ # Only processes subclasses that follow naming patterns:
724+ # - BaseclassModel (e.g., DescriptionModel extends Description)
725+ # - Baseclass<number> (e.g., Label1, Label2 extend Label)
726+
727+ # Pattern to match empty subclasses
728+ # Matches: class SubClass(BaseClass):
729+ # followed by optional whitespace/docstring and pass
730+ pattern = "" .join (
731+ (
732+ r"class\s+" , # 'class' keyword
733+ r"(\w+)" , # capture subclass name
734+ r"\s*\(\s*" , # opening parenthesis
735+ r"(\w+)" , # capture base class name
736+ r"\s*\)\s*:" , # closing parenthesis and colon
737+ r"\s*" , # optional whitespace
738+ r'(?:\n\s*(?:""".*?"""|\'\'\'.*?\'\'\')'
739+ # optional docstring (triple quotes)
740+ r"\s*)?" , # end optional docstring
741+ r"\n\s*pass\s*" , # pass statement
742+ r"(?:\n|$)" , # newline or end of string
743+ )
744+ )
745+
746+ # Find all empty subclasses
747+ matches = list (re .finditer (pattern , content , re .MULTILINE | re .DOTALL ))
748+
749+ # Filter matches based on naming patterns
750+ valid_matches = []
751+ for match in matches :
752+ subclass_name = match .group (1 )
753+ base_class_name = match .group (2 )
754+
755+ # Check if subclass follows the naming patterns
756+ if (
757+ subclass_name == base_class_name + "Model" # BaseclassModel pattern
758+ or re .match (
759+ rf"^{ re .escape (base_class_name )} \d+$" , subclass_name
760+ ) # Baseclass<number> pattern
761+ ):
762+ valid_matches .append (match )
763+
764+ content = content
765+ replacements = []
766+
767+ # Process matches in reverse order to avoid offset issues when removing
768+ for match in reversed (valid_matches ):
769+ subclass_name = match .group (1 )
770+ base_class_name = match .group (2 )
771+ replacements .append ((subclass_name , base_class_name ))
772+
773+ # Remove the entire class definition
774+ start , end = match .span ()
775+ # Also remove any trailing newlines to avoid extra blank lines
776+ while end < len (content ) and content [end ] == "\n " :
777+ end += 1
778+
779+ content = content [:start ] + content [end :]
780+
781+ # Replace all occurrences of subclass names with base class names
782+ for subclass_name , base_class_name in reversed (replacements ):
783+ pattern_replace = r"\b" + re .escape (subclass_name ) + r"\b"
784+ content = re .sub (pattern_replace , base_class_name , content )
785+
728786 if fetchSchemaParam .mode == "replace" :
729787 header = (
730788 "from uuid import uuid4\n "
0 commit comments