Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-typing_extensions for openSUSE:Factory checked in at 2022-09-07 11:05:32 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-typing_extensions (Old) and /work/SRC/openSUSE:Factory/.python-typing_extensions.new.2083 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-typing_extensions" Wed Sep 7 11:05:32 2022 rev:15 rq:1001419 version:4.3.0 Changes: -------- --- /work/SRC/openSUSE:Factory/python-typing_extensions/python-typing_extensions.changes 2022-04-22 21:53:35.602760813 +0200 +++ /work/SRC/openSUSE:Factory/.python-typing_extensions.new.2083/python-typing_extensions.changes 2022-09-07 11:05:36.412340984 +0200 @@ -1,0 +2,10 @@ +Mon Sep 5 06:47:51 UTC 2022 - John Vandenberg <jay...@gmail.com> + +- Add _typed_dict_test_helper.py missing from PyPI release +- Update to v4.3.0 + * Add typing_extensions.NamedTuple, allowing for generic NamedTuples + on Python <3.11 (backport from python/cpython#92027, by Serhiy Storchaka) + * Adjust typing_extensions.TypedDict to allow for generic TypedDicts + on Python <3.11 (backport from python/cpython#27663, by Samodya Abey) + +------------------------------------------------------------------- Old: ---- typing_extensions-4.2.0.tar.gz New: ---- _typed_dict_test_helper.py typing_extensions-4.3.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-typing_extensions.spec ++++++ --- /var/tmp/diff_new_pack.PkfYJ0/_old 2022-09-07 11:05:38.912347339 +0200 +++ /var/tmp/diff_new_pack.PkfYJ0/_new 2022-09-07 11:05:38.916347349 +0200 @@ -1,5 +1,5 @@ # -# spec file +# spec file for python-typing_extensions # # Copyright (c) 2022 SUSE LLC # @@ -28,12 +28,14 @@ %bcond_with test %endif Name: python-typing_extensions%{psuffix} -Version: 4.2.0 +Version: 4.3.0 Release: 0 Summary: Backported and Experimental Type Hints for Python 35+ License: Python-2.0 URL: https://github.com/python/typing/ Source0: https://files.pythonhosted.org/packages/source/t/typing_extensions/%{modname}-%{version}.tar.gz +# See https://github.com/python/typing_extensions/issues/61 +Source1: https://raw.githubusercontent.com/python/typing_extensions/main/src/_typed_dict_test_helper.py BuildRequires: %{python_module flit-core < 4} BuildRequires: %{python_module flit-core >= 3.4} BuildRequires: %{python_module pip} @@ -72,6 +74,11 @@ %prep %setup -q -n %{modname}-%{version} +# This should not be necessary in the next release +if [ -f src/_typed_dict_test_helper.py ]; then + exit 1 +fi +cp %{SOURCE1} src/ %build %pyproject_wheel @@ -90,7 +97,7 @@ %if ! %{with test} %files %{python_files} %license LICENSE -%doc README.rst +%doc CHANGELOG.md README.md %{python_sitelib}/typing_extensions.py* %pycache_only %{python_sitelib}/__pycache__/typing_extensions* %{python_sitelib}/typing_extensions-%{version}*-info ++++++ _typed_dict_test_helper.py ++++++ from __future__ import annotations from typing import Generic, Optional, T from typing_extensions import TypedDict class FooGeneric(TypedDict, Generic[T]): a: Optional[T] ++++++ typing_extensions-4.2.0.tar.gz -> typing_extensions-4.3.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/typing_extensions-4.2.0/CHANGELOG new/typing_extensions-4.3.0/CHANGELOG --- old/typing_extensions-4.2.0/CHANGELOG 2022-04-17 23:22:15.436696300 +0200 +++ new/typing_extensions-4.3.0/CHANGELOG 1970-01-01 01:00:00.000000000 +0100 @@ -1,81 +0,0 @@ -# Release 4.2.0 (April 17, 2022) - -- Re-export `typing.Unpack` and `typing.TypeVarTuple` on Python 3.11. -- Add `ParamSpecArgs` and `ParamSpecKwargs` to `__all__`. -- Improve "accepts only single type" error messages. -- Improve the distributed package. Patch by Marc Mueller (@cdce8p). -- Update `typing_extensions.dataclass_transform` to rename the - `field_descriptors` parameter to `field_specifiers` and accept - arbitrary keyword arguments. -- Add `typing_extensions.get_overloads` and - `typing_extensions.clear_overloads`, and add registry support to - `typing_extensions.overload`. Backport from python/cpython#89263. -- Add `typing_extensions.assert_type`. Backport from bpo-46480. -- Drop support for Python 3.6. Original patch by Adam Turner (@AA-Turner). - -# Release 4.1.1 (February 13, 2022) - -- Fix importing `typing_extensions` on Python 3.7.0 and 3.7.1. Original - patch by Nikita Sobolev (@sobolevn). - -# Release 4.1.0 (February 12, 2022) - -- Runtime support for PEP 646, adding `typing_extensions.TypeVarTuple` - and `typing_extensions.Unpack`. -- Add interaction of `Required` and `NotRequired` with `__required_keys__`, - `__optional_keys__` and `get_type_hints()`. Patch by David Cabot (@d-k-bo). -- Runtime support for PEP 675 and `typing_extensions.LiteralString`. -- Add `Never` and `assert_never`. Backport from bpo-46475. -- `ParamSpec` args and kwargs are now equal to themselves. Backport from - bpo-46676. Patch by Gregory Beauregard (@GBeauregard). -- Add `reveal_type`. Backport from bpo-46414. -- Runtime support for PEP 681 and `typing_extensions.dataclass_transform`. -- `Annotated` can now wrap `ClassVar` and `Final`. Backport from - bpo-46491. Patch by Gregory Beauregard (@GBeauregard). -- Add missed `Required` and `NotRequired` to `__all__`. Patch by - Yuri Karabas (@uriyyo). -- The `@final` decorator now sets the `__final__` attribute on the - decorated object to allow runtime introspection. Backport from - bpo-46342. -- Add `is_typeddict`. Patch by Chris Moradi (@chrismoradi) and James - Hilton-Balfe (@Gobot1234). - -# Release 4.0.1 (November 30, 2021) - -- Fix broken sdist in release 4.0.0. Patch by Adam Turner (@AA-Turner). -- Fix equality comparison for `Required` and `NotRequired`. Patch by - Jelle Zijlstra (@jellezijlstra). -- Fix usage of `Self` as a type argument. Patch by Chris Wesseling - (@CharString) and James Hilton-Balfe (@Gobot1234). - -# Release 4.0.0 (November 14, 2021) - -- Starting with version 4.0.0, typing_extensions uses Semantic Versioning. - See the README for more information. -- Dropped support for Python versions 3.5 and older, including Python 2.7. -- Simplified backports for Python 3.6.0 and newer. Patch by Adam Turner (@AA-Turner). - -## Added in version 4.0.0 - -- Runtime support for PEP 673 and `typing_extensions.Self`. Patch by - James Hilton-Balfe (@Gobot1234). -- Runtime support for PEP 655 and `typing_extensions.Required` and `NotRequired`. - Patch by David Foster (@davidfstr). - -## Removed in version 4.0.0 - -The following non-exported but non-private names have been removed as they are -unneeded for supporting Python 3.6 and newer. - -- TypingMeta -- OLD_GENERICS -- SUBS_TREE -- HAVE_ANNOTATED -- HAVE_PROTOCOLS -- V_co -- VT_co - -# Previous releases - -Prior to release 4.0.0 we did not provide a changelog. Please check -the Git history for details. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/typing_extensions-4.2.0/CHANGELOG.md new/typing_extensions-4.3.0/CHANGELOG.md --- old/typing_extensions-4.2.0/CHANGELOG.md 1970-01-01 01:00:00.000000000 +0100 +++ new/typing_extensions-4.3.0/CHANGELOG.md 2022-07-01 16:52:33.376041400 +0200 @@ -0,0 +1,90 @@ +# Release 4.3.0 (July 1, 2022) + +- Add `typing_extensions.NamedTuple`, allowing for generic `NamedTuple`s on + Python <3.11 (backport from python/cpython#92027, by Serhiy Storchaka). Patch + by Alex Waygood (@AlexWaygood). +- Adjust `typing_extensions.TypedDict` to allow for generic `TypedDict`s on + Python <3.11 (backport from python/cpython#27663, by Samodya Abey). Patch by + Alex Waygood (@AlexWaygood). + +# Release 4.2.0 (April 17, 2022) + +- Re-export `typing.Unpack` and `typing.TypeVarTuple` on Python 3.11. +- Add `ParamSpecArgs` and `ParamSpecKwargs` to `__all__`. +- Improve "accepts only single type" error messages. +- Improve the distributed package. Patch by Marc Mueller (@cdce8p). +- Update `typing_extensions.dataclass_transform` to rename the + `field_descriptors` parameter to `field_specifiers` and accept + arbitrary keyword arguments. +- Add `typing_extensions.get_overloads` and + `typing_extensions.clear_overloads`, and add registry support to + `typing_extensions.overload`. Backport from python/cpython#89263. +- Add `typing_extensions.assert_type`. Backport from bpo-46480. +- Drop support for Python 3.6. Original patch by Adam Turner (@AA-Turner). + +# Release 4.1.1 (February 13, 2022) + +- Fix importing `typing_extensions` on Python 3.7.0 and 3.7.1. Original + patch by Nikita Sobolev (@sobolevn). + +# Release 4.1.0 (February 12, 2022) + +- Runtime support for PEP 646, adding `typing_extensions.TypeVarTuple` + and `typing_extensions.Unpack`. +- Add interaction of `Required` and `NotRequired` with `__required_keys__`, + `__optional_keys__` and `get_type_hints()`. Patch by David Cabot (@d-k-bo). +- Runtime support for PEP 675 and `typing_extensions.LiteralString`. +- Add `Never` and `assert_never`. Backport from bpo-46475. +- `ParamSpec` args and kwargs are now equal to themselves. Backport from + bpo-46676. Patch by Gregory Beauregard (@GBeauregard). +- Add `reveal_type`. Backport from bpo-46414. +- Runtime support for PEP 681 and `typing_extensions.dataclass_transform`. +- `Annotated` can now wrap `ClassVar` and `Final`. Backport from + bpo-46491. Patch by Gregory Beauregard (@GBeauregard). +- Add missed `Required` and `NotRequired` to `__all__`. Patch by + Yuri Karabas (@uriyyo). +- The `@final` decorator now sets the `__final__` attribute on the + decorated object to allow runtime introspection. Backport from + bpo-46342. +- Add `is_typeddict`. Patch by Chris Moradi (@chrismoradi) and James + Hilton-Balfe (@Gobot1234). + +# Release 4.0.1 (November 30, 2021) + +- Fix broken sdist in release 4.0.0. Patch by Adam Turner (@AA-Turner). +- Fix equality comparison for `Required` and `NotRequired`. Patch by + Jelle Zijlstra (@jellezijlstra). +- Fix usage of `Self` as a type argument. Patch by Chris Wesseling + (@CharString) and James Hilton-Balfe (@Gobot1234). + +# Release 4.0.0 (November 14, 2021) + +- Starting with version 4.0.0, typing_extensions uses Semantic Versioning. + See the README for more information. +- Dropped support for Python versions 3.5 and older, including Python 2.7. +- Simplified backports for Python 3.6.0 and newer. Patch by Adam Turner (@AA-Turner). + +## Added in version 4.0.0 + +- Runtime support for PEP 673 and `typing_extensions.Self`. Patch by + James Hilton-Balfe (@Gobot1234). +- Runtime support for PEP 655 and `typing_extensions.Required` and `NotRequired`. + Patch by David Foster (@davidfstr). + +## Removed in version 4.0.0 + +The following non-exported but non-private names have been removed as they are +unneeded for supporting Python 3.6 and newer. + +- TypingMeta +- OLD_GENERICS +- SUBS_TREE +- HAVE_ANNOTATED +- HAVE_PROTOCOLS +- V_co +- VT_co + +# Previous releases + +Prior to release 4.0.0 we did not provide a changelog. Please check +the Git history for details. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/typing_extensions-4.2.0/PKG-INFO new/typing_extensions-4.3.0/PKG-INFO --- old/typing_extensions-4.2.0/PKG-INFO 1970-01-01 01:00:00.000000000 +0100 +++ new/typing_extensions-4.3.0/PKG-INFO 1970-01-01 01:00:00.000000000 +0100 @@ -1,11 +1,11 @@ Metadata-Version: 2.1 Name: typing_extensions -Version: 4.2.0 +Version: 4.3.0 Summary: Backported and Experimental Type Hints for Python 3.7+ Keywords: annotations,backport,checker,checking,function,hinting,hints,type,typechecking,typehinting,typehints,typing Author-email: "Guido van Rossum, Jukka Lehtosalo, ??ukasz Langa, Michael Lee" <levkivs...@gmail.com> Requires-Python: >=3.7 -Description-Content-Type: text/x-rst +Description-Content-Type: text/markdown Classifier: Development Status :: 5 - Production/Stable Classifier: Environment :: Console Classifier: Intended Audience :: Developers @@ -13,148 +13,149 @@ Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3 :: Only -Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: 3.7 Classifier: Programming Language :: Python :: 3.8 Classifier: Programming Language :: Python :: 3.9 Classifier: Programming Language :: Python :: 3.10 Classifier: Topic :: Software Development -Project-URL: Home, https://github.com/python/typing/blob/master/typing_extensions/README.rst +Project-URL: Bug Tracker, https://github.com/python/typing_extensions/issues +Project-URL: Changes, https://github.com/python/typing_extensions/blob/main/CHANGELOG.md +Project-URL: Documentation, https://typing.readthedocs.io/ +Project-URL: Home, https://github.com/python/typing_extensions +Project-URL: Q & A, https://github.com/python/typing/discussions +Project-URL: Repository, https://github.com/python/typing_extensions -================= -Typing Extensions -================= +# Typing Extensions -.. image:: https://badges.gitter.im/python/typing.svg - :alt: Chat at https://gitter.im/python/typing - :target: https://gitter.im/python/typing?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge +[](https://gitter.im/python/typing) -Overview -======== +## Overview -The ``typing_extensions`` module serves two related purposes: +The `typing_extensions` module serves two related purposes: - Enable use of new type system features on older Python versions. For example, - ``typing.TypeGuard`` is new in Python 3.10, but ``typing_extensions`` allows + `typing.TypeGuard` is new in Python 3.10, but `typing_extensions` allows users on Python 3.6 through 3.9 to use it too. - Enable experimentation with new type system PEPs before they are accepted and - added to the ``typing`` module. - -New features may be added to ``typing_extensions`` as soon as they are specified -in a PEP that has been added to the `python/peps <https://github.com/python/peps>`_ -repository. If the PEP is accepted, the feature will then be added to ``typing`` + added to the `typing` module. + +New features may be added to `typing_extensions` as soon as they are specified +in a PEP that has been added to the [python/peps](https://github.com/python/peps) +repository. If the PEP is accepted, the feature will then be added to `typing` for the next CPython release. No typing PEP has been rejected so far, so we haven't yet figured out how to deal with that possibility. -Starting with version 4.0.0, ``typing_extensions`` uses -`Semantic Versioning <https://semver.org/>`_. The +Starting with version 4.0.0, `typing_extensions` uses +[Semantic Versioning](https://semver.org/). The major version is incremented for all backwards-incompatible changes. Therefore, it's safe to depend -on ``typing_extensions`` like this: ``typing_extensions >=x.y, <(x+1)``, -where ``x.y`` is the first version that includes all features you need. +on `typing_extensions` like this: `typing_extensions >=x.y, <(x+1)`, +where `x.y` is the first version that includes all features you need. -``typing_extensions`` supports Python versions 3.7 and higher. In the future, +`typing_extensions` supports Python versions 3.7 and higher. In the future, support for older Python versions will be dropped some time after that version reaches end of life. -Included items -============== +## Included items This module currently contains the following: - Experimental features - - ``@dataclass_transform()`` (see PEP 681) + - (Currently none) -- In ``typing`` since Python 3.11 +- In `typing` since Python 3.11 - - ``assert_never`` - - ``assert_type`` - - ``clear_overloads`` - - ``get_overloads`` - - ``LiteralString`` (see PEP 675) - - ``Never`` - - ``NotRequired`` (see PEP 655) - - ``reveal_type`` - - ``Required`` (see PEP 655) - - ``Self`` (see PEP 673) - - ``TypeVarTuple`` (see PEP 646) - - ``Unpack`` (see PEP 646) - -- In ``typing`` since Python 3.10 - - - ``Concatenate`` (see PEP 612) - - ``ParamSpec`` (see PEP 612) - - ``ParamSpecArgs`` (see PEP 612) - - ``ParamSpecKwargs`` (see PEP 612) - - ``TypeAlias`` (see PEP 613) - - ``TypeGuard`` (see PEP 647) - - ``is_typeddict`` - -- In ``typing`` since Python 3.9 - - - ``Annotated`` (see PEP 593) - -- In ``typing`` since Python 3.8 - - - ``final`` (see PEP 591) - - ``Final`` (see PEP 591) - - ``Literal`` (see PEP 586) - - ``Protocol`` (see PEP 544) - - ``runtime_checkable`` (see PEP 544) - - ``TypedDict`` (see PEP 589) - - ``get_origin`` (``typing_extensions`` provides this function only in Python 3.7+) - - ``get_args`` (``typing_extensions`` provides this function only in Python 3.7+) - -- In ``typing`` since Python 3.7 - - - ``OrderedDict`` - -- In ``typing`` since Python 3.5 or 3.6 (see `the typing documentation - <https://docs.python.org/3.10/library/typing.html>`_ for details) - - - ``AsyncContextManager`` - - ``AsyncGenerator`` - - ``AsyncIterable`` - - ``AsyncIterator`` - - ``Awaitable`` - - ``ChainMap`` - - ``ClassVar`` (see PEP 526) - - ``ContextManager`` - - ``Coroutine`` - - ``Counter`` - - ``DefaultDict`` - - ``Deque`` - - ``NewType`` - - ``NoReturn`` - - ``overload`` - - ``Text`` - - ``Type`` - - ``TYPE_CHECKING`` - - ``get_type_hints`` + - `assert_never` + - `assert_type` + - `clear_overloads` + - `@dataclass_transform()` (see PEP 681) + - `get_overloads` + - `LiteralString` (see PEP 675) + - `Never` + - `NotRequired` (see PEP 655) + - `reveal_type` + - `Required` (see PEP 655) + - `Self` (see PEP 673) + - `TypeVarTuple` (see PEP 646) + - `Unpack` (see PEP 646) + +- In `typing` since Python 3.10 + + - `Concatenate` (see PEP 612) + - `ParamSpec` (see PEP 612) + - `ParamSpecArgs` (see PEP 612) + - `ParamSpecKwargs` (see PEP 612) + - `TypeAlias` (see PEP 613) + - `TypeGuard` (see PEP 647) + - `is_typeddict` + +- In `typing` since Python 3.9 + + - `Annotated` (see PEP 593) + +- In `typing` since Python 3.8 + + - `final` (see PEP 591) + - `Final` (see PEP 591) + - `Literal` (see PEP 586) + - `Protocol` (see PEP 544) + - `runtime_checkable` (see PEP 544) + - `TypedDict` (see PEP 589) + - `get_origin` (`typing_extensions` provides this function only in Python 3.7+) + - `get_args` (`typing_extensions` provides this function only in Python 3.7+) + +- In `typing` since Python 3.7 + + - `OrderedDict` + +- In `typing` since Python 3.5 or 3.6 (see [the typing documentation](https://docs.python.org/3.10/library/typing.html) for details) + + - `AsyncContextManager` + - `AsyncGenerator` + - `AsyncIterable` + - `AsyncIterator` + - `Awaitable` + - `ChainMap` + - `ClassVar` (see PEP 526) + - `ContextManager` + - `Coroutine` + - `Counter` + - `DefaultDict` + - `Deque` + - `NamedTuple` + - `NewType` + - `NoReturn` + - `overload` + - `Text` + - `Type` + - `TYPE_CHECKING` + - `get_type_hints` -Other Notes and Limitations -=========================== +# Other Notes and Limitations -Certain objects were changed after they were added to ``typing``, and -``typing_extensions`` provides a backport even on newer Python versions: +Certain objects were changed after they were added to `typing`, and +`typing_extensions` provides a backport even on newer Python versions: -- ``TypedDict`` does not store runtime information +- `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. -- ``get_origin`` and ``get_args`` lack support for ``Annotated`` in - Python 3.8 and lack support for ``ParamSpecArgs`` and ``ParamSpecKwargs`` + honor the `total` keyword with old-style `TypedDict()` in Python + 3.9.0 and 3.9.1. `TypedDict` also does not support multiple inheritance + with `typing.Generic` on Python <3.11. +- `get_origin` and `get_args` lack support for `Annotated` in + Python 3.8 and lack support for `ParamSpecArgs` and `ParamSpecKwargs` in 3.9. -- ``@final`` was changed in Python 3.11 to set the ``.__final__`` attribute. -- ``@overload`` was changed in Python 3.11 to make function overloads +- `@final` was changed in Python 3.11 to set the `.__final__` attribute. +- `@overload` was changed in Python 3.11 to make function overloads introspectable at runtime. In order to access overloads with - ``typing_extensions.get_overloads()``, you must use - ``@typing_extensions.overload``. + `typing_extensions.get_overloads()`, you must use + `@typing_extensions.overload`. +- `NamedTuple` was changed in Python 3.11 to allow for multiple inheritance + with `typing.Generic`. There are a few types whose interface was modified between different -versions of typing. For example, ``typing.Sequence`` was modified to -subclass ``typing.Reversible`` as of Python 3.5.3. +versions of typing. For example, `typing.Sequence` was modified to +subclass `typing.Reversible` as of Python 3.5.3. These changes are _not_ backported to prevent subtle compatibility issues when mixing the differing implementations of modified classes. @@ -162,15 +163,14 @@ Certain types have incorrect runtime behavior due to limitations of older versions of the typing module: -- ``ParamSpec`` and ``Concatenate`` will not work with ``get_args`` and - ``get_origin``. Certain PEP 612 special cases in user-defined - ``Generic``\ s are also not available. +- `ParamSpec` and `Concatenate` will not work with `get_args` and + `get_origin`. Certain PEP 612 special cases in user-defined + `Generic`s are also not available. These types are only guaranteed to work for static type checking. -Running tests -============= +## Running tests To run tests, navigate into the appropriate source directory and run -``test_typing_extensions.py``. +`test_typing_extensions.py`. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/typing_extensions-4.2.0/README.md new/typing_extensions-4.3.0/README.md --- old/typing_extensions-4.2.0/README.md 1970-01-01 01:00:00.000000000 +0100 +++ new/typing_extensions-4.3.0/README.md 2022-07-01 16:47:32.490316600 +0200 @@ -0,0 +1,148 @@ +# Typing Extensions + +[](https://gitter.im/python/typing) + +## Overview + +The `typing_extensions` module serves two related purposes: + +- Enable use of new type system features on older Python versions. For example, + `typing.TypeGuard` is new in Python 3.10, but `typing_extensions` allows + users on Python 3.6 through 3.9 to use it too. +- Enable experimentation with new type system PEPs before they are accepted and + added to the `typing` module. + +New features may be added to `typing_extensions` as soon as they are specified +in a PEP that has been added to the [python/peps](https://github.com/python/peps) +repository. If the PEP is accepted, the feature will then be added to `typing` +for the next CPython release. No typing PEP has been rejected so far, so we +haven't yet figured out how to deal with that possibility. + +Starting with version 4.0.0, `typing_extensions` uses +[Semantic Versioning](https://semver.org/). The +major version is incremented for all backwards-incompatible changes. +Therefore, it's safe to depend +on `typing_extensions` like this: `typing_extensions >=x.y, <(x+1)`, +where `x.y` is the first version that includes all features you need. + +`typing_extensions` supports Python versions 3.7 and higher. In the future, +support for older Python versions will be dropped some time after that version +reaches end of life. + +## Included items + +This module currently contains the following: + +- Experimental features + + - (Currently none) + +- In `typing` since Python 3.11 + + - `assert_never` + - `assert_type` + - `clear_overloads` + - `@dataclass_transform()` (see PEP 681) + - `get_overloads` + - `LiteralString` (see PEP 675) + - `Never` + - `NotRequired` (see PEP 655) + - `reveal_type` + - `Required` (see PEP 655) + - `Self` (see PEP 673) + - `TypeVarTuple` (see PEP 646) + - `Unpack` (see PEP 646) + +- In `typing` since Python 3.10 + + - `Concatenate` (see PEP 612) + - `ParamSpec` (see PEP 612) + - `ParamSpecArgs` (see PEP 612) + - `ParamSpecKwargs` (see PEP 612) + - `TypeAlias` (see PEP 613) + - `TypeGuard` (see PEP 647) + - `is_typeddict` + +- In `typing` since Python 3.9 + + - `Annotated` (see PEP 593) + +- In `typing` since Python 3.8 + + - `final` (see PEP 591) + - `Final` (see PEP 591) + - `Literal` (see PEP 586) + - `Protocol` (see PEP 544) + - `runtime_checkable` (see PEP 544) + - `TypedDict` (see PEP 589) + - `get_origin` (`typing_extensions` provides this function only in Python 3.7+) + - `get_args` (`typing_extensions` provides this function only in Python 3.7+) + +- In `typing` since Python 3.7 + + - `OrderedDict` + +- In `typing` since Python 3.5 or 3.6 (see [the typing documentation](https://docs.python.org/3.10/library/typing.html) for details) + + - `AsyncContextManager` + - `AsyncGenerator` + - `AsyncIterable` + - `AsyncIterator` + - `Awaitable` + - `ChainMap` + - `ClassVar` (see PEP 526) + - `ContextManager` + - `Coroutine` + - `Counter` + - `DefaultDict` + - `Deque` + - `NamedTuple` + - `NewType` + - `NoReturn` + - `overload` + - `Text` + - `Type` + - `TYPE_CHECKING` + - `get_type_hints` + +# Other Notes and Limitations + +Certain objects were changed after they were added to `typing`, and +`typing_extensions` provides a backport even on newer Python versions: + +- `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. `TypedDict` also does not support multiple inheritance + with `typing.Generic` on Python <3.11. +- `get_origin` and `get_args` lack support for `Annotated` in + Python 3.8 and lack support for `ParamSpecArgs` and `ParamSpecKwargs` + in 3.9. +- `@final` was changed in Python 3.11 to set the `.__final__` attribute. +- `@overload` was changed in Python 3.11 to make function overloads + introspectable at runtime. In order to access overloads with + `typing_extensions.get_overloads()`, you must use + `@typing_extensions.overload`. +- `NamedTuple` was changed in Python 3.11 to allow for multiple inheritance + with `typing.Generic`. + +There are a few types whose interface was modified between different +versions of typing. For example, `typing.Sequence` was modified to +subclass `typing.Reversible` as of Python 3.5.3. + +These changes are _not_ backported to prevent subtle compatibility +issues when mixing the differing implementations of modified classes. + +Certain types have incorrect runtime behavior due to limitations of older +versions of the typing module: + +- `ParamSpec` and `Concatenate` will not work with `get_args` and + `get_origin`. Certain PEP 612 special cases in user-defined + `Generic`s are also not available. + +These types are only guaranteed to work for static type checking. + +## Running tests + +To run tests, navigate into the appropriate source directory and run +`test_typing_extensions.py`. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/typing_extensions-4.2.0/README.rst new/typing_extensions-4.3.0/README.rst --- old/typing_extensions-4.2.0/README.rst 2022-04-16 19:21:08.568471700 +0200 +++ new/typing_extensions-4.3.0/README.rst 1970-01-01 01:00:00.000000000 +0100 @@ -1,152 +0,0 @@ -================= -Typing Extensions -================= - -.. image:: https://badges.gitter.im/python/typing.svg - :alt: Chat at https://gitter.im/python/typing - :target: https://gitter.im/python/typing?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge - -Overview -======== - -The ``typing_extensions`` module serves two related purposes: - -- Enable use of new type system features on older Python versions. For example, - ``typing.TypeGuard`` is new in Python 3.10, but ``typing_extensions`` allows - users on Python 3.6 through 3.9 to use it too. -- Enable experimentation with new type system PEPs before they are accepted and - added to the ``typing`` module. - -New features may be added to ``typing_extensions`` as soon as they are specified -in a PEP that has been added to the `python/peps <https://github.com/python/peps>`_ -repository. If the PEP is accepted, the feature will then be added to ``typing`` -for the next CPython release. No typing PEP has been rejected so far, so we -haven't yet figured out how to deal with that possibility. - -Starting with version 4.0.0, ``typing_extensions`` uses -`Semantic Versioning <https://semver.org/>`_. The -major version is incremented for all backwards-incompatible changes. -Therefore, it's safe to depend -on ``typing_extensions`` like this: ``typing_extensions >=x.y, <(x+1)``, -where ``x.y`` is the first version that includes all features you need. - -``typing_extensions`` supports Python versions 3.7 and higher. In the future, -support for older Python versions will be dropped some time after that version -reaches end of life. - -Included items -============== - -This module currently contains the following: - -- Experimental features - - - ``@dataclass_transform()`` (see PEP 681) - -- In ``typing`` since Python 3.11 - - - ``assert_never`` - - ``assert_type`` - - ``clear_overloads`` - - ``get_overloads`` - - ``LiteralString`` (see PEP 675) - - ``Never`` - - ``NotRequired`` (see PEP 655) - - ``reveal_type`` - - ``Required`` (see PEP 655) - - ``Self`` (see PEP 673) - - ``TypeVarTuple`` (see PEP 646) - - ``Unpack`` (see PEP 646) - -- In ``typing`` since Python 3.10 - - - ``Concatenate`` (see PEP 612) - - ``ParamSpec`` (see PEP 612) - - ``ParamSpecArgs`` (see PEP 612) - - ``ParamSpecKwargs`` (see PEP 612) - - ``TypeAlias`` (see PEP 613) - - ``TypeGuard`` (see PEP 647) - - ``is_typeddict`` - -- In ``typing`` since Python 3.9 - - - ``Annotated`` (see PEP 593) - -- In ``typing`` since Python 3.8 - - - ``final`` (see PEP 591) - - ``Final`` (see PEP 591) - - ``Literal`` (see PEP 586) - - ``Protocol`` (see PEP 544) - - ``runtime_checkable`` (see PEP 544) - - ``TypedDict`` (see PEP 589) - - ``get_origin`` (``typing_extensions`` provides this function only in Python 3.7+) - - ``get_args`` (``typing_extensions`` provides this function only in Python 3.7+) - -- In ``typing`` since Python 3.7 - - - ``OrderedDict`` - -- In ``typing`` since Python 3.5 or 3.6 (see `the typing documentation - <https://docs.python.org/3.10/library/typing.html>`_ for details) - - - ``AsyncContextManager`` - - ``AsyncGenerator`` - - ``AsyncIterable`` - - ``AsyncIterator`` - - ``Awaitable`` - - ``ChainMap`` - - ``ClassVar`` (see PEP 526) - - ``ContextManager`` - - ``Coroutine`` - - ``Counter`` - - ``DefaultDict`` - - ``Deque`` - - ``NewType`` - - ``NoReturn`` - - ``overload`` - - ``Text`` - - ``Type`` - - ``TYPE_CHECKING`` - - ``get_type_hints`` - -Other Notes and Limitations -=========================== - -Certain objects were changed after they were added to ``typing``, and -``typing_extensions`` provides a backport even on newer Python versions: - -- ``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. -- ``get_origin`` and ``get_args`` lack support for ``Annotated`` in - Python 3.8 and lack support for ``ParamSpecArgs`` and ``ParamSpecKwargs`` - in 3.9. -- ``@final`` was changed in Python 3.11 to set the ``.__final__`` attribute. -- ``@overload`` was changed in Python 3.11 to make function overloads - introspectable at runtime. In order to access overloads with - ``typing_extensions.get_overloads()``, you must use - ``@typing_extensions.overload``. - -There are a few types whose interface was modified between different -versions of typing. For example, ``typing.Sequence`` was modified to -subclass ``typing.Reversible`` as of Python 3.5.3. - -These changes are _not_ backported to prevent subtle compatibility -issues when mixing the differing implementations of modified classes. - -Certain types have incorrect runtime behavior due to limitations of older -versions of the typing module: - -- ``ParamSpec`` and ``Concatenate`` will not work with ``get_args`` and - ``get_origin``. Certain PEP 612 special cases in user-defined - ``Generic``\ s are also not available. - -These types are only guaranteed to work for static type checking. - -Running tests -============= - -To run tests, navigate into the appropriate source directory and run -``test_typing_extensions.py``. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/typing_extensions-4.2.0/pyproject.toml new/typing_extensions-4.3.0/pyproject.toml --- old/typing_extensions-4.2.0/pyproject.toml 2022-04-17 23:22:15.437512400 +0200 +++ new/typing_extensions-4.3.0/pyproject.toml 2022-07-01 16:52:33.377626700 +0200 @@ -6,11 +6,10 @@ # Project metadata [project] name = "typing_extensions" -version = "4.2.0" +version = "4.3.0" description = "Backported and Experimental Type Hints for Python 3.7+" -readme = "README.rst" +readme = "README.md" requires-python = ">=3.7" -urls.Home = "https://github.com/python/typing/blob/master/typing_extensions/README.rst" license.file = "LICENSE" keywords = [ "annotations", @@ -24,7 +23,7 @@ "typechecking", "typehinting", "typehints", - "typing" + "typing", ] # Classifiers list: https://pypi.org/classifiers/ classifiers = [ @@ -35,14 +34,21 @@ "Operating System :: OS Independent", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", - "Topic :: Software Development" + "Topic :: Software Development", ] +[project.urls] +Home = "https://github.com/python/typing_extensions" +Repository = "https://github.com/python/typing_extensions" +Changes = "https://github.com/python/typing_extensions/blob/main/CHANGELOG.md" +Documentation = "https://typing.readthedocs.io/" +"Bug Tracker" = "https://github.com/python/typing_extensions/issues" +"Q & A" = "https://github.com/python/typing/discussions" + # Project metadata -- authors. Flit stores this as a list of dicts, so it can't # be inline above. [[project.authors]] @@ -50,9 +56,5 @@ email = "levkivs...@gmail.com" [tool.flit.sdist] -include = [ - "CHANGELOG", - "README.rst", - "*/test*.py" -] +include = ["CHANGELOG.md", "README.md", "*/test*.py"] exclude = [] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/typing_extensions-4.2.0/src/test_typing_extensions.py new/typing_extensions-4.3.0/src/test_typing_extensions.py --- old/typing_extensions-4.2.0/src/test_typing_extensions.py 2022-04-17 23:22:15.439011000 +0200 +++ new/typing_extensions-4.3.0/src/test_typing_extensions.py 2022-07-01 16:47:32.493123500 +0200 @@ -5,6 +5,7 @@ import collections from collections import defaultdict import collections.abc +import copy from functools import lru_cache import inspect import pickle @@ -17,7 +18,7 @@ from typing import TypeVar, Optional, Union, Any, AnyStr from typing import T, KT, VT # Not in __all__. from typing import Tuple, List, Dict, Iterable, Iterator, Callable -from typing import Generic, NamedTuple +from typing import Generic from typing import no_type_check import typing_extensions from typing_extensions import NoReturn, ClassVar, Final, IntVar, Literal, Type, NewType, TypedDict, Self @@ -27,10 +28,13 @@ from typing_extensions import TypeVarTuple, Unpack, dataclass_transform, reveal_type, Never, assert_never, LiteralString from typing_extensions import assert_type, get_type_hints, get_origin, get_args from typing_extensions import clear_overloads, get_overloads, overload +from typing_extensions import NamedTuple +from _typed_dict_test_helper import FooGeneric # Flags used to mark tests that only apply after a specific # version of the typing module. TYPING_3_8_0 = sys.version_info[:3] >= (3, 8, 0) +TYPING_3_9_0 = sys.version_info[:3] >= (3, 9, 0) TYPING_3_10_0 = sys.version_info[:3] >= (3, 10, 0) # 3.11 makes runtime type checks (_type_check) more lenient. @@ -1661,6 +1665,15 @@ self.assertEqual(CustomProtocolWithoutInitA.__init__, CustomProtocolWithoutInitB.__init__) +class Point2DGeneric(Generic[T], TypedDict): + a: T + b: T + + +class BarGeneric(FooGeneric[T], total=False): + b: int + + class TypedDictTests(BaseTestCase): def test_basics_iterable_syntax(self): @@ -1766,7 +1779,9 @@ global EmpD # pickle wants to reference the class by name EmpD = TypedDict('EmpD', name=str, id=int) jane = EmpD({'name': 'jane', 'id': 37}) + point = Point2DGeneric(a=5.0, b=3.0) for proto in range(pickle.HIGHEST_PROTOCOL + 1): + # Test non-generic TypedDict z = pickle.dumps(jane, proto) jane2 = pickle.loads(z) self.assertEqual(jane2, jane) @@ -1774,6 +1789,14 @@ ZZ = pickle.dumps(EmpD, proto) EmpDnew = pickle.loads(ZZ) self.assertEqual(EmpDnew({'name': 'jane', 'id': 37}), jane) + # and generic TypedDict + y = pickle.dumps(point, proto) + point2 = pickle.loads(y) + self.assertEqual(point, point2) + self.assertEqual(point2, {'a': 5.0, 'b': 3.0}) + YY = pickle.dumps(Point2DGeneric, proto) + Point2DGenericNew = pickle.loads(YY) + self.assertEqual(Point2DGenericNew({'a': 5.0, 'b': 3.0}), point) def test_optional(self): EmpD = TypedDict('EmpD', name=str, id=int) @@ -1851,6 +1874,124 @@ assert is_typeddict(PointDict2D) is True assert is_typeddict(PointDict3D) is True + def test_get_type_hints_generic(self): + self.assertEqual( + get_type_hints(BarGeneric), + {'a': typing.Optional[T], 'b': int} + ) + + class FooBarGeneric(BarGeneric[int]): + c: str + + self.assertEqual( + get_type_hints(FooBarGeneric), + {'a': typing.Optional[T], 'b': int, 'c': str} + ) + + def test_generic_inheritance(self): + class A(TypedDict, Generic[T]): + a: T + + self.assertEqual(A.__bases__, (Generic, dict)) + self.assertEqual(A.__orig_bases__, (TypedDict, Generic[T])) + self.assertEqual(A.__mro__, (A, Generic, dict, object)) + self.assertEqual(A.__parameters__, (T,)) + self.assertEqual(A[str].__parameters__, ()) + self.assertEqual(A[str].__args__, (str,)) + + class A2(Generic[T], TypedDict): + a: T + + self.assertEqual(A2.__bases__, (Generic, dict)) + self.assertEqual(A2.__orig_bases__, (Generic[T], TypedDict)) + self.assertEqual(A2.__mro__, (A2, Generic, dict, object)) + self.assertEqual(A2.__parameters__, (T,)) + self.assertEqual(A2[str].__parameters__, ()) + self.assertEqual(A2[str].__args__, (str,)) + + class B(A[KT], total=False): + b: KT + + self.assertEqual(B.__bases__, (Generic, dict)) + self.assertEqual(B.__orig_bases__, (A[KT],)) + self.assertEqual(B.__mro__, (B, Generic, dict, object)) + self.assertEqual(B.__parameters__, (KT,)) + self.assertEqual(B.__total__, False) + self.assertEqual(B.__optional_keys__, frozenset(['b'])) + self.assertEqual(B.__required_keys__, frozenset(['a'])) + + self.assertEqual(B[str].__parameters__, ()) + self.assertEqual(B[str].__args__, (str,)) + self.assertEqual(B[str].__origin__, B) + + class C(B[int]): + c: int + + self.assertEqual(C.__bases__, (Generic, dict)) + self.assertEqual(C.__orig_bases__, (B[int],)) + self.assertEqual(C.__mro__, (C, Generic, dict, object)) + self.assertEqual(C.__parameters__, ()) + self.assertEqual(C.__total__, True) + self.assertEqual(C.__optional_keys__, frozenset(['b'])) + self.assertEqual(C.__required_keys__, frozenset(['a', 'c'])) + assert C.__annotations__ == { + 'a': T, + 'b': KT, + 'c': int, + } + with self.assertRaises(TypeError): + C[str] + + + class Point3D(Point2DGeneric[T], Generic[T, KT]): + c: KT + + self.assertEqual(Point3D.__bases__, (Generic, dict)) + self.assertEqual(Point3D.__orig_bases__, (Point2DGeneric[T], Generic[T, KT])) + self.assertEqual(Point3D.__mro__, (Point3D, Generic, dict, object)) + self.assertEqual(Point3D.__parameters__, (T, KT)) + self.assertEqual(Point3D.__total__, True) + self.assertEqual(Point3D.__optional_keys__, frozenset()) + self.assertEqual(Point3D.__required_keys__, frozenset(['a', 'b', 'c'])) + assert Point3D.__annotations__ == { + 'a': T, + 'b': T, + 'c': KT, + } + self.assertEqual(Point3D[int, str].__origin__, Point3D) + + with self.assertRaises(TypeError): + Point3D[int] + + with self.assertRaises(TypeError): + class Point3D(Point2DGeneric[T], Generic[KT]): + c: KT + + def test_implicit_any_inheritance(self): + class A(TypedDict, Generic[T]): + a: T + + class B(A[KT], total=False): + b: KT + + class WithImplicitAny(B): + c: int + + self.assertEqual(WithImplicitAny.__bases__, (Generic, dict,)) + self.assertEqual(WithImplicitAny.__mro__, (WithImplicitAny, Generic, dict, object)) + # Consistent with GenericTests.test_implicit_any + self.assertEqual(WithImplicitAny.__parameters__, ()) + self.assertEqual(WithImplicitAny.__total__, True) + self.assertEqual(WithImplicitAny.__optional_keys__, frozenset(['b'])) + self.assertEqual(WithImplicitAny.__required_keys__, frozenset(['a', 'c'])) + assert WithImplicitAny.__annotations__ == { + 'a': T, + 'b': KT, + 'c': int, + } + with self.assertRaises(TypeError): + WithImplicitAny[str] + class AnnotatedTests(BaseTestCase): @@ -2874,7 +3015,7 @@ if sys.version_info < (3, 10): exclude |= {'get_args', 'get_origin'} if sys.version_info < (3, 11): - exclude.add('final') + exclude |= {'final', 'NamedTuple'} for item in typing_extensions.__all__: if item not in exclude and hasattr(typing, item): self.assertIs( @@ -2892,6 +3033,305 @@ self.fail('Module does not compile with optimize=2 (-OO flag).') +class CoolEmployee(NamedTuple): + name: str + cool: int + + +class CoolEmployeeWithDefault(NamedTuple): + name: str + cool: int = 0 + + +class XMeth(NamedTuple): + x: int + + def double(self): + return 2 * self.x + + +class XRepr(NamedTuple): + x: int + y: int = 1 + + def __str__(self): + return f'{self.x} -> {self.y}' + + def __add__(self, other): + return 0 + + +@skipIf(TYPING_3_11_0, "These invariants should all be tested upstream on 3.11+") +class NamedTupleTests(BaseTestCase): + class NestedEmployee(NamedTuple): + name: str + cool: int + + def test_basics(self): + Emp = NamedTuple('Emp', [('name', str), ('id', int)]) + self.assertIsSubclass(Emp, tuple) + joe = Emp('Joe', 42) + jim = Emp(name='Jim', id=1) + self.assertIsInstance(joe, Emp) + self.assertIsInstance(joe, tuple) + self.assertEqual(joe.name, 'Joe') + self.assertEqual(joe.id, 42) + self.assertEqual(jim.name, 'Jim') + self.assertEqual(jim.id, 1) + self.assertEqual(Emp.__name__, 'Emp') + self.assertEqual(Emp._fields, ('name', 'id')) + self.assertEqual(Emp.__annotations__, + collections.OrderedDict([('name', str), ('id', int)])) + + def test_annotation_usage(self): + tim = CoolEmployee('Tim', 9000) + self.assertIsInstance(tim, CoolEmployee) + self.assertIsInstance(tim, tuple) + self.assertEqual(tim.name, 'Tim') + self.assertEqual(tim.cool, 9000) + self.assertEqual(CoolEmployee.__name__, 'CoolEmployee') + self.assertEqual(CoolEmployee._fields, ('name', 'cool')) + self.assertEqual(CoolEmployee.__annotations__, + collections.OrderedDict(name=str, cool=int)) + + def test_annotation_usage_with_default(self): + jelle = CoolEmployeeWithDefault('Jelle') + self.assertIsInstance(jelle, CoolEmployeeWithDefault) + self.assertIsInstance(jelle, tuple) + self.assertEqual(jelle.name, 'Jelle') + self.assertEqual(jelle.cool, 0) + cooler_employee = CoolEmployeeWithDefault('Sjoerd', 1) + self.assertEqual(cooler_employee.cool, 1) + + self.assertEqual(CoolEmployeeWithDefault.__name__, 'CoolEmployeeWithDefault') + self.assertEqual(CoolEmployeeWithDefault._fields, ('name', 'cool')) + self.assertEqual(CoolEmployeeWithDefault.__annotations__, + dict(name=str, cool=int)) + + with self.assertRaisesRegex( + TypeError, + 'Non-default namedtuple field y cannot follow default field x' + ): + class NonDefaultAfterDefault(NamedTuple): + x: int = 3 + y: int + + @skipUnless( + ( + TYPING_3_8_0 + or hasattr(CoolEmployeeWithDefault, '_field_defaults') + ), + '"_field_defaults" attribute was added in a micro version of 3.7' + ) + def test_field_defaults(self): + self.assertEqual(CoolEmployeeWithDefault._field_defaults, dict(cool=0)) + + def test_annotation_usage_with_methods(self): + self.assertEqual(XMeth(1).double(), 2) + self.assertEqual(XMeth(42).x, XMeth(42)[0]) + self.assertEqual(str(XRepr(42)), '42 -> 1') + self.assertEqual(XRepr(1, 2) + XRepr(3), 0) + + bad_overwrite_error_message = 'Cannot overwrite NamedTuple attribute' + + with self.assertRaisesRegex(AttributeError, bad_overwrite_error_message): + class XMethBad(NamedTuple): + x: int + def _fields(self): + return 'no chance for this' + + with self.assertRaisesRegex(AttributeError, bad_overwrite_error_message): + class XMethBad2(NamedTuple): + x: int + def _source(self): + return 'no chance for this as well' + + def test_multiple_inheritance(self): + class A: + pass + with self.assertRaisesRegex( + TypeError, + 'can only inherit from a NamedTuple type and Generic' + ): + class X(NamedTuple, A): + x: int + + with self.assertRaisesRegex( + TypeError, + 'can only inherit from a NamedTuple type and Generic' + ): + class X(NamedTuple, tuple): + x: int + + with self.assertRaisesRegex(TypeError, 'duplicate base class'): + class X(NamedTuple, NamedTuple): + x: int + + class A(NamedTuple): + x: int + with self.assertRaisesRegex( + TypeError, + 'can only inherit from a NamedTuple type and Generic' + ): + class X(NamedTuple, A): + y: str + + def test_generic(self): + class X(NamedTuple, Generic[T]): + x: T + self.assertEqual(X.__bases__, (tuple, Generic)) + self.assertEqual(X.__orig_bases__, (NamedTuple, Generic[T])) + self.assertEqual(X.__mro__, (X, tuple, Generic, object)) + + class Y(Generic[T], NamedTuple): + x: T + self.assertEqual(Y.__bases__, (Generic, tuple)) + self.assertEqual(Y.__orig_bases__, (Generic[T], NamedTuple)) + self.assertEqual(Y.__mro__, (Y, Generic, tuple, object)) + + for G in X, Y: + with self.subTest(type=G): + self.assertEqual(G.__parameters__, (T,)) + A = G[int] + self.assertIs(A.__origin__, G) + self.assertEqual(A.__args__, (int,)) + self.assertEqual(A.__parameters__, ()) + + a = A(3) + self.assertIs(type(a), G) + self.assertEqual(a.x, 3) + + with self.assertRaisesRegex(TypeError, 'Too many parameters'): + G[int, str] + + @skipUnless(TYPING_3_9_0, "tuple.__class_getitem__ was added in 3.9") + def test_non_generic_subscript_py39_plus(self): + # For backward compatibility, subscription works + # on arbitrary NamedTuple types. + class Group(NamedTuple): + key: T + group: list[T] + A = Group[int] + self.assertEqual(A.__origin__, Group) + self.assertEqual(A.__parameters__, ()) + self.assertEqual(A.__args__, (int,)) + a = A(1, [2]) + self.assertIs(type(a), Group) + self.assertEqual(a, (1, [2])) + + @skipIf(TYPING_3_9_0, "Test isn't relevant to 3.9+") + def test_non_generic_subscript_error_message_py38_minus(self): + class Group(NamedTuple): + key: T + group: List[T] + + with self.assertRaisesRegex(TypeError, 'not subscriptable'): + Group[int] + + for attr in ('__args__', '__origin__', '__parameters__'): + with self.subTest(attr=attr): + self.assertFalse(hasattr(Group, attr)) + + def test_namedtuple_keyword_usage(self): + LocalEmployee = NamedTuple("LocalEmployee", name=str, age=int) + nick = LocalEmployee('Nick', 25) + self.assertIsInstance(nick, tuple) + self.assertEqual(nick.name, 'Nick') + self.assertEqual(LocalEmployee.__name__, 'LocalEmployee') + self.assertEqual(LocalEmployee._fields, ('name', 'age')) + self.assertEqual(LocalEmployee.__annotations__, dict(name=str, age=int)) + with self.assertRaisesRegex( + TypeError, + 'Either list of fields or keywords can be provided to NamedTuple, not both' + ): + NamedTuple('Name', [('x', int)], y=str) + + def test_namedtuple_special_keyword_names(self): + NT = NamedTuple("NT", cls=type, self=object, typename=str, fields=list) + self.assertEqual(NT.__name__, 'NT') + self.assertEqual(NT._fields, ('cls', 'self', 'typename', 'fields')) + a = NT(cls=str, self=42, typename='foo', fields=[('bar', tuple)]) + self.assertEqual(a.cls, str) + self.assertEqual(a.self, 42) + self.assertEqual(a.typename, 'foo') + self.assertEqual(a.fields, [('bar', tuple)]) + + def test_empty_namedtuple(self): + NT = NamedTuple('NT') + + class CNT(NamedTuple): + pass # empty body + + for struct in [NT, CNT]: + with self.subTest(struct=struct): + self.assertEqual(struct._fields, ()) + self.assertEqual(struct.__annotations__, {}) + self.assertIsInstance(struct(), struct) + # Attribute was added in a micro version of 3.7 + # and is tested more fully elsewhere + if hasattr(struct, "_field_defaults"): + self.assertEqual(struct._field_defaults, {}) + + def test_namedtuple_errors(self): + with self.assertRaises(TypeError): + NamedTuple.__new__() + with self.assertRaises(TypeError): + NamedTuple() + with self.assertRaises(TypeError): + NamedTuple('Emp', [('name', str)], None) + with self.assertRaisesRegex(ValueError, 'cannot start with an underscore'): + NamedTuple('Emp', [('_name', str)]) + with self.assertRaises(TypeError): + NamedTuple(typename='Emp', name=str, id=int) + + def test_copy_and_pickle(self): + global Emp # pickle wants to reference the class by name + Emp = NamedTuple('Emp', [('name', str), ('cool', int)]) + for cls in Emp, CoolEmployee, self.NestedEmployee: + with self.subTest(cls=cls): + jane = cls('jane', 37) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + z = pickle.dumps(jane, proto) + jane2 = pickle.loads(z) + self.assertEqual(jane2, jane) + self.assertIsInstance(jane2, cls) + + jane2 = copy.copy(jane) + self.assertEqual(jane2, jane) + self.assertIsInstance(jane2, cls) + + jane2 = copy.deepcopy(jane) + self.assertEqual(jane2, jane) + self.assertIsInstance(jane2, cls) + + def test_docstring(self): + self.assertEqual(NamedTuple.__doc__, typing.NamedTuple.__doc__) + self.assertIsInstance(NamedTuple.__doc__, str) + + @skipUnless(TYPING_3_8_0, "NamedTuple had a bad signature on <=3.7") + def test_signature_is_same_as_typing_NamedTuple(self): + self.assertEqual(inspect.signature(NamedTuple), inspect.signature(typing.NamedTuple)) + + @skipIf(TYPING_3_8_0, "tests are only relevant to <=3.7") + def test_signature_on_37(self): + self.assertIsInstance(inspect.signature(NamedTuple), inspect.Signature) + self.assertFalse(hasattr(NamedTuple, "__text_signature__")) + + @skipUnless(TYPING_3_9_0, "NamedTuple was a class on 3.8 and lower") + def test_same_as_typing_NamedTuple_39_plus(self): + self.assertEqual( + set(dir(NamedTuple)), + set(dir(typing.NamedTuple)) | {"__text_signature__"} + ) + self.assertIs(type(NamedTuple), type(typing.NamedTuple)) + + @skipIf(TYPING_3_9_0, "tests are only relevant to <=3.8") + def test_same_as_typing_NamedTuple_38_minus(self): + self.assertEqual( + self.NestedEmployee.__annotations__, + self.NestedEmployee._field_types + ) + if __name__ == '__main__': main() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/typing_extensions-4.2.0/src/typing_extensions.py new/typing_extensions-4.3.0/src/typing_extensions.py --- old/typing_extensions-4.2.0/src/typing_extensions.py 2022-04-17 23:22:15.439957000 +0200 +++ new/typing_extensions-4.3.0/src/typing_extensions.py 2022-07-01 16:47:32.495242600 +0200 @@ -37,6 +37,7 @@ 'Counter', 'Deque', 'DefaultDict', + 'NamedTuple', 'OrderedDict', 'TypedDict', @@ -380,6 +381,46 @@ return all(callable(getattr(cls, attr, None)) for attr in _get_protocol_attrs(cls)) +def _maybe_adjust_parameters(cls): + """Helper function used in Protocol.__init_subclass__ and _TypedDictMeta.__new__. + + The contents of this function are very similar + to logic found in typing.Generic.__init_subclass__ + on the CPython main branch. + """ + tvars = [] + if '__orig_bases__' in cls.__dict__: + tvars = typing._collect_type_vars(cls.__orig_bases__) + # Look for Generic[T1, ..., Tn] or Protocol[T1, ..., Tn]. + # If found, tvars must be a subset of it. + # If not found, tvars is it. + # Also check for and reject plain Generic, + # and reject multiple Generic[...] and/or Protocol[...]. + gvars = None + for base in cls.__orig_bases__: + if (isinstance(base, typing._GenericAlias) and + base.__origin__ in (typing.Generic, Protocol)): + # for error messages + the_base = base.__origin__.__name__ + if gvars is not None: + raise TypeError( + "Cannot inherit from Generic[...]" + " and/or Protocol[...] multiple types.") + gvars = base.__parameters__ + if gvars is None: + gvars = tvars + else: + tvarset = set(tvars) + gvarset = set(gvars) + if not tvarset <= gvarset: + s_vars = ', '.join(str(t) for t in tvars if t not in gvarset) + s_args = ', '.join(str(g) for g in gvars) + raise TypeError(f"Some type variables ({s_vars}) are" + f" not listed in {the_base}[{s_args}]") + tvars = gvars + cls.__parameters__ = tuple(tvars) + + # 3.8+ if hasattr(typing, 'Protocol'): Protocol = typing.Protocol @@ -476,43 +517,13 @@ return typing._GenericAlias(cls, params) def __init_subclass__(cls, *args, **kwargs): - tvars = [] if '__orig_bases__' in cls.__dict__: error = typing.Generic in cls.__orig_bases__ else: error = typing.Generic in cls.__bases__ if error: raise TypeError("Cannot inherit from plain Generic") - if '__orig_bases__' in cls.__dict__: - tvars = typing._collect_type_vars(cls.__orig_bases__) - # Look for Generic[T1, ..., Tn] or Protocol[T1, ..., Tn]. - # If found, tvars must be a subset of it. - # If not found, tvars is it. - # Also check for and reject plain Generic, - # and reject multiple Generic[...] and/or Protocol[...]. - gvars = None - for base in cls.__orig_bases__: - if (isinstance(base, typing._GenericAlias) and - base.__origin__ in (typing.Generic, Protocol)): - # for error messages - the_base = base.__origin__.__name__ - if gvars is not None: - raise TypeError( - "Cannot inherit from Generic[...]" - " and/or Protocol[...] multiple types.") - gvars = base.__parameters__ - if gvars is None: - gvars = tvars - else: - tvarset = set(tvars) - gvarset = set(gvars) - if not tvarset <= gvarset: - s_vars = ', '.join(str(t) for t in tvars if t not in gvarset) - s_args = ', '.join(str(g) for g in gvars) - raise TypeError(f"Some type variables ({s_vars}) are" - f" not listed in {the_base}[{s_args}]") - tvars = gvars - cls.__parameters__ = tuple(tvars) + _maybe_adjust_parameters(cls) # Determine if this is a protocol or a concrete subclass. if not cls.__dict__.get('_is_protocol', None): @@ -613,6 +624,7 @@ # keyword with old-style TypedDict(). See https://bugs.python.org/issue42059 # The standard library TypedDict below Python 3.11 does not store runtime # information about optional and required keys when using Required or NotRequired. + # Generic TypedDicts are also impossible using typing.TypedDict on Python <3.11. TypedDict = typing.TypedDict _TypedDictMeta = typing._TypedDictMeta is_typeddict = typing.is_typeddict @@ -695,8 +707,16 @@ # Subclasses and instances of TypedDict return actual dictionaries # via _dict_new. ns['__new__'] = _typeddict_new if name == 'TypedDict' else _dict_new + # Don't insert typing.Generic into __bases__ here, + # or Generic.__init_subclass__ will raise TypeError + # in the super().__new__() call. + # Instead, monkey-patch __bases__ onto the class after it's been created. tp_dict = super().__new__(cls, name, (dict,), ns) + if any(issubclass(base, typing.Generic) for base in bases): + tp_dict.__bases__ = (typing.Generic, dict) + _maybe_adjust_parameters(tp_dict) + annotations = {} own_annotations = ns.get('__annotations__', {}) msg = "TypedDict('Name', {f0: t0, f1: t1, ...}); each t must be a type" @@ -1958,3 +1978,92 @@ if not hasattr(typing, "TypeVarTuple"): typing._collect_type_vars = _collect_type_vars typing._check_generic = _check_generic + + +# Backport typing.NamedTuple as it exists in Python 3.11. +# In 3.11, the ability to define generic `NamedTuple`s was supported. +# This was explicitly disallowed in 3.9-3.10, and only half-worked in <=3.8. +if sys.version_info >= (3, 11): + NamedTuple = typing.NamedTuple +else: + def _caller(): + try: + return sys._getframe(2).f_globals.get('__name__', '__main__') + except (AttributeError, ValueError): # For platforms without _getframe() + return None + + def _make_nmtuple(name, types, module, defaults=()): + fields = [n for n, t in types] + annotations = {n: typing._type_check(t, f"field {n} annotation must be a type") + for n, t in types} + nm_tpl = collections.namedtuple(name, fields, + defaults=defaults, module=module) + nm_tpl.__annotations__ = nm_tpl.__new__.__annotations__ = annotations + # The `_field_types` attribute was removed in 3.9; + # in earlier versions, it is the same as the `__annotations__` attribute + if sys.version_info < (3, 9): + nm_tpl._field_types = annotations + return nm_tpl + + _prohibited_namedtuple_fields = typing._prohibited + _special_namedtuple_fields = frozenset({'__module__', '__name__', '__annotations__'}) + + class _NamedTupleMeta(type): + def __new__(cls, typename, bases, ns): + assert _NamedTuple in bases + for base in bases: + if base is not _NamedTuple and base is not typing.Generic: + raise TypeError( + 'can only inherit from a NamedTuple type and Generic') + bases = tuple(tuple if base is _NamedTuple else base for base in bases) + types = ns.get('__annotations__', {}) + default_names = [] + for field_name in types: + if field_name in ns: + default_names.append(field_name) + elif default_names: + raise TypeError(f"Non-default namedtuple field {field_name} " + f"cannot follow default field" + f"{'s' if len(default_names) > 1 else ''} " + f"{', '.join(default_names)}") + nm_tpl = _make_nmtuple( + typename, types.items(), + defaults=[ns[n] for n in default_names], + module=ns['__module__'] + ) + nm_tpl.__bases__ = bases + if typing.Generic in bases: + class_getitem = typing.Generic.__class_getitem__.__func__ + nm_tpl.__class_getitem__ = classmethod(class_getitem) + # update from user namespace without overriding special namedtuple attributes + for key in ns: + if key in _prohibited_namedtuple_fields: + raise AttributeError("Cannot overwrite NamedTuple attribute " + key) + elif key not in _special_namedtuple_fields and key not in nm_tpl._fields: + setattr(nm_tpl, key, ns[key]) + if typing.Generic in bases: + nm_tpl.__init_subclass__() + return nm_tpl + + def NamedTuple(__typename, __fields=None, **kwargs): + if __fields is None: + __fields = kwargs.items() + elif kwargs: + raise TypeError("Either list of fields or keywords" + " can be provided to NamedTuple, not both") + return _make_nmtuple(__typename, __fields, module=_caller()) + + NamedTuple.__doc__ = typing.NamedTuple.__doc__ + _NamedTuple = type.__new__(_NamedTupleMeta, 'NamedTuple', (), {}) + + # On 3.8+, alter the signature so that it matches typing.NamedTuple. + # The signature of typing.NamedTuple on >=3.8 is invalid syntax in Python 3.7, + # so just leave the signature as it is on 3.7. + if sys.version_info >= (3, 8): + NamedTuple.__text_signature__ = '(typename, fields=None, /, **kwargs)' + + def _namedtuple_mro_entries(bases): + assert NamedTuple in bases + return (_NamedTuple,) + + NamedTuple.__mro_entries__ = _namedtuple_mro_entries