We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Bug: Schema generation partially broken since litestar version 2.3.0
### Description

2.2.1 is my last working version of litestar. 

Before:
<img width="467" alt="image" src="https://github.com/litestar-org/litestar/assets/85191795/dc9594b1-4b09-4607-9061-dcd65bf0a09f">

After:
I first get this `internal server error` when i first try to go to my Swagger URL

<img width="436" alt="image" src="https://github.com/litestar-org/litestar/assets/85191795/90112884-907e-4ee0-a14c-a92c338ef761">

And then when i refresh once more, it goes to my swagger page, but only 2/3 of it.



<img width="217" alt="image" src="https://github.com/litestar-org/litestar/assets/85191795/74f16208-e80a-46de-b580-3dd566e0f14b">

With no changes in my code, the problems just start at version 2.3.0 and beyond. Just wanted to bring attention to this, as I will now be sticking to litestar 2.2.1 until this is resolved.

### URL to code causing the issue

_No response_

### MCVE

```python
How my app code looks like when passing in my controllers:

app = Litestar(
    route_handlers=[
        read_root,
        refresh_templates,
        LinuxPXEController,
        WindowsPXEController,
        ESXiPXEController
    ],
 ...
```


### Steps to reproduce

_No response_

### Screenshots

```bash
"![SCREENSHOT_DESCRIPTION](SCREENSHOT_LINK.png)"
```


### Logs

_No response_

### Litestar Version

2.3.0

### Platform

- [X] Linux
- [X] Mac
- [ ] Windows
- [ ] Other (Please specify in the description above)

