Repository: litestar-org/polyfactory
Pull request #660 (2025-03-16 13:44:18)

fix: ignore dataclass types in pydantic field parsing
<!--
By submitting this pull request, you agree to:
- follow [Litestar's Code of Conduct](https://github.com/litestar-org/.github/blob/main/CODE_OF_CONDUCT.md)
- follow [Litestar's contribution guidelines](https://github.com/litestar-org/.github/blob/main/CONTRIBUTING.md)
- follow the [PSFs's Code of Conduct](https://www.python.org/psf/conduct/)
-->
## Description

- See title

<!--
Please add in issue numbers this pull request will close, if applicable
Examples: Fixes #4321 or Closes #1234

Ensure you are using a supported keyword to properly link an issue:
https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword
-->
## Closes

Fixes https://github.com/litestar-org/polyfactory/issues/658


sonarqubecloud[bot]: ## [![Quality Gate Passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-passed-20px.png 'Quality Gate Passed')](https://sonarcloud.io/dashboard?id=starlite-api_polyfactory&pullRequest=660) **Quality Gate passed**  
Issues  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 New issues](https://sonarcloud.io/project/issues?id=starlite-api_polyfactory&pullRequest=660&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/accepted-16px.png '') [0 Accepted issues](https://sonarcloud.io/project/issues?id=starlite-api_polyfactory&pullRequest=660&issueStatuses=ACCEPTED)

Measures  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=starlite-api_polyfactory&pullRequest=660&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [100.0% Coverage on New Code](https://sonarcloud.io/component_measures?id=starlite-api_polyfactory&pullRequest=660&metric=new_coverage&view=list)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=starlite-api_polyfactory&pullRequest=660&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarQube Cloud](https://sonarcloud.io/dashboard?id=starlite-api_polyfactory&pullRequest=660)


github-actions[bot]: Documentation preview will be available shortly at https://litestar-org.github.io/polyfactory-docs-preview/660

Patch:
diff --git a/polyfactory/field_meta.py b/polyfactory/field_meta.py
index 07447d1..5dfd6c1 100644
--- a/polyfactory/field_meta.py
+++ b/polyfactory/field_meta.py
@@ -1,13 +1,13 @@
 from __future__ import annotations
 
-from dataclasses import asdict, is_dataclass
+from dataclasses import asdict
 from typing import TYPE_CHECKING, Any, Hashable, Literal, Mapping, Pattern, TypedDict, cast
 
 from typing_extensions import get_args, get_origin
 
 from polyfactory.constants import DEFAULT_RANDOM, TYPE_MAPPING
 from polyfactory.utils.deprecation import check_for_deprecated_parameters
-from polyfactory.utils.helpers import get_annotation_metadata, unwrap_annotated, unwrap_new_type
+from polyfactory.utils.helpers import get_annotation_metadata, is_dataclass_instance, unwrap_annotated, unwrap_new_type
 from polyfactory.utils.predicates import is_annotated
 from polyfactory.utils.types import NoneType
 
@@ -181,7 +181,7 @@ class FieldMeta:
                     constraints["pattern"] = "[[:ascii:]]"
                 elif func is str.isdigit:
                     constraints["pattern"] = "[[:digit:]]"
-            elif is_dataclass(value) and (value_dict := asdict(value)) and ("allowed_schemes" in value_dict):  # type: ignore[arg-type]
+            elif is_dataclass_instance(value) and (value_dict := asdict(value)) and ("allowed_schemes" in value_dict):
                 constraints["url"] = {k: v for k, v in value_dict.items() if v is not None}
             # This is to support `Constraints`, but we can't do a isinstance with `Constraints` since isinstance
             # checks with `TypedDict` is not supported.
diff --git a/polyfactory/utils/helpers.py b/polyfactory/utils/helpers.py
index b505098..01e2b3a 100644
--- a/polyfactory/utils/helpers.py
+++ b/polyfactory/utils/helpers.py
@@ -2,6 +2,7 @@ from __future__ import annotations
 
 import sys
 from collections import deque
+from dataclasses import is_dataclass
 from typing import TYPE_CHECKING, Any, Mapping, Sequence
 
 from typing_extensions import TypeAliasType, get_args, get_origin
@@ -198,3 +199,7 @@ def get_collection_type(annotation: Any) -> type[list | tuple | set | frozenset
 
     msg = f"Unknown collection type - {annotation}"
     raise ValueError(msg)
+
+
+def is_dataclass_instance(obj: Any) -> bool:
+    return is_dataclass(obj) and not isinstance(obj, type)


Test patch:
diff --git a/tests/test_pydantic_factory.py b/tests/test_pydantic_factory.py
index 03c88e2..c26168d 100644
--- a/tests/test_pydantic_factory.py
+++ b/tests/test_pydantic_factory.py
@@ -1038,3 +1038,12 @@ def test_annotated_children() -> None:
     AFactory = ModelFactory.create_factory(A)
 
     assert AFactory.build()
+
+
+@pytest.mark.skipif(IS_PYDANTIC_V1, reason="pydantic 2 only test")
+def test_skip_validation() -> None:
+    class A(BaseModel):
+        a: Annotated[int, pydantic.SkipValidation]
+
+    AFactory = ModelFactory.create_factory(A)
+    assert AFactory.build()