bpo-44807: Allow Protocol classes to define __init__#31628
bpo-44807: Allow Protocol classes to define __init__#31628JelleZijlstra merged 7 commits intopython:mainfrom
Conversation
Lib/test/test_typing.py
Outdated
|
|
||
| # the protocol itself cannot be instantiated | ||
| with self.assertRaises(TypeError): | ||
| P() |
There was a problem hiding this comment.
But presumably P(1) will work?
There was a problem hiding this comment.
Great catch. This is a bad assertion with an even worse comment: this TypeError is occurring because it's missing an argument, not because of the no-instantiation check. I'm inclined to just remove this assertRaises. What do you think?
There was a problem hiding this comment.
Agree that the current test doesn't make much sense. It would be useful though to add a test that asserts that P.__init__ doesn't get clobbered. For example, you could call P.__init__(some_object, 1) directly.
(Also, unrelatedly, this change will need a NEWS entry.)
There was a problem hiding this comment.
Thank you for the feedback.
I split up the test into 2:
- Verify that
__init__is no longer clobbered (as per your suggestion) - Check that concrete subclasses can inherit and use init from a protocol class
Misc/NEWS.d/next/Library/2022-03-02-04-25-58.bpo-44807.gHNC9J.rst
Outdated
Show resolved
Hide resolved
Co-authored-by: Jelle Zijlstra <[email protected]>
Co-authored-by: Jelle Zijlstra <[email protected]>
Co-authored-by: Jelle Zijlstra <[email protected]>
JelleZijlstra
left a comment
There was a problem hiding this comment.
Planning to merge this (cc @gvanrossum ).
Changelog: ============ - Fix use of @deprecated on classes with __new__ but no __init__. - Fix regression in version 4.6.1 where comparing a generic class against a runtime-checkable protocol using isinstance() would cause AttributeError to be raised if using Python 3.7. - Change deprecated @runtime to formal API @runtime_checkable in the error message. - Fix regression in 4.6.0 where attempting to define a Protocol that was generic over a ParamSpec or a TypeVarTuple would cause TypeError to be raised. - typing_extensions is now documented at https://typing-extensions.readthedocs.io/en/latest/. - Add typing_extensions.Buffer, a marker class for buffer types, as proposed by PEP 688. Equivalent to collections.abc.Buffer in Python 3.12. - Backport two CPython PRs fixing various issues with typing.Literal: python/cpython#23294 and python/cpython#23383. Both CPython PRs were originally, and both were backported to Python >=3.9.1, but no earlier. - A side effect of one of the changes is that equality comparisons of Literal objects will now raise a TypeError if one of the Literal objects being compared has a mutable parameter. (Using mutable parameters with Literal is not supported by PEP 586 or by any major static type checkers.) - Literal is now reimplemented on all Python versions <= 3.10.0. - Backport CPython PR 26067, ensuring that isinstance() calls on protocols raise TypeError when the protocol is not decorated with @runtime_checkable. - Backport several significant performance improvements to runtime-checkable protocols that have been made in Python 3.12 (see python/cpython#74690 for details). - A side effect of one of the performance improvements is that the members of a runtime-checkable protocol are now considered "frozen" at runtime as soon as the class has been created. Monkey-patching attributes onto a runtime-checkable protocol will still work, but will have no impact on isinstance() checks comparing objects to the protocol. See "What's New in Python 3.12" for more details. - isinstance() checks against runtime-checkable protocols now use inspect.getattr_static() rather than hasattr() to lookup whether attributes exist (backporting python/cpython#103034). - Backport the ability to define __init__ methods on Protocol classes, a change made in Python 3.11 (originally implemented in python/cpython#31628 - Speedup isinstance(3, typing_extensions.SupportsIndex) by >10x on Python <3.12. - Add typing_extensions versions of SupportsInt, SupportsFloat, SupportsComplex, SupportsBytes, SupportsAbs and SupportsRound. These have the same semantics as the versions from the typing module, but isinstance() checks against the typing_extensions versions are >10x faster at runtime on Python <3.12. - Add __orig_bases__ to non-generic TypedDicts, call-based TypedDicts, and call-based NamedTuples. - Add typing_extensions.get_original_bases, a backport of types.get_original_bases, introduced in Python 3.12 (CPython PR python/cpython#101827, originally - This function should always produce correct results when called on classes constructed using features from typing_extensions. - Constructing a call-based TypedDict using keyword arguments for the fields now causes a DeprecationWarning to be emitted. This matches the behaviour of typing.TypedDict on 3.11 and 3.12. - Backport the implementation of NewType from 3.10 (where it is implemented as a class rather than a function). This allows user-defined NewTypes to be pickled. - Fix tests and import on Python 3.12, where typing.TypeVar can no longer be subclassed. - Add typing_extensions.TypeAliasType, a backport of typing.TypeAliasType from PEP 695. - Backport changes to the repr of typing.Unpack that were made in order to implement PEP 692 (backport of python/cpython#104048). (From OE-Core rev: 2b1d07c7deb4f0247765bc737fb11a1747143edf) Signed-off-by: Wang Mingyu <[email protected]> Signed-off-by: Alexandre Belloni <[email protected]>
Changelog: ============ - Fix use of @deprecated on classes with __new__ but no __init__. - Fix regression in version 4.6.1 where comparing a generic class against a runtime-checkable protocol using isinstance() would cause AttributeError to be raised if using Python 3.7. - Change deprecated @runtime to formal API @runtime_checkable in the error message. - Fix regression in 4.6.0 where attempting to define a Protocol that was generic over a ParamSpec or a TypeVarTuple would cause TypeError to be raised. - typing_extensions is now documented at https://typing-extensions.readthedocs.io/en/latest/. - Add typing_extensions.Buffer, a marker class for buffer types, as proposed by PEP 688. Equivalent to collections.abc.Buffer in Python 3.12. - Backport two CPython PRs fixing various issues with typing.Literal: python/cpython#23294 and python/cpython#23383. Both CPython PRs were originally, and both were backported to Python >=3.9.1, but no earlier. - A side effect of one of the changes is that equality comparisons of Literal objects will now raise a TypeError if one of the Literal objects being compared has a mutable parameter. (Using mutable parameters with Literal is not supported by PEP 586 or by any major static type checkers.) - Literal is now reimplemented on all Python versions <= 3.10.0. - Backport CPython PR 26067, ensuring that isinstance() calls on protocols raise TypeError when the protocol is not decorated with @runtime_checkable. - Backport several significant performance improvements to runtime-checkable protocols that have been made in Python 3.12 (see python/cpython#74690 for details). - A side effect of one of the performance improvements is that the members of a runtime-checkable protocol are now considered "frozen" at runtime as soon as the class has been created. Monkey-patching attributes onto a runtime-checkable protocol will still work, but will have no impact on isinstance() checks comparing objects to the protocol. See "What's New in Python 3.12" for more details. - isinstance() checks against runtime-checkable protocols now use inspect.getattr_static() rather than hasattr() to lookup whether attributes exist (backporting python/cpython#103034). - Backport the ability to define __init__ methods on Protocol classes, a change made in Python 3.11 (originally implemented in python/cpython#31628 - Speedup isinstance(3, typing_extensions.SupportsIndex) by >10x on Python <3.12. - Add typing_extensions versions of SupportsInt, SupportsFloat, SupportsComplex, SupportsBytes, SupportsAbs and SupportsRound. These have the same semantics as the versions from the typing module, but isinstance() checks against the typing_extensions versions are >10x faster at runtime on Python <3.12. - Add __orig_bases__ to non-generic TypedDicts, call-based TypedDicts, and call-based NamedTuples. - Add typing_extensions.get_original_bases, a backport of types.get_original_bases, introduced in Python 3.12 (CPython PR python/cpython#101827, originally - This function should always produce correct results when called on classes constructed using features from typing_extensions. - Constructing a call-based TypedDict using keyword arguments for the fields now causes a DeprecationWarning to be emitted. This matches the behaviour of typing.TypedDict on 3.11 and 3.12. - Backport the implementation of NewType from 3.10 (where it is implemented as a class rather than a function). This allows user-defined NewTypes to be pickled. - Fix tests and import on Python 3.12, where typing.TypeVar can no longer be subclassed. - Add typing_extensions.TypeAliasType, a backport of typing.TypeAliasType from PEP 695. - Backport changes to the repr of typing.Unpack that were made in order to implement PEP 692 (backport of python/cpython#104048). (From OE-Core rev: a37154b9166323d05cca970ebb37bee0d5250893) Signed-off-by: Wang Mingyu <[email protected]> Signed-off-by: Alexandre Belloni <[email protected]> Signed-off-by: Richard Purdie <[email protected]>
Changelog: ============ - Fix use of @deprecated on classes with __new__ but no __init__. - Fix regression in version 4.6.1 where comparing a generic class against a runtime-checkable protocol using isinstance() would cause AttributeError to be raised if using Python 3.7. - Change deprecated @runtime to formal API @runtime_checkable in the error message. - Fix regression in 4.6.0 where attempting to define a Protocol that was generic over a ParamSpec or a TypeVarTuple would cause TypeError to be raised. - typing_extensions is now documented at https://typing-extensions.readthedocs.io/en/latest/. - Add typing_extensions.Buffer, a marker class for buffer types, as proposed by PEP 688. Equivalent to collections.abc.Buffer in Python 3.12. - Backport two CPython PRs fixing various issues with typing.Literal: python/cpython#23294 and python/cpython#23383. Both CPython PRs were originally, and both were backported to Python >=3.9.1, but no earlier. - A side effect of one of the changes is that equality comparisons of Literal objects will now raise a TypeError if one of the Literal objects being compared has a mutable parameter. (Using mutable parameters with Literal is not supported by PEP 586 or by any major static type checkers.) - Literal is now reimplemented on all Python versions <= 3.10.0. - Backport CPython PR 26067, ensuring that isinstance() calls on protocols raise TypeError when the protocol is not decorated with @runtime_checkable. - Backport several significant performance improvements to runtime-checkable protocols that have been made in Python 3.12 (see python/cpython#74690 for details). - A side effect of one of the performance improvements is that the members of a runtime-checkable protocol are now considered "frozen" at runtime as soon as the class has been created. Monkey-patching attributes onto a runtime-checkable protocol will still work, but will have no impact on isinstance() checks comparing objects to the protocol. See "What's New in Python 3.12" for more details. - isinstance() checks against runtime-checkable protocols now use inspect.getattr_static() rather than hasattr() to lookup whether attributes exist (backporting python/cpython#103034). - Backport the ability to define __init__ methods on Protocol classes, a change made in Python 3.11 (originally implemented in python/cpython#31628 - Speedup isinstance(3, typing_extensions.SupportsIndex) by >10x on Python <3.12. - Add typing_extensions versions of SupportsInt, SupportsFloat, SupportsComplex, SupportsBytes, SupportsAbs and SupportsRound. These have the same semantics as the versions from the typing module, but isinstance() checks against the typing_extensions versions are >10x faster at runtime on Python <3.12. - Add __orig_bases__ to non-generic TypedDicts, call-based TypedDicts, and call-based NamedTuples. - Add typing_extensions.get_original_bases, a backport of types.get_original_bases, introduced in Python 3.12 (CPython PR python/cpython#101827, originally - This function should always produce correct results when called on classes constructed using features from typing_extensions. - Constructing a call-based TypedDict using keyword arguments for the fields now causes a DeprecationWarning to be emitted. This matches the behaviour of typing.TypedDict on 3.11 and 3.12. - Backport the implementation of NewType from 3.10 (where it is implemented as a class rather than a function). This allows user-defined NewTypes to be pickled. - Fix tests and import on Python 3.12, where typing.TypeVar can no longer be subclassed. - Add typing_extensions.TypeAliasType, a backport of typing.TypeAliasType from PEP 695. - Backport changes to the repr of typing.Unpack that were made in order to implement PEP 692 (backport of python/cpython#104048). Signed-off-by: Wang Mingyu <[email protected]> Signed-off-by: Alexandre Belloni <[email protected]>
[](https://renovatebot.com) This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [typing-extensions](https://togithub.com/python/typing_extensions) ([changelog](https://togithub.com/python/typing_extensions/blob/main/CHANGELOG.md)) | `==4.5.0` -> `==4.6.3` | [](https://docs.renovatebot.com/merge-confidence/) | [](https://docs.renovatebot.com/merge-confidence/) | [](https://docs.renovatebot.com/merge-confidence/) | [](https://docs.renovatebot.com/merge-confidence/) | --- ### Release Notes <details> <summary>python/typing_extensions</summary> ### [`v4.6.3`](https://togithub.com/python/typing_extensions/blob/HEAD/CHANGELOG.md#Release-463-June-1-2023) [Compare Source](https://togithub.com/python/typing_extensions/compare/4.6.2...4.6.3) - Fix a regression introduced in v4.6.0 in the implementation of runtime-checkable protocols. The regression meant that doing `class Foo(X, typing_extensions.Protocol)`, where `X` was a class that had `abc.ABCMeta` as its metaclass, would then cause subsequent `isinstance(1, X)` calls to erroneously raise `TypeError`. Patch by Alex Waygood (backporting the CPython[https://github.com/python/cpython/pull/105152](https://togithub.com/python/cpython/pull/105152)l/105152). - Sync the repository's LICENSE file with that of CPython. `typing_extensions` is distributed under the same license as CPython itself. - Skip a problematic test on Python 3.12.0b1. The test fails on 3.12.0b1 due to a bug in CPython, which will be fixed in 3.12.0b2. The `typing_extensions` test suite now passes on 3.12.0b1. ### [`v4.6.2`](https://togithub.com/python/typing_extensions/blob/HEAD/CHANGELOG.md#Release-462-May-25-2023) [Compare Source](https://togithub.com/python/typing_extensions/compare/4.6.1...4.6.2) - Fix use of `@deprecated` on classes with `__new__` but no `__init__`. Patch by Jelle Zijlstra. - Fix regression in version 4.6.1 where comparing a generic class against a runtime-checkable protocol using `isinstance()` would cause `AttributeError` to be raised if using Python 3.7. ### [`v4.6.1`](https://togithub.com/python/typing_extensions/blob/HEAD/CHANGELOG.md#Release-461-May-23-2023) [Compare Source](https://togithub.com/python/typing_extensions/compare/4.6.0...4.6.1) - Change deprecated `@runtime` to formal API `@runtime_checkable` in the error message. Patch by Xuehai Pan. - Fix regression in 4.6.0 where attempting to define a `Protocol` that was generic over a `ParamSpec` or a `TypeVarTuple` would cause `TypeError` to be raised. Patch by Alex Waygood. ### [`v4.6.0`](https://togithub.com/python/typing_extensions/blob/HEAD/CHANGELOG.md#Release-460-May-22-2023) [Compare Source](https://togithub.com/python/typing_extensions/compare/4.5.0...4.6.0) - `typing_extensions` is now documented at https://typing-extensions.readthedocs.io/en/latest/. Patch by Jelle Zijlstra. - Add `typing_extensions.Buffer`, a marker class for buffer types, as proposed by PEP 688. Equivalent to `collections.abc.Buffer` in Python 3.12. Patch by Jelle Zijlstra. - Backport two CPython PRs fixing various issues with `typing.Literal`: [https://github.com/python/cpython/pull/23294](https://togithub.com/python/cpython/pull/23294)3294 [https://github.com/python/cpython/pull/23383](https://togithub.com/python/cpython/pull/23383)ll/23383. Both CPython PRs were originally by Yurii Karabas, and both were backported to Python >=3.9.1, but no earlier. Patch by Alex Waygood. A side effect of one of the changes is that equality comparisons of `Literal` objects will now raise a `TypeError` if one of the `Literal` objects being compared has a mutable parameter. (Using mutable parameters with `Literal` is not supported by PEP 586 or by any major static type checkers.) - `Literal` is now reimplemented on all Python versions <= 3.10.0. The `typing_extensions` version does not suffer from the bug that was fixed in [https://github.com/python/cpython/pull/29334](https://togithub.com/python/cpython/pull/29334)9334. (The CPython bugfix was backported to CPython 3.10.1 and 3.9.8, but no earlier.) - Backport [CPython PR 26067](https://togithub.com/python/cpython/pull/26067) (originally by Yurii Karabas), ensuring that `isinstance()` calls on protocols raise `TypeError` when the protocol is not decorated with `@runtime_checkable`. Patch by Alex Waygood. - Backport several significant performance improvements to runtime-checkable protocols that have been made in Python 3.12 ([https://github.com/python/cpython/issues/74690](https://togithub.com/python/cpython/issues/74690)es/74690 for details). Patch by Alex Waygood. A side effect of one of the performance improvements is that the members of a runtime-checkable protocol are now considered “frozen” at runtime as soon as the class has been created. Monkey-patching attributes onto a runtime-checkable protocol will still work, but will have no impact on `isinstance()` checks comparing objects to the protocol. See ["What's New in Python 3.12"](https://docs.python.org/3.12/whatsnew/3.12.html#typing) for more details. - `isinstance()` checks against runtime-checkable protocols now use `inspect.getattr_static()` rather than `hasattr()` to lookup whether attributes exist (backport[https://github.com/python/cpython/pull/103034](https://togithub.com/python/cpython/pull/103034)3034). This means that descriptors and `__getattr__` methods are no longer unexpectedly evaluated during `isinstance()` checks against runtime-checkable protocols. However, it may also mean that some objects which used to be considered instances of a runtime-checkable protocol on older versions of `typing_extensions` may no longer be considered instances of that protocol using the new release, and vice versa. Most users are unlikely to be affected by this change. Patch by Alex Waygood. - Backport the ability to define `__init__` methods on Protocol classes, a change made in Python 3.11 (originally implemented[https://github.com/python/cpython/pull/31628](https://togithub.com/python/cpython/pull/31628)ll/31628 by Adrian Garcia Badaracco). Patch by Alex Waygood. - Speedup `isinstance(3, typing_extensions.SupportsIndex)` by >10x on Python <3.12. Patch by Alex Waygood. - Add `typing_extensions` versions of `SupportsInt`, `SupportsFloat`, `SupportsComplex`, `SupportsBytes`, `SupportsAbs` and `SupportsRound`. These have the same semantics as the versions from the `typing` module, but `isinstance()` checks against the `typing_extensions` versions are >10x faster at runtime on Python <3.12. Patch by Alex Waygood. - Add `__orig_bases__` to non-generic TypedDicts, call-based TypedDicts, and call-based NamedTuples. Other TypedDicts and NamedTuples already had the attribute. Patch by Adrian Garcia Badaracco. - Add `typing_extensions.get_original_bases`, a backport of [`types.get_original_bases`](https://docs.python.org/3.12/library/types.html#types.get_original_bases), introduced in Python 3.12 (CPython[https://github.com/python/cpython/pull/101827](https://togithub.com/python/cpython/pull/101827)l/101827, originally by James Hilton-Balfe). Patch by Alex Waygood. This function should always produce correct results when called on classes constructed using features from `typing_extensions`. However, it may produce incorrect results when called on some `NamedTuple` or `TypedDict` classes that use `typing.{NamedTuple,TypedDict}` on Python <=3.11. - Constructing a call-based `TypedDict` using keyword arguments for the fields now causes a `DeprecationWarning` to be emitted. This matches the behaviour of `typing.TypedDict` on 3.11 and 3.12. - Backport the implementation of `NewType` from 3.10 (where it is implemented as a class rather than a function). This allows user-defined `NewType`s to be pickled. Patch by Alex Waygood. - Fix tests and import on Python 3.12, where `typing.TypeVar` can no longer be subclassed. Patch by Jelle Zijlstra. - Add `typing_extensions.TypeAliasType`, a backport of `typing.TypeAliasType` from PEP 695. Patch by Jelle Zijlstra. - Backport changes to the repr of `typing.Unpack` that were made in order to implement [PEP 692](https://peps.python.org/pep-0692/) (backport of [https://github.com/python/cpython/pull/104048](https://togithub.com/python/cpython/pull/104048)4048). Patch by Alex Waygood. </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Mend Renovate](https://www.mend.io/free-developer-tools/renovate/). View repository job log [here](https://app.renovatebot.com/dashboard#github/allenporter/flux-local). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNS4xMDUuMiIsInVwZGF0ZWRJblZlciI6IjM1LjEwNS4yIiwidGFyZ2V0QnJhbmNoIjoibWFpbiJ9--> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
https://bugs.python.org/issue44807