Repository: pydantic/pydantic

Issue:
Add is_pydantic_dataclass to public API
### Initial Checks

- [X] I have searched Google & GitHub for similar requests and couldn't find anything
- [X] I have read and followed [the docs](https://docs.pydantic.dev) and still think this feature is missing

### Description

We are incrementally changing our validators from mutiple other libs to pydantic. Part of our strategy depends on detecting which validator we need to use based on the "schema" that was provided. 

For pydantic dataclasses we would like to use `pydantic._internal._dataclasses.is_pydantic_dataclass`, but would rather not use a any internals that might be subject to breaking changes.

### Affected Components

- [ ] [Compatibility between releases](https://docs.pydantic.dev/changelog/)
- [ ] [Data validation/parsing](https://docs.pydantic.dev/usage/models/#basic-model-usage)
- [ ] [Data serialization](https://docs.pydantic.dev/usage/exporting_models/) - `.model_dump()` and `.model_dump_json()`
- [ ] [JSON Schema](https://docs.pydantic.dev/usage/schema/)
- [X] [Dataclasses](https://docs.pydantic.dev/usage/dataclasses/)
- [ ] [Model Config](https://docs.pydantic.dev/usage/model_config/)
- [ ] [Field Types](https://docs.pydantic.dev/usage/types/) - adding or changing a particular data type
- [ ] [Function validation decorator](https://docs.pydantic.dev/usage/validation_decorator/)
- [ ] [Generic Models](https://docs.pydantic.dev/usage/models/#generic-models)
- [ ] [Other Model behaviour](https://docs.pydantic.dev/usage/models/) - `model_construct()`, pickling, private attributes, ORM mode
- [ ] [Plugins](https://docs.pydantic.dev/) and integration with other tools - mypy, FastAPI, python-devtools, Hypothesis, VS Code, PyCharm, etc.

Selected Assignee: @samuelcolvin


Discussion:
Fine by me, PR welcome to move the function to `pydantic.dataclasses`.

Resolving patch:
diff --git a/pydantic/_internal/_dataclasses.py b/pydantic/_internal/_dataclasses.py
--- a/pydantic/_internal/_dataclasses.py
+++ b/pydantic/_internal/_dataclasses.py
@@ -259,15 +259,3 @@ class B(A):
         and not hasattr(_cls, '__pydantic_validator__')
         and set(_cls.__dataclass_fields__).issuperset(set(getattr(_cls, '__annotations__', {})))
     )
-
-
-def is_pydantic_dataclass(_cls: type[Any]) -> TypeGuard[type[PydanticDataclass]]:
-    """Whether a class is a pydantic dataclass.
-
-    Args:
-        cls: The class.
-
-    Returns:
-        `True` if the class is a pydantic dataclass, `False` otherwise.
-    """
-    return dataclasses.is_dataclass(_cls) and '__pydantic_validator__' in _cls.__dict__
diff --git a/pydantic/_internal/_generate_schema.py b/pydantic/_internal/_generate_schema.py
--- a/pydantic/_internal/_generate_schema.py
+++ b/pydantic/_internal/_generate_schema.py
@@ -1317,7 +1317,7 @@ def _dataclass_schema(
 
                 self = self._current_generate_schema
 
-                from ._dataclasses import is_pydantic_dataclass
+                from ..dataclasses import is_pydantic_dataclass
 
                 if is_pydantic_dataclass(dataclass):
                     fields = dataclass.__pydantic_fields__
diff --git a/pydantic/dataclasses.py b/pydantic/dataclasses.py
--- a/pydantic/dataclasses.py
+++ b/pydantic/dataclasses.py
@@ -6,7 +6,7 @@
 import types
 from typing import TYPE_CHECKING, Any, Callable, Generic, NoReturn, TypeVar, overload
 
-from typing_extensions import Literal, dataclass_transform
+from typing_extensions import Literal, TypeGuard, dataclass_transform
 
 from ._internal import _config, _decorators, _typing_extra
 from ._internal import _dataclasses as _pydantic_dataclasses
@@ -276,3 +276,15 @@ def rebuild_dataclass(
             raise_errors=raise_errors,
             types_namespace=types_namespace,
         )
+
+
+def is_pydantic_dataclass(__cls: type[Any]) -> TypeGuard[type[PydanticDataclass]]:
+    """Whether a class is a pydantic dataclass.
+
+    Args:
+        __cls: The class.
+
+    Returns:
+        `True` if the class is a pydantic dataclass, `False` otherwise.
+    """
+    return dataclasses.is_dataclass(__cls) and '__pydantic_validator__' in __cls.__dict__


Test patch:
diff --git a/tests/test_dataclasses.py b/tests/test_dataclasses.py
--- a/tests/test_dataclasses.py
+++ b/tests/test_dataclasses.py
@@ -33,7 +33,7 @@
     model_validator,
 )
 from pydantic._internal._mock_val_ser import MockValSer
-from pydantic.dataclasses import rebuild_dataclass
+from pydantic.dataclasses import is_pydantic_dataclass, rebuild_dataclass
 from pydantic.fields import Field, FieldInfo
 from pydantic.json_schema import model_json_schema
 
@@ -2487,3 +2487,16 @@ class A:
     assert count == 0
     TypeAdapter(A).validate_python({'a': 123})
     assert count == 1
+
+
+def test_is_pydantic_dataclass():
+    @pydantic.dataclasses.dataclass
+    class PydanticDataclass:
+        a: int
+
+    @dataclasses.dataclass
+    class StdLibDataclass:
+        b: int
+
+    assert is_pydantic_dataclass(PydanticDataclass) is True
+    assert is_pydantic_dataclass(StdLibDataclass) is False