Repository: litestar-org/polyfactory (python)

Issue:
Docs: How to handle Callable types
### Summary

Python version: 3.13
Polyfactory: 2.19.0
Pydantic: 2.10.6

Given the following:
```
MyTypedFunc = Callable[
    [str],
    Coroutine[Any, Any, AsyncIterable],
]


class TestClass(BaseModel):
    name: str
    my_function: MyTypedFunc


class TestClassFactory(ModelFactory[TestClass]):
    __model__ = TestClass


def test_test_class() -> None:
    iut = TestClassFactory.build()

    assert isinstance(iut, TestClass)
```
When run in pytest, I get the following error at the `build()` statement:
```
>   return tuple(TYPE_MAPPING.get(arg, arg) for arg in get_args(self.annotation))
E   TypeError: unhashable type: 'list'
```
I have tried mocking the function and ignoring the field.  It isn't clear in the documentation how to handle this scenario, and, for all it's praise, AI, hasn't been any help at all.

Is there a way to handle this?

Pull request description:
fix: allow non-hashable type args
<!--
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

- Allow non-hashable types by checking
- Note this would still raise parameter error in some circumstances but does not raise an internal error allowing the user to specify the way to resolve the type

<!--
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

- Closes #639


Patch:
diff --git a/polyfactory/field_meta.py b/polyfactory/field_meta.py
index 8dd0e3d..07447d1 100644
--- a/polyfactory/field_meta.py
+++ b/polyfactory/field_meta.py
@@ -1,7 +1,7 @@
 from __future__ import annotations
 
 from dataclasses import asdict, is_dataclass
-from typing import TYPE_CHECKING, Any, Literal, Mapping, Pattern, TypedDict, cast
+from typing import TYPE_CHECKING, Any, Hashable, Literal, Mapping, Pattern, TypedDict, cast
 
 from typing_extensions import get_args, get_origin
 
@@ -93,7 +93,10 @@ class FieldMeta:
 
         :returns: a tuple of types.
         """
-        return tuple(TYPE_MAPPING.get(arg, arg) for arg in get_args(self.annotation))
+        return tuple(
+            TYPE_MAPPING.get(arg, arg) if isinstance(arg, Hashable) else arg  # pyright: ignore[reportCallIssue,reportArgumentType]
+            for arg in get_args(self.annotation)
+        )
 
     @classmethod
     def from_type(


Test patch:
diff --git a/tests/test_complex_types.py b/tests/test_complex_types.py
index dcc699f..c11f15d 100644
--- a/tests/test_complex_types.py
+++ b/tests/test_complex_types.py
@@ -203,3 +203,13 @@ def test_sequence_dict() -> None:
     result = MyFactory.build()
 
     assert result.sequence_dict
+
+
+def test_build_with_callable() -> None:
+    @dataclass
+    class A:
+        foo: Callable[[str], int]
+
+    factory = DataclassFactory.create_factory(A)
+    with pytest.raises(ParameterException, match="Unsupported type:"):
+        factory.build()