Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,23 @@ concurrency:
cancel-in-progress: true

jobs:
docs:
name: Build docs
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
persist-credentials: false

- name: Install the latest version of uv
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
with:
python-version: "3.14"

- name: Build docs in nitpicky mode
run: uvx --from sphinx sphinx-build -n -W -b html doc doc/_build/html

tests:
name: Run tests

Expand Down
10 changes: 10 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,16 @@ Running these commands in the `src/` directory ensures that the local file
`typing_extensions.py` is used, instead of any other version of the library you
may have installed.

# Building the documentation

To build the documentation in nitpicky mode and treat warnings as errors, run:

```
uvx --from sphinx sphinx-build -n -W -b html doc doc/_build/html
```

The generated HTML documentation is written to `doc/_build/html`.

# Linting

Linting is done via pre-commit. We recommend running pre-commit via a tool such
Expand Down
9 changes: 6 additions & 3 deletions doc/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,12 @@
templates_path = ['_templates']
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']

# This should usually point to /3, unless there is a necessity to link to
# features in future versions of Python.
intersphinx_mapping = {'py': ('https://docs.python.org/3', None)}
# Use Python 3.15 for new features and Python 3.14 as a fallback for APIs that
# were removed in Python 3.15.
intersphinx_mapping = {
'py': ('https://docs.python.org/3.15', None),
'py314': ('https://docs.python.org/3.14', None),
}

add_module_names = False

Expand Down
40 changes: 28 additions & 12 deletions doc/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -587,14 +587,26 @@ Special typing primitives
``typing_extensions`` backports various bug fixes and improvements
to ``TypedDict``.

:py:class:`TypedDict` does not store runtime information
about which (if any) keys are non-required in Python 3.8, and does not
honor the ``total`` keyword with old-style ``TypedDict()`` in Python
3.9.0 and 3.9.1. :py:class:`typing.TypedDict` also does not support multiple inheritance
with :py:class:`typing.Generic` on Python <3.11, and :py:class:`typing.TypedDict` classes do not
consistently have the ``__orig_bases__`` attribute on Python <3.12. The
``typing_extensions`` backport provides all of these features and bugfixes on
all Python versions.
Features backported by `typing_extensions` include:

* :py:class:`typing.TypedDict` does not store runtime information about which
(if any) keys are non-required in Python 3.8, and does not honor the
*total* keyword with old-style ``TypedDict()`` on Python 3.9.0 and 3.9.1.
* :py:class:`typing.TypedDict` does not support multiple inheritance with
:py:class:`typing.Generic` on Python <3.11
* :py:class:`typing.TypedDict` classes do not consistently have the
:attr:`!__orig_bases__` attribute on Python <3.12.
* :py:class:`typing.TypedDict` does not expose the
:py:attr:`~typing.TypedDict.__readonly_keys__` and
:py:attr:`~typing.TypedDict.__mutable_keys__` attributes on Python <3.13.
* :py:class:`typing.TypedDict` does not support the *extra_items* or *closed*
keyword arguments on Python <3.15, and also does not expose the
:py:attr:`~typing.TypedDict.__extra_items__` and
:py:attr:`~typing.TypedDict.__closed__` attributes on Python <3.15.

``typing_extensions`` also currently includes experimental support for
:pep:`764` (inline ``TypedDict``\ s), which is not yet supported in the
standard library on any Python version.

Historically, ``TypedDict`` has supported an alternative creation syntax
where the fields are supplied as keyword arguments (e.g.,
Expand All @@ -603,6 +615,9 @@ Special typing primitives
raises a :py:exc:`DeprecationWarning` when this syntax is used in Python 3.12
or lower and fails with a :py:exc:`TypeError` in Python 3.13 and higher.

Introspection attributes
------------------------

``typing_extensions`` supports the :data:`ReadOnly` qualifier
introduced by :pep:`705`. It is reflected in the following attributes:

Expand All @@ -620,7 +635,7 @@ Special typing primitives

.. versionadded:: 4.9.0

The ``closed`` and ``extra_items`` keyword arguments introduced by
The *closed* and *extra_items* keyword arguments introduced by
:pep:`728` and supported in Python 3.15 and newer are supported.

For runtime introspection, two attributes can be looked at:
Expand All @@ -640,6 +655,9 @@ Special typing primitives

.. versionadded:: 4.10.0

History
-------

.. versionchanged:: 4.3.0

Added support for generic ``TypedDict``\ s.
Expand Down Expand Up @@ -873,9 +891,7 @@ Protocols
Decorators
~~~~~~~~~~

.. decorator:: dataclass_transform(*, eq_default=False, order_default=False,
kw_only_default=False, frozen_default=False,
field_specifiers=(), **kwargs)
.. decorator:: dataclass_transform(*, eq_default=False, order_default=False, kw_only_default=False, frozen_default=False, field_specifiers=(), **kwargs)

See :py:func:`typing.dataclass_transform` and :pep:`681`. In ``typing`` since 3.11.

Expand Down
7 changes: 4 additions & 3 deletions src/test_typing_extensions.py
Original file line number Diff line number Diff line change
Expand Up @@ -7175,7 +7175,10 @@ def test_all_names_in___all__(self):
self.assertLessEqual(exclude, actual_names)

def test_typing_extensions_defers_when_possible(self):
exclude = set()
# These two are currently always different to `typing.TypedDict`
# as PEP 764 has not yet been accepted/implemented upstream.
exclude = {'TypedDict', 'is_typeddict'}

if sys.version_info < (3, 10):
exclude |= {'get_args', 'get_origin'}
if sys.version_info < (3, 10, 1):
Expand All @@ -7202,8 +7205,6 @@ def test_typing_extensions_defers_when_possible(self):
exclude |= {
'TypeVarTuple'
}
if not typing_extensions._PEP_728_IMPLEMENTED:
exclude |= {'TypedDict', 'is_typeddict'}
for item in typing_extensions.__all__:
if item not in exclude and hasattr(typing, item):
self.assertIs(
Expand Down
9 changes: 5 additions & 4 deletions src/typing_extensions.py
Original file line number Diff line number Diff line change
Expand Up @@ -1131,10 +1131,10 @@ def __reduce__(self):


# Update this to something like >=3.13.0b1 if and when
# PEP 728 is implemented in CPython
_PEP_728_IMPLEMENTED = False
# PEP 764 is implemented in CPython
_PEP_764_IMPLEMENTED = False

if _PEP_728_IMPLEMENTED:
if _PEP_764_IMPLEMENTED:
# The standard library TypedDict in Python 3.9.0/1 does not honour the "total"
# keyword with old-style TypedDict(). See https://bugs.python.org/issue42059
# The standard library TypedDict below Python 3.11 does not store runtime
Expand All @@ -1144,7 +1144,8 @@ def __reduce__(self):
# to enable better runtime introspection.
# On 3.13 we deprecate some odd ways of creating TypedDicts.
# Also on 3.13, PEP 705 adds the ReadOnly[] qualifier.
# PEP 728 (still pending) makes more changes.
# PEP 728 (Python 3.15+) adds the `extra_items` and `closed` keywords.
# PEP 764 (still pending) allows the `TypedDict` special form to be subscripted.
TypedDict = typing.TypedDict
_TypedDictMeta = typing._TypedDictMeta
is_typeddict = typing.is_typeddict
Expand Down
Loading