Repository: pydantic/pydantic

Issue:
Contradictory typing.TypedDict >=3.11 or >=3.12 support
### Initial Checks

- [X] I confirm that I'm using Pydantic V2

### Description

Hi,

The following piece of code is contradictory with respect to the python version which supports typing.TypedDict:

```python
def _typed_dict_schema(self, typed_dict_cls: Any, origin: Any) -> core_schema.CoreSchema:
        """Generate schema for a TypedDict.

        It is not possible to track required/optional keys in TypedDict without __required_keys__
        since TypedDict.__new__ erases the base classes (it replaces them with just `dict`)
        and thus we can track usage of total=True/False
        __required_keys__ was added in Python 3.9
        (https://github.com/miss-islington/cpython/blob/1e9939657dd1f8eb9f596f77c1084d2d351172fc/Doc/library/typing.rst?plain=1#L1546-L1548)
        however it is buggy
        (https://github.com/python/typing_extensions/blob/ac52ac5f2cb0e00e7988bae1e2a1b8257ac88d6d/src/typing_extensions.py#L657-L666).
        Hence to avoid creating validators that do not do what users expect we only
        support typing.TypedDict on Python >= 3.11 or typing_extension.TypedDict on all versions
        """
        with self.defs.get_schema_or_ref(typed_dict_cls) as (typed_dict_ref, maybe_schema):
            if maybe_schema is not None:
                return maybe_schema

            typevars_map = get_standard_typevars_map(typed_dict_cls)
            if origin is not None:
                typed_dict_cls = origin

            if not _SUPPORTS_TYPEDDICT and type(typed_dict_cls).__module__ == 'typing':
                raise PydanticUserError(
                    'Please use `typing_extensions.TypedDict` instead of `typing.TypedDict` on Python < 3.12.',
                    code='typed-dict-version',
                )
```

The code comes from /pydantic/_internal/_generate_schema.py, line ~780

Curious which of the 2 it is, support from >=3.11 or >=3.12? The actual check is performed for 3.12, but the docstring states that 3.11 is sufficient. In case support for 3.11 should be available, the following check should be adjusted:

```python
_SUPPORTS_TYPEDDICT = sys.version_info >= (3, 12)
```

Line 70 in the same file.

### Example Code

```Python
import pydantic
from typing import TypedDict

# breaks on python 3.11, while the docstring above mentions it should actually be supported
```


### Python, Pydantic & OS Version

```Text
pydantic version: 2.0.2
        pydantic-core version: 2.1.2 release build profile
                 install path: C:\Users\vantongeren\Documents\code\server-devops-engine\api\venv\Lib\site-packages\pydantic
               python version: 3.11.3 (tags/v3.11.3:f3909b8, Apr  4 2023, 23:49:59) [MSC v.1934 64 bit (AMD64)]
                     platform: Windows-10-10.0.19045-SP0
     optional deps. installed: ['typing-extensions']
```


Selected Assignee: @samuelcolvin


Discussion:
@adriangb can you look at this, I thought 3.11 was enough, but I might be wrong.
We need 3.12 for the standard library version
Can I ask why? The Required/NotRequired annotations were added to the standard library in Python 3.11, and the comment in the typing_extensions link specifically says that `The standard library TypedDict below Python 3.11 does not store runtime information about optional and required keys when using Required or NotRequired.`, so shouldn't 3.11 be supported too?
We need https://github.com/python/cpython/pull/103698 for various things to work

Resolving patch:
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
@@ -839,8 +839,11 @@ def _typed_dict_schema(self, typed_dict_cls: Any, origin: Any) -> core_schema.Co
         (https://github.com/miss-islington/cpython/blob/1e9939657dd1f8eb9f596f77c1084d2d351172fc/Doc/library/typing.rst?plain=1#L1546-L1548)
         however it is buggy
         (https://github.com/python/typing_extensions/blob/ac52ac5f2cb0e00e7988bae1e2a1b8257ac88d6d/src/typing_extensions.py#L657-L666).
+
+        On 3.11 but < 3.12 TypedDict does not preserve inheritance information.
+
         Hence to avoid creating validators that do not do what users expect we only
-        support typing.TypedDict on Python >= 3.11 or typing_extension.TypedDict on all versions
+        support typing.TypedDict on Python >= 3.12 or typing_extension.TypedDict on all versions
         """
         with self.defs.get_schema_or_ref(typed_dict_cls) as (typed_dict_ref, maybe_schema):
             if maybe_schema is not None:


Test patch: