Repository: koxudaxi/datamodel-code-generator

Issue:
generator appends "1" to two components
### Discussed in https://github.com/koxudaxi/datamodel-code-generator/discussions/827

<div type='discussions-op-text'>

<sup>Originally posted by **azatoth** August 21, 2022</sup>
When I'm running the generator on https://ll.thespacedevs.com/2.2.0/schema (no option flags supplied to the binary), it will for the components `Launcher` and `LauncherConfig`, it will append a "1" to the class names.
I don't see any apparent conflicts in the spec, thus I'm a bit lost why this happens. It doesn't happens to any of the other components in the spec file.

Any input would be grateful.</div>

I've boiled down the issue to following minimal spec:


```yaml
openapi: 3.0.3
info:
  title: Foo
  version: "1.0"
paths:
  /:
    get:
      responses:
        '200':
          description: ''
components:
  schemas:
    Foo:
      type: object
      properties:
        foo_bar:
          allOf:
          - $ref: '#/components/schemas/FooBarOther'

    FooBar:
      type: object
      properties:
        id:
          type: integer

    FooBarOther:
      type: object
      properties:
        id:
          type: integer
```

That will result in following python code:

```py3
from __future__ import annotations

from typing import Optional

from pydantic import BaseModel


class FooBar1(BaseModel):
    id: Optional[int] = None


class FooBarOther(BaseModel):
    id: Optional[int] = None


class Foo(BaseModel):
    foo_bar: Optional[FooBarOther] = None
```

I notice if I break out the `$ref` from the `allOf`, it will not generate a numbered class name.
Also that property name must be snake case of an existing model.

I'm positive this is not the intended result, thus I'm filing this issue.


Discussion:

Resolving patch:
diff --git a/datamodel_code_generator/parser/jsonschema.py b/datamodel_code_generator/parser/jsonschema.py
--- a/datamodel_code_generator/parser/jsonschema.py
+++ b/datamodel_code_generator/parser/jsonschema.py
@@ -516,6 +516,7 @@ def parse_all_of(
             )
         # ignore an undetected object
         if ignore_duplicate_model and not fields and len(base_classes) == 1:
+            self.model_resolver.delete(path)
             return self.data_type(reference=base_classes[0])
         if self.use_title_as_name and obj.title:
             name = obj.title
diff --git a/datamodel_code_generator/reference.py b/datamodel_code_generator/reference.py
--- a/datamodel_code_generator/reference.py
+++ b/datamodel_code_generator/reference.py
@@ -550,6 +550,9 @@ def add(
     def get(self, path: Union[Sequence[str], str]) -> Optional[Reference]:
         return self.references.get(self.resolve_ref(path))
 
+    def delete(self, path: Union[Sequence[str], str]) -> None:
+        del self.references[self.resolve_ref(path)]
+
     def default_class_name_generator(self, name: str) -> str:
         # TODO: create a validate for class name
         return self.field_name_resolvers[ModelType.CLASS].get_valid_name(


Test patch:
diff --git a/tests/data/expected/parser/openapi/openapi_parser_parse_allof_same_prefix_with_ref/output.py b/tests/data/expected/parser/openapi/openapi_parser_parse_allof_same_prefix_with_ref/output.py
new file mode 100644
--- /dev/null
+++ b/tests/data/expected/parser/openapi/openapi_parser_parse_allof_same_prefix_with_ref/output.py
@@ -0,0 +1,17 @@
+from __future__ import annotations
+
+from typing import Optional
+
+from pydantic import BaseModel
+
+
+class FooBar(BaseModel):
+    id: Optional[int] = None
+
+
+class FooBarBaz(BaseModel):
+    id: Optional[int] = None
+
+
+class Foo(BaseModel):
+    foo_bar: Optional[FooBarBaz] = None
diff --git a/tests/data/openapi/allof_same_prefix_with_ref.yaml b/tests/data/openapi/allof_same_prefix_with_ref.yaml
new file mode 100644
--- /dev/null
+++ b/tests/data/openapi/allof_same_prefix_with_ref.yaml
@@ -0,0 +1,30 @@
+openapi: 3.0.3
+info:
+  title: Foo
+  version: "1.0"
+paths:
+  /:
+    get:
+      responses:
+        '200':
+          description: ''
+components:
+  schemas:
+    Foo:
+      type: object
+      properties:
+        foo_bar:
+          allOf:
+          - $ref: '#/components/schemas/FooBarBaz'
+
+    FooBar:
+      type: object
+      properties:
+        id:
+          type: integer
+
+    FooBarBaz:
+      type: object
+      properties:
+        id:
+          type: integer
diff --git a/tests/parser/test_openapi.py b/tests/parser/test_openapi.py
--- a/tests/parser/test_openapi.py
+++ b/tests/parser/test_openapi.py
@@ -421,6 +421,20 @@ def test_openapi_parser_parse_nested_oneof():
     )
 
 
+def test_openapi_parser_parse_allof_ref():
+    parser = OpenAPIParser(
+        Path(DATA_PATH / 'allof_same_prefix_with_ref.yaml'),
+    )
+    assert (
+        parser.parse()
+        == (
+            EXPECTED_OPEN_API_PATH
+            / 'openapi_parser_parse_allof_same_prefix_with_ref'
+            / 'output.py'
+        ).read_text()
+    )
+
+
 def test_openapi_parser_parse_allof():
     parser = OpenAPIParser(
         Path(DATA_PATH / 'allof.yaml'),