<!-- POLAR PLEDGE BADGE START -->
---
> [!NOTE]  
> While we are open for sponsoring on [GitHub Sponsors](https://github.com/sponsors/litestar-org/) and 
> [OpenCollective](https://opencollective.com/litestar), we also utilize [Polar.sh](https://polar.sh/) to engage in pledge-based sponsorship.
>
> Check out all issues funded or available for funding [on our Polar.sh Litestar dashboard](https://polar.sh/litestar-org)
> * If you would like to see an issue prioritized, make a pledge towards it!
> * We receive the pledge once the issue is completed & verified
> * This, along with engagement in the community, helps us know which features are a priority to our users.

<a href="https://polar.sh/litestar-org/litestar/issues/2635">
<picture>
  <source media="(prefers-color-scheme: dark)" srcset="https://polar.sh/api/github/litestar-org/litestar/issues/2635/pledge.svg?darkmode=1">
  <img alt="Fund with Polar" src="https://polar.sh/api/github/litestar-org/litestar/issues/2635/pledge.svg">
</picture>
</a>
<!-- POLAR PLEDGE BADGE END -->


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `litestar/contrib/pydantic/utils.py`
Content:
```
1 from __future__ import annotations
2 
3 from typing import TYPE_CHECKING, Any
4 
5 from typing_extensions import get_type_hints
6 
7 from litestar.types import Empty
8 from litestar.utils import is_class_and_subclass
9 from litestar.utils.predicates import is_generic
10 from litestar.utils.typing import (
11     _substitute_typevars,
12     get_origin_or_inner_type,
13     get_type_hints_with_generics_resolved,
14     instantiable_type_mapping,
15 )
16 
17 # isort: off
18 try:
19     from pydantic import v1 as pydantic_v1
20     import pydantic as pydantic_v2
21     from pydantic.fields import PydanticUndefined as Pydantic2Undefined  # type: ignore[attr-defined]
22     from pydantic.v1.fields import Undefined as Pydantic1Undefined
23 
24     PYDANTIC_UNDEFINED_SENTINELS = {Pydantic1Undefined, Pydantic2Undefined}
25 except ImportError:
26     try:
27         import pydantic as pydantic_v1  # type: ignore[no-redef]
28         from pydantic.fields import Undefined as Pydantic1Undefined  # type: ignore[attr-defined, no-redef]
29 
30         pydantic_v2 = Empty  # type: ignore[assignment]
31         PYDANTIC_UNDEFINED_SENTINELS = {Pydantic1Undefined}
32 
33     except ImportError:  # pyright: ignore
34         pydantic_v1 = Empty  # type: ignore[assignment]
35         pydantic_v2 = Empty  # type: ignore[assignment]
36         PYDANTIC_UNDEFINED_SENTINELS = set()
37 # isort: on
38 
39 
40 if TYPE_CHECKING:
41     from typing_extensions import TypeGuard
42 
43 
44 def is_pydantic_model_class(
45     annotation: Any,
46 ) -> TypeGuard[type[pydantic_v1.BaseModel | pydantic_v2.BaseModel]]:  # pyright: ignore
47     """Given a type annotation determine if the annotation is a subclass of pydantic's BaseModel.
48 
49     Args:
50         annotation: A type.
51 
52     Returns:
53         A typeguard determining whether the type is :data:`BaseModel pydantic.BaseModel>`.
54     """
55     if pydantic_v1 is Empty:  # type: ignore[comparison-overlap] # pragma: no cover
56         return False
57 
58     if pydantic_v2 is Empty:  # type: ignore[comparison-overlap] # pragma: no cover
59         return is_class_and_subclass(annotation, pydantic_v1.BaseModel)
60 
61     return is_class_and_subclass(annotation, (pydantic_v1.BaseModel, pydantic_v2.BaseModel))
62 
63 
64 def is_pydantic_model_instance(
65     annotation: Any,
66 ) -> TypeGuard[pydantic_v1.BaseModel | pydantic_v2.BaseModel]:  # pyright: ignore
67     """Given a type annotation determine if the annotation is an instance of pydantic's BaseModel.
68 
69     Args:
70         annotation: A type.
71 
72     Returns:
73         A typeguard determining whether the type is :data:`BaseModel pydantic.BaseModel>`.
74     """
75     if pydantic_v1 is Empty:  # type: ignore[comparison-overlap] # pragma: no cover
76         return False
77 
78     if pydantic_v2 is Empty:  # type: ignore[comparison-overlap] # pragma: no cover
79         return isinstance(annotation, pydantic_v1.BaseModel)
80 
81     return isinstance(annotation, (pydantic_v1.BaseModel, pydantic_v2.BaseModel))
82 
83 
84 def is_pydantic_constrained_field(annotation: Any) -> bool:
85     """Check if the given annotation is a constrained pydantic type.
86 
87     Args:
88         annotation: A type annotation
89 
90     Returns:
91         True if pydantic is installed and the type is a constrained type, otherwise False.
92     """
93     if pydantic_v1 is Empty:  # type: ignore[comparison-overlap] # pragma: no cover
94         return False
95 
96     return any(
97         is_class_and_subclass(annotation, constrained_type)  # pyright: ignore
98         for constrained_type in (
99             pydantic_v1.ConstrainedBytes,
100             pydantic_v1.ConstrainedDate,
101             pydantic_v1.ConstrainedDecimal,
102             pydantic_v1.ConstrainedFloat,
103             pydantic_v1.ConstrainedFrozenSet,
104             pydantic_v1.ConstrainedInt,
105             pydantic_v1.ConstrainedList,
106             pydantic_v1.ConstrainedSet,
107             pydantic_v1.ConstrainedStr,
108         )
109     )
110 
111 
112 def pydantic_unwrap_and_get_origin(annotation: Any) -> Any | None:
113     if pydantic_v2 is Empty or is_class_and_subclass(annotation, pydantic_v1.BaseModel):  # type: ignore[comparison-overlap]
114         return get_origin_or_inner_type(annotation)
115 
116     origin = annotation.__pydantic_generic_metadata__["origin"]
117     return instantiable_type_mapping.get(origin, origin)
118 
119 
120 def pydantic_get_type_hints_with_generics_resolved(
121     annotation: Any,
122     globalns: dict[str, Any] | None = None,
123     localns: dict[str, Any] | None = None,
124     include_extras: bool = False,
125 ) -> dict[str, Any]:
126     if pydantic_v2 is Empty or is_class_and_subclass(annotation, pydantic_v1.BaseModel):  # type: ignore[comparison-overlap]
127         return get_type_hints_with_generics_resolved(annotation)
128 
129     origin = pydantic_unwrap_and_get_origin(annotation)
130     if origin is None:
131         type_hints = get_type_hints(annotation, globalns=globalns, localns=localns, include_extras=include_extras)
132         typevar_map = {p: p for p in annotation.__pydantic_generic_metadata__["parameters"]}
133     else:
134         type_hints = get_type_hints(origin, globalns=globalns, localns=localns, include_extras=include_extras)
135         args = annotation.__pydantic_generic_metadata__["args"]
136         parameters = origin.__pydantic_generic_metadata__["parameters"]
137         typevar_map = dict(zip(parameters, args))
138 
139     return {n: _substitute_typevars(type_, typevar_map) for n, type_ in type_hints.items()}
140 
141 
142 def pydantic_get_unwrapped_annotation_and_type_hints(annotation: Any) -> tuple[Any, dict[str, Any]]:
143     """Get the unwrapped annotation and the type hints after resolving generics.
144 
145     Args:
146         annotation: A type annotation.
147 
148     Returns:
149         A tuple containing the unwrapped annotation and the type hints.
150     """
151 
152     if is_generic(annotation):
153         origin = pydantic_unwrap_and_get_origin(annotation)
154         return origin or annotation, pydantic_get_type_hints_with_generics_resolved(annotation, include_extras=True)
155     return annotation, get_type_hints(annotation, include_extras=True)
156 
157 
158 def is_pydantic_2_model(
159     obj: type[pydantic_v1.BaseModel | pydantic_v2.BaseModel],  # pyright: ignore
160 ) -> TypeGuard[pydantic_v2.BaseModel]:  # pyright: ignore
161     return issubclass(obj, pydantic_v2.BaseModel)  # pyright: ignore
162 
163 
164 def is_pydantic_undefined(value: Any) -> bool:
165     return value in PYDANTIC_UNDEFINED_SENTINELS
166
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/litestar/contrib/pydantic/utils.py b/litestar/contrib/pydantic/utils.py
--- a/litestar/contrib/pydantic/utils.py
+++ b/litestar/contrib/pydantic/utils.py
@@ -162,4 +162,4 @@
 
 
 def is_pydantic_undefined(value: Any) -> bool:
-    return value in PYDANTIC_UNDEFINED_SENTINELS
+    return any(v is value for v in PYDANTIC_UNDEFINED_SENTINELS)

{"golden_diff": "diff --git a/litestar/contrib/pydantic/utils.py b/litestar/contrib/pydantic/utils.py\n--- a/litestar/contrib/pydantic/utils.py\n+++ b/litestar/contrib/pydantic/utils.py\n@@ -162,4 +162,4 @@\n \n \n def is_pydantic_undefined(value: Any) -> bool:\n-    return value in PYDANTIC_UNDEFINED_SENTINELS\n+    return any(v is value for v in PYDANTIC_UNDEFINED_SENTINELS)\n", "issue": "Bug: Schema generation partially broken since litestar version 2.3.0\n### Description\n\n2.2.1 is my last working version of litestar. \r\n\r\nBefore:\r\n<img width=\"467\" alt=\"image\" src=\"https://github.com/litestar-org/litestar/assets/85191795/dc9594b1-4b09-4607-9061-dcd65bf0a09f\">\r\n\r\nAfter:\r\nI first get this `internal server error` when i first try to go to my Swagger URL\r\n\r\n<img width=\"436\" alt=\"image\" src=\"https://github.com/litestar-org/litestar/assets/85191795/90112884-907e-4ee0-a14c-a92c338ef761\">\r\n\r\nAnd then when i refresh once more, it goes to my swagger page, but only 2/3 of it.\r\n\r\n\r\n\r\n<img width=\"217\" alt=\"image\" src=\"https://github.com/litestar-org/litestar/assets/85191795/74f16208-e80a-46de-b580-3dd566e0f14b\">\r\n\r\nWith no changes in my code, the problems just start at version 2.3.0 and beyond. Just wanted to bring attention to this, as I will now be sticking to litestar 2.2.1 until this is resolved.\n\n### URL to code causing the issue\n\n_No response_\n\n### MCVE\n\n```python\nHow my app code looks like when passing in my controllers:\r\n\r\napp = Litestar(\r\n    route_handlers=[\r\n        read_root,\r\n        refresh_templates,\r\n        LinuxPXEController,\r\n        WindowsPXEController,\r\n        ESXiPXEController\r\n    ],\r\n ...\n```\n\n\n### Steps to reproduce\n\n_No response_\n\n### Screenshots\n\n```bash\n\"![SCREENSHOT_DESCRIPTION](SCREENSHOT_LINK.png)\"\n```\n\n\n### Logs\n\n_No response_\n\n### Litestar Version\n\n2.3.0\n\n### Platform\n\n- [X] Linux\n- [X] Mac\n- [ ] Windows\n- [ ] Other (Please specify in the description above)\n\n<!-- POLAR PLEDGE BADGE START -->\n---\n> [!NOTE]  \n> While we are open for sponsoring on [GitHub Sponsors](https://github.com/sponsors/litestar-org/) and \n> [OpenCollective](https://opencollective.com/litestar), we also utilize [Polar.sh](https://polar.sh/) to engage in pledge-based sponsorship.\n>\n> Check out all issues funded or available for funding [on our Polar.sh Litestar dashboard](https://polar.sh/litestar-org)\n> * If you would like to see an issue prioritized, make a pledge towards it!\n> * We receive the pledge once the issue is completed & verified\n> * This, along with engagement in the community, helps us know which features are a priority to our users.\n\n<a href=\"https://polar.sh/litestar-org/litestar/issues/2635\">\n<picture>\n  <source media=\"(prefers-color-scheme: dark)\" srcset=\"https://polar.sh/api/github/litestar-org/litestar/issues/2635/pledge.svg?darkmode=1\">\n  <img alt=\"Fund with Polar\" src=\"https://polar.sh/api/github/litestar-org/litestar/issues/2635/pledge.svg\">\n</picture>\n</a>\n<!-- POLAR PLEDGE BADGE END -->\n\n", "before_files": [{"content": "from __future__ import annotations\n\nfrom typing import TYPE_CHECKING, Any\n\nfrom typing_extensions import get_type_hints\n\nfrom litestar.types import Empty\nfrom litestar.utils import is_class_and_subclass\nfrom litestar.utils.predicates import is_generic\nfrom litestar.utils.typing import (\n    _substitute_typevars,\n    get_origin_or_inner_type,\n    get_type_hints_with_generics_resolved,\n    instantiable_type_mapping,\n)\n\n# isort: off\ntry:\n    from pydantic import v1 as pydantic_v1\n    import pydantic as pydantic_v2\n    from pydantic.fields import PydanticUndefined as Pydantic2Undefined  # type: ignore[attr-defined]\n    from pydantic.v1.fields import Undefined as Pydantic1Undefined\n\n    PYDANTIC_UNDEFINED_SENTINELS = {Pydantic1Undefined, Pydantic2Undefined}\nexcept ImportError:\n    try:\n        import pydantic as pydantic_v1  # type: ignore[no-redef]\n        from pydantic.fields import Undefined as Pydantic1Undefined  # type: ignore[attr-defined, no-redef]\n\n        pydantic_v2 = Empty  # type: ignore[assignment]\n        PYDANTIC_UNDEFINED_SENTINELS = {Pydantic1Undefined}\n\n    except ImportError:  # pyright: ignore\n        pydantic_v1 = Empty  # type: ignore[assignment]\n        pydantic_v2 = Empty  # type: ignore[assignment]\n        PYDANTIC_UNDEFINED_SENTINELS = set()\n# isort: on\n\n\nif TYPE_CHECKING:\n    from typing_extensions import TypeGuard\n\n\ndef is_pydantic_model_class(\n    annotation: Any,\n) -> TypeGuard[type[pydantic_v1.BaseModel | pydantic_v2.BaseModel]]:  # pyright: ignore\n    \"\"\"Given a type annotation determine if the annotation is a subclass of pydantic's BaseModel.\n\n    Args:\n        annotation: A type.\n\n    Returns:\n        A typeguard determining whether the type is :data:`BaseModel pydantic.BaseModel>`.\n    \"\"\"\n    if pydantic_v1 is Empty:  # type: ignore[comparison-overlap] # pragma: no cover\n        return False\n\n    if pydantic_v2 is Empty:  # type: ignore[comparison-overlap] # pragma: no cover\n        return is_class_and_subclass(annotation, pydantic_v1.BaseModel)\n\n    return is_class_and_subclass(annotation, (pydantic_v1.BaseModel, pydantic_v2.BaseModel))\n\n\ndef is_pydantic_model_instance(\n    annotation: Any,\n) -> TypeGuard[pydantic_v1.BaseModel | pydantic_v2.BaseModel]:  # pyright: ignore\n    \"\"\"Given a type annotation determine if the annotation is an instance of pydantic's BaseModel.\n\n    Args:\n        annotation: A type.\n\n    Returns:\n        A typeguard determining whether the type is :data:`BaseModel pydantic.BaseModel>`.\n    \"\"\"\n    if pydantic_v1 is Empty:  # type: ignore[comparison-overlap] # pragma: no cover\n        return False\n\n    if pydantic_v2 is Empty:  # type: ignore[comparison-overlap] # pragma: no cover\n        return isinstance(annotation, pydantic_v1.BaseModel)\n\n    return isinstance(annotation, (pydantic_v1.BaseModel, pydantic_v2.BaseModel))\n\n\ndef is_pydantic_constrained_field(annotation: Any) -> bool:\n    \"\"\"Check if the given annotation is a constrained pydantic type.\n\n    Args:\n        annotation: A type annotation\n\n    Returns:\n        True if pydantic is installed and the type is a constrained type, otherwise False.\n    \"\"\"\n    if pydantic_v1 is Empty:  # type: ignore[comparison-overlap] # pragma: no cover\n        return False\n\n    return any(\n        is_class_and_subclass(annotation, constrained_type)  # pyright: ignore\n        for constrained_type in (\n            pydantic_v1.ConstrainedBytes,\n            pydantic_v1.ConstrainedDate,\n            pydantic_v1.ConstrainedDecimal,\n            pydantic_v1.ConstrainedFloat,\n            pydantic_v1.ConstrainedFrozenSet,\n            pydantic_v1.ConstrainedInt,\n            pydantic_v1.ConstrainedList,\n            pydantic_v1.ConstrainedSet,\n            pydantic_v1.ConstrainedStr,\n        )\n    )\n\n\ndef pydantic_unwrap_and_get_origin(annotation: Any) -> Any | None:\n    if pydantic_v2 is Empty or is_class_and_subclass(annotation, pydantic_v1.BaseModel):  # type: ignore[comparison-overlap]\n        return get_origin_or_inner_type(annotation)\n\n    origin = annotation.__pydantic_generic_metadata__[\"origin\"]\n    return instantiable_type_mapping.get(origin, origin)\n\n\ndef pydantic_get_type_hints_with_generics_resolved(\n    annotation: Any,\n    globalns: dict[str, Any] | None = None,\n    localns: dict[str, Any] | None = None,\n    include_extras: bool = False,\n) -> dict[str, Any]:\n    if pydantic_v2 is Empty or is_class_and_subclass(annotation, pydantic_v1.BaseModel):  # type: ignore[comparison-overlap]\n        return get_type_hints_with_generics_resolved(annotation)\n\n    origin = pydantic_unwrap_and_get_origin(annotation)\n    if origin is None:\n        type_hints = get_type_hints(annotation, globalns=globalns, localns=localns, include_extras=include_extras)\n        typevar_map = {p: p for p in annotation.__pydantic_generic_metadata__[\"parameters\"]}\n    else:\n        type_hints = get_type_hints(origin, globalns=globalns, localns=localns, include_extras=include_extras)\n        args = annotation.__pydantic_generic_metadata__[\"args\"]\n        parameters = origin.__pydantic_generic_metadata__[\"parameters\"]\n        typevar_map = dict(zip(parameters, args))\n\n    return {n: _substitute_typevars(type_, typevar_map) for n, type_ in type_hints.items()}\n\n\ndef pydantic_get_unwrapped_annotation_and_type_hints(annotation: Any) -> tuple[Any, dict[str, Any]]:\n    \"\"\"Get the unwrapped annotation and the type hints after resolving generics.\n\n    Args:\n        annotation: A type annotation.\n\n    Returns:\n        A tuple containing the unwrapped annotation and the type hints.\n    \"\"\"\n\n    if is_generic(annotation):\n        origin = pydantic_unwrap_and_get_origin(annotation)\n        return origin or annotation, pydantic_get_type_hints_with_generics_resolved(annotation, include_extras=True)\n    return annotation, get_type_hints(annotation, include_extras=True)\n\n\ndef is_pydantic_2_model(\n    obj: type[pydantic_v1.BaseModel | pydantic_v2.BaseModel],  # pyright: ignore\n) -> TypeGuard[pydantic_v2.BaseModel]:  # pyright: ignore\n    return issubclass(obj, pydantic_v2.BaseModel)  # pyright: ignore\n\n\ndef is_pydantic_undefined(value: Any) -> bool:\n    return value in PYDANTIC_UNDEFINED_SENTINELS\n", "path": "litestar/contrib/pydantic/utils.py"}], "after_files": [{"content": "from __future__ import annotations\n\nfrom typing import TYPE_CHECKING, Any\n\nfrom typing_extensions import get_type_hints\n\nfrom litestar.types import Empty\nfrom litestar.utils import is_class_and_subclass\nfrom litestar.utils.predicates import is_generic\nfrom litestar.utils.typing import (\n    _substitute_typevars,\n    get_origin_or_inner_type,\n    get_type_hints_with_generics_resolved,\n    instantiable_type_mapping,\n)\n\n# isort: off\ntry:\n    from pydantic import v1 as pydantic_v1\n    import pydantic as pydantic_v2\n    from pydantic.fields import PydanticUndefined as Pydantic2Undefined  # type: ignore[attr-defined]\n    from pydantic.v1.fields import Undefined as Pydantic1Undefined\n\n    PYDANTIC_UNDEFINED_SENTINELS = {Pydantic1Undefined, Pydantic2Undefined}\nexcept ImportError:\n    try:\n        import pydantic as pydantic_v1  # type: ignore[no-redef]\n        from pydantic.fields import Undefined as Pydantic1Undefined  # type: ignore[attr-defined, no-redef]\n\n        pydantic_v2 = Empty  # type: ignore[assignment]\n        PYDANTIC_UNDEFINED_SENTINELS = {Pydantic1Undefined}\n\n    except ImportError:  # pyright: ignore\n        pydantic_v1 = Empty  # type: ignore[assignment]\n        pydantic_v2 = Empty  # type: ignore[assignment]\n        PYDANTIC_UNDEFINED_SENTINELS = set()\n# isort: on\n\n\nif TYPE_CHECKING:\n    from typing_extensions import TypeGuard\n\n\ndef is_pydantic_model_class(\n    annotation: Any,\n) -> TypeGuard[type[pydantic_v1.BaseModel | pydantic_v2.BaseModel]]:  # pyright: ignore\n    \"\"\"Given a type annotation determine if the annotation is a subclass of pydantic's BaseModel.\n\n    Args:\n        annotation: A type.\n\n    Returns:\n        A typeguard determining whether the type is :data:`BaseModel pydantic.BaseModel>`.\n    \"\"\"\n    if pydantic_v1 is Empty:  # type: ignore[comparison-overlap] # pragma: no cover\n        return False\n\n    if pydantic_v2 is Empty:  # type: ignore[comparison-overlap] # pragma: no cover\n        return is_class_and_subclass(annotation, pydantic_v1.BaseModel)\n\n    return is_class_and_subclass(annotation, (pydantic_v1.BaseModel, pydantic_v2.BaseModel))\n\n\ndef is_pydantic_model_instance(\n    annotation: Any,\n) -> TypeGuard[pydantic_v1.BaseModel | pydantic_v2.BaseModel]:  # pyright: ignore\n    \"\"\"Given a type annotation determine if the annotation is an instance of pydantic's BaseModel.\n\n    Args:\n        annotation: A type.\n\n    Returns:\n        A typeguard determining whether the type is :data:`BaseModel pydantic.BaseModel>`.\n    \"\"\"\n    if pydantic_v1 is Empty:  # type: ignore[comparison-overlap] # pragma: no cover\n        return False\n\n    if pydantic_v2 is Empty:  # type: ignore[comparison-overlap] # pragma: no cover\n        return isinstance(annotation, pydantic_v1.BaseModel)\n\n    return isinstance(annotation, (pydantic_v1.BaseModel, pydantic_v2.BaseModel))\n\n\ndef is_pydantic_constrained_field(annotation: Any) -> bool:\n    \"\"\"Check if the given annotation is a constrained pydantic type.\n\n    Args:\n        annotation: A type annotation\n\n    Returns:\n        True if pydantic is installed and the type is a constrained type, otherwise False.\n    \"\"\"\n    if pydantic_v1 is Empty:  # type: ignore[comparison-overlap] # pragma: no cover\n        return False\n\n    return any(\n        is_class_and_subclass(annotation, constrained_type)  # pyright: ignore\n        for constrained_type in (\n            pydantic_v1.ConstrainedBytes,\n            pydantic_v1.ConstrainedDate,\n            pydantic_v1.ConstrainedDecimal,\n            pydantic_v1.ConstrainedFloat,\n            pydantic_v1.ConstrainedFrozenSet,\n            pydantic_v1.ConstrainedInt,\n            pydantic_v1.ConstrainedList,\n            pydantic_v1.ConstrainedSet,\n            pydantic_v1.ConstrainedStr,\n        )\n    )\n\n\ndef pydantic_unwrap_and_get_origin(annotation: Any) -> Any | None:\n    if pydantic_v2 is Empty or is_class_and_subclass(annotation, pydantic_v1.BaseModel):  # type: ignore[comparison-overlap]\n        return get_origin_or_inner_type(annotation)\n\n    origin = annotation.__pydantic_generic_metadata__[\"origin\"]\n    return instantiable_type_mapping.get(origin, origin)\n\n\ndef pydantic_get_type_hints_with_generics_resolved(\n    annotation: Any,\n    globalns: dict[str, Any] | None = None,\n    localns: dict[str, Any] | None = None,\n    include_extras: bool = False,\n) -> dict[str, Any]:\n    if pydantic_v2 is Empty or is_class_and_subclass(annotation, pydantic_v1.BaseModel):  # type: ignore[comparison-overlap]\n        return get_type_hints_with_generics_resolved(annotation)\n\n    origin = pydantic_unwrap_and_get_origin(annotation)\n    if origin is None:\n        type_hints = get_type_hints(annotation, globalns=globalns, localns=localns, include_extras=include_extras)\n        typevar_map = {p: p for p in annotation.__pydantic_generic_metadata__[\"parameters\"]}\n    else:\n        type_hints = get_type_hints(origin, globalns=globalns, localns=localns, include_extras=include_extras)\n        args = annotation.__pydantic_generic_metadata__[\"args\"]\n        parameters = origin.__pydantic_generic_metadata__[\"parameters\"]\n        typevar_map = dict(zip(parameters, args))\n\n    return {n: _substitute_typevars(type_, typevar_map) for n, type_ in type_hints.items()}\n\n\ndef pydantic_get_unwrapped_annotation_and_type_hints(annotation: Any) -> tuple[Any, dict[str, Any]]:\n    \"\"\"Get the unwrapped annotation and the type hints after resolving generics.\n\n    Args:\n        annotation: A type annotation.\n\n    Returns:\n        A tuple containing the unwrapped annotation and the type hints.\n    \"\"\"\n\n    if is_generic(annotation):\n        origin = pydantic_unwrap_and_get_origin(annotation)\n        return origin or annotation, pydantic_get_type_hints_with_generics_resolved(annotation, include_extras=True)\n    return annotation, get_type_hints(annotation, include_extras=True)\n\n\ndef is_pydantic_2_model(\n    obj: type[pydantic_v1.BaseModel | pydantic_v2.BaseModel],  # pyright: ignore\n) -> TypeGuard[pydantic_v2.BaseModel]:  # pyright: ignore\n    return issubclass(obj, pydantic_v2.BaseModel)  # pyright: ignore\n\n\ndef is_pydantic_undefined(value: Any) -> bool:\n    return any(v is value for v in PYDANTIC_UNDEFINED_SENTINELS)\n", "path": "litestar/contrib/pydantic/utils.py"}]}