Repository: koxudaxi/datamodel-code-generator

Issue:
Model class names are missing the last letter in models generated from 2020-12 JSON schema specification
**Describe the bug**
When generating data models from the [2020-12 JSON schema specification](https://json-schema.org/draft/2020-12/schema), all direct subclasses of `BaseModel` are missing the last letter in their class name. For example:

```python
class Unevaluate(BaseModel):
    unevaluatedItems: Optional[Any] = None
    unevaluatedProperties: Optional[Any] = None
```

This class should generate with the name `Unevaluated`, but it instead generates with the name `Unevaluate`.

**To Reproduce**

Example schema: https://json-schema.org/draft/2020-12/schema

Used commandline:
```
$ datamodel-codegen --url https://json-schema.org/draft/2020-12/schema --input-file-type jsonschema --output model.py --output-model-type pydantic_v2.BaseModel
```

**Expected behavior**

The expected behaviour is for the class names to not be missing the final letter in their names.

**Version:**
 - OS: macOS 14.5
 - Python version: 3.12.3
 - datamodel-code-generator version: 0.25.8

**Additional context**

I'm pretty sure I know how to fix this, but I don't feel like I have enough context to understand all the implications of this change.

In `reference.py` at line 567, we have this piece of code:
```python
        if len(split_ref) == 1:
            original_name = Path(
                split_ref[0][:-1] if self.is_external_root_ref(path) else split_ref[0]
            ).stem
        else:
            original_name = (
                Path(split_ref[1][:-1]).stem
                if self.is_external_root_ref(path)
                else split_ref[1]
            )
```
The problem seems to happen in the case where `ref` does *not* have the ending `#`, but the path does. For example, when `path` is `'https://json-schema.org/draft/2020-12/meta/core#'` and `ref` is `'meta/core'`. In this case, it seems you can replace the `[:1]` indexing with `.rstrip('#')` to make it so that it will still drop the `#` without ever cutting off the end of the word. 

```python
        if len(split_ref) == 1:
            original_name = Path(
                split_ref[0].rstrip('#')
                if self.is_external_root_ref(path)
                else split_ref[0]
            ).stem
        else:
            original_name = (
                Path(split_ref[1].rstrip('#')).stem
                if self.is_external_root_ref(path)
                else split_ref[1]
            )
```

This code change does pass all of the tests, but I'm just not certain about whether this change is fixing the root cause or not. For all I know, the path having a `#` at the end and the `ref` not having one is the true root cause, I just don't feel like I have enough familiarity to say.


Discussion:
I have the same problem and would love to be able to have this fixed.



Patch:
diff --git a/datamodel_code_generator/reference.py b/datamodel_code_generator/reference.py
index e32aac88c..ecf8ee6de 100644
--- a/datamodel_code_generator/reference.py
+++ b/datamodel_code_generator/reference.py
@@ -573,11 +573,13 @@ def add_ref(self, ref: str, resolved: bool = False) -> Reference:
         split_ref = ref.rsplit('/', 1)
         if len(split_ref) == 1:
             original_name = Path(
-                split_ref[0][:-1] if self.is_external_root_ref(path) else split_ref[0]
+                split_ref[0].rstrip('#')
+                if self.is_external_root_ref(path)
+                else split_ref[0]
             ).stem
         else:
             original_name = (
-                Path(split_ref[1][:-1]).stem
+                Path(split_ref[1].rstrip('#')).stem
                 if self.is_external_root_ref(path)
                 else split_ref[1]
             )


Test patch:
diff --git a/tests/test_reference.py b/tests/test_reference.py
index 3d282fa67..232a594cd 100644
--- a/tests/test_reference.py
+++ b/tests/test_reference.py
@@ -2,7 +2,7 @@
 
 import pytest
 
-from datamodel_code_generator.reference import get_relative_path
+from datamodel_code_generator.reference import ModelResolver, get_relative_path
 
 
 @pytest.mark.parametrize(
@@ -47,3 +47,23 @@ def test_get_relative_path_windows(
     assert PureWindowsPath(
         get_relative_path(PureWindowsPath(base_path), PureWindowsPath(target_path))
     ) == PureWindowsPath(expected)
+
+
+def test_model_resolver_add_ref_with_hash():
+    model_resolver = ModelResolver()
+    reference = model_resolver.add_ref(
+        'https://json-schema.org/draft/2020-12/meta/core#'
+    )
+    assert reference.original_name == 'core'
+
+
+def test_model_resolver_add_ref_without_hash():
+    model_resolver = ModelResolver()
+    reference = model_resolver.add_ref('meta/core')
+    assert reference.original_name == 'core'
+
+
+def test_model_resolver_add_ref_unevaluated():
+    model_resolver = ModelResolver()
+    reference = model_resolver.add_ref('meta/unevaluated')
+    assert reference.original_name == 'unevaluated'