Repository: pydantic/pydantic
Pull request: Added fix for signature of inherited dataclass
<!-- Thank you for your contribution! -->
<!-- Unless your change is trivial, please create an issue to discuss the change before creating a PR -->

## Change Summary
Added fix for signature of inherited dataclass when using the pydantic dataclass decorator. 

There is a bug in the following code 

```python
from pydantic.dataclasses import dataclass

@dataclass
class A:
    a: int

@dataclass
class B(A):
    b: int
```
where the signature of the class B does not include the subclass (B) fields (see issue #7906 )

<!-- Please give a short summary of the changes. -->

* Used generate_model_signature to create a temporary signature before running generate_dataclass_signature
* Added unit test for fix

## Related issue number
<!-- WARNING: please use "fix #123" style references so the issue is closed when this PR is merged. -->
fix #7906 

## Checklist

* [ ] The pull request title is a good summary of the changes - it will be used in the changelog
* [x] Unit tests for the changes exist
* [ ] Tests pass on CI
* [ ] Documentation reflects the changes where applicable
* [x] My PR is ready to review, **please add a comment including the phrase "please review" to assign reviewers**

# please review


Problem statement:
Signature of inherited dataclass does not include subclass field
### Initial Checks

- [X] I confirm that I'm using Pydantic V2

### Description

Hello, I found that the signature of inherited dataclass seems to have only its superclass fields.  Is this expected behavior at pydantic v2?  Due to this, FastAPI seems to ignore the subclass field value.

### Example Code

```Python
from pydantic.dataclasses import dataclass

@dataclass
class A:
    a: int

@dataclass
class B(A):
    b: int

# In [4]: B.__signature__
# Out[4]: <Signature (a: int) -> None>  # "b: int" is missing
```


### Python, Pydantic & OS Version

```Text
pydantic version: 2.4.2
        pydantic-core version: 2.10.1
          pydantic-core build: profile=release pgo=false
               python version: 3.9.13 (main, Sep 17 2022, 22:53:18)  [Clang 14.0.0 (clang-1400.0.29.102)]
                     platform: macOS-13.6-arm64-arm-64bit
             related packages: email-validator-2.0.0.post2 pydantic-extra-types-2.1.0 mypy-1.3.0 typing_extensions-4.8.0 fastapi-0.104.0 pydantic-settings-2.0.3
```

Hints from issue discussion:
Hi @shinaji,

Thanks for reporting this. Looks like a bug with the pydantic dataclass signature generation. I've marked this with the `good first issue` tag, if anyone wants to help!
This should be helpful:

https://github.com/pydantic/pydantic/blob/f645f196b063843865b34bd696e4b85bae9c034c/pydantic/_internal/_dataclasses.py#L188-L193

Commit message: Added fix for dataclass inheritance signature bug.

Patch to review:
diff --git a/pydantic/_internal/_dataclasses.py b/pydantic/_internal/_dataclasses.py
index d1d1c5fa0c9..a0dab4d4c2e 100644
--- a/pydantic/_internal/_dataclasses.py
+++ b/pydantic/_internal/_dataclasses.py
@@ -27,6 +27,7 @@
 from ._generate_schema import GenerateSchema
 from ._generics import get_standard_typevars_map
 from ._mock_val_ser import set_dataclass_mocks
+from ._model_construction import generate_model_signature
 from ._schema_generation_shared import CallbackGetCoreSchemaHandler
 from ._utils import is_valid_identifier
 
@@ -123,19 +124,25 @@ def complete_dataclass(
         typevars_map,
     )
 
-    # dataclass.__init__ must be defined here so its `__qualname__` can be changed since functions can't be copied.
+    # Get a temporary signature before we change the __init__
+    fields = cls.__pydantic_fields__  # type: ignore
+    temp_sig = generate_model_signature(cls.__init__, fields, config_wrapper)
 
+    # dataclass.__init__ must be defined here so its `__qualname__` can be changed since functions can't be copied.
     def __init__(__dataclass_self__: PydanticDataclass, *args: Any, **kwargs: Any) -> None:
         __tracebackhide__ = True
         s = __dataclass_self__
         s.__pydantic_validator__.validate_python(ArgsKwargs(args, kwargs), self_instance=s)
 
     __init__.__qualname__ = f'{cls.__qualname__}.__init__'
-    sig = generate_dataclass_signature(cls)
+
     cls.__init__ = __init__  # type: ignore
-    cls.__signature__ = sig  # type: ignore
     cls.__pydantic_config__ = config_wrapper.config_dict  # type: ignore
-
+    # Set to the temporary signature
+    cls.__signature__ = temp_sig  # type: ignore
+    # Get the final signature by running the generate_dataclass_signature
+    sig = generate_dataclass_signature(cls)
+    cls.__signature__ = sig  # type: ignore
     get_core_schema = getattr(cls, '__get_pydantic_core_schema__', None)
     try:
         if get_core_schema:
diff --git a/tests/test_dataclasses.py b/tests/test_dataclasses.py
index 0f3d1d6dd50..7b363ad7e15 100644
--- a/tests/test_dataclasses.py
+++ b/tests/test_dataclasses.py
@@ -2507,6 +2507,19 @@ class Model:
     )
 
 
+def test_inherited_dataclass_signature():
+    @pydantic.dataclasses.dataclass
+    class A:
+        a: int
+
+    @pydantic.dataclasses.dataclass
+    class B(A):
+        b: int
+
+    assert str(inspect.signature(A)) == '(a: int) -> None'
+    assert str(inspect.signature(B)) == '(a: int, b: int) -> None'
+
+
 def test_dataclasses_with_slots_and_default():
     @pydantic.dataclasses.dataclass(slots=True)
     class A:


Code review comments:
diff_hunk: @@ -123,19 +124,25 @@ def complete_dataclass(
         typevars_map,
     )
 
-    # dataclass.__init__ must be defined here so its `__qualname__` can be changed since functions can't be copied.
+    # Get a temporary signature before we change the __init__
+    fields = cls.__pydantic_fields__  # type: ignore
+    temp_sig = generate_model_signature(cls.__init__, fields, config_wrapper)
path: pydantic/_internal/_dataclasses.py
text: @user1:
I think a cleaner approach here would be to modify the `generate_dataclass_signature` function to be more like the `generate_model_signature` function, instead of calling the `generate_model_signature` function in addition to `generate_dataclass_signature`.

please update

@author:
I've made the changes.