Repository: pydantic/pydantic
Pull request: fix: adding a check that alias is validated as an identifier for Python
<!-- Thank you for your contribution! -->
<!-- Unless your change is trivial, please create an issue to discuss the change before creating a PR -->

## Change Summary

Changes in `generate_dataclass_signature` function. I used `is_valid_identifier` function from `_utils.py` for `alias` and `validation_alias` as new statement when `name` parameter is replaced by the alias or the validation alias.

I didn't want to use `:=` (walrus operator) in if statement because it isn't support for Python 3.7, so I assigned variables first to make the code more readable.

<!-- Please give a short summary of the changes. -->

## Related issue number

Fix: #7226 

<!-- WARNING: please use "fix #123" style references so the issue is closed when this PR is merged. -->

## Checklist

* [x] 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
* [x] 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**


Problem statement:
Field alias does not accept parameter name with dashes in pydantic dataclasses
### Initial Checks

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

### Description

Using a Field with an alias with a dash for a pydantic dataclass leads to a ValueError that the alias with dash is not a valid parameter name. For BaseModel it works fine.

### Example Code

```Python
from pydantic import BaseModel, Field
from pydantic.dataclasses import dataclass


class Example1(BaseModel):
    some_var: str = Field(..., alias="some-var")


@dataclass(frozen=True)
class Example2:
    some_other_var: str = Field(..., alias="some-other-var")
```


### Python, Pydantic & OS Version

```Text
pydantic version: 2.2.1
        pydantic-core version: 2.6.1
          pydantic-core build: profile=release pgo=false
                 install path: xxxxx
               python version: 3.10.12 | packaged by conda-forge | (main, Jun 23 2023, 22:34:57) [MSC v.1936 64 bit (AMD64)]
                     platform: Windows-10-10.0.19045-SP0
     optional deps. installed: ['typing-extensions']
```


Selected Assignee: @adriangb

Hints from issue discussion:
I can confirm this is a bug. Would you like to try to make a PR to fix it?

Commit message: refactor: rename class Example -> Foo in test

Patch to review:
diff --git a/pydantic/_internal/_dataclasses.py b/pydantic/_internal/_dataclasses.py
index 4c2c4d025a4..6d40460fdf7 100644
--- a/pydantic/_internal/_dataclasses.py
+++ b/pydantic/_internal/_dataclasses.py
@@ -22,6 +22,7 @@
 from ._generics import get_standard_typevars_map
 from ._mock_val_ser import set_dataclass_mock_validator
 from ._schema_generation_shared import CallbackGetCoreSchemaHandler
+from ._utils import is_valid_identifier
 
 if typing.TYPE_CHECKING:
     from ..config import ConfigDict
@@ -204,10 +205,12 @@ def generate_dataclass_signature(cls: type[StandardDataclass]) -> Signature:
 
             # Replace the field name with the alias if present
             name = param.name
-            if param_default.validation_alias is None and isinstance(param_default.alias, str):
-                name = param_default.alias
-            elif isinstance(param_default.validation_alias, str):
-                name = param_default.validation_alias
+            alias = param_default.alias
+            validation_alias = param_default.validation_alias
+            if validation_alias is None and isinstance(alias, str) and is_valid_identifier(alias):
+                name = alias
+            elif isinstance(validation_alias, str) and is_valid_identifier(validation_alias):
+                name = validation_alias
 
             # Replace the field default
             default = param_default.default
diff --git a/tests/test_dataclasses.py b/tests/test_dataclasses.py
index e829b922b75..46f10c7b7a2 100644
--- a/tests/test_dataclasses.py
+++ b/tests/test_dataclasses.py
@@ -2547,3 +2547,15 @@ class Model(BaseModel, Base):
         pass
 
     assert Model().a == 5
+
+
+def test_alias_with_dashes():
+    """Test for fix issue #7226."""
+    data = {'some-var': 'some_value'}
+
+    @pydantic.dataclasses.dataclass
+    class Foo:
+        some_var: str = Field(..., alias='some-var')
+
+    obj = Foo(**data)
+    assert obj.some_var == data['some-var']


Code review comments:
diff_hunk: @@ -2547,3 +2547,15 @@ class Model(BaseModel, Base):
         pass
 
     assert Model().a == 5
+
+
+def test_alias_with_dashes():
+    """Test for fix issue #7226."""
+    data = {'some-var': 'some_value'}
+
+    @pydantic.dataclasses.dataclass
+    class Foo:
+        some_var: str = Field(..., alias='some-var')
+
+    obj = Foo(**data)
+    assert obj.some_var == data['some-var']
path: tests/test_dataclasses.py
text: @user2:
```suggestion
def test_alias_with_dashes():
    """Test for fix issue #7226."""
    @user1.dataclasses.dataclass
    class Foo:
        some_var: str = Field(alias='some-var')

    obj = Foo(**{'some-var': 'some_value'})
    assert obj.some_var == 'some_value'
```