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 2021-07-16 22:12:38
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-typing_extensions (Old)
and /work/SRC/openSUSE:Factory/.python-typing_extensions.new.2632 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-typing_extensions"
Fri Jul 16 22:12:38 2021 rev:12 rq:905852 version:3.10.0.0
Changes:
--------
---
/work/SRC/openSUSE:Factory/python-typing_extensions/python-typing_extensions.changes
2021-01-15 19:42:59.381717399 +0100
+++
/work/SRC/openSUSE:Factory/.python-typing_extensions.new.2632/python-typing_extensions.changes
2021-07-16 22:13:07.470668098 +0200
@@ -1,0 +2,11 @@
+Mon Jul 12 13:11:30 UTC 2021 - Mark??ta Machov?? <[email protected]>
+
+- Update to 3.10.0.0
+ * Implement TypeGuard (PEP 649)
+ * backport ParamSpecArgs/Kwargs
+ * Fixed required/optional keys with old-style TypedDict
+ * Bring in protocol???s __init__ behaviour same like in python > 3.8
+ * Support PEP 612 in typing_extensions (Python 3)
+ * Add OrderedDict to typing_extensions
+
+-------------------------------------------------------------------
Old:
----
typing_extensions-3.7.4.3.tar.gz
New:
----
typing_extensions-3.10.0.0.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-typing_extensions.spec ++++++
--- /var/tmp/diff_new_pack.GPxiN5/_old 2021-07-16 22:13:08.022664197 +0200
+++ /var/tmp/diff_new_pack.GPxiN5/_new 2021-07-16 22:13:08.022664197 +0200
@@ -1,5 +1,5 @@
#
-# spec file for package python-typing_extensions
+# spec file
#
# Copyright (c) 2021 SUSE LLC
#
@@ -28,7 +28,7 @@
%bcond_with test
%endif
Name: python-typing_extensions%{psuffix}
-Version: 3.7.4.3
+Version: 3.10.0.0
Release: 0
Summary: Backported and Experimental Type Hints for Python 35+
License: Python-2.0
++++++ typing_extensions-3.7.4.3.tar.gz -> typing_extensions-3.10.0.0.tar.gz
++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/typing_extensions-3.7.4.3/PKG-INFO
new/typing_extensions-3.10.0.0/PKG-INFO
--- old/typing_extensions-3.7.4.3/PKG-INFO 2020-08-23 18:33:40.000000000
+0200
+++ new/typing_extensions-3.10.0.0/PKG-INFO 2021-05-01 19:56:08.000000000
+0200
@@ -1,25 +1,26 @@
Metadata-Version: 1.1
Name: typing_extensions
-Version: 3.7.4.3
+Version: 3.10.0.0
Summary: Backported and Experimental Type Hints for Python 3.5+
Home-page:
https://github.com/python/typing/blob/master/typing_extensions/README.rst
-Author: Guido van Rossum, Jukka Lehtosalo, Lukasz Langa, Michael Lee
+Author: Guido van Rossum, Jukka Lehtosalo, ??ukasz Langa, Michael Lee
Author-email: [email protected]
License: PSF
Description: Typing Extensions -- Backported and Experimental Type Hints for
Python
- The ``typing`` module was added to the standard library in Python 3.5
on
- a provisional basis and will no longer be provisional in Python 3.7.
However,
- this means users of Python 3.5 - 3.6 who are unable to upgrade will
not be
+ The ``typing`` module was added to the standard library in Python 3.5,
but
+ many new features have been added to the module since then.
+ This means users of Python 3.5 - 3.6 who are unable to upgrade will
not be
able to take advantage of new types added to the ``typing`` module,
such as
- ``typing.Text`` or ``typing.Coroutine``.
+ ``typing.Protocol`` or ``typing.TypedDict``.
- The ``typing_extensions`` module contains both backports of these
changes
- as well as experimental types that will eventually be added to the
``typing``
- module, such as ``Protocol`` or ``TypedDict``.
+ The ``typing_extensions`` module contains backports of these changes.
+ Experimental types that will eventually be added to the ``typing``
+ module are also included in ``typing_extensions``, such as
+ ``typing.ParamSpec`` and ``typing.TypeGuard``.
- Users of other Python versions should continue to install and use
- the ``typing`` module from PyPi instead of using this one unless
specifically
+ Users of Python versions before 3.5 should install and use
+ the ``typing`` module from PyPI instead of using this one, unless
specifically
writing code that must be compatible with multiple Python versions or
requires
experimental types.
@@ -37,4 +38,5 @@
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
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/typing_extensions-3.7.4.3/README.rst
new/typing_extensions-3.10.0.0/README.rst
--- old/typing_extensions-3.7.4.3/README.rst 2020-02-11 19:17:38.000000000
+0100
+++ new/typing_extensions-3.10.0.0/README.rst 2021-05-01 19:50:21.000000000
+0200
@@ -21,7 +21,7 @@
static duck typing) or ``TypedDict`` (see PEP 589).
Users of other Python versions should continue to install and use
-use the ``typing`` module from PyPi instead of using this one unless
+the ``typing`` module from PyPi instead of using this one unless
specifically writing code that must be compatible with multiple Python
versions or requires experimental types.
@@ -44,21 +44,29 @@
- ``NewType``
- ``NoReturn``
- ``overload`` (note that older versions of ``typing`` only let you use
``overload`` in stubs)
+- ``OrderedDict``
- ``Protocol`` (except on Python 3.5.0)
-- ``runtime`` (except on Python 3.5.0)
+- ``runtime_checkable`` (except on Python 3.5.0)
- ``Text``
- ``Type``
- ``TypedDict``
+- ``TypeAlias``
- ``TYPE_CHECKING``
Python 3.4+ only:
-----------------
- ``ChainMap``
+- ``ParamSpec``
+- ``Concatenate``
+- ``ParamSpecArgs``
+- ``ParamSpecKwargs``
+- ``TypeGuard``
Python 3.5+ only:
-----------------
+- ``Annotated`` (except on Python 3.5.0-3.5.2)
- ``AsyncIterable``
- ``AsyncIterator``
- ``AsyncContextManager``
@@ -80,6 +88,12 @@
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. For example, ``ParamSpec`` and ``Concatenate``
+will not work with ``get_args``, ``get_origin`` or user-defined ``Generic``\ s
+because they need to be lists to work with older versions of ``Callable``.
+These types are only guaranteed to work for static type checking.
+
Running tests
=============
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/typing_extensions-3.7.4.3/setup.py
new/typing_extensions-3.10.0.0/setup.py
--- old/typing_extensions-3.7.4.3/setup.py 2020-08-23 18:32:30.000000000
+0200
+++ new/typing_extensions-3.10.0.0/setup.py 2021-05-01 19:50:21.000000000
+0200
@@ -9,23 +9,24 @@
'to install the typing package.\n')
exit(1)
-version = '3.7.4.3'
+version = '3.10.0.0'
description = 'Backported and Experimental Type Hints for Python 3.5+'
long_description = '''\
Typing Extensions -- Backported and Experimental Type Hints for Python
-The ``typing`` module was added to the standard library in Python 3.5 on
-a provisional basis and will no longer be provisional in Python 3.7. However,
-this means users of Python 3.5 - 3.6 who are unable to upgrade will not be
+The ``typing`` module was added to the standard library in Python 3.5, but
+many new features have been added to the module since then.
+This means users of Python 3.5 - 3.6 who are unable to upgrade will not be
able to take advantage of new types added to the ``typing`` module, such as
-``typing.Text`` or ``typing.Coroutine``.
+``typing.Protocol`` or ``typing.TypedDict``.
-The ``typing_extensions`` module contains both backports of these changes
-as well as experimental types that will eventually be added to the ``typing``
-module, such as ``Protocol`` or ``TypedDict``.
+The ``typing_extensions`` module contains backports of these changes.
+Experimental types that will eventually be added to the ``typing``
+module are also included in ``typing_extensions``, such as
+``typing.ParamSpec`` and ``typing.TypeGuard``.
-Users of other Python versions should continue to install and use
-the ``typing`` module from PyPi instead of using this one unless specifically
+Users of Python versions before 3.5 should install and use
+the ``typing`` module from PyPI instead of using this one, unless specifically
writing code that must be compatible with multiple Python versions or requires
experimental types.
'''
@@ -43,6 +44,7 @@
'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.8',
'Programming Language :: Python :: 3.9',
+ 'Programming Language :: Python :: 3.10',
'Topic :: Software Development',
]
@@ -57,7 +59,7 @@
version=version,
description=description,
long_description=long_description,
- author='Guido van Rossum, Jukka Lehtosalo, Lukasz Langa, Michael Lee',
+ author='Guido van Rossum, Jukka Lehtosalo, ??ukasz Langa, Michael Lee',
author_email='[email protected]',
url='https://github.com/python/typing/blob/master/typing_extensions/README.rst',
license='PSF',
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/typing_extensions-3.7.4.3/src_py2/typing_extensions.egg-info/PKG-INFO
new/typing_extensions-3.10.0.0/src_py2/typing_extensions.egg-info/PKG-INFO
--- old/typing_extensions-3.7.4.3/src_py2/typing_extensions.egg-info/PKG-INFO
1970-01-01 01:00:00.000000000 +0100
+++ new/typing_extensions-3.10.0.0/src_py2/typing_extensions.egg-info/PKG-INFO
2021-05-01 19:56:08.000000000 +0200
@@ -0,0 +1,42 @@
+Metadata-Version: 1.1
+Name: typing-extensions
+Version: 3.10.0.0
+Summary: Backported and Experimental Type Hints for Python 3.5+
+Home-page:
https://github.com/python/typing/blob/master/typing_extensions/README.rst
+Author: Guido van Rossum, Jukka Lehtosalo, ??ukasz Langa, Michael Lee
+Author-email: [email protected]
+License: PSF
+Description: Typing Extensions -- Backported and Experimental Type Hints for
Python
+
+ The ``typing`` module was added to the standard library in Python 3.5,
but
+ many new features have been added to the module since then.
+ This means users of Python 3.5 - 3.6 who are unable to upgrade will
not be
+ able to take advantage of new types added to the ``typing`` module,
such as
+ ``typing.Protocol`` or ``typing.TypedDict``.
+
+ The ``typing_extensions`` module contains backports of these changes.
+ Experimental types that will eventually be added to the ``typing``
+ module are also included in ``typing_extensions``, such as
+ ``typing.ParamSpec`` and ``typing.TypeGuard``.
+
+ Users of Python versions before 3.5 should install and use
+ the ``typing`` module from PyPI instead of using this one, unless
specifically
+ writing code that must be compatible with multiple Python versions or
requires
+ experimental types.
+
+Keywords: typing function annotations type hints hinting checking checker
typehints typehinting typechecking backport
+Platform: UNKNOWN
+Classifier: Development Status :: 3 - Alpha
+Classifier: Environment :: Console
+Classifier: Intended Audience :: Developers
+Classifier: License :: OSI Approved :: Python Software Foundation License
+Classifier: Operating System :: OS Independent
+Classifier: Programming Language :: Python :: 2.7
+Classifier: Programming Language :: Python :: 3.4
+Classifier: Programming Language :: Python :: 3.5
+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
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/typing_extensions-3.7.4.3/src_py2/typing_extensions.egg-info/SOURCES.txt
new/typing_extensions-3.10.0.0/src_py2/typing_extensions.egg-info/SOURCES.txt
---
old/typing_extensions-3.7.4.3/src_py2/typing_extensions.egg-info/SOURCES.txt
1970-01-01 01:00:00.000000000 +0100
+++
new/typing_extensions-3.10.0.0/src_py2/typing_extensions.egg-info/SOURCES.txt
2021-05-01 19:56:08.000000000 +0200
@@ -0,0 +1,14 @@
+LICENSE
+MANIFEST.in
+README.rst
+setup.cfg
+setup.py
+src_py2/test_typing_extensions.py
+src_py2/typing_extensions.py
+src_py2/typing_extensions.egg-info/PKG-INFO
+src_py2/typing_extensions.egg-info/SOURCES.txt
+src_py2/typing_extensions.egg-info/dependency_links.txt
+src_py2/typing_extensions.egg-info/requires.txt
+src_py2/typing_extensions.egg-info/top_level.txt
+src_py3/test_typing_extensions.py
+src_py3/typing_extensions.py
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/typing_extensions-3.7.4.3/src_py2/typing_extensions.egg-info/dependency_links.txt
new/typing_extensions-3.10.0.0/src_py2/typing_extensions.egg-info/dependency_links.txt
---
old/typing_extensions-3.7.4.3/src_py2/typing_extensions.egg-info/dependency_links.txt
1970-01-01 01:00:00.000000000 +0100
+++
new/typing_extensions-3.10.0.0/src_py2/typing_extensions.egg-info/dependency_links.txt
2021-05-01 19:56:08.000000000 +0200
@@ -0,0 +1 @@
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/typing_extensions-3.7.4.3/src_py2/typing_extensions.egg-info/requires.txt
new/typing_extensions-3.10.0.0/src_py2/typing_extensions.egg-info/requires.txt
---
old/typing_extensions-3.7.4.3/src_py2/typing_extensions.egg-info/requires.txt
1970-01-01 01:00:00.000000000 +0100
+++
new/typing_extensions-3.10.0.0/src_py2/typing_extensions.egg-info/requires.txt
2021-05-01 19:56:08.000000000 +0200
@@ -0,0 +1,3 @@
+
+[:python_version < "3.5"]
+typing>=3.7.4
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/typing_extensions-3.7.4.3/src_py2/typing_extensions.egg-info/top_level.txt
new/typing_extensions-3.10.0.0/src_py2/typing_extensions.egg-info/top_level.txt
---
old/typing_extensions-3.7.4.3/src_py2/typing_extensions.egg-info/top_level.txt
1970-01-01 01:00:00.000000000 +0100
+++
new/typing_extensions-3.10.0.0/src_py2/typing_extensions.egg-info/top_level.txt
2021-05-01 19:56:08.000000000 +0200
@@ -0,0 +1 @@
+typing_extensions
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/typing_extensions-3.7.4.3/src_py3/test_typing_extensions.py
new/typing_extensions-3.10.0.0/src_py3/test_typing_extensions.py
--- old/typing_extensions-3.7.4.3/src_py3/test_typing_extensions.py
2020-07-08 00:29:25.000000000 +0200
+++ new/typing_extensions-3.10.0.0/src_py3/test_typing_extensions.py
2021-05-01 19:50:21.000000000 +0200
@@ -7,13 +7,14 @@
import subprocess
import types
from unittest import TestCase, main, skipUnless, skipIf
-from typing import TypeVar, Optional
+from typing import TypeVar, Optional, Union
from typing import T, KT, VT # Not in __all__.
-from typing import Tuple, List, Dict, Iterator
+from typing import Tuple, List, Dict, Iterator, Callable
from typing import Generic
from typing import no_type_check
from typing_extensions import NoReturn, ClassVar, Final, IntVar, Literal,
Type, NewType, TypedDict
-from typing_extensions import TypeAlias
+from typing_extensions import TypeAlias, ParamSpec, Concatenate,
ParamSpecArgs, ParamSpecKwargs, TypeGuard
+
try:
from typing_extensions import Protocol, runtime, runtime_checkable
except ImportError:
@@ -51,6 +52,7 @@
TYPING_3_5_1 = TYPING_LATEST or sys.version_info[:3] >= (3, 5, 1)
TYPING_3_5_3 = TYPING_LATEST or sys.version_info[:3] >= (3, 5, 3)
TYPING_3_6_1 = TYPING_LATEST or sys.version_info[:3] >= (3, 6, 1)
+TYPING_3_10_0 = TYPING_LATEST or sys.version_info[:3] >= (3, 10, 0)
# For typing versions where issubclass(...) and
# isinstance(...) checks are forbidden.
@@ -517,6 +519,80 @@
self.assertNotEqual(gth(Loop, globals())['attr'], Final)
+@skipUnless(PEP_560, "Python 3.7+ required")
+class GetUtilitiesTestCase(TestCase):
+ def test_get_origin(self):
+ from typing_extensions import get_origin
+
+ T = TypeVar('T')
+ P = ParamSpec('P')
+ class C(Generic[T]): pass
+ self.assertIs(get_origin(C[int]), C)
+ self.assertIs(get_origin(C[T]), C)
+ self.assertIs(get_origin(int), None)
+ self.assertIs(get_origin(ClassVar[int]), ClassVar)
+ self.assertIs(get_origin(Union[int, str]), Union)
+ self.assertIs(get_origin(Literal[42, 43]), Literal)
+ self.assertIs(get_origin(Final[List[int]]), Final)
+ self.assertIs(get_origin(Generic), Generic)
+ self.assertIs(get_origin(Generic[T]), Generic)
+ self.assertIs(get_origin(List[Tuple[T, T]][int]), list)
+ self.assertIs(get_origin(Annotated[T, 'thing']), Annotated)
+ self.assertIs(get_origin(List), list)
+ self.assertIs(get_origin(Tuple), tuple)
+ self.assertIs(get_origin(Callable), collections.abc.Callable)
+ if sys.version_info >= (3, 9):
+ self.assertIs(get_origin(list[int]), list)
+ self.assertIs(get_origin(list), None)
+ self.assertIs(get_origin(P.args), P)
+ self.assertIs(get_origin(P.kwargs), P)
+
+ def test_get_args(self):
+ from typing_extensions import get_args
+
+ T = TypeVar('T')
+ class C(Generic[T]): pass
+ self.assertEqual(get_args(C[int]), (int,))
+ self.assertEqual(get_args(C[T]), (T,))
+ self.assertEqual(get_args(int), ())
+ self.assertEqual(get_args(ClassVar[int]), (int,))
+ self.assertEqual(get_args(Union[int, str]), (int, str))
+ self.assertEqual(get_args(Literal[42, 43]), (42, 43))
+ self.assertEqual(get_args(Final[List[int]]), (List[int],))
+ self.assertEqual(get_args(Union[int, Tuple[T, int]][str]),
+ (int, Tuple[str, int]))
+ self.assertEqual(get_args(typing.Dict[int, Tuple[T,
T]][Optional[int]]),
+ (int, Tuple[Optional[int], Optional[int]]))
+ self.assertEqual(get_args(Callable[[], T][int]), ([], int))
+ self.assertEqual(get_args(Callable[..., int]), (..., int))
+ self.assertEqual(get_args(Union[int, Callable[[Tuple[T, ...]], str]]),
+ (int, Callable[[Tuple[T, ...]], str]))
+ self.assertEqual(get_args(Tuple[int, ...]), (int, ...))
+ self.assertEqual(get_args(Tuple[()]), ((),))
+ self.assertEqual(get_args(Annotated[T, 'one', 2, ['three']]), (T,
'one', 2, ['three']))
+ self.assertEqual(get_args(List), ())
+ self.assertEqual(get_args(Tuple), ())
+ self.assertEqual(get_args(Callable), ())
+ if sys.version_info >= (3, 9):
+ self.assertEqual(get_args(list[int]), (int,))
+ self.assertEqual(get_args(list), ())
+ if sys.version_info >= (3, 9):
+ # Support Python versions with and without the fix for
+ # https://bugs.python.org/issue42195
+ # The first variant is for 3.9.2+, the second for 3.9.0 and 1
+ self.assertIn(get_args(collections.abc.Callable[[int], str]),
+ (([int], str), ([[int]], str)))
+ self.assertIn(get_args(collections.abc.Callable[[], str]),
+ (([], str), ([[]], str)))
+ self.assertEqual(get_args(collections.abc.Callable[..., str]),
(..., str))
+ P = ParamSpec('P')
+ # In 3.9 and lower we use typing_extensions's hacky implementation
+ # of ParamSpec, which gets incorrectly wrapped in a list
+ self.assertIn(get_args(Callable[P, int]), [(P, int), ([P], int)])
+ self.assertEqual(get_args(Callable[Concatenate[int, P], int]),
+ (Concatenate[int, P], int))
+
+
class CollectionsAbcTests(BaseTestCase):
def test_isinstance_collections(self):
@@ -609,6 +685,30 @@
if TYPING_3_5_3:
self.assertNotIsSubclass(collections.defaultdict, MyDefDict)
+ @skipUnless(CAN_INSTANTIATE_COLLECTIONS, "Behavior added in typing 3.6.1")
+ def test_ordereddict_instantiation(self):
+ self.assertIs(
+ type(typing_extensions.OrderedDict()),
+ collections.OrderedDict)
+ self.assertIs(
+ type(typing_extensions.OrderedDict[KT, VT]()),
+ collections.OrderedDict)
+ self.assertIs(
+ type(typing_extensions.OrderedDict[str, int]()),
+ collections.OrderedDict)
+
+ def test_ordereddict_subclass(self):
+
+ class MyOrdDict(typing_extensions.OrderedDict[str, int]):
+ pass
+
+ od = MyOrdDict()
+ self.assertIsInstance(od, MyOrdDict)
+
+ self.assertIsSubclass(MyOrdDict, collections.OrderedDict)
+ if TYPING_3_5_3:
+ self.assertNotIsSubclass(collections.OrderedDict, MyOrdDict)
+
def test_chainmap_instantiation(self):
self.assertIs(type(typing_extensions.ChainMap()), collections.ChainMap)
self.assertIs(type(typing_extensions.ChainMap[KT, VT]()),
collections.ChainMap)
@@ -1240,8 +1340,9 @@
self.assertIsSubclass(P, PR)
with self.assertRaises(TypeError):
PR[int]
- with self.assertRaises(TypeError):
- PR[int, 1]
+ if not TYPING_3_10_0:
+ with self.assertRaises(TypeError):
+ PR[int, 1]
class P1(Protocol, Generic[T]):
def bar(self, x: T) -> str: ...
class P2(Generic[T], Protocol):
@@ -1254,7 +1355,7 @@
def bar(self, x: str) -> str:
return x
self.assertIsInstance(Test(), PSub)
- if TYPING_3_5_3:
+ if TYPING_3_5_3 and not TYPING_3_10_0:
with self.assertRaises(TypeError):
PR[int, ClassVar]
@@ -1421,6 +1522,15 @@
self.assertIsSubclass(B, Custom)
self.assertNotIsSubclass(A, Custom)
+ def test_no_init_same_for_different_protocol_implementations(self):
+ class CustomProtocolWithoutInitA(Protocol):
+ pass
+
+ class CustomProtocolWithoutInitB(Protocol):
+ pass
+
+ self.assertEqual(CustomProtocolWithoutInitA.__init__,
CustomProtocolWithoutInitB.__init__)
+
class TypedDictTests(BaseTestCase):
@@ -1494,7 +1604,7 @@
def test_typeddict_errors(self):
Emp = TypedDict('Emp', {'name': str, 'id': int})
- if sys.version_info[:2] >= (3, 9):
+ if sys.version_info >= (3, 9, 2):
self.assertEqual(TypedDict.__module__, 'typing')
else:
self.assertEqual(TypedDict.__module__, 'typing_extensions')
@@ -1516,7 +1626,7 @@
def test_py36_class_syntax_usage(self):
self.assertEqual(LabelPoint2D.__name__, 'LabelPoint2D')
self.assertEqual(LabelPoint2D.__module__, __name__)
- self.assertEqual(LabelPoint2D.__annotations__, {'x': int, 'y': int,
'label': str})
+ self.assertEqual(get_type_hints(LabelPoint2D), {'x': int, 'y': int,
'label': str})
self.assertEqual(LabelPoint2D.__bases__, (dict,))
self.assertEqual(LabelPoint2D.__total__, True)
self.assertNotIsSubclass(LabelPoint2D, typing.Sequence)
@@ -1550,11 +1660,15 @@
self.assertEqual(D(), {})
self.assertEqual(D(x=1), {'x': 1})
self.assertEqual(D.__total__, False)
+ self.assertEqual(D.__required_keys__, frozenset())
+ self.assertEqual(D.__optional_keys__, {'x'})
if PY36:
self.assertEqual(Options(), {})
self.assertEqual(Options(log_level=2), {'log_level': 2})
self.assertEqual(Options.__total__, False)
+ self.assertEqual(Options.__required_keys__, frozenset())
+ self.assertEqual(Options.__optional_keys__, {'log_level',
'log_path'})
@skipUnless(PY36, 'Python 3.6 required')
def test_optional_keys(self):
@@ -1565,11 +1679,11 @@
def test_keys_inheritance(self):
assert BaseAnimal.__required_keys__ == frozenset(['name'])
assert BaseAnimal.__optional_keys__ == frozenset([])
- assert BaseAnimal.__annotations__ == {'name': str}
+ assert get_type_hints(BaseAnimal) == {'name': str}
assert Animal.__required_keys__ == frozenset(['name'])
assert Animal.__optional_keys__ == frozenset(['tail', 'voice'])
- assert Animal.__annotations__ == {
+ assert get_type_hints(Animal) == {
'name': str,
'tail': bool,
'voice': str,
@@ -1577,7 +1691,7 @@
assert Cat.__required_keys__ == frozenset(['name', 'fur_color'])
assert Cat.__optional_keys__ == frozenset(['tail', 'voice'])
- assert Cat.__annotations__ == {
+ assert get_type_hints(Cat) == {
'fur_color': str,
'name': str,
'tail': bool,
@@ -1872,6 +1986,172 @@
with self.assertRaises(TypeError):
TypeAlias[int]
+class ParamSpecTests(BaseTestCase):
+
+ def test_basic_plain(self):
+ P = ParamSpec('P')
+ self.assertEqual(P, P)
+ self.assertIsInstance(P, ParamSpec)
+ # Should be hashable
+ hash(P)
+
+ def test_repr(self):
+ P = ParamSpec('P')
+ P_co = ParamSpec('P_co', covariant=True)
+ P_contra = ParamSpec('P_contra', contravariant=True)
+ P_2 = ParamSpec('P_2')
+ self.assertEqual(repr(P), '~P')
+ self.assertEqual(repr(P_2), '~P_2')
+
+ # Note: PEP 612 doesn't require these to be repr-ed correctly, but
+ # just follow CPython.
+ self.assertEqual(repr(P_co), '+P_co')
+ self.assertEqual(repr(P_contra), '-P_contra')
+
+ def test_valid_uses(self):
+ P = ParamSpec('P')
+ T = TypeVar('T')
+ C1 = typing.Callable[P, int]
+ C2 = typing.Callable[P, T]
+
+ # Note: no tests for Callable.__args__ and Callable.__parameters__ here
+ # because pre-3.10 Callable sees ParamSpec as a plain list, not a
+ # TypeVar.
+
+ # Test collections.abc.Callable too.
+ if sys.version_info[:2] >= (3, 9):
+ C3 = collections.abc.Callable[P, int]
+ C4 = collections.abc.Callable[P, T]
+
+ # ParamSpec instances should also have args and kwargs attributes.
+ self.assertIn('args', dir(P))
+ self.assertIn('kwargs', dir(P))
+
+ def test_args_kwargs(self):
+ P = ParamSpec('P')
+ self.assertIn('args', dir(P))
+ self.assertIn('kwargs', dir(P))
+ self.assertIsInstance(P.args, ParamSpecArgs)
+ self.assertIsInstance(P.kwargs, ParamSpecKwargs)
+ self.assertIs(P.args.__origin__, P)
+ self.assertIs(P.kwargs.__origin__, P)
+ self.assertEqual(repr(P.args), "P.args")
+ self.assertEqual(repr(P.kwargs), "P.kwargs")
+
+ # Note: ParamSpec doesn't work for pre-3.10 user-defined Generics due
+ # to type checks inside Generic.
+
+ def test_pickle(self):
+ global P, P_co, P_contra
+ P = ParamSpec('P')
+ P_co = ParamSpec('P_co', covariant=True)
+ P_contra = ParamSpec('P_contra', contravariant=True)
+ for proto in range(pickle.HIGHEST_PROTOCOL):
+ with self.subTest('Pickle protocol {proto}'.format(proto=proto)):
+ for paramspec in (P, P_co, P_contra):
+ z = pickle.loads(pickle.dumps(paramspec, proto))
+ self.assertEqual(z.__name__, paramspec.__name__)
+ self.assertEqual(z.__covariant__, paramspec.__covariant__)
+ self.assertEqual(z.__contravariant__,
paramspec.__contravariant__)
+ self.assertEqual(z.__bound__, paramspec.__bound__)
+
+ def test_eq(self):
+ P = ParamSpec('P')
+ self.assertEqual(P, P)
+ self.assertEqual(hash(P), hash(P))
+ # ParamSpec should compare by id similar to TypeVar in CPython
+ self.assertNotEqual(ParamSpec('P'), P)
+ self.assertIsNot(ParamSpec('P'), P)
+ # Note: normally you don't test this as it breaks when there's
+ # a hash collision. However, ParamSpec *must* guarantee that
+ # as long as two objects don't have the same ID, their hashes
+ # won't be the same.
+ self.assertNotEqual(hash(ParamSpec('P')), hash(P))
+
+
+class ConcatenateTests(BaseTestCase):
+ def test_basics(self):
+ P = ParamSpec('P')
+
+ class MyClass: ...
+
+ c = Concatenate[MyClass, P]
+ self.assertNotEqual(c, Concatenate)
+
+ def test_valid_uses(self):
+ P = ParamSpec('P')
+ T = TypeVar('T')
+ C1 = typing.Callable[Concatenate[int, P], int]
+ C2 = typing.Callable[Concatenate[int, T, P], T]
+
+ # Test collections.abc.Callable too.
+ if sys.version_info[:2] >= (3, 9):
+ C3 = collections.abc.Callable[Concatenate[int, P], int]
+ C4 = collections.abc.Callable[Concatenate[int, T, P], T]
+
+ def test_basic_introspection(self):
+ P = ParamSpec('P')
+ C1 = Concatenate[int, P]
+ C2 = Concatenate[int, T, P]
+ self.assertEqual(C1.__origin__, Concatenate)
+ self.assertEqual(C1.__args__, (int, P))
+ self.assertEqual(C2.__origin__, Concatenate)
+ self.assertEqual(C2.__args__, (int, T, P))
+
+ def test_eq(self):
+ P = ParamSpec('P')
+ C1 = Concatenate[int, P]
+ C2 = Concatenate[int, P]
+ C3 = Concatenate[int, T, P]
+ self.assertEqual(C1, C2)
+ self.assertEqual(hash(C1), hash(C2))
+ self.assertNotEqual(C1, C3)
+
+
+class TypeGuardTests(BaseTestCase):
+ def test_basics(self):
+ TypeGuard[int] # OK
+ self.assertEqual(TypeGuard[int], TypeGuard[int])
+
+ def foo(arg) -> TypeGuard[int]: ...
+ self.assertEqual(gth(foo), {'return': TypeGuard[int]})
+
+ def test_repr(self):
+ if hasattr(typing, 'TypeGuard'):
+ mod_name = 'typing'
+ else:
+ mod_name = 'typing_extensions'
+ self.assertEqual(repr(TypeGuard), '{}.TypeGuard'.format(mod_name))
+ cv = TypeGuard[int]
+ self.assertEqual(repr(cv), '{}.TypeGuard[int]'.format(mod_name))
+ cv = TypeGuard[Employee]
+ self.assertEqual(repr(cv),
'{}.TypeGuard[{}.Employee]'.format(mod_name, __name__))
+ cv = TypeGuard[Tuple[int]]
+ self.assertEqual(repr(cv),
'{}.TypeGuard[typing.Tuple[int]]'.format(mod_name))
+
+ @skipUnless(SUBCLASS_CHECK_FORBIDDEN, "Behavior added in typing 3.5.3")
+ def test_cannot_subclass(self):
+ with self.assertRaises(TypeError):
+ class C(type(TypeGuard)):
+ pass
+ with self.assertRaises(TypeError):
+ class C(type(TypeGuard[int])):
+ pass
+
+ def test_cannot_init(self):
+ with self.assertRaises(TypeError):
+ TypeGuard()
+ with self.assertRaises(TypeError):
+ type(TypeGuard)()
+ with self.assertRaises(TypeError):
+ type(TypeGuard[Optional[int]])()
+
+ def test_no_isinstance(self):
+ with self.assertRaises(TypeError):
+ isinstance(1, TypeGuard[int])
+ with self.assertRaises(TypeError):
+ issubclass(int, TypeGuard)
+
class AllTests(BaseTestCase):
@@ -1888,6 +2168,10 @@
self.assertIn('overload', a)
self.assertIn('Text', a)
self.assertIn('TYPE_CHECKING', a)
+ self.assertIn('TypeAlias', a)
+ self.assertIn('ParamSpec', a)
+ self.assertIn("Concatenate", a)
+
if TYPING_3_5_3:
self.assertIn('Annotated', a)
if PEP_560:
@@ -1916,7 +2200,7 @@
'Final',
'get_type_hints'
}
- if sys.version_info[:2] == (3, 8):
+ if sys.version_info < (3, 10):
exclude |= {'get_args', 'get_origin'}
for item in typing_extensions.__all__:
if item not in exclude and hasattr(typing, item):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/typing_extensions-3.7.4.3/src_py3/typing_extensions.egg-info/PKG-INFO
new/typing_extensions-3.10.0.0/src_py3/typing_extensions.egg-info/PKG-INFO
--- old/typing_extensions-3.7.4.3/src_py3/typing_extensions.egg-info/PKG-INFO
2020-08-23 18:33:40.000000000 +0200
+++ new/typing_extensions-3.10.0.0/src_py3/typing_extensions.egg-info/PKG-INFO
1970-01-01 01:00:00.000000000 +0100
@@ -1,40 +0,0 @@
-Metadata-Version: 1.1
-Name: typing-extensions
-Version: 3.7.4.3
-Summary: Backported and Experimental Type Hints for Python 3.5+
-Home-page:
https://github.com/python/typing/blob/master/typing_extensions/README.rst
-Author: Guido van Rossum, Jukka Lehtosalo, Lukasz Langa, Michael Lee
-Author-email: [email protected]
-License: PSF
-Description: Typing Extensions -- Backported and Experimental Type Hints for
Python
-
- The ``typing`` module was added to the standard library in Python 3.5
on
- a provisional basis and will no longer be provisional in Python 3.7.
However,
- this means users of Python 3.5 - 3.6 who are unable to upgrade will
not be
- able to take advantage of new types added to the ``typing`` module,
such as
- ``typing.Text`` or ``typing.Coroutine``.
-
- The ``typing_extensions`` module contains both backports of these
changes
- as well as experimental types that will eventually be added to the
``typing``
- module, such as ``Protocol`` or ``TypedDict``.
-
- Users of other Python versions should continue to install and use
- the ``typing`` module from PyPi instead of using this one unless
specifically
- writing code that must be compatible with multiple Python versions or
requires
- experimental types.
-
-Keywords: typing function annotations type hints hinting checking checker
typehints typehinting typechecking backport
-Platform: UNKNOWN
-Classifier: Development Status :: 3 - Alpha
-Classifier: Environment :: Console
-Classifier: Intended Audience :: Developers
-Classifier: License :: OSI Approved :: Python Software Foundation License
-Classifier: Operating System :: OS Independent
-Classifier: Programming Language :: Python :: 2.7
-Classifier: Programming Language :: Python :: 3.4
-Classifier: Programming Language :: Python :: 3.5
-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: Topic :: Software Development
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/typing_extensions-3.7.4.3/src_py3/typing_extensions.egg-info/SOURCES.txt
new/typing_extensions-3.10.0.0/src_py3/typing_extensions.egg-info/SOURCES.txt
---
old/typing_extensions-3.7.4.3/src_py3/typing_extensions.egg-info/SOURCES.txt
2020-08-23 18:33:40.000000000 +0200
+++
new/typing_extensions-3.10.0.0/src_py3/typing_extensions.egg-info/SOURCES.txt
1970-01-01 01:00:00.000000000 +0100
@@ -1,14 +0,0 @@
-LICENSE
-MANIFEST.in
-README.rst
-setup.cfg
-setup.py
-src_py2/test_typing_extensions.py
-src_py2/typing_extensions.py
-src_py3/test_typing_extensions.py
-src_py3/typing_extensions.py
-src_py3/typing_extensions.egg-info/PKG-INFO
-src_py3/typing_extensions.egg-info/SOURCES.txt
-src_py3/typing_extensions.egg-info/dependency_links.txt
-src_py3/typing_extensions.egg-info/requires.txt
-src_py3/typing_extensions.egg-info/top_level.txt
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/typing_extensions-3.7.4.3/src_py3/typing_extensions.egg-info/dependency_links.txt
new/typing_extensions-3.10.0.0/src_py3/typing_extensions.egg-info/dependency_links.txt
---
old/typing_extensions-3.7.4.3/src_py3/typing_extensions.egg-info/dependency_links.txt
2020-08-23 18:33:40.000000000 +0200
+++
new/typing_extensions-3.10.0.0/src_py3/typing_extensions.egg-info/dependency_links.txt
1970-01-01 01:00:00.000000000 +0100
@@ -1 +0,0 @@
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/typing_extensions-3.7.4.3/src_py3/typing_extensions.egg-info/requires.txt
new/typing_extensions-3.10.0.0/src_py3/typing_extensions.egg-info/requires.txt
---
old/typing_extensions-3.7.4.3/src_py3/typing_extensions.egg-info/requires.txt
2020-08-23 18:33:40.000000000 +0200
+++
new/typing_extensions-3.10.0.0/src_py3/typing_extensions.egg-info/requires.txt
1970-01-01 01:00:00.000000000 +0100
@@ -1,3 +0,0 @@
-
-[:python_version < "3.5"]
-typing>=3.7.4
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/typing_extensions-3.7.4.3/src_py3/typing_extensions.egg-info/top_level.txt
new/typing_extensions-3.10.0.0/src_py3/typing_extensions.egg-info/top_level.txt
---
old/typing_extensions-3.7.4.3/src_py3/typing_extensions.egg-info/top_level.txt
2020-08-23 18:33:40.000000000 +0200
+++
new/typing_extensions-3.10.0.0/src_py3/typing_extensions.egg-info/top_level.txt
1970-01-01 01:00:00.000000000 +0100
@@ -1 +0,0 @@
-typing_extensions
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/typing_extensions-3.7.4.3/src_py3/typing_extensions.py
new/typing_extensions-3.10.0.0/src_py3/typing_extensions.py
--- old/typing_extensions-3.7.4.3/src_py3/typing_extensions.py 2020-07-08
00:29:25.000000000 +0200
+++ new/typing_extensions-3.10.0.0/src_py3/typing_extensions.py 2021-05-01
19:50:21.000000000 +0200
@@ -115,7 +115,9 @@
__all__ = [
# Super-special typing primitives.
'ClassVar',
+ 'Concatenate',
'Final',
+ 'ParamSpec',
'Type',
# ABCs (from collections.abc).
@@ -134,6 +136,7 @@
'Counter',
'Deque',
'DefaultDict',
+ 'OrderedDict'
'TypedDict',
# Structural checks, a.k.a. protocols.
@@ -146,6 +149,8 @@
'NewType',
'overload',
'Text',
+ 'TypeAlias',
+ 'TypeGuard',
'TYPE_CHECKING',
]
@@ -938,6 +943,34 @@
return _generic_new(collections.defaultdict, cls, *args, **kwds)
+if hasattr(typing, 'OrderedDict'):
+ OrderedDict = typing.OrderedDict
+elif (3, 7, 0) <= sys.version_info[:3] < (3, 7, 2):
+ OrderedDict = typing._alias(collections.OrderedDict, (KT, VT))
+elif _geqv_defined:
+ class OrderedDict(collections.OrderedDict, typing.MutableMapping[KT, VT],
+ metaclass=_ExtensionsGenericMeta,
+ extra=collections.OrderedDict):
+
+ __slots__ = ()
+
+ def __new__(cls, *args, **kwds):
+ if _geqv(cls, OrderedDict):
+ return collections.OrderedDict(*args, **kwds)
+ return _generic_new(collections.OrderedDict, cls, *args, **kwds)
+else:
+ class OrderedDict(collections.OrderedDict, typing.MutableMapping[KT, VT],
+ metaclass=_ExtensionsGenericMeta,
+ extra=collections.OrderedDict):
+
+ __slots__ = ()
+
+ def __new__(cls, *args, **kwds):
+ if cls._gorg is OrderedDict:
+ return collections.OrderedDict(*args, **kwds)
+ return _generic_new(collections.OrderedDict, cls, *args, **kwds)
+
+
if hasattr(typing, 'Counter'):
Counter = typing.Counter
elif (3, 5, 0) <= sys.version_info[:3] <= (3, 5, 1):
@@ -1119,6 +1152,11 @@
if hasattr(typing, 'Protocol'):
Protocol = typing.Protocol
elif HAVE_PROTOCOLS and not PEP_560:
+
+ def _no_init(self, *args, **kwargs):
+ if type(self)._is_protocol:
+ raise TypeError('Protocols cannot be instantiated')
+
class _ProtocolMeta(GenericMeta):
"""Internal metaclass for Protocol.
@@ -1209,9 +1247,6 @@
raise TypeError('Protocols can only inherit from other'
' protocols, got %r' % base)
- def _no_init(self, *args, **kwargs):
- if type(self)._is_protocol:
- raise TypeError('Protocols cannot be instantiated')
cls.__init__ = _no_init
def _proto_hook(other):
@@ -1366,6 +1401,10 @@
elif PEP_560:
from typing import _type_check, _GenericAlias, _collect_type_vars # noqa
+ def _no_init(self, *args, **kwargs):
+ if type(self)._is_protocol:
+ raise TypeError('Protocols cannot be instantiated')
+
class _ProtocolMeta(abc.ABCMeta):
# This metaclass is a bit unfortunate and exists only because of the
lack
# of __instancehook__.
@@ -1542,10 +1581,6 @@
isinstance(base, _ProtocolMeta) and base._is_protocol):
raise TypeError('Protocols can only inherit from other'
' protocols, got %r' % base)
-
- def _no_init(self, *args, **kwargs):
- if type(self)._is_protocol:
- raise TypeError('Protocols cannot be instantiated')
cls.__init__ = _no_init
@@ -1584,9 +1619,11 @@
pass
-if sys.version_info[:2] >= (3, 9):
+if sys.version_info >= (3, 9, 2):
# The standard library TypedDict in Python 3.8 does not store runtime
information
# about which (if any) keys are optional. See
https://bugs.python.org/issue38834
+ # 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
TypedDict = typing.TypedDict
else:
def _check_fails(cls, other):
@@ -1643,19 +1680,24 @@
raise TypeError("TypedDict takes either a dict or keyword
arguments,"
" but not both")
- ns = {'__annotations__': dict(fields), '__total__': total}
+ ns = {'__annotations__': dict(fields)}
try:
# Setting correct module is necessary to make typed dict classes
pickleable.
ns['__module__'] = sys._getframe(1).f_globals.get('__name__',
'__main__')
except (AttributeError, ValueError):
pass
- return _TypedDictMeta(typename, (), ns)
+ return _TypedDictMeta(typename, (), ns, total=total)
_typeddict_new.__text_signature__ = ('($cls, _typename, _fields=None,'
' /, *, total=True, **kwargs)')
class _TypedDictMeta(type):
+ def __init__(cls, name, bases, ns, total=True):
+ # In Python 3.4 and 3.5 the __init__ method also needs to support
the keyword arguments.
+ # See
https://www.python.org/dev/peps/pep-0487/#implementation-details
+ super(_TypedDictMeta, cls).__init__(name, bases, ns)
+
def __new__(cls, name, bases, ns, total=True):
# Create new typed dict class object.
# This method is called directly when TypedDict is subclassed,
@@ -2024,11 +2066,23 @@
# Python 3.8 has get_origin() and get_args() but those implementations aren't
# Annotated-aware, so we can't use those, only Python 3.9 versions will do.
-if sys.version_info[:2] >= (3, 9):
+# Similarly, Python 3.9's implementation doesn't support ParamSpecArgs and
+# ParamSpecKwargs.
+if sys.version_info[:2] >= (3, 10):
get_origin = typing.get_origin
get_args = typing.get_args
elif PEP_560:
- from typing import _GenericAlias # noqa
+ from typing import _GenericAlias
+ try:
+ # 3.9+
+ from typing import _BaseGenericAlias
+ except ImportError:
+ _BaseGenericAlias = _GenericAlias
+ try:
+ # 3.9+
+ from typing import GenericAlias
+ except ImportError:
+ GenericAlias = _GenericAlias
def get_origin(tp):
"""Get the unsubscripted version of a type.
@@ -2043,10 +2097,12 @@
get_origin(Generic[T]) is Generic
get_origin(Union[T, int]) is Union
get_origin(List[Tuple[T, T]][int]) == list
+ get_origin(P.args) is P
"""
if isinstance(tp, _AnnotatedAlias):
return Annotated
- if isinstance(tp, _GenericAlias):
+ if isinstance(tp, (_GenericAlias, GenericAlias, _BaseGenericAlias,
+ ParamSpecArgs, ParamSpecKwargs)):
return tp.__origin__
if tp is Generic:
return Generic
@@ -2065,7 +2121,9 @@
"""
if isinstance(tp, _AnnotatedAlias):
return (tp.__origin__,) + tp.__metadata__
- if isinstance(tp, _GenericAlias):
+ if isinstance(tp, (_GenericAlias, GenericAlias)):
+ if getattr(tp, "_special", False):
+ return ()
res = tp.__args__
if get_origin(tp) is collections.abc.Callable and res[0] is not
Ellipsis:
res = (list(res[:-1]), res[-1])
@@ -2166,3 +2224,582 @@
It's invalid when used anywhere except as in the example above.
"""
__slots__ = ()
+
+
+# Python 3.10+ has PEP 612
+if hasattr(typing, 'ParamSpecArgs'):
+ ParamSpecArgs = typing.ParamSpecArgs
+ ParamSpecKwargs = typing.ParamSpecKwargs
+else:
+ class _Immutable:
+ """Mixin to indicate that object should not be copied."""
+ __slots__ = ()
+
+ def __copy__(self):
+ return self
+
+ def __deepcopy__(self, memo):
+ return self
+
+ class ParamSpecArgs(_Immutable):
+ """The args for a ParamSpec object.
+
+ Given a ParamSpec object P, P.args is an instance of ParamSpecArgs.
+
+ ParamSpecArgs objects have a reference back to their ParamSpec:
+
+ P.args.__origin__ is P
+
+ This type is meant for runtime introspection and has no special
meaning to
+ static type checkers.
+ """
+ def __init__(self, origin):
+ self.__origin__ = origin
+
+ def __repr__(self):
+ return "{}.args".format(self.__origin__.__name__)
+
+ class ParamSpecKwargs(_Immutable):
+ """The kwargs for a ParamSpec object.
+
+ Given a ParamSpec object P, P.kwargs is an instance of ParamSpecKwargs.
+
+ ParamSpecKwargs objects have a reference back to their ParamSpec:
+
+ P.kwargs.__origin__ is P
+
+ This type is meant for runtime introspection and has no special
meaning to
+ static type checkers.
+ """
+ def __init__(self, origin):
+ self.__origin__ = origin
+
+ def __repr__(self):
+ return "{}.kwargs".format(self.__origin__.__name__)
+
+if hasattr(typing, 'ParamSpec'):
+ ParamSpec = typing.ParamSpec
+else:
+
+ # Inherits from list as a workaround for Callable checks in Python < 3.9.2.
+ class ParamSpec(list):
+ """Parameter specification variable.
+
+ Usage::
+
+ P = ParamSpec('P')
+
+ Parameter specification variables exist primarily for the benefit of
static
+ type checkers. They are used to forward the parameter types of one
+ callable to another callable, a pattern commonly found in higher order
+ functions and decorators. They are only valid when used in
``Concatenate``,
+ or s the first argument to ``Callable``. In Python 3.10 and higher,
+ they are also supported in user-defined Generics at runtime.
+ See class Generic for more information on generic types. An
+ example for annotating a decorator::
+
+ T = TypeVar('T')
+ P = ParamSpec('P')
+
+ def add_logging(f: Callable[P, T]) -> Callable[P, T]:
+ '''A type-safe decorator to add logging to a function.'''
+ def inner(*args: P.args, **kwargs: P.kwargs) -> T:
+ logging.info(f'{f.__name__} was called')
+ return f(*args, **kwargs)
+ return inner
+
+ @add_logging
+ def add_two(x: float, y: float) -> float:
+ '''Add two numbers together.'''
+ return x + y
+
+ Parameter specification variables defined with covariant=True or
+ contravariant=True can be used to declare covariant or contravariant
+ generic types. These keyword arguments are valid, but their actual
semantics
+ are yet to be decided. See PEP 612 for details.
+
+ Parameter specification variables can be introspected. e.g.:
+
+ P.__name__ == 'T'
+ P.__bound__ == None
+ P.__covariant__ == False
+ P.__contravariant__ == False
+
+ Note that only parameter specification variables defined in global
scope can
+ be pickled.
+ """
+
+ @property
+ def args(self):
+ return ParamSpecArgs(self)
+
+ @property
+ def kwargs(self):
+ return ParamSpecKwargs(self)
+
+ def __init__(self, name, *, bound=None, covariant=False,
contravariant=False):
+ super().__init__([self])
+ self.__name__ = name
+ self.__covariant__ = bool(covariant)
+ self.__contravariant__ = bool(contravariant)
+ if bound:
+ self.__bound__ = typing._type_check(bound, 'Bound must be a
type.')
+ else:
+ self.__bound__ = None
+
+ # for pickling:
+ try:
+ def_mod = sys._getframe(1).f_globals.get('__name__',
'__main__')
+ except (AttributeError, ValueError):
+ def_mod = None
+ if def_mod != 'typing_extensions':
+ self.__module__ = def_mod
+
+ def __repr__(self):
+ if self.__covariant__:
+ prefix = '+'
+ elif self.__contravariant__:
+ prefix = '-'
+ else:
+ prefix = '~'
+ return prefix + self.__name__
+
+ def __hash__(self):
+ return object.__hash__(self)
+
+ def __eq__(self, other):
+ return self is other
+
+ def __reduce__(self):
+ return self.__name__
+
+ # Hack to get typing._type_check to pass.
+ def __call__(self, *args, **kwargs):
+ pass
+
+ # Note: Can't fake ParamSpec as a TypeVar to get it to work
+ # with Generics. ParamSpec isn't an instance of TypeVar in 3.10.
+ # So encouraging code like isinstance(ParamSpec('P'), TypeVar))
+ # will lead to breakage in 3.10.
+ # This also means no accurate __parameters__ for GenericAliases.
+
+# Inherits from list as a workaround for Callable checks in Python < 3.9.2.
+class _ConcatenateGenericAlias(list):
+ def __init__(self, origin, args):
+ super().__init__(args)
+ self.__origin__ = origin
+ self.__args__ = args
+
+ def __repr__(self):
+ _type_repr = typing._type_repr
+ return '{origin}[{args}]' \
+ .format(origin=_type_repr(self.__origin__),
+ args=', '.join(_type_repr(arg) for arg in
self.__args__))
+
+ def __hash__(self):
+ return hash((self.__origin__, self.__args__))
+
+@_tp_cache
+def _concatenate_getitem(self, parameters):
+ if parameters == ():
+ raise TypeError("Cannot take a Concatenate of no types.")
+ if not isinstance(parameters, tuple):
+ parameters = (parameters,)
+ if not isinstance(parameters[-1], ParamSpec):
+ raise TypeError("The last parameter to Concatenate should be a "
+ "ParamSpec variable.")
+ msg = "Concatenate[arg, ...]: each arg must be a type."
+ parameters = tuple(typing._type_check(p, msg) for p in parameters)
+ return _ConcatenateGenericAlias(self, parameters)
+
+
+if hasattr(typing, 'Concatenate'):
+ Concatenate = typing.Concatenate
+ _ConcatenateGenericAlias = typing._ConcatenateGenericAlias # noqa
+elif sys.version_info[:2] >= (3, 9):
+ @_TypeAliasForm
+ def Concatenate(self, parameters):
+ """Used in conjunction with ``ParamSpec`` and ``Callable`` to
represent a
+ higher order function which adds, removes or transforms parameters of a
+ callable.
+
+ For example::
+
+ Callable[Concatenate[int, P], int]
+
+ See PEP 612 for detailed information.
+ """
+ return _concatenate_getitem(self, parameters)
+
+elif sys.version_info[:2] >= (3, 7):
+ class _ConcatenateForm(typing._SpecialForm, _root=True):
+ def __repr__(self):
+ return 'typing_extensions.' + self._name
+
+ def __getitem__(self, parameters):
+ return _concatenate_getitem(self, parameters)
+
+ Concatenate = _ConcatenateForm('Concatenate',
+ doc="""Used in conjunction with ``ParamSpec`` and ``Callable`` to
represent a
+ higher order function which adds, removes or transforms parameters of a
+ callable.
+
+ For example::
+
+ Callable[Concatenate[int, P], int]
+
+ See PEP 612 for detailed information.
+ """)
+
+elif hasattr(typing, '_FinalTypingBase'):
+ class _ConcatenateAliasMeta(typing.TypingMeta):
+ """Metaclass for Concatenate."""
+
+ def __repr__(self):
+ return 'typing_extensions.Concatenate'
+
+ class _ConcatenateAliasBase(typing._FinalTypingBase,
+ metaclass=_ConcatenateAliasMeta,
+ _root=True):
+ """Used in conjunction with ``ParamSpec`` and ``Callable`` to
represent a
+ higher order function which adds, removes or transforms parameters of a
+ callable.
+
+ For example::
+
+ Callable[Concatenate[int, P], int]
+
+ See PEP 612 for detailed information.
+ """
+ __slots__ = ()
+
+ def __instancecheck__(self, obj):
+ raise TypeError("Concatenate cannot be used with isinstance().")
+
+ def __subclasscheck__(self, cls):
+ raise TypeError("Concatenate cannot be used with issubclass().")
+
+ def __repr__(self):
+ return 'typing_extensions.Concatenate'
+
+ def __getitem__(self, parameters):
+ return _concatenate_getitem(self, parameters)
+
+ Concatenate = _ConcatenateAliasBase(_root=True)
+# For 3.5.0 - 3.5.2
+else:
+ class _ConcatenateAliasMeta(typing.TypingMeta):
+ """Metaclass for Concatenate."""
+
+ def __instancecheck__(self, obj):
+ raise TypeError("TypeAlias cannot be used with isinstance().")
+
+ def __subclasscheck__(self, cls):
+ raise TypeError("TypeAlias cannot be used with issubclass().")
+
+ def __call__(self, *args, **kwargs):
+ raise TypeError("Cannot instantiate TypeAlias")
+
+ def __getitem__(self, parameters):
+ return _concatenate_getitem(self, parameters)
+
+ class Concatenate(metaclass=_ConcatenateAliasMeta, _root=True):
+ """Used in conjunction with ``ParamSpec`` and ``Callable`` to
represent a
+ higher order function which adds, removes or transforms parameters of a
+ callable.
+
+ For example::
+
+ Callable[Concatenate[int, P], int]
+
+ See PEP 612 for detailed information.
+ """
+ __slots__ = ()
+
+if hasattr(typing, 'TypeGuard'):
+ TypeGuard = typing.TypeGuard
+elif sys.version_info[:2] >= (3, 9):
+ class _TypeGuardForm(typing._SpecialForm, _root=True):
+ def __repr__(self):
+ return 'typing_extensions.' + self._name
+
+ @_TypeGuardForm
+ def TypeGuard(self, parameters):
+ """Special typing form used to annotate the return type of a
user-defined
+ type guard function. ``TypeGuard`` only accepts a single type
argument.
+ At runtime, functions marked this way should return a boolean.
+
+ ``TypeGuard`` aims to benefit *type narrowing* -- a technique used by
static
+ type checkers to determine a more precise type of an expression within
a
+ program's code flow. Usually type narrowing is done by analyzing
+ conditional code flow and applying the narrowing to a block of code.
The
+ conditional expression here is sometimes referred to as a "type guard".
+
+ Sometimes it would be convenient to use a user-defined boolean function
+ as a type guard. Such a function should use ``TypeGuard[...]`` as its
+ return type to alert static type checkers to this intention.
+
+ Using ``-> TypeGuard`` tells the static type checker that for a given
+ function:
+
+ 1. The return value is a boolean.
+ 2. If the return value is ``True``, the type of its argument
+ is the type inside ``TypeGuard``.
+
+ For example::
+
+ def is_str(val: Union[str, float]):
+ # "isinstance" type guard
+ if isinstance(val, str):
+ # Type of ``val`` is narrowed to ``str``
+ ...
+ else:
+ # Else, type of ``val`` is narrowed to ``float``.
+ ...
+
+ Strict type narrowing is not enforced -- ``TypeB`` need not be a
narrower
+ form of ``TypeA`` (it can even be a wider form) and this may lead to
+ type-unsafe results. The main reason is to allow for things like
+ narrowing ``List[object]`` to ``List[str]`` even though the latter is
not
+ a subtype of the former, since ``List`` is invariant. The
responsibility of
+ writing type-safe type guards is left to the user.
+
+ ``TypeGuard`` also works with type variables. For more information,
see
+ PEP 647 (User-Defined Type Guards).
+ """
+ item = typing._type_check(parameters, '{} accepts only single
type.'.format(self))
+ return _GenericAlias(self, (item,))
+
+elif sys.version_info[:2] >= (3, 7):
+ class _TypeGuardForm(typing._SpecialForm, _root=True):
+
+ def __repr__(self):
+ return 'typing_extensions.' + self._name
+
+ def __getitem__(self, parameters):
+ item = typing._type_check(parameters,
+ '{} accepts only a single
type'.format(self._name))
+ return _GenericAlias(self, (item,))
+
+ TypeGuard = _TypeGuardForm(
+ 'TypeGuard',
+ doc="""Special typing form used to annotate the return type of a
user-defined
+ type guard function. ``TypeGuard`` only accepts a single type
argument.
+ At runtime, functions marked this way should return a boolean.
+
+ ``TypeGuard`` aims to benefit *type narrowing* -- a technique used by
static
+ type checkers to determine a more precise type of an expression within
a
+ program's code flow. Usually type narrowing is done by analyzing
+ conditional code flow and applying the narrowing to a block of code.
The
+ conditional expression here is sometimes referred to as a "type guard".
+
+ Sometimes it would be convenient to use a user-defined boolean function
+ as a type guard. Such a function should use ``TypeGuard[...]`` as its
+ return type to alert static type checkers to this intention.
+
+ Using ``-> TypeGuard`` tells the static type checker that for a given
+ function:
+
+ 1. The return value is a boolean.
+ 2. If the return value is ``True``, the type of its argument
+ is the type inside ``TypeGuard``.
+
+ For example::
+
+ def is_str(val: Union[str, float]):
+ # "isinstance" type guard
+ if isinstance(val, str):
+ # Type of ``val`` is narrowed to ``str``
+ ...
+ else:
+ # Else, type of ``val`` is narrowed to ``float``.
+ ...
+
+ Strict type narrowing is not enforced -- ``TypeB`` need not be a
narrower
+ form of ``TypeA`` (it can even be a wider form) and this may lead to
+ type-unsafe results. The main reason is to allow for things like
+ narrowing ``List[object]`` to ``List[str]`` even though the latter is
not
+ a subtype of the former, since ``List`` is invariant. The
responsibility of
+ writing type-safe type guards is left to the user.
+
+ ``TypeGuard`` also works with type variables. For more information,
see
+ PEP 647 (User-Defined Type Guards).
+ """)
+elif hasattr(typing, '_FinalTypingBase'):
+ class _TypeGuard(typing._FinalTypingBase, _root=True):
+ """Special typing form used to annotate the return type of a
user-defined
+ type guard function. ``TypeGuard`` only accepts a single type
argument.
+ At runtime, functions marked this way should return a boolean.
+
+ ``TypeGuard`` aims to benefit *type narrowing* -- a technique used by
static
+ type checkers to determine a more precise type of an expression within
a
+ program's code flow. Usually type narrowing is done by analyzing
+ conditional code flow and applying the narrowing to a block of code.
The
+ conditional expression here is sometimes referred to as a "type guard".
+
+ Sometimes it would be convenient to use a user-defined boolean function
+ as a type guard. Such a function should use ``TypeGuard[...]`` as its
+ return type to alert static type checkers to this intention.
+
+ Using ``-> TypeGuard`` tells the static type checker that for a given
+ function:
+
+ 1. The return value is a boolean.
+ 2. If the return value is ``True``, the type of its argument
+ is the type inside ``TypeGuard``.
+
+ For example::
+
+ def is_str(val: Union[str, float]):
+ # "isinstance" type guard
+ if isinstance(val, str):
+ # Type of ``val`` is narrowed to ``str``
+ ...
+ else:
+ # Else, type of ``val`` is narrowed to ``float``.
+ ...
+
+ Strict type narrowing is not enforced -- ``TypeB`` need not be a
narrower
+ form of ``TypeA`` (it can even be a wider form) and this may lead to
+ type-unsafe results. The main reason is to allow for things like
+ narrowing ``List[object]`` to ``List[str]`` even though the latter is
not
+ a subtype of the former, since ``List`` is invariant. The
responsibility of
+ writing type-safe type guards is left to the user.
+
+ ``TypeGuard`` also works with type variables. For more information,
see
+ PEP 647 (User-Defined Type Guards).
+ """
+
+ __slots__ = ('__type__',)
+
+ def __init__(self, tp=None, **kwds):
+ self.__type__ = tp
+
+ def __getitem__(self, item):
+ cls = type(self)
+ if self.__type__ is None:
+ return cls(typing._type_check(item,
+ '{} accepts only a single
type.'.format(cls.__name__[1:])),
+ _root=True)
+ raise TypeError('{} cannot be further subscripted'
+ .format(cls.__name__[1:]))
+
+ def _eval_type(self, globalns, localns):
+ new_tp = typing._eval_type(self.__type__, globalns, localns)
+ if new_tp == self.__type__:
+ return self
+ return type(self)(new_tp, _root=True)
+
+ def __repr__(self):
+ r = super().__repr__()
+ if self.__type__ is not None:
+ r += '[{}]'.format(typing._type_repr(self.__type__))
+ return r
+
+ def __hash__(self):
+ return hash((type(self).__name__, self.__type__))
+
+ def __eq__(self, other):
+ if not isinstance(other, _TypeGuard):
+ return NotImplemented
+ if self.__type__ is not None:
+ return self.__type__ == other.__type__
+ return self is other
+
+ TypeGuard = _TypeGuard(_root=True)
+else:
+ class _TypeGuardMeta(typing.TypingMeta):
+ """Metaclass for TypeGuard"""
+
+ def __new__(cls, name, bases, namespace, tp=None, _root=False):
+ self = super().__new__(cls, name, bases, namespace, _root=_root)
+ if tp is not None:
+ self.__type__ = tp
+ return self
+
+ def __instancecheck__(self, obj):
+ raise TypeError("TypeGuard cannot be used with isinstance().")
+
+ def __subclasscheck__(self, cls):
+ raise TypeError("TypeGuard cannot be used with issubclass().")
+
+ def __getitem__(self, item):
+ cls = type(self)
+ if self.__type__ is not None:
+ raise TypeError('{} cannot be further subscripted'
+ .format(cls.__name__[1:]))
+
+ param = typing._type_check(
+ item,
+ '{} accepts only single type.'.format(cls.__name__[1:]))
+ return cls(self.__name__, self.__bases__,
+ dict(self.__dict__), tp=param, _root=True)
+
+ def _eval_type(self, globalns, localns):
+ new_tp = typing._eval_type(self.__type__, globalns, localns)
+ if new_tp == self.__type__:
+ return self
+ return type(self)(self.__name__, self.__bases__,
+ dict(self.__dict__), tp=self.__type__,
+ _root=True)
+
+ def __repr__(self):
+ r = super().__repr__()
+ if self.__type__ is not None:
+ r += '[{}]'.format(typing._type_repr(self.__type__))
+ return r
+
+ def __hash__(self):
+ return hash((type(self).__name__, self.__type__))
+
+ def __eq__(self, other):
+ if not hasattr(other, "__type__"):
+ return NotImplemented
+ if self.__type__ is not None:
+ return self.__type__ == other.__type__
+ return self is other
+
+ class TypeGuard(typing.Final, metaclass=_TypeGuardMeta, _root=True):
+ """Special typing form used to annotate the return type of a
user-defined
+ type guard function. ``TypeGuard`` only accepts a single type
argument.
+ At runtime, functions marked this way should return a boolean.
+
+ ``TypeGuard`` aims to benefit *type narrowing* -- a technique used by
static
+ type checkers to determine a more precise type of an expression within
a
+ program's code flow. Usually type narrowing is done by analyzing
+ conditional code flow and applying the narrowing to a block of code.
The
+ conditional expression here is sometimes referred to as a "type guard".
+
+ Sometimes it would be convenient to use a user-defined boolean function
+ as a type guard. Such a function should use ``TypeGuard[...]`` as its
+ return type to alert static type checkers to this intention.
+
+ Using ``-> TypeGuard`` tells the static type checker that for a given
+ function:
+
+ 1. The return value is a boolean.
+ 2. If the return value is ``True``, the type of its argument
+ is the type inside ``TypeGuard``.
+
+ For example::
+
+ def is_str(val: Union[str, float]):
+ # "isinstance" type guard
+ if isinstance(val, str):
+ # Type of ``val`` is narrowed to ``str``
+ ...
+ else:
+ # Else, type of ``val`` is narrowed to ``float``.
+ ...
+
+ Strict type narrowing is not enforced -- ``TypeB`` need not be a
narrower
+ form of ``TypeA`` (it can even be a wider form) and this may lead to
+ type-unsafe results. The main reason is to allow for things like
+ narrowing ``List[object]`` to ``List[str]`` even though the latter is
not
+ a subtype of the former, since ``List`` is invariant. The
responsibility of
+ writing type-safe type guards is left to the user.
+
+ ``TypeGuard`` also works with type variables. For more information,
see
+ PEP 647 (User-Defined Type Guards).
+ """
+ __type__ = None