Skip to content

Commit

Permalink
Make func is_pydantic_dataclass public
Browse files Browse the repository at this point in the history
Move is_pydantic_dataclass to pydantic.dataclasses
Add test for is_pydantic_dataclass
Add documentation for is_pydantic_dataclass
  • Loading branch information
GabrielCappelli committed Aug 22, 2023
1 parent ca2fbdc commit 2fe4aff
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 15 deletions.
28 changes: 28 additions & 0 deletions docs/usage/dataclasses.md
Expand Up @@ -356,6 +356,34 @@ print(repr(m))
#> Model(dc=DC(a=ArbitraryType(value=3), b='qwe'), other='other')
```

### Checking if a dataclass is a pydantic dataclass

Pydantic dataclasses are still considered dataclasses, so using `dataclasses.is_dataclass` will return `True`. To check if a type is specifically a pydantic dataclass you can use `pydantic.dataclasses.is_pydantic_dataclass`.

```py
import dataclasses

import pydantic


@dataclasses.dataclass
class StdLibDataclass:
id: int


PydanticDataclass = pydantic.dataclasses.dataclass(StdLibDataclass)

print(dataclasses.is_dataclass(StdLibDataclass))
#> True
print(pydantic.dataclasses.is_pydantic_dataclass(StdLibDataclass))
#> False

print(dataclasses.is_dataclass(PydanticDataclass))
#> True
print(pydantic.dataclasses.is_pydantic_dataclass(PydanticDataclass))
#> True
```

## Initialization hooks

When you initialize a dataclass, it is possible to execute code *before* or *after* validation
Expand Down
12 changes: 0 additions & 12 deletions pydantic/_internal/_dataclasses.py
Expand Up @@ -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__
2 changes: 1 addition & 1 deletion pydantic/_internal/_generate_schema.py
Expand Up @@ -1308,7 +1308,7 @@ def _dataclass_schema(

self = self._current_generate_schema

from ._dataclasses import is_pydantic_dataclass
from pydantic.dataclasses import is_pydantic_dataclass

if is_pydantic_dataclass(dataclass):
fields = dataclass.__pydantic_fields__
Expand Down
14 changes: 13 additions & 1 deletion pydantic/dataclasses.py
Expand Up @@ -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
Expand Down Expand Up @@ -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__
15 changes: 14 additions & 1 deletion tests/test_dataclasses.py
Expand Up @@ -33,7 +33,7 @@
model_validator,
)
from pydantic._internal._mock_validator import MockValidator
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

Expand Down Expand Up @@ -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

0 comments on commit 2fe4aff

Please sign in to comment.