Snap for 8451885 from ebe8664570bacfa7ef742249c351e0db32ac3ac2 to tm-d1-release

Change-Id: If0e4261fa634bc62b2c7e455403dc1b9ab5b33fb
diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..26fb670
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,12 @@
+root = true
+
+[*.{py,pyi,rst,md,yml,yaml,toml,json}]
+trim_trailing_whitespace = true
+insert_final_newline = true
+indent_style = space
+
+[*.{py,pyi,toml,json}]
+indent_size = 4
+
+[*.{yml,yaml}]
+indent_size = 2
diff --git a/.flake8 b/.flake8
new file mode 100644
index 0000000..53cf55a
--- /dev/null
+++ b/.flake8
@@ -0,0 +1,15 @@
+[flake8]
+
+max-line-length = 90
+ignore =
+  # irrelevant plugins
+  B3,
+  DW12,
+  # code is sometimes better without this
+  E129,
+  # consistency with mypy
+  W504
+exclude =
+  # tests have more relaxed formatting rules
+  # and its own specific config in .flake8-tests
+  typing_extensions/src/test_typing_extensions.py,
diff --git a/.flake8-tests b/.flake8-tests
new file mode 100644
index 0000000..5a97fe8
--- /dev/null
+++ b/.flake8-tests
@@ -0,0 +1,28 @@
+# This configuration is specific to test_*.py; you need to invoke it
+# by specifically naming this config, like this:
+#
+# $ flake8 --config=.flake8-tests [SOURCES]
+#
+# This will be possibly merged in the future.
+
+[flake8]
+max-line-length = 100
+ignore =
+  # temporary ignores until we sort it out
+  B017,
+  E302,
+  E303,
+  E306,
+  E501,
+  E701,
+  E704,
+  F722,
+  F811,
+  F821,
+  F841,
+  W503,
+  # irrelevant plugins
+  B3,
+  DW12,
+  # consistency with mypy
+  W504
diff --git a/.github/ISSUE_TEMPLATE/documentation-issue.md b/.github/ISSUE_TEMPLATE/documentation-issue.md
new file mode 100644
index 0000000..6122c8f
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/documentation-issue.md
@@ -0,0 +1,10 @@
+---
+name: Documentation issue
+about: Report a problem or suggest changes for the documentation at https://typing.readthedocs.io/
+title: ''
+labels: 'topic: documentation'
+assignees: ''
+
+---
+
+<!-- Please describe the problem or your idea or suggestion below. Please include the URL of the page this issue is about, if applicable. -->
diff --git a/.github/ISSUE_TEMPLATE/new-typing-feature.md b/.github/ISSUE_TEMPLATE/new-typing-feature.md
new file mode 100644
index 0000000..733df29
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/new-typing-feature.md
@@ -0,0 +1,10 @@
+---
+name: New typing feature
+about: Suggest a new feature for Python's typing system
+title: ''
+labels: 'topic: feature'
+assignees: ''
+
+---
+
+<!-- Please describe the problem you face as well as your idea below, ideally using examples for both. -->
diff --git a/.github/ISSUE_TEMPLATE/other-issue.md b/.github/ISSUE_TEMPLATE/other-issue.md
new file mode 100644
index 0000000..484282c
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/other-issue.md
@@ -0,0 +1,10 @@
+---
+name: Other issue
+about: Report any other issue
+title: ''
+labels: 'topic: other'
+assignees: ''
+
+---
+
+<!-- Please describe your issue below. -->
diff --git a/.github/ISSUE_TEMPLATE/typing-extensions-issue.md b/.github/ISSUE_TEMPLATE/typing-extensions-issue.md
new file mode 100644
index 0000000..226796e
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/typing-extensions-issue.md
@@ -0,0 +1,10 @@
+---
+name: typing-extensions issue
+about: Report a problem or suggest changes for the typing-extensions library
+title: ''
+labels: 'topic: typing-extensions'
+assignees: ''
+
+---
+
+<!-- Please describe your problem or suggestion below, ideally using code examples. Please state which version of Python and typing-extensions you are using. -->
diff --git a/.github/workflows/build-docs.yml b/.github/workflows/build-docs.yml
new file mode 100644
index 0000000..43711d0
--- /dev/null
+++ b/.github/workflows/build-docs.yml
@@ -0,0 +1,26 @@
+name: Build the documentation
+
+on:
+  pull_request:
+
+permissions:
+  contents: read
+
+jobs:
+  build:
+
+    name: Build documentation
+    runs-on: ubuntu-latest
+
+    steps:
+    - uses: actions/checkout@v2
+    - name: Set up Python
+      uses: actions/setup-python@v2
+      with:
+        python-version: 3.9
+    - name: Install dependencies
+      run: |
+        pip install --upgrade pip
+        pip install -r docs/requirements.txt
+    - name: Build the documentation
+      run: make -C docs html
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 0000000..302b2ca
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,64 @@
+name: Test and lint
+
+on:
+  push:
+  pull_request:
+
+permissions:
+  contents: read
+
+jobs:
+  tests:
+    name: Run tests
+
+    strategy:
+      fail-fast: false
+      matrix:
+        # We try to test on the earliest available bugfix release of each
+        # Python version, because typing sometimes changed between bugfix releases.
+        # For available versions, see:
+        # https://raw.githubusercontent.com/actions/python-versions/main/versions-manifest.json
+        python-version: ["3.7", "3.7.1", "3.8", "3.8.0", "3.9", "3.9.0", "3.10", "3.10.0", "3.11-dev"]
+
+    runs-on: ubuntu-latest
+
+    steps:
+      - uses: actions/checkout@v2
+
+      - name: Set up Python
+        uses: actions/setup-python@v2
+        with:
+          python-version: ${{ matrix.python-version }}
+
+      - name: Test typing_extensions
+        continue-on-error: ${{ matrix.python-version == '3.11-dev' }}
+        run: |
+          # Be wary of running `pip install` here, since it becomes easy for us to
+          # accidentally pick up typing_extensions as installed by a dependency
+          cd typing_extensions/src
+          python -m unittest test_typing_extensions.py
+
+  linting:
+    name: Lint
+
+    runs-on: ubuntu-latest
+
+    steps:
+      - uses: actions/checkout@v2
+      - name: Set up Python 3
+        uses: actions/setup-python@v2
+        with:
+          python-version: 3
+          cache: "pip"
+          cache-dependency-path: "test-requirements.txt"
+
+      - name: Install dependencies
+        run: |
+          pip install --upgrade pip
+          pip install -r test-requirements.txt
+
+      - name: Lint implementation
+        run: flake8
+
+      - name: Lint tests
+        run: flake8 --config=.flake8-tests typing_extensions/src/test_typing_extensions.py
diff --git a/.github/workflows/package.yml b/.github/workflows/package.yml
new file mode 100644
index 0000000..25f9586
--- /dev/null
+++ b/.github/workflows/package.yml
@@ -0,0 +1,71 @@
+name: Test packaging
+
+on:
+  push:
+  pull_request:
+
+permissions:
+  contents: read
+
+jobs:
+  wheel:
+    name: Test wheel install
+    runs-on: ubuntu-latest
+
+    steps:
+      - uses: actions/checkout@v2
+
+      - name: Set up Python
+        uses: actions/setup-python@v2
+        with:
+          python-version: 3
+
+      - name: Install pypa/build
+        run: |
+          # Be wary of running `pip install` here, since it becomes easy for us to
+          # accidentally pick up typing_extensions as installed by a dependency 
+          python -m pip install --upgrade build
+          python -m pip list
+
+      - name: Build and install wheel
+        run: |
+          cd typing_extensions
+          python -m build .
+          export path_to_file=$(find dist -type f -name "typing_extensions-*.whl")
+          echo "::notice::Installing wheel: $path_to_file"
+          pip install -vvv $path_to_file
+          python -m pip list
+
+      - name: Attempt to import typing_extensions
+        run: python -c "import typing_extensions; print(typing_extensions.__all__)"
+
+  sdist:
+    name: Test sdist install
+    runs-on: ubuntu-latest
+
+    steps:
+      - uses: actions/checkout@v2
+
+      - name: Set up Python
+        uses: actions/setup-python@v2
+        with:
+          python-version: 3
+
+      - name: Install pypa/build
+        run: |
+          # Be wary of running `pip install` here, since it becomes easy for us to
+          # accidentally pick up typing_extensions as installed by a dependency 
+          python -m pip install --upgrade build
+          python -m pip list
+
+      - name: Build and install sdist
+        run: |
+          cd typing_extensions
+          python -m build .
+          export path_to_file=$(find dist -type f -name "typing_extensions-*.tar.gz")
+          echo "::notice::Installing sdist: $path_to_file"
+          pip install -vvv $path_to_file
+          python -m pip list
+
+      - name: Attempt to import typing_extensions
+        run: python -c "import typing_extensions; print(typing_extensions.__all__)"
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..0ad58f4
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,17 @@
+MANIFEST
+
+__pycache__/
+build/
+dist/
+tmp/
+venv*/
+
+.cache/
+.idea/
+.tox/
+.venv*/
+.vscode/
+
+*.swp
+*.pyc
+*.egg-info/
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..095e826
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,55 @@
+Code in this repository should follow CPython's style guidelines and
+contributors need to sign the PSF Contributor Agreement.
+
+# typing\_extensions
+
+The `typing_extensions` module provides a way to access new features from the standard
+library `typing` module in older versions of Python. For example, Python 3.10 adds
+`typing.TypeGuard`, but users of older versions of Python can use `typing_extensions` to
+use `TypeGuard` in their code even if they are unable to upgrade to Python 3.10.
+
+If you contribute the runtime implementation of a new `typing` feature to CPython, you
+are encouraged to also implement the feature in `typing_extensions`. Because the runtime
+implementation of much of the infrastructure in the `typing` module has changed over
+time, this may require different code for some older Python versions.
+
+`typing_extensions` may also include experimental features that are not yet part of the
+standard library, so that users can experiment with them before they are added to the
+standard library. Such features should ideally already be specified in a PEP or draft
+PEP.
+
+`typing_extensions` supports Python versions 3.7 and up.
+
+# Versioning scheme
+
+Starting with version 4.0.0, `typing_extensions` uses
+[Semantic Versioning](https://semver.org/). The major version is incremented for all
+backwards-incompatible changes.
+
+# Workflow for PyPI releases
+
+- Ensure that GitHub Actions reports no errors.
+
+- Update the version number in `typing_extensions/pyproject.toml` and in
+  `typing_extensions/CHANGELOG`.
+
+- Make sure your environment is up to date
+
+ - `git checkout master`
+ - `git pull`
+ - `python -m pip install --upgrade build twine`
+
+- Build the source and wheel distributions:
+
+  - `cd typing_extensions`
+  - `rm -rf dist/`
+  - `python -m build .`
+
+- Install the built distributions locally and test (if you were using `tox`, you already
+  tested the source distribution).
+
+- Run `twine upload dist/*`.
+
+- Tag the release. The tag should be just the version number, e.g. `4.1.1`.
+
+- `git push --tags`
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..583f9f6
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,254 @@
+A. HISTORY OF THE SOFTWARE
+==========================
+
+Python was created in the early 1990s by Guido van Rossum at Stichting
+Mathematisch Centrum (CWI, see http://www.cwi.nl) in the Netherlands
+as a successor of a language called ABC.  Guido remains Python's
+principal author, although it includes many contributions from others.
+
+In 1995, Guido continued his work on Python at the Corporation for
+National Research Initiatives (CNRI, see http://www.cnri.reston.va.us)
+in Reston, Virginia where he released several versions of the
+software.
+
+In May 2000, Guido and the Python core development team moved to
+BeOpen.com to form the BeOpen PythonLabs team.  In October of the same
+year, the PythonLabs team moved to Digital Creations (now Zope
+Corporation, see http://www.zope.com).  In 2001, the Python Software
+Foundation (PSF, see http://www.python.org/psf/) was formed, a
+non-profit organization created specifically to own Python-related
+Intellectual Property.  Zope Corporation is a sponsoring member of
+the PSF.
+
+All Python releases are Open Source (see http://www.opensource.org for
+the Open Source Definition).  Historically, most, but not all, Python
+releases have also been GPL-compatible; the table below summarizes
+the various releases.
+
+    Release         Derived     Year        Owner       GPL-
+                    from                                compatible? (1)
+
+    0.9.0 thru 1.2              1991-1995   CWI         yes
+    1.3 thru 1.5.2  1.2         1995-1999   CNRI        yes
+    1.6             1.5.2       2000        CNRI        no
+    2.0             1.6         2000        BeOpen.com  no
+    1.6.1           1.6         2001        CNRI        yes (2)
+    2.1             2.0+1.6.1   2001        PSF         no
+    2.0.1           2.0+1.6.1   2001        PSF         yes
+    2.1.1           2.1+2.0.1   2001        PSF         yes
+    2.1.2           2.1.1       2002        PSF         yes
+    2.1.3           2.1.2       2002        PSF         yes
+    2.2 and above   2.1.1       2001-now    PSF         yes
+
+Footnotes:
+
+(1) GPL-compatible doesn't mean that we're distributing Python under
+    the GPL.  All Python licenses, unlike the GPL, let you distribute
+    a modified version without making your changes open source.  The
+    GPL-compatible licenses make it possible to combine Python with
+    other software that is released under the GPL; the others don't.
+
+(2) According to Richard Stallman, 1.6.1 is not GPL-compatible,
+    because its license has a choice of law clause.  According to
+    CNRI, however, Stallman's lawyer has told CNRI's lawyer that 1.6.1
+    is "not incompatible" with the GPL.
+
+Thanks to the many outside volunteers who have worked under Guido's
+direction to make these releases possible.
+
+
+B. TERMS AND CONDITIONS FOR ACCESSING OR OTHERWISE USING PYTHON
+===============================================================
+
+PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
+--------------------------------------------
+
+1. This LICENSE AGREEMENT is between the Python Software Foundation
+("PSF"), and the Individual or Organization ("Licensee") accessing and
+otherwise using this software ("Python") in source or binary form and
+its associated documentation.
+
+2. Subject to the terms and conditions of this License Agreement, PSF hereby
+grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce,
+analyze, test, perform and/or display publicly, prepare derivative works,
+distribute, and otherwise use Python alone or in any derivative version,
+provided, however, that PSF's License Agreement and PSF's notice of copyright,
+i.e., "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+2011, 2012, 2013, 2014 Python Software Foundation; All Rights Reserved" are
+retained in Python alone or in any derivative version prepared by Licensee.
+
+3. In the event Licensee prepares a derivative work that is based on
+or incorporates Python or any part thereof, and wants to make
+the derivative work available to others as provided herein, then
+Licensee hereby agrees to include in any such work a brief summary of
+the changes made to Python.
+
+4. PSF is making Python available to Licensee on an "AS IS"
+basis.  PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
+IMPLIED.  BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND
+DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
+FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT
+INFRINGE ANY THIRD PARTY RIGHTS.
+
+5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
+FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
+A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON,
+OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
+
+6. This License Agreement will automatically terminate upon a material
+breach of its terms and conditions.
+
+7. Nothing in this License Agreement shall be deemed to create any
+relationship of agency, partnership, or joint venture between PSF and
+Licensee.  This License Agreement does not grant permission to use PSF
+trademarks or trade name in a trademark sense to endorse or promote
+products or services of Licensee, or any third party.
+
+8. By copying, installing or otherwise using Python, Licensee
+agrees to be bound by the terms and conditions of this License
+Agreement.
+
+
+BEOPEN.COM LICENSE AGREEMENT FOR PYTHON 2.0
+-------------------------------------------
+
+BEOPEN PYTHON OPEN SOURCE LICENSE AGREEMENT VERSION 1
+
+1. This LICENSE AGREEMENT is between BeOpen.com ("BeOpen"), having an
+office at 160 Saratoga Avenue, Santa Clara, CA 95051, and the
+Individual or Organization ("Licensee") accessing and otherwise using
+this software in source or binary form and its associated
+documentation ("the Software").
+
+2. Subject to the terms and conditions of this BeOpen Python License
+Agreement, BeOpen hereby grants Licensee a non-exclusive,
+royalty-free, world-wide license to reproduce, analyze, test, perform
+and/or display publicly, prepare derivative works, distribute, and
+otherwise use the Software alone or in any derivative version,
+provided, however, that the BeOpen Python License is retained in the
+Software, alone or in any derivative version prepared by Licensee.
+
+3. BeOpen is making the Software available to Licensee on an "AS IS"
+basis.  BEOPEN MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
+IMPLIED.  BY WAY OF EXAMPLE, BUT NOT LIMITATION, BEOPEN MAKES NO AND
+DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
+FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE WILL NOT
+INFRINGE ANY THIRD PARTY RIGHTS.
+
+4. BEOPEN SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF THE
+SOFTWARE FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS
+AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THE SOFTWARE, OR ANY
+DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
+
+5. This License Agreement will automatically terminate upon a material
+breach of its terms and conditions.
+
+6. This License Agreement shall be governed by and interpreted in all
+respects by the law of the State of California, excluding conflict of
+law provisions.  Nothing in this License Agreement shall be deemed to
+create any relationship of agency, partnership, or joint venture
+between BeOpen and Licensee.  This License Agreement does not grant
+permission to use BeOpen trademarks or trade names in a trademark
+sense to endorse or promote products or services of Licensee, or any
+third party.  As an exception, the "BeOpen Python" logos available at
+http://www.pythonlabs.com/logos.html may be used according to the
+permissions granted on that web page.
+
+7. By copying, installing or otherwise using the software, Licensee
+agrees to be bound by the terms and conditions of this License
+Agreement.
+
+
+CNRI LICENSE AGREEMENT FOR PYTHON 1.6.1
+---------------------------------------
+
+1. This LICENSE AGREEMENT is between the Corporation for National
+Research Initiatives, having an office at 1895 Preston White Drive,
+Reston, VA 20191 ("CNRI"), and the Individual or Organization
+("Licensee") accessing and otherwise using Python 1.6.1 software in
+source or binary form and its associated documentation.
+
+2. Subject to the terms and conditions of this License Agreement, CNRI
+hereby grants Licensee a nonexclusive, royalty-free, world-wide
+license to reproduce, analyze, test, perform and/or display publicly,
+prepare derivative works, distribute, and otherwise use Python 1.6.1
+alone or in any derivative version, provided, however, that CNRI's
+License Agreement and CNRI's notice of copyright, i.e., "Copyright (c)
+1995-2001 Corporation for National Research Initiatives; All Rights
+Reserved" are retained in Python 1.6.1 alone or in any derivative
+version prepared by Licensee.  Alternately, in lieu of CNRI's License
+Agreement, Licensee may substitute the following text (omitting the
+quotes): "Python 1.6.1 is made available subject to the terms and
+conditions in CNRI's License Agreement.  This Agreement together with
+Python 1.6.1 may be located on the Internet using the following
+unique, persistent identifier (known as a handle): 1895.22/1013.  This
+Agreement may also be obtained from a proxy server on the Internet
+using the following URL: http://hdl.handle.net/1895.22/1013".
+
+3. In the event Licensee prepares a derivative work that is based on
+or incorporates Python 1.6.1 or any part thereof, and wants to make
+the derivative work available to others as provided herein, then
+Licensee hereby agrees to include in any such work a brief summary of
+the changes made to Python 1.6.1.
+
+4. CNRI is making Python 1.6.1 available to Licensee on an "AS IS"
+basis.  CNRI MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
+IMPLIED.  BY WAY OF EXAMPLE, BUT NOT LIMITATION, CNRI MAKES NO AND
+DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
+FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 1.6.1 WILL NOT
+INFRINGE ANY THIRD PARTY RIGHTS.
+
+5. CNRI SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
+1.6.1 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
+A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 1.6.1,
+OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
+
+6. This License Agreement will automatically terminate upon a material
+breach of its terms and conditions.
+
+7. This License Agreement shall be governed by the federal
+intellectual property law of the United States, including without
+limitation the federal copyright law, and, to the extent such
+U.S. federal law does not apply, by the law of the Commonwealth of
+Virginia, excluding Virginia's conflict of law provisions.
+Notwithstanding the foregoing, with regard to derivative works based
+on Python 1.6.1 that incorporate non-separable material that was
+previously distributed under the GNU General Public License (GPL), the
+law of the Commonwealth of Virginia shall govern this License
+Agreement only as to issues arising under or with respect to
+Paragraphs 4, 5, and 7 of this License Agreement.  Nothing in this
+License Agreement shall be deemed to create any relationship of
+agency, partnership, or joint venture between CNRI and Licensee.  This
+License Agreement does not grant permission to use CNRI trademarks or
+trade name in a trademark sense to endorse or promote products or
+services of Licensee, or any third party.
+
+8. By clicking on the "ACCEPT" button where indicated, or by copying,
+installing or otherwise using Python 1.6.1, Licensee agrees to be
+bound by the terms and conditions of this License Agreement.
+
+        ACCEPT
+
+
+CWI LICENSE AGREEMENT FOR PYTHON 0.9.0 THROUGH 1.2
+--------------------------------------------------
+
+Copyright (c) 1991 - 1995, Stichting Mathematisch Centrum Amsterdam,
+The Netherlands.  All rights reserved.
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Stichting Mathematisch
+Centrum or CWI not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
+THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
+FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
diff --git a/METADATA b/METADATA
new file mode 100644
index 0000000..aae60ef
--- /dev/null
+++ b/METADATA
@@ -0,0 +1,16 @@
+name: "typing"
+description:
+    "Static Typing for Python"
+third_party {
+  url {
+    type: HOMEPAGE
+    value: "https://github.com/python/typing"
+  }
+  url {
+    type: GIT
+    value: "https://github.com/python/typing"
+  }
+  version: "4.1.1"
+  last_upgrade_date { year: 2022 month: 4 day: 13 }
+  license_type: NOTICE
+}
diff --git a/MODULE_LICENSE_GPL b/MODULE_LICENSE_GPL
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/MODULE_LICENSE_GPL
diff --git a/NOTICE b/NOTICE
new file mode 100644
index 0000000..583f9f6
--- /dev/null
+++ b/NOTICE
@@ -0,0 +1,254 @@
+A. HISTORY OF THE SOFTWARE
+==========================
+
+Python was created in the early 1990s by Guido van Rossum at Stichting
+Mathematisch Centrum (CWI, see http://www.cwi.nl) in the Netherlands
+as a successor of a language called ABC.  Guido remains Python's
+principal author, although it includes many contributions from others.
+
+In 1995, Guido continued his work on Python at the Corporation for
+National Research Initiatives (CNRI, see http://www.cnri.reston.va.us)
+in Reston, Virginia where he released several versions of the
+software.
+
+In May 2000, Guido and the Python core development team moved to
+BeOpen.com to form the BeOpen PythonLabs team.  In October of the same
+year, the PythonLabs team moved to Digital Creations (now Zope
+Corporation, see http://www.zope.com).  In 2001, the Python Software
+Foundation (PSF, see http://www.python.org/psf/) was formed, a
+non-profit organization created specifically to own Python-related
+Intellectual Property.  Zope Corporation is a sponsoring member of
+the PSF.
+
+All Python releases are Open Source (see http://www.opensource.org for
+the Open Source Definition).  Historically, most, but not all, Python
+releases have also been GPL-compatible; the table below summarizes
+the various releases.
+
+    Release         Derived     Year        Owner       GPL-
+                    from                                compatible? (1)
+
+    0.9.0 thru 1.2              1991-1995   CWI         yes
+    1.3 thru 1.5.2  1.2         1995-1999   CNRI        yes
+    1.6             1.5.2       2000        CNRI        no
+    2.0             1.6         2000        BeOpen.com  no
+    1.6.1           1.6         2001        CNRI        yes (2)
+    2.1             2.0+1.6.1   2001        PSF         no
+    2.0.1           2.0+1.6.1   2001        PSF         yes
+    2.1.1           2.1+2.0.1   2001        PSF         yes
+    2.1.2           2.1.1       2002        PSF         yes
+    2.1.3           2.1.2       2002        PSF         yes
+    2.2 and above   2.1.1       2001-now    PSF         yes
+
+Footnotes:
+
+(1) GPL-compatible doesn't mean that we're distributing Python under
+    the GPL.  All Python licenses, unlike the GPL, let you distribute
+    a modified version without making your changes open source.  The
+    GPL-compatible licenses make it possible to combine Python with
+    other software that is released under the GPL; the others don't.
+
+(2) According to Richard Stallman, 1.6.1 is not GPL-compatible,
+    because its license has a choice of law clause.  According to
+    CNRI, however, Stallman's lawyer has told CNRI's lawyer that 1.6.1
+    is "not incompatible" with the GPL.
+
+Thanks to the many outside volunteers who have worked under Guido's
+direction to make these releases possible.
+
+
+B. TERMS AND CONDITIONS FOR ACCESSING OR OTHERWISE USING PYTHON
+===============================================================
+
+PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
+--------------------------------------------
+
+1. This LICENSE AGREEMENT is between the Python Software Foundation
+("PSF"), and the Individual or Organization ("Licensee") accessing and
+otherwise using this software ("Python") in source or binary form and
+its associated documentation.
+
+2. Subject to the terms and conditions of this License Agreement, PSF hereby
+grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce,
+analyze, test, perform and/or display publicly, prepare derivative works,
+distribute, and otherwise use Python alone or in any derivative version,
+provided, however, that PSF's License Agreement and PSF's notice of copyright,
+i.e., "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+2011, 2012, 2013, 2014 Python Software Foundation; All Rights Reserved" are
+retained in Python alone or in any derivative version prepared by Licensee.
+
+3. In the event Licensee prepares a derivative work that is based on
+or incorporates Python or any part thereof, and wants to make
+the derivative work available to others as provided herein, then
+Licensee hereby agrees to include in any such work a brief summary of
+the changes made to Python.
+
+4. PSF is making Python available to Licensee on an "AS IS"
+basis.  PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
+IMPLIED.  BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND
+DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
+FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT
+INFRINGE ANY THIRD PARTY RIGHTS.
+
+5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
+FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
+A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON,
+OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
+
+6. This License Agreement will automatically terminate upon a material
+breach of its terms and conditions.
+
+7. Nothing in this License Agreement shall be deemed to create any
+relationship of agency, partnership, or joint venture between PSF and
+Licensee.  This License Agreement does not grant permission to use PSF
+trademarks or trade name in a trademark sense to endorse or promote
+products or services of Licensee, or any third party.
+
+8. By copying, installing or otherwise using Python, Licensee
+agrees to be bound by the terms and conditions of this License
+Agreement.
+
+
+BEOPEN.COM LICENSE AGREEMENT FOR PYTHON 2.0
+-------------------------------------------
+
+BEOPEN PYTHON OPEN SOURCE LICENSE AGREEMENT VERSION 1
+
+1. This LICENSE AGREEMENT is between BeOpen.com ("BeOpen"), having an
+office at 160 Saratoga Avenue, Santa Clara, CA 95051, and the
+Individual or Organization ("Licensee") accessing and otherwise using
+this software in source or binary form and its associated
+documentation ("the Software").
+
+2. Subject to the terms and conditions of this BeOpen Python License
+Agreement, BeOpen hereby grants Licensee a non-exclusive,
+royalty-free, world-wide license to reproduce, analyze, test, perform
+and/or display publicly, prepare derivative works, distribute, and
+otherwise use the Software alone or in any derivative version,
+provided, however, that the BeOpen Python License is retained in the
+Software, alone or in any derivative version prepared by Licensee.
+
+3. BeOpen is making the Software available to Licensee on an "AS IS"
+basis.  BEOPEN MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
+IMPLIED.  BY WAY OF EXAMPLE, BUT NOT LIMITATION, BEOPEN MAKES NO AND
+DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
+FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE WILL NOT
+INFRINGE ANY THIRD PARTY RIGHTS.
+
+4. BEOPEN SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF THE
+SOFTWARE FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS
+AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THE SOFTWARE, OR ANY
+DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
+
+5. This License Agreement will automatically terminate upon a material
+breach of its terms and conditions.
+
+6. This License Agreement shall be governed by and interpreted in all
+respects by the law of the State of California, excluding conflict of
+law provisions.  Nothing in this License Agreement shall be deemed to
+create any relationship of agency, partnership, or joint venture
+between BeOpen and Licensee.  This License Agreement does not grant
+permission to use BeOpen trademarks or trade names in a trademark
+sense to endorse or promote products or services of Licensee, or any
+third party.  As an exception, the "BeOpen Python" logos available at
+http://www.pythonlabs.com/logos.html may be used according to the
+permissions granted on that web page.
+
+7. By copying, installing or otherwise using the software, Licensee
+agrees to be bound by the terms and conditions of this License
+Agreement.
+
+
+CNRI LICENSE AGREEMENT FOR PYTHON 1.6.1
+---------------------------------------
+
+1. This LICENSE AGREEMENT is between the Corporation for National
+Research Initiatives, having an office at 1895 Preston White Drive,
+Reston, VA 20191 ("CNRI"), and the Individual or Organization
+("Licensee") accessing and otherwise using Python 1.6.1 software in
+source or binary form and its associated documentation.
+
+2. Subject to the terms and conditions of this License Agreement, CNRI
+hereby grants Licensee a nonexclusive, royalty-free, world-wide
+license to reproduce, analyze, test, perform and/or display publicly,
+prepare derivative works, distribute, and otherwise use Python 1.6.1
+alone or in any derivative version, provided, however, that CNRI's
+License Agreement and CNRI's notice of copyright, i.e., "Copyright (c)
+1995-2001 Corporation for National Research Initiatives; All Rights
+Reserved" are retained in Python 1.6.1 alone or in any derivative
+version prepared by Licensee.  Alternately, in lieu of CNRI's License
+Agreement, Licensee may substitute the following text (omitting the
+quotes): "Python 1.6.1 is made available subject to the terms and
+conditions in CNRI's License Agreement.  This Agreement together with
+Python 1.6.1 may be located on the Internet using the following
+unique, persistent identifier (known as a handle): 1895.22/1013.  This
+Agreement may also be obtained from a proxy server on the Internet
+using the following URL: http://hdl.handle.net/1895.22/1013".
+
+3. In the event Licensee prepares a derivative work that is based on
+or incorporates Python 1.6.1 or any part thereof, and wants to make
+the derivative work available to others as provided herein, then
+Licensee hereby agrees to include in any such work a brief summary of
+the changes made to Python 1.6.1.
+
+4. CNRI is making Python 1.6.1 available to Licensee on an "AS IS"
+basis.  CNRI MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
+IMPLIED.  BY WAY OF EXAMPLE, BUT NOT LIMITATION, CNRI MAKES NO AND
+DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
+FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 1.6.1 WILL NOT
+INFRINGE ANY THIRD PARTY RIGHTS.
+
+5. CNRI SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
+1.6.1 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
+A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 1.6.1,
+OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
+
+6. This License Agreement will automatically terminate upon a material
+breach of its terms and conditions.
+
+7. This License Agreement shall be governed by the federal
+intellectual property law of the United States, including without
+limitation the federal copyright law, and, to the extent such
+U.S. federal law does not apply, by the law of the Commonwealth of
+Virginia, excluding Virginia's conflict of law provisions.
+Notwithstanding the foregoing, with regard to derivative works based
+on Python 1.6.1 that incorporate non-separable material that was
+previously distributed under the GNU General Public License (GPL), the
+law of the Commonwealth of Virginia shall govern this License
+Agreement only as to issues arising under or with respect to
+Paragraphs 4, 5, and 7 of this License Agreement.  Nothing in this
+License Agreement shall be deemed to create any relationship of
+agency, partnership, or joint venture between CNRI and Licensee.  This
+License Agreement does not grant permission to use CNRI trademarks or
+trade name in a trademark sense to endorse or promote products or
+services of Licensee, or any third party.
+
+8. By clicking on the "ACCEPT" button where indicated, or by copying,
+installing or otherwise using Python 1.6.1, Licensee agrees to be
+bound by the terms and conditions of this License Agreement.
+
+        ACCEPT
+
+
+CWI LICENSE AGREEMENT FOR PYTHON 0.9.0 THROUGH 1.2
+--------------------------------------------------
+
+Copyright (c) 1991 - 1995, Stichting Mathematisch Centrum Amsterdam,
+The Netherlands.  All rights reserved.
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Stichting Mathematisch
+Centrum or CWI not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
+THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
+FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
diff --git a/OWNERS b/OWNERS
new file mode 100644
index 0000000..eb86f14
--- /dev/null
+++ b/OWNERS
@@ -0,0 +1,8 @@
+# Android side engprod team
+jdesprez@google.com
+frankfeng@google.com
+murj@google.com
+
+# Mobly team - use for mobly bugs
+angli@google.com
+lancefluger@google.com
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..64b9118
--- /dev/null
+++ b/README.md
@@ -0,0 +1,41 @@
+[![Chat at https://gitter.im/python/typing](https://badges.gitter.im/python/typing.svg)](https://gitter.im/python/typing?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
+
+Static Typing for Python
+========================
+
+Documentation and Support
+-------------------------
+
+The documentation for Python's static typing can be found at
+[typing.readthedocs.io](https://typing.readthedocs.io/). You can get
+help either in our [support forum](https://github.com/python/typing/discussions) or
+chat with us on [Gitter](https://gitter.im/python/typing).
+
+Improvements to the type system should be discussed on the
+[typing-sig](https://mail.python.org/mailman3/lists/typing-sig.python.org/)
+mailing list, although the [issues](https://github.com/python/typing/issues) in this
+repository contain some historic discussions.
+
+Repository Content
+------------------
+
+This GitHub repository is used for several things:
+
+- The `typing_extensions` module lives in the
+  [typing\_extensions](./typing_extensions) directory.
+
+- The documentation at [typing.readthedocs.io](https://typing.readthedocs.io/)
+  is maintained in the [docs directory](./docs).
+
+- A [discussion forum](https://github.com/python/typing/discussions) for typing-related user
+  help is hosted here.
+
+Historically, this repository hosted a backport of the
+[`typing` module](https://docs.python.org/3/library/typing.html) for older
+Python versions. The last released version, supporting Python 2.7 and 3.4,
+is [available at PyPI](https://pypi.org/project/typing/).
+
+Workflow
+--------
+
+See [CONTRIBUTING.md](/CONTRIBUTING.md) for more.
diff --git a/docs/Makefile b/docs/Makefile
new file mode 100644
index 0000000..4f7c95a
--- /dev/null
+++ b/docs/Makefile
@@ -0,0 +1,46 @@
+# Minimal makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line, and also
+# from the environment for the first two.
+SOURCEDIR     = .
+SOURCES       =
+BUILDDIR      = _build
+PYTHON       = python3
+VENVDIR      = ./venv
+SPHINXBUILD  = PATH=$(VENVDIR)/bin:$$PATH sphinx-build
+
+ALLSPHINXOPTS = -b $(BUILDER) -d build/doctrees $(SPHINXOPTS) . build/$(BUILDER) $(SOURCES)
+
+.PHONY: help clean build html text venv Makefile
+
+# Put it first so that "make" without argument is like "make help".
+help:
+	@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
+
+clean:
+	-rm -rf build/* $(VENVDIR)/*
+
+build:
+	-mkdir -p build
+	$(SPHINXBUILD) $(ALLSPHINXOPTS)
+	@echo
+
+html: BUILDER = html
+html: build
+	@echo "Build finished. The HTML pages are in build/html."
+
+text: BUILDER = text
+text: build
+	@echo "Build finished; the text files are in build/text."
+
+venv:
+	$(PYTHON) -m venv $(VENVDIR)
+	$(VENVDIR)/bin/python3 -m pip install -U pip setuptools
+	$(VENVDIR)/bin/python3 -m pip install -r requirements.txt
+	@echo "The venv has been created in the $(VENVDIR) directory"
+
+# Catch-all target: route all unknown targets to Sphinx using the new
+# "make mode" option.  $(O) is meant as a shortcut for $(SPHINXOPTS).
+%: Makefile
+	@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
diff --git a/docs/README.rst b/docs/README.rst
new file mode 100644
index 0000000..6b431c8
--- /dev/null
+++ b/docs/README.rst
@@ -0,0 +1,50 @@
+Python Typing Documentation
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Reading the docs
+=================
+
+The live documentation for Python's static typing can be found at
+`typing.readthedocs.io <https://typing.readthedocs.io/>`_.
+
+Building the docs
+=================
+
+The documentation is built with tools which are not included in this
+tree but are maintained separately and are available from
+`PyPI <https://pypi.org/>`_.
+
+* `Sphinx <https://pypi.org/project/Sphinx/>`_
+* `python-docs-theme <https://pypi.org/project/python-docs-theme/>`_
+
+The easiest way to install these tools is to create a virtual environment and
+install the tools into there.
+
+Using make
+----------
+
+To get started on UNIX, you can create a virtual environment with the command ::
+
+  make venv
+
+That will install all the tools necessary to build the documentation. Assuming
+the virtual environment was created in the ``venv`` directory (the default;
+configurable with the VENVDIR variable), you can run the following command to
+build the HTML output files::
+
+  make html
+
+By default, if the virtual environment is not created, the Makefile will
+look for instances of sphinxbuild and blurb installed on your process PATH
+(configurable with the SPHINXBUILD and BLURB variables).
+
+Available make targets are:
+
+* "clean", which removes all build files.
+
+* "venv", which creates a virtual environment with all necessary tools
+  installed.
+
+* "html", which builds standalone HTML files for offline viewing.
+
+* "text", which builds a plain text file for each source file.
diff --git a/docs/conf.py b/docs/conf.py
new file mode 100644
index 0000000..f16401b
--- /dev/null
+++ b/docs/conf.py
@@ -0,0 +1,55 @@
+# Configuration file for the Sphinx documentation builder.
+#
+# This file only contains a selection of the most common options. For a full
+# list see the documentation:
+# https://www.sphinx-doc.org/en/master/usage/configuration.html
+
+# -- Path setup --------------------------------------------------------------
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+#
+# import os
+# import sys
+# sys.path.insert(0, os.path.abspath('.'))
+
+
+# -- Project information -----------------------------------------------------
+
+project = 'typing'
+copyright = '2021, The Python Typing Team'
+author = 'The Python Typing Team'
+
+
+# -- General configuration ---------------------------------------------------
+
+# Add any Sphinx extension module names here, as strings. They can be
+# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
+# ones.
+extensions = [
+]
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+# This pattern also affects html_static_path and html_extra_path.
+exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store', 'venv', 'README.rst']
+
+
+# -- Options for HTML output -------------------------------------------------
+
+# The theme to use for HTML and HTML Help pages.  See the documentation for
+# a list of builtin themes.
+#
+html_theme = 'python_docs_theme'
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = []
+
+extensions = ['sphinx.ext.intersphinx']
+intersphinx_mapping = {'python': ('https://docs.python.org/3', None)}
diff --git a/docs/index.rst b/docs/index.rst
new file mode 100644
index 0000000..b5fe268
--- /dev/null
+++ b/docs/index.rst
@@ -0,0 +1,99 @@
+*************************
+Static Typing with Python
+*************************
+
+.. Introduction
+.. ============
+..
+.. .. toctree::
+..    :maxdepth: 2
+..
+..    source/introduction
+
+Guides
+======
+
+.. toctree::
+   :maxdepth: 2
+
+   source/guides
+
+Reference
+=========
+
+.. toctree::
+   :maxdepth: 2
+
+   source/reference
+
+Indices and tables
+==================
+
+* :ref:`genindex`
+* :ref:`search`
+
+Discussions and Support
+=======================
+
+* `User help forum <https://github.com/python/typing/discussions>`_
+* `User chat on Gitter <http://gitter.im/python/typing>`_
+* `Developer mailing list <https://mail.python.org/archives/list/typing-sig@python.org/>`_
+
+Typing-related Tools
+====================
+
+Type Checkers
+-------------
+
+* `mypy <http://mypy-lang.org/>`_, the reference implementation for type
+  checkers. Supports Python 2 and 3.
+* `pyre <https://pyre-check.org/>`_, written in OCaml and optimized for
+  performance. Supports Python 3 only.
+* `pyright <https://github.com/microsoft/pyright>`_, a type checker that
+  emphasizes speed. Supports Python 3 only.
+* `pytype <https://google.github.io/pytype/>`_, checks and infers types for
+  unannotated code. Supports Python 2 and 3.
+
+Development Environments
+------------------------
+
+* `PyCharm <https://www.jetbrains.com/pycharm/>`_, an IDE that supports
+  type stubs both for type checking and code completion.
+* `Visual Studio Code <https://code.visualstudio.com/>`_, a code editor that
+  supports type checking using mypy, pyright, or the
+  `Pylance <https://marketplace.visualstudio.com/items?itemName=ms-python.vscode-pylance>`_
+  extension.
+
+Linters and Formatters
+----------------------
+
+* `black <https://black.readthedocs.io/>`_, a code formatter with support for
+  type stub files.
+* `flake8-pyi <https://github.com/ambv/flake8-pyi>`_, a plugin for the
+  `flake8 <https://flake8.pycqa.org/>`_ linter that adds support for type
+  stubs.
+
+Typing PEPs
+===========
+
+* `PEP 483 <https://www.python.org/dev/peps/pep-0483/>`_, background on type hints
+* `PEP 484 <https://www.python.org/dev/peps/pep-0484/>`_, type hints
+* `PEP 526 <https://www.python.org/dev/peps/pep-0526/>`_, variable annotations and ``ClassVar``
+* `PEP 544 <https://www.python.org/dev/peps/pep-0544/>`_, ``Protocol``
+* `PEP 561 <https://www.python.org/dev/peps/pep-0561/>`_, distributing typed packages
+* `PEP 563 <https://www.python.org/dev/peps/pep-0563/>`_, ``from __future__ import annotations``
+* `PEP 585 <https://www.python.org/dev/peps/pep-0585/>`_, subscriptable generics in the standard library
+* `PEP 586 <https://www.python.org/dev/peps/pep-0586/>`_, ``Literal``
+* `PEP 589 <https://www.python.org/dev/peps/pep-0589/>`_, ``TypedDict``
+* `PEP 591 <https://www.python.org/dev/peps/pep-0591/>`_, ``Final``
+* `PEP 593 <https://www.python.org/dev/peps/pep-0593/>`_, ``Annotated``
+* `PEP 604 <https://www.python.org/dev/peps/pep-0604/>`_, union syntax with ``|``
+* `PEP 612 <https://www.python.org/dev/peps/pep-0612/>`_, ``ParamSpec``
+* `PEP 613 <https://www.python.org/dev/peps/pep-0613/>`_, ``TypeAlias``
+* `PEP 646 <https://www.python.org/dev/peps/pep-0646/>`_, variadic generics and ``TypeVarTuple``
+* `PEP 647 <https://www.python.org/dev/peps/pep-0647/>`_, ``TypeGuard``
+* `PEP 655 <https://www.python.org/dev/peps/pep-0655/>`_, ``Required`` and ``NotRequired``
+* `PEP 673 <https://www.python.org/dev/peps/pep-0673/>`_, ``Self``
+* `PEP 675 <https://www.python.org/dev/peps/pep-0675/>`_, ``LiteralString``
+* `PEP 677 <https://www.python.org/dev/peps/pep-0677/>`_ (rejected), callable type syntax
+* `PEP 681 <https://www.python.org/dev/peps/pep-0681/>`_ (draft), ``@dataclass_transform()``
diff --git a/docs/make.bat b/docs/make.bat
new file mode 100644
index 0000000..2119f51
--- /dev/null
+++ b/docs/make.bat
@@ -0,0 +1,35 @@
+@ECHO OFF

+

+pushd %~dp0

+

+REM Command file for Sphinx documentation

+

+if "%SPHINXBUILD%" == "" (

+	set SPHINXBUILD=sphinx-build

+)

+set SOURCEDIR=.

+set BUILDDIR=_build

+

+if "%1" == "" goto help

+

+%SPHINXBUILD% >NUL 2>NUL

+if errorlevel 9009 (

+	echo.

+	echo.The 'sphinx-build' command was not found. Make sure you have Sphinx

+	echo.installed, then set the SPHINXBUILD environment variable to point

+	echo.to the full path of the 'sphinx-build' executable. Alternatively you

+	echo.may add the Sphinx directory to PATH.

+	echo.

+	echo.If you don't have Sphinx installed, grab it from

+	echo.http://sphinx-doc.org/

+	exit /b 1

+)

+

+%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%

+goto end

+

+:help

+%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%

+

+:end

+popd

diff --git a/docs/requirements.txt b/docs/requirements.txt
new file mode 100644
index 0000000..4aa5fce
--- /dev/null
+++ b/docs/requirements.txt
@@ -0,0 +1,10 @@
+# Requirements to build the Python documentation
+
+# Sphinx version is pinned so that new versions that introduce new warnings
+# won't suddenly cause build failures. Updating the version is fine as long
+# as no warnings are raised by doing so.
+sphinx==4.2.0
+
+# The theme used by the documentation is stored separately, so we need
+# to install that as well.
+python-docs-theme
diff --git a/docs/source/annotations.rst b/docs/source/annotations.rst
new file mode 100644
index 0000000..ea5c471
--- /dev/null
+++ b/docs/source/annotations.rst
@@ -0,0 +1,68 @@
+****************
+Type Annotations
+****************
+
+Functions
+=========
+
+Parameters
+----------
+
+Asynchronous Functions
+----------------------
+
+Generators
+----------
+
+Lambdas
+-------
+
+
+Classes
+=======
+
+Overloads and Overrides
+-----------------------
+
+Instance vs. Class Attributes
+-----------------------------
+
+Final attributes
+----------------
+
+Abstract base classes
+---------------------
+
+
+Globals
+=======
+
+
+Attributes
+==========
+
+
+Locals
+======
+
+Empty Containers
+----------------
+
+
+Runtime Considerations
+======================
+
+Comment vs. Inline Support
+--------------------------
+
+Forward References
+------------------
+
+Generic types that don't implement `__getitem__`
+------------------------------------------------
+
+Conditioning on static type checking
+------------------------------------
+
+from `__future__` import annotations
+------------------------------------
diff --git a/docs/source/basics.rst b/docs/source/basics.rst
new file mode 100644
index 0000000..9b2bf52
--- /dev/null
+++ b/docs/source/basics.rst
@@ -0,0 +1,3 @@
+**********
+The Basics
+**********
diff --git a/docs/source/dependencies.rst b/docs/source/dependencies.rst
new file mode 100644
index 0000000..b16fa63
--- /dev/null
+++ b/docs/source/dependencies.rst
@@ -0,0 +1,12 @@
+**************************
+Libraries and Dependencies
+**************************
+
+:doc:`libraries`
+
+Typeshed
+========
+
+
+Placeholder Stubs
+=================
diff --git a/docs/source/faq.rst b/docs/source/faq.rst
new file mode 100644
index 0000000..906e277
--- /dev/null
+++ b/docs/source/faq.rst
@@ -0,0 +1,23 @@
+**************************
+Frequently Asked Questions
+**************************
+
+
+Why Types?
+==========
+
+
+Unsupported Python Features
+===========================
+
+
+Common Errors
+=============
+
+
+Typing PEPs
+===========
+
+
+Relevant Talks and Resources
+============================
diff --git a/docs/source/guides.rst b/docs/source/guides.rst
new file mode 100644
index 0000000..c9af381
--- /dev/null
+++ b/docs/source/guides.rst
@@ -0,0 +1,10 @@
+******************
+Type System Guides
+******************
+
+.. toctree::
+   :maxdepth: 2
+   :caption: Contents:
+
+   libraries
+   unreachable
diff --git a/docs/source/inference.rst b/docs/source/inference.rst
new file mode 100644
index 0000000..291dec4
--- /dev/null
+++ b/docs/source/inference.rst
@@ -0,0 +1,28 @@
+**************
+Type Inference
+**************
+
+Rules for local inference
+=========================
+
+Explicit vs. Implicit Local Types
+---------------------------------
+
+Changing Types
+==============
+
+Asserts
+-------
+
+Casts
+-----
+
+Type Guards
+-----------
+
+
+Protocols and Duck Typing
+=========================
+
+Callback Protocols
+------------------
diff --git a/docs/source/introduction.rst b/docs/source/introduction.rst
new file mode 100644
index 0000000..fb97355
--- /dev/null
+++ b/docs/source/introduction.rst
@@ -0,0 +1,41 @@
+*******************************
+Introduction to Types in Python
+*******************************
+
+
+Background
+==========
+
+How to read type annotations
+----------------------------
+
+When and why types are useful
+-----------------------------
+
+
+Gradual Typing: Static Types in a Dynamic Language
+==================================================
+
+Opt-in type checking
+--------------------
+
+Type stubs
+----------
+
+:doc:`stubs`
+
+Strategies for increasing coverage
+----------------------------------
+
+
+Getting Started
+===============
+
+Python type checkers
+--------------------
+
+How to annotate an existing codebase
+------------------------------------
+
+Typeshed
+--------
diff --git a/docs/source/libraries.rst b/docs/source/libraries.rst
new file mode 100644
index 0000000..96e5370
--- /dev/null
+++ b/docs/source/libraries.rst
@@ -0,0 +1,602 @@
+.. _libraries:
+
+***********************
+Typing Python Libraries
+***********************
+
+Much of Python’s popularity can be attributed to the rich collection of
+Python libraries available to developers. Authors of these libraries
+play an important role in improving the experience for Python
+developers. This document provides some recommendations and guidance for
+Python library authors.
+
+These recommendations are intended to provide the following benefits:
+
+1. Consumers of libraries should have a great coding experience with
+   fast and accurate completion suggestions, class and function
+   documentation, signature help (including parameter default values),
+   hover text, and auto-imports. This should happen by default without
+   needing to download extra packages and without any special
+   configuration. These features should be consistent across the Python
+   ecosystem regardless of a developer’s choice of editor, IDE, notebook
+   environment, etc.
+2. Consumers of libraries should be able to rely on complete and
+   accurate type information so static type checkers can detect and
+   report type inconsistencies and other violations of the interface
+   contract.
+3. Library authors should be able to specify a well-defined interface
+   contract that is enforced by tools. This allows a library
+   implementation to evolve and improve without breaking consumers of
+   the library.
+4. Library authors should have the benefits of static type checking to
+   produce high-quality, bug-free implementations.
+
+Inlined Type Annotations and Type Stubs
+=======================================
+
+`PEP 561 <https://www.python.org/dev/peps/pep-0561/>`__ documents
+several ways type information can be delivered for a library: inlined
+type annotations, type stub files included in the package, a separate
+companion type stub package, and type stubs in the typeshed repository.
+Some of these options fall short on delivering the benefits above. We
+therefore provide the following more specific guidance to library
+authors.
+
+.. note::
+   All libraries should include inlined type annotations for the
+   functions, classes, methods, and constants that comprise the public
+   interface for the library.
+
+Inlined type annotations should be included directly within the source
+code that ships with the package. Of the options listed in PEP 561,
+inlined type annotations offer the most benefits. They typically require
+the least effort to add and maintain, they are always consistent with
+the implementation, and docstrings and default parameter values are
+readily available, allowing language servers to enhance the development
+experience.
+
+There are cases where inlined type annotations are not possible — most
+notably when a library’s exposed functionality is implemented in a
+language other than Python.
+
+.. note::
+   Libraries that expose symbols implemented in languages other than
+   Python should include stub (``.pyi``) files that describe the types for
+   those symbols. These stubs should also contain docstrings and default
+   parameter values.
+
+In many existing type stubs (such as those found in typeshed), default
+parameter values are replaced with with ``...`` and all docstrings are
+removed. We recommend that default values and docstrings remain within
+the type stub file so language servers can display this information to
+developers.
+
+Library Interface
+=================
+
+`PEP 561 <https://www.python.org/dev/peps/pep-0561/>`__ indicates that a
+``py.typed`` marker file must be included in the package if the author
+wishes to support type checking of their code.
+
+If a ``py.typed`` module is present, a type checker will treat all modules
+within that package (i.e. all files that end in ``.py`` or ``.pyi``) as
+importable unless the file name begins with an underscore. These modules
+comprise the supported interface for the library.
+
+Each module exposes a set of symbols. Some of these symbols are
+considered "private” — implementation details that are not part of the
+library’s interface. Type checkers can use the following rules
+to determine which symbols are visible outside of the package.
+
+-  Symbols whose names begin with an underscore (but are not dunder
+   names) are considered private.
+-  Imported symbols are considered private by default. If they use the
+   ``import A as A`` (a redundant module alias), ``from X import A as A`` (a
+   redundant symbol alias), or ``from . import A`` forms, symbol ``A`` is
+   not private unless the name begins with an underscore. If a file
+   ``__init__.py`` uses form ``from .A import X``, symbol ``A`` is treated
+   likewise. If a wildcard import (of the form ``from X import *``) is
+   used, all symbols referenced by the wildcard are not private.
+-  A module can expose an ``__all__`` symbol at the module level that
+   provides a list of names that are considered part of the interface.
+   This overrides all other rules above, allowing imported symbols or
+   symbols whose names begin with an underscore to be included in the
+   interface.
+-  Local variables within a function (including nested functions) are
+   always considered private.
+
+The following idioms are supported for defining the values contained
+within ``__all__``. These restrictions allow type checkers to statically
+determine the value of ``__all__``.
+
+-  ``__all__ = ('a', b')``
+-  ``__all__ = ['a', b']``
+-  ``__all__ += ['a', b']``
+-  ``__all__ += submodule.__all__``
+-  ``__all__.extend(['a', b'])``
+-  ``__all__.extend(submodule.__all__)``
+-  ``__all__.append('a')``
+-  ``__all__.remove('a')``
+
+Type Completeness
+=================
+
+A “py.typed” library should aim to be type complete so that type
+checking and inspection can work to their full extent. Here we say that a
+library is “type complete” if all of the symbols
+that comprise its interface have type annotations that refer to types
+that are fully known. Private symbols are exempt.
+
+The following are best practice recommendations for how to define “type complete”:
+
+Classes:
+
+-  All class variables, instance variables, and methods that are
+   “visible” (not overridden) are annotated and refer to known types
+-  If a class is a subclass of a generic class, type arguments are
+   provided for each generic type parameter, and these type arguments
+   are known types
+
+Functions and Methods:
+
+-  All input parameters have type annotations that refer to known types
+-  The return parameter is annotated and refers to a known type
+-  The result of applying one or more decorators results in a known type
+
+Type Aliases:
+
+-  All of the types referenced by the type alias are known
+
+Variables:
+
+-  All variables have type annotations that refer to known types
+
+Type annotations can be omitted in a few specific cases where the type
+is obvious from the context:
+
+-  Constants that are assigned simple literal values
+   (e.g. ``RED = '#F00'`` or ``MAX_TIMEOUT = 50`` or
+   ``room_temperature: Final = 20``). A constant is a symbol that is
+   assigned only once and is either annotated with ``Final`` or is named
+   in all-caps. A constant that is not assigned a simple literal value
+   requires explicit annotations, preferably with a ``Final`` annotation
+   (e.g. ``WOODWINDS: Final[List[str]] = ['Oboe', 'Bassoon']``).
+-  Enum values within an Enum class do not require annotations because
+   they take on the type of the Enum class.
+-  Type aliases do not require annotations. A type alias is a symbol
+   that is defined at a module level with a single assignment where the
+   assigned value is an instantiable type, as opposed to a class
+   instance
+   (e.g. ``Foo = Callable[[Literal["a", "b"]], Union[int, str]]`` or
+   ``Bar = Optional[MyGenericClass[int]]``).
+-  The “self” parameter in an instance method and the “cls” parameter in
+   a class method do not require an explicit annotation.
+-  The return type for an ``__init__`` method does not need to be
+   specified, since it is always ``None``.
+-  The following module-level symbols do not require type annotations:
+   ``__all__``,\ ``__author__``, ``__copyright__``, ``__email__``,
+   ``__license__``, ``__title__``, ``__uri__``, ``__version__``.
+-  The following class-level symbols do not require type annotations:
+   ``__class__``, ``__dict__``, ``__doc__``, ``__module__``,
+   ``__slots__``.
+
+Examples of known and unknown types
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code:: python
+
+
+   # Variable with unknown type
+   a = [3, 4, 5]
+
+   # Variable with known type
+   a: List[int] = [3, 4, 5]
+
+   # Type alias with partially unknown type (because type
+   # arguments are missing for list and dict)
+   DictOrList = Union[list, dict]
+
+   # Type alias with known type
+   DictOrList = Union[List[Any], Dict[str, Any]]
+
+   # Generic type alias with known type
+   _T = TypeVar("_T")
+   DictOrList = Union[List[_T], Dict[str, _T]]
+
+   # Function with known type
+   def func(a: Optional[int], b: Dict[str, float] = {}) -> None:
+       pass
+
+   # Function with partially unknown type (because type annotations
+   # are missing for input parameters and return type)
+   def func(a, b):
+       pass
+
+   # Function with partially unknown type (because of missing
+   # type args on Dict)
+   def func(a: int, b: Dict) -> None:
+       pass
+
+   # Function with partially unknown type (because return type
+   # annotation is missing)
+   def func(a: int, b: Dict[str, float]):
+       pass
+
+   # Decorator with partially unknown type (because type annotations
+   # are missing for input parameters and return type)
+   def my_decorator(func):
+       return func
+
+   # Function with partially unknown type (because type is obscured
+   # by untyped decorator)
+   @my_decorator
+   def func(a: int) -> str:
+       pass
+
+
+   # Class with known type
+   class MyClass:
+       height: float = 2.0
+
+       def __init__(self, name: str, age: int):
+           self.age: int = age
+
+       @property
+       def name(self) -> str:
+           ...
+
+   # Class with partially unknown type
+   class MyClass:
+       # Missing type annotation for class variable
+       height = 2.0
+
+       # Missing input parameter annotations
+       def __init__(self, name, age):
+           # Missing type annotation for instance variable
+           self.age = age
+
+       # Missing return type annotation
+       @property
+       def name(self):
+           ...
+
+   # Class with partially unknown type
+   class BaseClass:
+       # Missing type annotation
+       height = 2.0
+
+       # Missing type annotation
+       def get_stuff(self):
+           ...
+
+   # Class with known type (because it overrides all symbols
+   # exposed by BaseClass that have incomplete types)
+   class DerivedClass(BaseClass):
+       height: float
+
+       def get_stuff(self) -> str:
+           ...
+
+   # Class with partially unknown type because base class
+   # (dict) is generic, and type arguments are not specified.
+   class DictSubclass(dict):
+       pass
+
+Best Practices for Inlined Types
+================================
+
+Wide vs. Narrow Types
+~~~~~~~~~~~~~~~~~~~~~
+
+In type theory, when comparing two types that are related to each other,
+the “wider” type is the one that is more general, and the “narrower”
+type is more specific. For example, ``Sequence[str]`` is a wider type
+than ``List[str]`` because all ``List`` objects are also ``Sequence``
+objects, but the converse is not true. A subclass is narrower than a
+class it derives from. A union of types is wider than the individual
+types that comprise the union.
+
+In general, a function input parameter should be annotated with the
+widest possible type supported by the implementation. For example, if
+the implementation requires the caller to provide an iterable collection
+of strings, the parameter should be annotated as ``Iterable[str]``, not
+as ``List[str]``. The latter type is narrower than necessary, so if a
+user attempts to pass a tuple of strings (which is supported by the
+implementation), a type checker will complain about a type
+incompatibility.
+
+As a specific application of the “use the widest type possible” rule,
+libraries should generally use immutable forms of container types
+instead of mutable forms (unless the function needs to modify the
+container). Use ``Sequence`` rather than ``List``, ``Mapping`` rather
+than ``Dict``, etc. Immutable containers allow for more flexibility
+because their type parameters are covariant rather than invariant. A
+parameter that is typed as ``Sequence[Union[str, int]]`` can accept a
+``List[int]``, ``Sequence[str]``, and a ``Sequence[int]``. But a
+parameter typed as ``List[Union[str, int]]`` is much more restrictive
+and accepts only a ``List[Union[str, int]]``.
+
+Overloads
+~~~~~~~~~
+
+If a function or method can return multiple different types and those
+types can be determined based on the presence or types of certain
+parameters, use the ``@overload`` mechanism defined in `PEP
+484 <https://www.python.org/dev/peps/pep-0484/#id45>`__. When overloads
+are used within a “.py” file, they must appear prior to the function
+implementation, which should not have an ``@overload`` decorator.
+
+Keyword-only Parameters
+~~~~~~~~~~~~~~~~~~~~~~~
+
+If a function or method is intended to take parameters that are
+specified only by name, use the keyword-only separator (``*``).
+
+.. code:: python
+
+   def create_user(age: int, *, dob: Optional[date] = None):
+       ...
+
+Annotating Decorators
+~~~~~~~~~~~~~~~~~~~~~
+
+Decorators modify the behavior of a class or a function. Providing
+annotations for decorators is straightforward if the decorator retains
+the original signature of the decorated function.
+
+.. code:: python
+
+   _F = TypeVar("_F", bound=Callable[..., Any])
+
+   def simple_decorator(_func: _F) -> _F:
+       """
+        Simple decorators are invoked without parentheses like this:
+          @simple_decorator
+          def my_function(): ...
+        """
+      ...
+
+   def complex_decorator(*, mode: str) -> Callable[[_F], _F]:
+       """
+        Complex decorators are invoked with arguments like this:
+          @complex_decorator(mode="easy")
+          def my_function(): ...
+        """
+      ...
+
+Decorators that mutate the signature of the decorated function present
+challenges for type annotations. The ``ParamSpec`` and ``Concatenate``
+mechanisms described in `PEP
+612 <https://www.python.org/dev/peps/pep-0612/>`__ provide some help
+here, but these are available only in Python 3.10 and newer. More
+complex signature mutations may require type annotations that erase the
+original signature, thus blinding type checkers and other tools that
+provide signature assistance. As such, library authors are discouraged
+from creating decorators that mutate function signatures in this manner.
+
+Generic Classes and Functions
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Classes and functions that can operate in a generic manner on various
+types should declare themselves as generic using the mechanisms
+described in `PEP 484 <https://www.python.org/dev/peps/pep-0484/>`__.
+This includes the use of ``TypeVar`` symbols. Typically, a ``TypeVar``
+should be private to the file that declares it, and should therefore
+begin with an underscore.
+
+Type Aliases
+~~~~~~~~~~~~
+
+Type aliases are symbols that refer to other types. Generic type aliases
+(those that refer to unspecialized generic classes) are supported by
+most type checkers.
+
+`PEP 613 <https://www.python.org/dev/peps/pep-0613/>`__ provides a way
+to explicitly designate a symbol as a type alias using the new TypeAlias
+annotation.
+
+.. code:: python
+
+   # Simple type alias
+   FamilyPet = Union[Cat, Dog, GoldFish]
+
+   # Generic type alias
+   ListOrTuple = Union[List[_T], Tuple[_T, ...]]
+
+   # Recursive type alias
+   TreeNode = Union[LeafNode, List["TreeNode"]]
+
+   # Explicit type alias using PEP 613 syntax
+   StrOrInt: TypeAlias = Union[str, int]
+
+Abstract Classes and Methods
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Classes that must be subclassed should derive from ``ABC``, and methods
+or properties that must be overridden should be decorated with the
+``@abstractmethod`` decorator. This allows type checkers to validate
+that the required methods have been overridden and provide developers
+with useful error messages when they are not. It is customary to
+implement an abstract method by raising a ``NotImplementedError``
+exception.
+
+.. code:: python
+
+   from abc import ABC, abstractmethod
+
+   class Hashable(ABC):
+      @property
+      @abstractmethod
+      def hash_value(self) -> int:
+         """Subclasses must override"""
+         raise NotImplementedError()
+
+      @abstractmethod
+      def print(self) -> str:
+         """Subclasses must override"""
+         raise NotImplementedError()
+
+Final Classes and Methods
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Classes that are not intended to be subclassed should be decorated as
+``@final`` as described in `PEP
+591 <https://www.python.org/dev/peps/pep-0591/>`__. The same decorator
+can also be used to specify methods that cannot be overridden by
+subclasses.
+
+Literals
+~~~~~~~~
+
+Type annotations should make use of the Literal type where appropriate,
+as described in `PEP 586 <https://www.python.org/dev/peps/pep-0586/>`__.
+Literals allow for more type specificity than their non-literal
+counterparts.
+
+Constants
+~~~~~~~~~
+
+Constant values (those that are read-only) can be specified using the
+Final annotation as described in `PEP
+591 <https://www.python.org/dev/peps/pep-0591/>`__.
+
+Type checkers will also typically treat variables that are named using
+all upper-case characters as constants.
+
+In both cases, it is OK to omit the declared type of a constant if it is
+assigned a literal str, int, float, bool or None value. In such cases,
+the type inference rules are clear and unambiguous, and adding a literal
+type annotation would be redundant.
+
+.. code:: python
+
+   # All-caps constant with inferred type
+   COLOR_FORMAT_RGB = "rgb"
+
+   # All-caps constant with explicit type
+   COLOR_FORMAT_RGB: Literal["rgb"] = "rgb"
+   LATEST_VERSION: Tuple[int, int] = (4, 5)
+
+   # Final variable with inferred type
+   ColorFormatRgb: Final = "rgb"
+
+   # Final variable with explicit type
+   ColorFormatRgb: Final[Literal["rgb"]] = "rgb"
+   LATEST_VERSION: Final[Tuple[int, int]] = (4, 5)
+
+Typed Dictionaries, Data Classes, and Named Tuples
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If your library runs only on newer versions of Python, you are
+encouraged to use some of the new type-friendly classes.
+
+NamedTuple (described in `PEP
+484 <https://www.python.org/dev/peps/pep-0484/>`__) is preferred over
+namedtuple.
+
+Data classes (described in `PEP
+557 <https://www.python.org/dev/peps/pep-0557/>`__) is preferred over
+untyped dictionaries.
+
+TypedDict (described in `PEP
+589 <https://www.python.org/dev/peps/pep-0589/>`__) is preferred over
+untyped dictionaries.
+
+Compatibility with Older Python Versions
+========================================
+
+Each new version of Python from 3.5 onward has introduced new typing
+constructs. This presents a challenge for library authors who want to
+maintain runtime compatibility with older versions of Python. This
+section documents several techniques that can be used to add types while
+maintaining backward compatibility.
+
+Quoted Annotations
+~~~~~~~~~~~~~~~~~~
+
+Type annotations for variables, parameters, and return types can be
+placed in quotes. The Python interpreter will then ignore them, whereas
+a type checker will interpret them as type annotations.
+
+.. code:: python
+
+   # Older versions of Python do not support subscripting
+   # for the OrderedDict type, so the annotation must be
+   # enclosed in quotes.
+   def get_config(self) -> "OrderedDict[str, str]":
+      return self._config
+
+Type Comment Annotations
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+Python 3.0 introduced syntax for parameter and return type annotations,
+as specified in `PEP 484 <https://www.python.org/dev/peps/pep-0484/>`__.
+Python 3.6 introduced support for variable type annotations, as
+specified in `PEP 526 <https://www.python.org/dev/peps/pep-0526/>`__.
+
+If you need to support older versions of Python, type annotations can
+still be provided as “type comments”. These comments take the form #
+type: .
+
+.. code:: python
+
+   class Foo:
+      # Variable type comments go at the end of the line
+      # where the variable is assigned.
+      timeout = None # type: Optional[int]
+
+      # Function type comments can be specified on the
+      # line after the function signature.
+      def send_message(self, name, length):
+         # type: (str, int) -> None
+         ...
+
+      # Function type comments can also specify the type
+      # of each parameter on its own line.
+      def receive_message(
+         self,
+         name, # type: str
+         length # type: int
+      ):
+         # type: () -> Message
+         ...
+
+typing_extensions
+~~~~~~~~~~~~~~~~~
+
+New type features that require runtime support are typically included in
+the stdlib ``typing`` module. Where possible, these new features are
+back-ported to a runtime library called ``typing_extensions`` that works
+with older Python runtimes.
+
+TYPE_CHECKING
+~~~~~~~~~~~~~
+
+The ``typing`` module exposes a variable called ``TYPE_CHECKING`` which
+has a value of False within the Python runtime but a value of True when
+the type checker is performing its analysis. This allows type checking
+statements to be conditionalized.
+
+Care should be taken when using ``TYPE_CHECKING`` because behavioral
+changes between type checking and runtime could mask problems that the
+type checker would otherwise catch.
+
+Non-Standard Type Behaviors
+===========================
+
+Type annotations provide a way to annotate typical type behaviors, but
+some classes implement specialized, non-standard behaviors that cannot
+be described using standard type annotations. For now, such types need
+to be annotated as Any, which is unfortunate because the benefits of
+static typing are lost.
+
+Docstrings
+==========
+
+Docstrings should be provided for all classes, functions, and methods in
+the interface. They should be formatted according to `PEP
+257 <https://www.python.org/dev/peps/pep-0257/>`__.
+
+There is currently no single agreed-upon standard for function and
+method docstrings, but several common variants have emerged. We
+recommend using one of these variants.
diff --git a/docs/source/quality.rst b/docs/source/quality.rst
new file mode 100644
index 0000000..328550c
--- /dev/null
+++ b/docs/source/quality.rst
@@ -0,0 +1,200 @@
+.. _tools:
+
+********************************************
+Testing and Ensuring Type Annotation Quality
+********************************************
+
+Testing Annotation Accuracy
+===========================
+
+When creating a package with type annotations, authors may want to validate
+that the annotations they publish meet their expectations.
+This is especially important for library authors, for whom the published
+annotations are part of the public interface to their package.
+
+There are several approaches to this problem, and this document will show
+a few of them.
+
+.. note::
+
+    For simplicity, we will assume that type-checking is done with ``mypy``.
+    Many of these strategies can be applied to other type-checkers as well.
+
+Testing Using ``mypy --warn-unused-ignores``
+--------------------------------------------
+
+Clever use of ``--warn-unused-ignores`` can be used to check that certain
+expressions are or are not well-typed.
+
+The idea is to write normal python files which contain valid expressions along
+with invalid expressions annotated with ``type: ignore`` comments. When
+``mypy --warn-unused-ignores`` is run on these files, it should pass.
+A directory of test files, ``typing_tests/``, can be maintained.
+
+This strategy does not offer strong guarantees about the types under test, but
+it requires no additional tooling.
+
+If the following file is under test
+
+.. code-block:: python
+
+    # foo.py
+    def bar(x: int) -> str:
+        return str(x)
+
+Then the following file tests ``foo.py``:
+
+.. code-block:: python
+
+    bar(42)
+    bar("42")  # type: ignore [arg-type]
+    bar(y=42)  # type: ignore [call-arg]
+    r1: str = bar(42)
+    r2: int = bar(42)  # type: ignore [assignment]
+
+Checking ``reveal_type`` output from ``mypy.api.run``
+-----------------------------------------------------
+
+``mypy`` provides a subpackage named ``api`` for invoking ``mypy`` from a
+python process. In combination with ``reveal_type``, this can be used to write
+a function which gets the ``reveal_type`` output from an expression. Once
+that's obtained, tests can assert strings and regular expression matches
+against it.
+
+This approach requires writing a set of helpers to provide a good testing
+experience, and it runs mypy once per test case (which can be slow).
+However, it builds only on ``mypy`` and the test framework of your choice.
+
+The following example could be integrated into a testsuite written in
+any framework:
+
+.. code-block:: python
+
+    import re
+    from mypy import api
+
+    def get_reveal_type_output(filename):
+        result = api.run([filename])
+        stdout = result[0]
+        match = re.search(r'note: Revealed type is "([^"]+)"', stdout)
+        assert match is not None
+        return match.group(1)
+
+
+For example, we can use the above to provide a ``run_reveal_type`` pytest
+fixture which generates a temporary file and uses it as the input to
+``get_reveal_type_output``:
+
+.. code-block:: python
+
+    import os
+    import pytest
+
+    @pytest.fixture
+    def _in_tmp_path(tmp_path):
+        cur = os.getcwd()
+        try:
+            os.chdir(tmp_path)
+            yield
+        finally:
+            os.chdir(cur)
+
+    @pytest.fixture
+    def run_reveal_type(tmp_path, _in_tmp_path):
+        content_path = tmp_path / "reveal_type_test.py"
+
+        def func(code_snippet, *, preamble = ""):
+            content_path.write_text(preamble + f"reveal_type({code_snippet})")
+            return get_reveal_type_output("reveal_type_test.py")
+
+        return func
+
+
+For more details, see `the documentation on mypy.api
+<https://mypy.readthedocs.io/en/stable/extending_mypy.html#integrating-mypy-into-another-python-application>`_.
+
+pytest-mypy-plugins
+-------------------
+
+`pytest-mypy-plugins <https://github.com/typeddjango/pytest-mypy-plugins>`_ is
+a plugin for ``pytest`` which defines typing test cases as YAML data.
+The test cases are run through ``mypy`` and the output of ``reveal_type`` can
+be asserted.
+
+This project supports complex typing arrangements like ``pytest`` parametrized
+tests and per-test ``mypy`` configuration. It requires that you are using
+``pytest`` to run your tests, and runs ``mypy`` in a subprocess per test case.
+
+This is an example of a parametrized test with ``pytest-mypy-plugins``:
+
+.. code-block:: yaml
+
+    - case: with_params
+      parametrized:
+        - val: 1
+          rt: builtins.int
+        - val: 1.0
+          rt: builtins.float
+      main: |
+        reveal_type({[ val }})  # N: Revealed type is '{{ rt }}'
+
+Improving Type Completeness
+===========================
+
+One of the goals of many libraries is to ensure that they are "fully type
+annotated", meaning that they provide complete and accurate type annotations
+for all functions, classes, and objects. Having full annotations is referred to
+as "type completeness" or "type coverage".
+
+Here are some tips for increasing the type completeness score for your
+library:
+
+-  Make type completeness an output of your testing process. Several type
+   checkers have options for generating useful output, warnings, or even
+   reports.
+-  If your package includes tests or sample code, consider removing them
+   from the distribution. If there is good reason to include them,
+   consider placing them in a directory that begins with an underscore
+   so they are not considered part of your library’s interface.
+-  If your package includes submodules that are meant to be
+   implementation details, rename those files to begin with an
+   underscore.
+-  If a symbol is not intended to be part of the library’s interface and
+   is considered an implementation detail, rename it such that it begins
+   with an underscore. It will then be considered private and excluded
+   from the type completeness check.
+-  If your package exposes types from other libraries, work with the
+   maintainers of these other libraries to achieve type completeness.
+
+.. warning::
+
+    The ways in which different type checkers evaluate and help you achieve
+    better type coverage may differ. Some of the above recommendations may or
+    may not be helpful to you, depending on which type checking tools you use.
+
+``mypy`` disallow options
+-------------------------
+
+``mypy`` offers several options which can detect untyped code.
+More details can be found in `the mypy documentation on these options
+<https://mypy.readthedocs.io/en/latest/command_line.html#untyped-definitions-and-calls>`_.
+
+Some basic usages which make ``mypy`` error on untyped data are::
+
+    mypy --disallow-untyped-defs
+    mypy --disallow-incomplete-defs
+
+``pyright`` type verification
+-----------------------------
+
+pyright has a special command line flag, ``--verifytypes``, for verifying
+type completeness. You can learn more about it from
+`the pyright documentation on verifying type completeness
+<https://github.com/microsoft/pyright/blob/main/docs/typed-libraries.md#verifying-type-completeness>`_.
+
+``mypy`` reports
+----------------
+
+``mypy`` offers several options options for generating reports on its analysis.
+See `the mypy documentation on report generation
+<https://mypy.readthedocs.io/en/stable/command_line.html#report-generation>`_ for details.
diff --git a/docs/source/reference.rst b/docs/source/reference.rst
new file mode 100644
index 0000000..c7fc57e
--- /dev/null
+++ b/docs/source/reference.rst
@@ -0,0 +1,22 @@
+*********************
+Type System Reference
+*********************
+
+.. toctree::
+   :maxdepth: 2
+   :caption: Contents:
+
+   stubs
+   quality
+   typing Module Documentation <https://docs.python.org/3/library/typing.html>
+
+.. The following pages are desired in a new TOC which will cover multiple
+.. topics. For now, they are not linked because the pages are empty.
+..
+..   basics
+..   type_system
+..   annotations
+..   inference
+..   type_compatibility
+..   dependencies
+..   faq
diff --git a/docs/source/stubs.rst b/docs/source/stubs.rst
new file mode 100644
index 0000000..ffd6c9b
--- /dev/null
+++ b/docs/source/stubs.rst
@@ -0,0 +1,1129 @@
+.. _stubs:
+
+**********
+Type Stubs
+**********
+
+Introduction
+============
+
+*type stubs*, also called *stub files*, provide type information for untyped
+Python packages and modules. Type stubs serve multiple purposes:
+
+* They are the only way to add type information to extension modules.
+* They can provide type information for packages that do not wish to
+  add them inline.
+* They can be distributed separately from the implementation.
+  This allows stubs to be developed at a different pace or by different
+  authors, which is especially useful when adding type annotations to
+  existing packages.
+* They can act as documentation, succinctly explaining the external
+  API of a package, without including the implementation or private
+  members.
+
+This document aims to give guidance to both authors of type stubs and developers
+of type checkers and other tools. It describes the constructs that can be used safely in type stubs,
+suggests a style guide for them, and lists constructs that type
+checkers are expected to support.
+
+Type stubs that only use constructs described in this document should work with
+all type checkers that also follow this document.
+Type stub authors can elect to use additional constructs, but
+must be prepared that some type checkers will not parse them as expected.
+
+A type checker that conforms to this document will parse a type stub that only uses
+constructs described here without error and will not interpret any
+construct in a contradictory manner. However, type checkers are not
+required to implement checks for all these constructs, and
+can elect to ignore unsupported ones. Additionally type checkers
+can support constructs not described in this document and tool authors are
+encouraged to experiment with additional features.
+
+Syntax
+======
+
+Type stubs are syntactically valid Python 3.7 files with a ``.pyi`` suffix.
+The Python syntax used for type stubs is independent from the Python
+versions supported by the implementation, and from the Python version the type
+checker runs under (if any). Therefore, type stub authors should use the
+latest available syntax features in stubs (up to Python 3.7), even if the
+implementation supports older, pre-3.7 Python versions.
+Type checker authors are encouraged to support syntax features from
+post-3.7 Python versions, although type stub authors should not use such
+features if they wish to maintain compatibility with all type checkers.
+
+For example, Python 3.7 added the ``async`` keyword (see PEP 492 [#pep492]_).
+Stub authors should use it to mark coroutines, even if the implementation
+still uses the ``@coroutine`` decorator. On the other hand, type stubs should
+not use the positional-only syntax from PEP 570 [#pep570]_, introduced in
+Python 3.8, although type checker authors are encouraged to support it.
+
+Stubs are treated as if ``from __future__ import annotations`` is enabled.
+In particular, built-in generics, pipe union syntax (``X | Y``), and forward
+references can be used.
+
+Starting with Python 3.8, the :py:mod:`ast` module from the standard library supports
+all syntax features required by this PEP. Older Python versions can use the
+`typed_ast <https://pypi.org/project/typed-ast/>`_ package from the
+Python Package Index, which also supports Python 3.7 syntax and ``# type``
+comments.
+
+Distribution
+============
+
+Type stubs can be distributed with or separately from the implementation;
+see PEP 561 [#pep561]_ for more information. The
+`typeshed <https://github.com/python/typeshed>`_ project
+includes stubs for Python's standard library and several third-party
+packages. The stubs for the standard library are usually distributed with type checkers and do not
+require separate installation. Stubs for third-party libraries are
+available on the `Python Package Index <https://pypi.org>`_. A stub package for
+a library called ``widget`` will be called ``types-widget``.
+
+Supported Constructs
+====================
+
+This sections lists constructs that type checkers will accept in type stubs.
+Type stub authors can safely use these constructs. If a
+construct is marked as "unspecified", type checkers may handle it
+as they best see fit or report an error. Linters should usually
+flag those constructs. Type stub authors should avoid using them to
+ensure compatibility across type checkers.
+
+Unless otherwise mentioned, type stubs support all features from the
+``typing`` module of the latest released Python version. If a stub uses
+typing features from a later Python version than what the implementation
+supports, these features can be imported from ``typing_extensions`` instead
+of ``typing``.
+
+For example, a stub could use ``Literal``, introduced in Python 3.8,
+for a library supporting Python 3.7+::
+
+    from typing_extensions import Literal
+
+    def foo(x: Literal[""]) -> int: ...
+
+Comments
+--------
+
+Standard Python comments are accepted everywhere Python syntax allows them.
+
+Two kinds of structured comments are accepted:
+
+* A ``# type: X`` comment at the end of a line that defines a variable,
+  declaring that the variable has type ``X``. However, PEP 526-style [#pep526]_
+  variable annotations are preferred over type comments.
+* A ``# type: ignore`` comment at the end of any line, which suppresses all type
+  errors in that line. The type checker mypy supports suppressing certain
+  type errors by using ``# type: ignore[error-type]``. This is not supported
+  by other type checkers and should not be used in stubs.
+
+Imports
+-------
+
+Type stubs distinguish between imports that are re-exported and those
+that are only used internally. Imports are re-exported if they use one of these
+forms:[#pep484]_
+
+* ``import X as X``
+* ``from Y import X as X``
+* ``from Y import *``
+
+Here are some examples of imports that make names available for internal use in
+a stub but do not re-export them::
+
+    import X
+    from Y import X
+    from Y import X as OtherX
+
+Type aliases can be used to re-export an import under a different name::
+
+    from foo import bar as _bar
+    new_bar = _bar  # "bar" gets re-exported with the name "new_bar"
+
+Sub-modules are always exported when they are imported in a module.
+For example, consider the following file structure::
+
+    foo/
+        __init__.pyi
+        bar.pyi
+
+Then ``foo`` will export ``bar`` when one of the following constructs is used in
+``__init__.pyi``::
+
+    from . import bar
+    from .bar import Bar
+
+Stubs support customizing star import semantics by defining a module-level
+variable called ``__all__``. In stubs, this must be a string list literal.
+Other types are not supported. Neither is the dynamic creation of this
+variable (for example by concatenation).
+
+By default, ``from foo import *`` imports all names in ``foo`` that
+do not begin with an underscore. When ``__all__`` is defined, only those names
+specified in ``__all__`` are imported::
+
+    __all__ = ['public_attr', '_private_looking_public_attr']
+
+    public_attr: int
+    _private_looking_public_attr: int
+    private_attr: int
+
+Type checkers support cyclic imports in stub files.
+
+Built-in Generics
+-----------------
+
+PEP 585 [#pep585]_ built-in generics are supported and should be used instead
+of the corresponding types from ``typing``::
+
+    from collections import defaultdict
+
+    def foo(t: type[MyClass]) -> list[int]: ...
+    x: defaultdict[int]
+
+Using imports from ``collections.abc`` instead of ``typing`` is
+generally possible and recommended::
+
+    from collections.abc import Iterable
+
+    def foo(iter: Iterable[int]) -> None: ...
+
+Unions
+------
+
+Declaring unions with ``Union`` and ``Optional`` is supported by all
+type checkers. With a few exceptions [#ts-4819]_, the shorthand syntax
+is also supported::
+
+    def foo(x: int | str) -> int | None: ...  # recommended
+    def foo(x: Union[int, str]) -> Optional[int]: ...  # ok
+
+Module Level Attributes
+-----------------------
+
+Module level variables and constants can be annotated using either
+type comments or variable annotation syntax::
+
+    x: int  # recommended
+    x: int = 0
+    x = 0  # type: int
+    x = ...  # type: int
+
+The type of a variable is unspecified when the variable is unannotated or
+when the annotation
+and the assigned value disagree. As an exception, the ellipsis literal can
+stand in for any type::
+
+    x = 0  # type is unspecified
+    x = ...  # type is unspecified
+    x: int = ""  # type is unspecified
+    x: int = ...  # type is int
+
+Classes
+-------
+
+Class definition syntax follows general Python syntax, but type checkers
+are only expected to understand the following constructs in class bodies:
+
+* The ellipsis literal ``...`` is ignored and used for empty
+  class bodies. Using ``pass`` in class bodies is undefined.
+* Instance attributes follow the same rules as module level attributes
+  (see above).
+* Method definitions (see below) and properties.
+* Method aliases.
+* Inner class definitions.
+
+More complex statements don't need to be supported::
+
+    class Simple: ...
+
+    class Complex(Base):
+        read_write: int
+        @property
+        def read_only(self) -> int: ...
+        def do_stuff(self, y: str) -> None: ...
+        doStuff = do_stuff
+
+The type of generic classes can be narrowed by annotating the ``self``
+argument of the ``__init__`` method::
+
+    class Foo(Generic[_T]):
+        @overload
+        def __init__(self: Foo[str], type: Literal["s"]) -> None: ...
+        @overload
+        def __init__(self: Foo[int], type: Literal["i"]) -> None: ...
+        @overload
+        def __init__(self, type: str) -> None: ...
+
+The class must match the class in which it is declared. Using other classes,
+including sub or super classes, will not work. In addition, the ``self``
+annotation cannot contain type variables.
+
+.. _supported-functions:
+
+Functions and Methods
+---------------------
+
+Function and method definition syntax follows general Python syntax.
+Unless an argument name is prefixed with two underscores (but not suffixed
+with two underscores), it can be used as a keyword argument [#pep484]_::
+
+    # x is positional-only
+    # y can be used positionally or as keyword argument
+    # z is keyword-only
+    def foo(__x, y, *, z): ...
+
+PEP 570 [#pep570]_ style positional-only parameters are currently not
+supported.
+
+If an argument or return type is unannotated, per PEP 484 [#pep484]_ its
+type is assumed to be ``Any``. It is preferred to leave unknown
+types unannotated rather than explicitly marking them as ``Any``, as some
+type checkers can optionally warn about unannotated arguments.
+
+If an argument has a literal or constant default value, it must match the implementation
+and the type of the argument (if specified) must match the default value.
+Alternatively, ``...`` can be used in place of any default value::
+
+    # The following arguments all have type Any.
+    def unannotated(a, b=42, c=...): ...
+    # The following arguments all have type int.
+    def annotated(a: int, b: int = 42, c: int = ...): ...
+    # The following default values are invalid and the types are unspecified.
+    def invalid(a: int = "", b: Foo = Foo()): ...
+
+For a class ``C``, the type of the first argument to a classmethod is
+assumed to be ``type[C]``, if unannotated. For other non-static methods,
+its type is assumed to be ``C``::
+
+    class Foo:
+        def do_things(self): ...  # self has type Foo
+        @classmethod
+        def create_it(cls): ...  # cls has type Type[Foo]
+        @staticmethod
+        def utility(x): ...  # x has type Any
+
+But::
+
+    _T = TypeVar("_T")
+
+    class Foo:
+        def do_things(self: _T) -> _T: ...  # self has type _T
+        @classmethod
+        def create_it(cls: _T) -> _T: ...  # cls has type _T
+
+PEP 612 [#pep612]_ parameter specification variables (``ParamSpec``)
+are supported in argument and return types::
+
+    _P = ParamSpec("_P")
+    _R = TypeVar("_R")
+
+    def foo(cb: Callable[_P, _R], *args: _P.args, **kwargs: _P.kwargs) -> _R: ...
+
+However, ``Concatenate`` from PEP 612 is not yet supported; nor is using
+a ``ParamSpec`` to parameterize a generic class.
+
+PEP 647 [#pep647]_ type guards are supported.
+
+Using a function or method body other than the ellipsis literal is currently
+unspecified. Stub authors may experiment with other bodies, but it is up to
+individual type checkers how to interpret them::
+
+    def foo(): ...  # compatible
+    def bar(): pass  # behavior undefined
+
+All variants of overloaded functions and methods must have an ``@overload``
+decorator::
+
+    @overload
+    def foo(x: str) -> str: ...
+    @overload
+    def foo(x: float) -> int: ...
+
+The following (which would be used in the implementation) is wrong in
+type stubs::
+
+    @overload
+    def foo(x: str) -> str: ...
+    @overload
+    def foo(x: float) -> int: ...
+    def foo(x: str | float) -> Any: ...
+
+Aliases and NewType
+-------------------
+
+Type checkers should accept module-level type aliases, optionally using
+``TypeAlias`` (PEP 613 [#pep613]_), e.g.::
+
+  _IntList = list[int]
+  _StrList: TypeAlias = list[str]
+
+Type checkers should also accept regular module-level or class-level aliases,
+e.g.::
+
+  def a() -> None: ...
+  b = a
+
+  class C:
+      def f(self) -> int: ...
+      g = f
+
+A type alias may contain type variables. As per PEP 484 [#pep484]_,
+all type variables must be substituted when the alias is used::
+
+  _K = TypeVar("_K")
+  _V = TypeVar("_V")
+  _MyMap: TypeAlias = dict[str, dict[_K, _V]]
+
+  # either concrete types or other type variables can be substituted
+  def f(x: _MyMap[str, _V]) -> _V: ...
+  # explicitly substitute in Any rather than using a bare alias
+  def g(x: _MyMap[Any, Any]) -> Any: ...
+
+Otherwise, type variables in aliases follow the same rules as type variables in
+generic class definitions.
+
+``typing.NewType`` is also supported in stubs.
+
+Decorators
+----------
+
+Type stubs may only use decorators defined in the ``typing`` module, plus a
+fixed set of additional ones:
+
+* ``classmethod``
+* ``staticmethod``
+* ``property`` (including ``.setter``)
+* ``abc.abstractmethod``
+* ``dataclasses.dataclass``
+* ``asyncio.coroutine`` (although ``async`` should be used instead)
+
+The behavior of other decorators should instead be incorporated into the types.
+For example, for the following function::
+
+  import contextlib
+  @contextlib.contextmanager
+  def f():
+      yield 42
+
+the stub definition should be::
+
+  from contextlib import AbstractContextManager
+  def f() -> AbstractContextManager[int]: ...
+
+Version and Platform Checks
+---------------------------
+
+Type stubs for libraries that support multiple Python versions can use version
+checks to supply version-specific type hints. Type stubs for different Python
+versions should still conform to the most recent supported Python version's
+syntax, as explain in the Syntax_ section above.
+
+Version checks are if-statements that use ``sys.version_info`` to determine the
+current Python version. Version checks should only check against the ``major`` and
+``minor`` parts of ``sys.version_info``. Type checkers are only required to
+support the tuple-based version check syntax::
+
+    if sys.version_info >= (3,):
+        # Python 3-specific type hints. This tuple-based syntax is recommended.
+    else:
+        # Python 2-specific type hints.
+
+    if sys.version_info >= (3, 5):
+        # Specific minor version features can be easily checked with tuples.
+
+    if sys.version_info < (3,):
+        # This is only necessary when a feature has no Python 3 equivalent.
+
+Type stubs should avoid checking against ``sys.version_info.major``
+directly and should not use comparison operators other than ``<`` and ``>=``.
+
+No::
+
+    if sys.version_info.major >= 3:
+        # Semantically the same as the first tuple check.
+
+    if sys.version_info[0] >= 3:
+        # This is also the same.
+
+    if sys.version_info <= (2, 7):
+        # This does not work because e.g. (2, 7, 1) > (2, 7).
+
+Some type stubs also may need to specify type hints for different platforms.
+Platform checks must be equality comparisons between ``sys.platform`` and the name
+of a platform as a string literal:
+
+Yes::
+
+    if sys.platform == 'win32':
+        # Windows-specific type hints.
+    else:
+        # Posix-specific type hints.
+
+No::
+
+    if sys.platform.startswith('linux'):
+        # Not necessary since Python 3.3.
+
+    if sys.platform in ['linux', 'cygwin', 'darwin']:
+        # Only '==' or '!=' should be used in platform checks.
+
+Version and platform comparisons can be chained using the ``and`` and ``or``
+operators::
+
+    if sys.platform == 'linux' and (sys.version_info < (3,) or sys,version_info >= (3, 7)): ...
+
+Enums
+-----
+
+Enum classes are supported in stubs, regardless of the Python version targeted by
+the stubs.
+
+Enum members may be specified just like other forms of assignments, for example as
+``x: int``, ``x = 0``, or ``x = ...``.  The first syntax is preferred because it
+allows type checkers to correctly type the ``.value`` attribute of enum members,
+without providing unnecessary information like the runtime value of the enum member.
+
+Additional properties on enum members should be specified with ``@property``, so they
+do not get interpreted by type checkers as enum members.
+
+Yes::
+
+    from enum import Enum
+    
+    class Color(Enum):
+        RED: int
+        BLUE: int
+        @property
+        def rgb_value(self) -> int: ...
+
+    class Color(Enum):
+        # discouraged; type checkers will not understand that Color.RED.value is an int
+        RED = ...
+        BLUE = ...
+        @property
+        def rgb_value(self) -> int: ...
+
+No::
+
+    from enum import Enum
+    
+    class Color(Enum):
+        RED: int
+        BLUE: int
+        rgb_value: int  # no way for type checkers to know that this is not an enum member
+
+Unsupported Features
+--------------------
+
+Currently, the following features are not supported by all type checkers
+and should not be used in stubs:
+
+* Positional-only argument syntax (PEP 570 [#pep570]_). Instead, use
+  the syntax described in the section :ref:`supported-functions`.
+  [#ts-4972]_
+
+Type Stub Content
+=================
+
+This section documents best practices on what elements to include or
+leave out of type stubs.
+
+Modules excluded fom stubs
+--------------------------
+
+Not all modules should be included into stubs.
+
+It is recommended to exclude:
+
+1. Implementation details, with `multiprocessing/popen_spawn_win32.py <https://github.com/python/cpython/blob/main/Lib/multiprocessing/popen_spawn_win32.py>`_ as a notable example
+2. Modules that are not supposed to be imported, such as ``__main__.py``
+3. Protected modules that start with a single ``_`` char. However, when needed protected modules can still be added (see :ref:`undocumented-objects` section below)
+
+Public Interface
+----------------
+
+Stubs should include the complete public interface (classes, functions,
+constants, etc.) of the module they cover, but it is not always
+clear exactly what is part of the interface.
+
+The following should always be included:
+
+* All objects listed in the module's documentation.
+* All objects included in ``__all__`` (if present).
+
+Other objects may be included if they are not prefixed with an underscore
+or if they are being used in practice. (See the next section.)
+
+.. _undocumented-objects:
+
+Undocumented Objects
+--------------------
+
+Undocumented objects may be included as long as they are marked with a comment
+of the form ``# undocumented``.
+
+Example::
+
+    def list2cmdline(seq: Sequence[str]) -> str: ...  # undocumented
+
+Such undocumented objects are allowed because omitting objects can confuse
+users. Users who see an error like "module X has no attribute Y" will
+not know whether the error appeared because their code had a bug or
+because the stub is wrong. Although it may also be helpful for a type
+checker to point out usage of private objects, false negatives (no errors for
+wrong code) are preferable over false positives (type errors
+for correct code). In addition, even for private objects a type checker
+can be helpful in pointing out that an incorrect type was used.
+
+``__all__``
+------------
+
+A type stub should contain an ``__all__`` variable if and only if it also
+present at runtime. In that case, the contents of ``__all__`` should be
+identical in the stub and at runtime. If the runtime dynamically adds
+or removes elements (for example if certain functions are only available on
+some platforms), include all possible elements in the stubs.
+
+Stub-Only Objects
+-----------------
+
+Definitions that do not exist at runtime may be included in stubs to aid in
+expressing types. Sometimes, it is desirable to make a stub-only class available
+to a stub's users - for example, to allow them to type the return value of a
+public method for which a library does not provided a usable runtime type::
+
+  from typing import Protocol
+
+  class _Readable(Protocol):
+      def read(self) -> str: ...
+
+  def get_reader() -> _Readable: ...
+
+Structural Types
+----------------
+
+As seen in the example with ``_Readable`` in the previous section, a common use
+of stub-only objects is to model types that are best described by their
+structure. These objects are called protocols [#pep544]_, and it is encouraged
+to use them freely to describe simple structural types.
+
+It is `recommended <#private-definitions>`_ to prefix stubs-only object names with ``_``.
+
+Incomplete Stubs
+----------------
+
+Partial stubs can be useful, especially for larger packages, but they should
+follow the following guidelines:
+
+* Included functions and methods should list all arguments, but the arguments
+  can be left unannotated.
+* Do not use ``Any`` to mark unannotated arguments or return values.
+* Partial classes should include a ``__getattr__()`` method marked with an
+  ``# incomplete`` comment (see example below).
+* Partial modules (i.e. modules that are missing some or all classes,
+  functions, or attributes) should include a top-level ``__getattr__()``
+  function marked with an ``# incomplete`` comment (see example below).
+* Partial packages (i.e. packages that are missing one or more sub-modules)
+  should have a ``__init__.pyi`` stub that is marked as incomplete (see above).
+  A better alternative is to create empty stubs for all sub-modules and
+  mark them as incomplete individually.
+
+Example of a partial module with a partial class ``Foo`` and a partially
+annotated function ``bar()``::
+
+    def __getattr__(name: str) -> Any: ...  # incomplete
+
+    class Foo:
+        def __getattr__(self, name: str) -> Any:  # incomplete
+        x: int
+        y: str
+
+    def bar(x: str, y, *, z=...): ...
+
+The ``# incomplete`` comment is mainly intended as a reminder for stub
+authors, but can be used by tools to flag such items.
+
+Attribute Access
+----------------
+
+Python has several methods for customizing attribute access: ``__getattr__``,
+``__getattribute__``, ``__setattr__``, and ``__delattr__``. Of these,
+``__getattr__`` and ``__setattr___`` should sometimes be included in stubs.
+
+In addition to marking incomplete definitions, ``__getattr__`` should be
+included when a class or module allows any name to be accessed. For example, consider
+the following class::
+
+  class Foo:
+      def __getattribute__(self, name):
+          return self.__dict__.setdefault(name)
+
+An appropriate stub definition is::
+
+  from typing import Any
+  class Foo:
+      def __getattr__(self, name: str) -> Any | None: ...
+
+Note that only ``__getattr__``, not ``__getattribute__``, is guaranteed to be
+supported in stubs.
+
+On the other hand, ``__getattr__`` should be omitted even if the source code
+includes it, if only limited names are allowed. For example, consider this class::
+
+  class ComplexNumber:
+      def __init__(self, n):
+          self._n = n
+      def __getattr__(self, name):
+          if name in ("real", "imag"):
+              return getattr(self._n, name)
+          raise AttributeError(name)
+
+In this case, the stub should list the attributes individually::
+
+  class ComplexNumber:
+      @property
+      def real(self) -> float: ...
+      @property
+      def imag(self) -> float: ...
+      def __init__(self, n: complex) -> None: ...
+
+``__setattr___`` should be included when a class allows any name to be set and
+restricts the type. For example::
+
+  class IntHolder:
+      def __setattr__(self, name, value):
+          if isinstance(value, int):
+              return super().__setattr__(name, value)
+          raise ValueError(value)
+
+A good stub definition would be::
+
+  class IntHolder:
+      def __setattr__(self, name: str, value: int) -> None: ...
+
+``__delattr__`` should not be included in stubs.
+
+Finally, even in the presence of ``__getattr__`` and ``__setattr__``, it is
+still recommended to separately define known attributes.
+
+Constants
+---------
+
+When the value of a constant is important, annotate it using ``Literal``
+instead of its type.
+
+Yes::
+
+    TEL_LANDLINE: Literal["landline"]
+    TEL_MOBILE: Literal["mobile"]
+    DAY_FLAG: Literal[0x01]
+    NIGHT_FLAG: Literal[0x02]
+
+No::
+
+    TEL_LANDLINE: str
+    TEL_MOBILE: str
+    DAY_FLAG: int
+    NIGHT_FLAG: int
+
+Documentation or Implementation
+-------------------------------
+
+Sometimes a library's documented types will differ from the actual types in the
+code. In such cases, type stub authors should use their best judgment. Consider
+these two examples::
+
+  def print_elements(x):
+      """Print every element of list x."""
+      for y in x:
+          print(y)
+
+  def maybe_raise(x):
+      """Raise an error if x (a boolean) is true."""
+      if x:
+          raise ValueError()
+
+The implementation of ``print_elements`` takes any iterable, despite the
+documented type of ``list``. In this case, annotate the argument as
+``Iterable[Any]``, to follow this PEP's style recommendation of preferring
+abstract types.
+
+For ``maybe_raise``, on the other hand, it is better to annotate the argument as
+``bool`` even though the implementation accepts any object. This guards against
+common mistakes like unintentionally passing in ``None``.
+
+If in doubt, consider asking the library maintainers about their intent.
+
+Style Guide
+===========
+
+The recommendations in this section are aimed at type stub authors
+who wish to provide a consistent style for type stubs. Type checkers
+should not reject stubs that do not follow these recommendations, but
+linters can warn about them.
+
+Stub files should generally follow the Style Guide for Python Code (PEP 8)
+[#pep8]_. There are a few exceptions, outlined below, that take the
+different structure of stub files into account and are aimed to create
+more concise files.
+
+Maximum Line Length
+-------------------
+
+Type stubs should be limited to 130 characters per line.
+
+Blank Lines
+-----------
+
+Do not use empty lines between functions, methods, and fields, except to
+group them with one empty line. Use one empty line around classes, but do not
+use empty lines between body-less classes, except for grouping.
+
+Yes::
+
+    def time_func() -> None: ...
+    def date_func() -> None: ...
+
+    def ip_func() -> None: ...
+
+    class Foo:
+        x: int
+        y: int
+        def __init__(self) -> None: ...
+
+    class MyError(Exception): ...
+    class AnotherError(Exception): ...
+
+No::
+
+    def time_func() -> None: ...
+
+    def date_func() -> None: ...  # do no leave unnecessary empty lines
+
+    def ip_func() -> None: ...
+
+
+    class Foo:  # leave only one empty line above
+        x: int
+    class MyError(Exception): ...  # leave an empty line between the classes
+
+Shorthand Syntax
+----------------
+
+Where possible, use shorthand syntax for unions instead of
+``Union`` or ``Optional``. ``None`` should be the last
+element of an union.
+
+Yes::
+
+    def foo(x: str | int) -> None: ...
+    def bar(x: str | None) -> int | None: ...
+
+No::
+
+    def foo(x: Union[str, int]) -> None: ...
+    def bar(x: Optional[str]) -> Optional[int]: ...
+    def baz(x: None | str) -> None: ...
+
+Module Level Attributes
+-----------------------
+
+Do not use an assignment for module-level attributes.
+
+Yes::
+
+    CONST: Literal["const"]
+    x: int
+
+No::
+
+    CONST = "const"
+    x: int = 0
+    y: float = ...
+    z = 0  # type: int
+    a = ...  # type: int
+
+Type Aliases
+------------
+
+Use ``TypeAlias`` for type aliases (but not for regular aliases).
+
+Yes::
+
+    _IntList: TypeAlias = list[int]
+    g = os.stat
+    Path = pathlib.Path
+    ERROR = errno.EEXIST
+
+No::
+
+    _IntList = list[int]
+    g: TypeAlias = os.stat
+    Path: TypeAlias = pathlib.Path
+    ERROR: TypeAlias = errno.EEXIST
+
+Classes
+-------
+
+Classes without bodies should use the ellipsis literal ``...`` in place
+of the body on the same line as the class definition.
+
+Yes::
+
+    class MyError(Exception): ...
+
+No::
+
+    class MyError(Exception):
+        ...
+    class AnotherError(Exception): pass
+
+Instance attributes and class variables follow the same recommendations as
+module level attributes:
+
+Yes::
+
+    class Foo:
+        c: ClassVar[str]
+        x: int
+
+No::
+
+    class Foo:
+        c: ClassVar[str] = ""
+        d: ClassVar[int] = ...
+        x = 4
+        y: int = ...
+
+Functions and Methods
+---------------------
+
+Use the same argument names as in the implementation, because
+otherwise using keyword arguments will fail. Of course, this
+does not apply to positional-only arguments, which are marked with a double
+underscore.
+
+Use the ellipsis literal ``...`` in place of actual default argument
+values. Use an explicit ``X | None`` annotation instead of
+a ``None`` default.
+
+Yes::
+
+    def foo(x: int = ...) -> None: ...
+    def bar(y: str | None = ...) -> None: ...
+
+No::
+
+    def foo(x: int = 0) -> None: ...
+    def bar(y: str = None) -> None: ...
+    def baz(z: str | None = None) -> None: ...
+
+Do not annotate ``self`` and ``cls`` in method definitions, except when
+referencing a type variable.
+
+Yes::
+
+    _T = TypeVar("_T")
+    class Foo:
+        def bar(self) -> None: ...
+        @classmethod
+        def create(cls: type[_T]) -> _T: ...
+
+No::
+
+    class Foo:
+        def bar(self: Foo) -> None: ...
+        @classmethod
+        def baz(cls: type[Foo]) -> int: ...
+
+The bodies of functions and methods should consist of only the ellipsis
+literal ``...`` on the same line as the closing parenthesis and colon.
+
+Yes::
+
+    def to_int1(x: str) -> int: ...
+    def to_int2(
+        x: str,
+    ) -> int: ...
+
+No::
+
+    def to_int1(x: str) -> int:
+        return int(x)
+    def to_int2(x: str) -> int:
+        ...
+    def to_int3(x: str) -> int: pass
+
+.. _private-definitions:
+
+Private Definitions
+-------------------
+
+Type variables, type aliases, and other definitions that should not
+be used outside the stub should be marked as private by prefixing them
+with an underscore.
+
+Yes::
+
+    _T = TypeVar("_T")
+    _DictList = Dict[str, List[Optional[int]]
+
+No::
+
+    T = TypeVar("T")
+    DictList = Dict[str, List[Optional[int]]]
+
+Language Features
+-----------------
+
+Use the latest language features available as outlined
+in the Syntax_ section, even for stubs targeting older Python versions.
+Do not use quotes around forward references and do not use ``__future__``
+imports.
+
+Yes::
+
+    class Py35Class:
+        x: int
+        forward_reference: OtherClass
+    class OtherClass: ...
+
+No::
+
+    class Py35Class:
+        x = 0  # type: int
+        forward_reference: 'OtherClass'
+    class OtherClass: ...
+
+Types
+-----
+
+Generally, use ``Any`` when a type cannot be expressed appropriately
+with the current type system or using the correct type is unergonomic.
+
+Use ``float`` instead of ``int | float``.
+Use ``None`` instead of ``Literal[None]``.
+For argument types,
+use ``bytes`` instead of ``bytes | memoryview | bytearray``.
+
+Use ``Text`` in stubs that support Python 2 when something accepts both
+``str`` and ``unicode``. Avoid using ``Text`` in stubs or branches for
+Python 3 only.
+
+Yes::
+
+    if sys.version_info < (3,):
+        def foo(s: Text) -> None: ...
+    else:
+        def foo(s: str, *, i: int) -> None: ...
+    def bar(s: Text) -> None: ...
+
+No::
+
+    if sys.version_info < (3,):
+        def foo(s: unicode) -> None: ...
+    else:
+        def foo(s: Text, *, i: int) -> None: ...
+
+For arguments, prefer protocols and abstract types (``Mapping``,
+``Sequence``, ``Iterable``, etc.). If an argument accepts literally any value,
+use ``object`` instead of ``Any``.
+
+For return values, prefer concrete types (``list``, ``dict``, etc.) for
+concrete implementations. The return values of protocols
+and abstract base classes must be judged on a case-by-case basis.
+
+Yes::
+
+    def map_it(input: Iterable[str]) -> list[int]: ...
+    def create_map() -> dict[str, int]: ...
+    def to_string(o: object) -> str: ...  # accepts any object
+
+No::
+
+    def map_it(input: list[str]) -> list[int]: ...
+    def create_map() -> MutableMapping[str, int]: ...
+    def to_string(o: Any) -> str: ...
+
+Maybe::
+
+    class MyProto(Protocol):
+        def foo(self) -> list[int]: ...
+        def bar(self) -> Mapping[str]: ...
+
+Avoid union return types, since they require ``isinstance()`` checks.
+Use ``Any`` or ``X | Any`` if necessary.
+
+Use built-in generics instead of the aliases from ``typing``,
+where possible. See the section `Built-in Generics`_ for cases,
+where it's not possible to use them.
+
+Yes::
+
+    from collections.abc import Iterable
+
+    def foo(x: type[MyClass]) -> list[str]: ...
+    def bar(x: Iterable[str]) -> None: ...
+
+No::
+
+    from typing import Iterable, List, Type
+
+    def foo(x: Type[MyClass]) -> List[str]: ...
+    def bar(x: Iterable[str]) -> None: ...
+
+NamedTuple and TypedDict
+------------------------
+
+Use the class-based syntax for ``typing.NamedTuple`` and
+``typing.TypedDict``, following the Classes section of this style guide.
+
+Yes::
+
+    from typing import NamedTuple, TypedDict
+    class Point(NamedTuple):
+        x: float
+        y: float
+
+    class Thing(TypedDict):
+        stuff: str
+        index: int
+
+No::
+
+    from typing import NamedTuple, TypedDict
+    Point = NamedTuple("Point", [('x', float), ('y', float)])
+    Thing = TypedDict("Thing", {'stuff': str, 'index': int})
+
+References
+==========
+
+PEPs
+----
+
+.. [#pep8] PEP 8 -- Style Guide for Python Code, van Rossum et al. (https://www.python.org/dev/peps/pep-0008/)
+.. [#pep484] PEP 484 -- Type Hints, van Rossum et al. (https://www.python.org/dev/peps/pep-0484)
+.. [#pep492] PEP 492 -- Coroutines with async and await syntax, Selivanov (https://www.python.org/dev/peps/pep-0492/)
+.. [#pep526] PEP 526 -- Syntax for Variable Annotations, Gonzalez et al. (https://www.python.org/dev/peps/pep-0526)
+.. [#pep544] PEP 544 -- Protocols: Structural Subtyping, Levkivskyi et al. (https://www.python.org/dev/peps/pep-0544)
+.. [#pep561] PEP 561 -- Distributing and Packaging Type Information, Smith (https://www.python.org/dev/peps/pep-0561)
+.. [#pep570] PEP 570 -- Python Positional-Only Parameters, Hastings et al. (https://www.python.org/dev/peps/pep-0570)
+.. [#pep585] PEP 585 -- Type Hinting Generics In Standard Collections, Langa (https://www.python.org/dev/peps/pep-0585)
+.. [#pep604] PEP 604 -- Allow writing union types as X | Y, Prados and Moss (https://www.python.org/dev/peps/pep-0604)
+.. [#pep612] PEP 612 -- Parameter Specification Variables, Mendoza (https://www.python.org/dev/peps/pep-0612)
+.. [#pep613] PEP 613 -- Explicit Type Aliases, Zhu (https://www.python.org/dev/peps/pep-0613)
+.. [#pep647] PEP 647 -- User-Defined Type Guards, Traut (https://www.python.org/dev/peps/pep-0647)
+.. [#pep3107] PEP 3107 -- Function Annotations, Winter and Lownds (https://www.python.org/dev/peps/pep-3107)
+
+Bugs
+----
+
+.. [#ts-4819] typeshed issue #4819 -- PEP 604 tracker (https://github.com/python/typeshed/issues/4819)
+.. [#ts-4972] typeshed issue #4972 -- PEP 570 tracker (https://github.com/python/typeshed/issues/4972)
+
+Copyright
+=========
+
+This document is placed in the public domain or under the CC0-1.0-Universal license, whichever is more permissive.
diff --git a/docs/source/type_compatibility.rst b/docs/source/type_compatibility.rst
new file mode 100644
index 0000000..43ebd32
--- /dev/null
+++ b/docs/source/type_compatibility.rst
@@ -0,0 +1,17 @@
+******************
+Type Compatibility
+******************
+
+
+The Class Hierarchy
+===================
+
+Mutable Containers
+------------------
+
+Comparing Callables: Covariance and Contravariance
+--------------------------------------------------
+
+
+Metaclasses
+===========
diff --git a/docs/source/type_system.rst b/docs/source/type_system.rst
new file mode 100644
index 0000000..6d7954b
--- /dev/null
+++ b/docs/source/type_system.rst
@@ -0,0 +1,58 @@
+***************
+The Type System
+***************
+
+Built-in Types
+==============
+
+`typing Module Documentation <https://docs.python.org/3/library/typing.html>`__
+
+Built-in Primitives
+-------------------
+
+Built-in operators
+------------------
+
+Advanced Types
+--------------
+
+
+Simple User-Defined Types
+=========================
+
+
+Type Aliases
+============
+
+Recursive Aliases
+-----------------
+
+
+Data Structures
+===============
+
+Typed Dictionary
+----------------
+
+Dataclass
+---------
+
+
+Generic Types
+=============
+
+
+Type Variables
+==============
+
+TypeVar
+-------
+
+Variadics
+---------
+
+ParamSpec
+^^^^^^^^^
+
+TypeVarTuple
+^^^^^^^^^^^^
diff --git a/docs/source/unreachable.rst b/docs/source/unreachable.rst
new file mode 100644
index 0000000..16c37d8
--- /dev/null
+++ b/docs/source/unreachable.rst
@@ -0,0 +1,148 @@
+.. _unreachable:
+
+********************************************
+Unreachable Code and Exhaustiveness Checking
+********************************************
+
+Sometimes it is necessary to write code that should never execute, and
+sometimes we write code that we expect to execute, but that is actually
+unreachable. The type checker can help in both cases.
+
+In this guide, we'll cover:
+
+- ``Never``, the primitive type used for unreachable code
+- ``assert_never()``, a helper for exhaustiveness checking
+- Directly marking code as unreachable
+- Detecting unexpectedly unreachable code
+
+``Never`` and ``NoReturn``
+==========================
+
+Type theory has a concept of a
+`bottom type <https://en.wikipedia.org/wiki/Bottom_type>`__,
+a type that has no values. Concretely, this can be used to represent
+the return type of a function that never returns, or the argument type
+of a function that may never be called. You can also think of the
+bottom type as a union with no members.
+
+The Python type system has long provided a type called ``NoReturn``.
+While it was originally meant only for functions that never return,
+this concept is naturally extended to the bottom type in general, and all
+type checkers treat ``NoReturn`` as a general bottom type.
+
+To make the meaning of this type more explicit, Python 3.11 and
+typing-extensions 4.1 add a new primitive, ``Never``. To type checkers,
+it has the same meaning as ``NoReturn``.
+
+In this guide, we'll use ``Never`` for the bottom type, but if you cannot
+use it yet, you can always use ``typing.NoReturn`` instead.
+
+``assert_never()`` and Exhaustiveness Checking
+==============================================
+
+The ``Never`` type can be leveraged to perform static exhaustiveness checking,
+where we use the type checker to make sure that we covered all possible
+cases. For example, this can come up when code performs a separate action
+for each member of an enum, or for each type in a union.
+
+To have the type checker do exhaustiveness checking for us, we call a
+function with a parameter typed as ``Never``. The type checker will allow
+this call only if it can prove that the code is not reachable.
+
+As an example, consider this simple calculator:
+
+.. code:: python
+
+   import enum
+   from typing_extensions import Never
+
+   def assert_never(arg: Never) -> Never:
+       raise AssertionError("Expected code to be unreachable")
+
+   class Op(enum.Enum):
+       ADD = 1
+       SUBTRACT = 2
+
+   def calculate(left: int, op: Op, right: int) -> int:
+       match op:
+           case Op.ADD:
+               return left + right
+           case Op.SUBTRACT:
+               return left - right
+           case _:
+               assert_never(op)
+
+The ``match`` statement covers all members of the ``Op`` enum,
+so the ``assert_never()`` call is unreachable and the type checker
+will accept this code. However, if you add another member to the
+enum (say, ``MULTIPLY``) but don't update the ``match`` statement,
+the type checker will give an error saying that you are not handling
+the ``MULTIPLY`` case.
+
+Because the ``assert_never()`` helper function is frequently useful,
+it is provided by the standard library as ``typing.assert_never``
+starting in Python 3.11,
+and is also present in ``typing_extensions`` starting at version 4.1.
+However, it is also possible to define a similar function in your own
+code, for example if you want to customize the runtime error message.
+
+You can also use ``assert_never()`` with a sequence of ``if`` statements:
+
+.. code:: python
+
+   def calculate(left: int, op: Op, right: int) -> int:
+       if op is Op.ADD:
+           return left + right
+       elif op is Op.SUBTRACT:
+           return left - right
+       else:
+           assert_never(op)
+
+Marking Code as Unreachable
+=======================
+
+Sometimes a piece of code is unreachable, but the type system is not
+powerful enough to recognize that. For example, consider a function that
+finds the lowest unused street number in a street:
+
+.. code:: python
+
+   import itertools
+
+   def is_used(street: str, number: int) -> bool:
+       ...
+ 
+   def lowest_unused(street: str) -> int:
+       for i in itertools.count(1):
+           if not is_used(street, i):
+               return i
+       assert False, "unreachable"
+
+Because ``itertools.count()`` is an infinite iterator, this function
+will never reach the ``assert False`` statement. However, there is
+no way for the type checker to know that, so without the ``assert False``,
+the type checker will complain that the function is missing a return
+statement.
+
+Note how this is different from ``assert_never()``:
+
+- If we used ``assert_never()`` in the ``lowest_unused()`` function,
+  the type checker would produce an error, because the type checker
+  cannot prove that the line is unreachable.
+- If we used ``assert False`` instead of ``assert_never()`` in the
+  ``calculate()`` example above, we would not get the benefits of
+  exhaustiveness checking. If the code is actually reachable,
+  the type checker will not warn us and we could hit the assertion
+  at runtime.
+
+While ``assert False`` is the most idiomatic way to express this pattern,
+any statement that ends execution will do. For example, you could raise
+an exception or call a function that returns ``Never``.
+
+Detecting Unexpectedly Unreachable Code
+=======================================
+
+Another possible problem is code that is supposed to execute, but that
+can actually be statically determined to be unreachable.
+Some type checkers have an option that enables warnings for code
+detected as unreachable (e.g., ``--warn-unreachable`` in mypy).
diff --git a/scripts/requirements.txt b/scripts/requirements.txt
new file mode 100644
index 0000000..d5f8f29
--- /dev/null
+++ b/scripts/requirements.txt
@@ -0,0 +1,2 @@
+requests>=2.25.0,<3
+types-requests>=2.25.0,<3
diff --git a/scripts/typing-summary.py b/scripts/typing-summary.py
new file mode 100755
index 0000000..f5f9825
--- /dev/null
+++ b/scripts/typing-summary.py
@@ -0,0 +1,144 @@
+#!/usr/bin/env python3
+
+"""
+Generate a summary of last week's issues tagged with "topic: feature".
+
+The summary will include a list of new and changed issues and is sent each
+Monday at 0200 CE(S)T to the typing-sig mailing list. Due to limitation
+with GitHub Actions, the mail is sent from a private server, currently
+maintained by @srittau.
+"""
+
+from __future__ import annotations
+
+import datetime
+from dataclasses import dataclass
+from typing import Any, Iterable, Sequence
+
+import requests
+
+ISSUES_API_URL = "https://api.github.com/repos/python/typing/issues"
+ISSUES_URL = "https://github.com/python/typing/issues?q=label%3A%22topic%3A+feature%22"
+ISSUES_LABEL = "topic: feature"
+SENDER_EMAIL = "Typing Bot <noreply@python.org>"
+RECEIVER_EMAIL = "typing-sig@python.org"
+
+
+@dataclass
+class Issue:
+    number: int
+    title: str
+    url: str
+    created: datetime.datetime
+    user: str
+    pull_request: bool = False
+
+
+def main() -> None:
+    since = previous_week_start()
+    issues = fetch_issues(since)
+    new, updated = split_issues(issues, since)
+    print_summary(since, new, updated)
+
+
+def previous_week_start() -> datetime.date:
+    today = datetime.date.today()
+    return today - datetime.timedelta(days=today.weekday() + 7)
+
+
+def fetch_issues(since: datetime.date) -> list[Issue]:
+    """Return (new, updated) issues."""
+    j = requests.get(
+        ISSUES_API_URL,
+        params={
+            "labels": ISSUES_LABEL,
+            "since": f"{since:%Y-%m-%d}T00:00:00Z",
+            "per_page": "100",
+            "state": "open",
+        },
+        headers={"Accept": "application/vnd.github.v3+json"},
+    ).json()
+    assert isinstance(j, list)
+    return [parse_issue(j_i) for j_i in j]
+
+
+def parse_issue(j: Any) -> Issue:
+    number = j["number"]
+    title = j["title"]
+    url = j["html_url"]
+    created_at = datetime.datetime.fromisoformat(j["created_at"][:-1])
+    user = j["user"]["login"]
+    pull_request = "pull_request" in j
+    assert isinstance(number, int)
+    assert isinstance(title, str)
+    assert isinstance(url, str)
+    assert isinstance(user, str)
+    return Issue(number, title, url, created_at, user, pull_request)
+
+
+def split_issues(
+    issues: Iterable[Issue], since: datetime.date
+) -> tuple[list[Issue], list[Issue]]:
+    new = []
+    updated = []
+    for issue in issues:
+        if issue.created.date() >= since:
+            new.append(issue)
+        else:
+            updated.append(issue)
+    new.sort(key=lambda i: i.number)
+    updated.sort(key=lambda i: i.number)
+    return new, updated
+
+
+def print_summary(
+    since: datetime.date, new: Sequence[Issue], changed: Sequence[Issue]
+) -> None:
+    print(f"From: {SENDER_EMAIL}")
+    print(f"To: {RECEIVER_EMAIL}")
+    print(f"Subject: Opened and changed typing issues week {since:%G-W%V}")
+    print()
+    print(generate_mail(new, changed))
+
+
+def generate_mail(new: Sequence[Issue], changed: Sequence[Issue]) -> str:
+    if len(new) == 0 and len(changed) == 0:
+        s = (
+            "No issues or pull requests with the label 'topic: feature' were opened\n"
+            "or updated last week in the typing repository on GitHub.\n\n"
+        )
+    else:
+        s = (
+            "The following is an overview of all issues and pull requests in the\n"
+            "typing repository on GitHub with the label 'topic: feature'\n"
+            "that were opened or updated last week, excluding closed issues.\n\n"
+            "---------------------------------------------------\n\n"
+        )
+    if len(new) > 0:
+        s += "The following issues and pull requests were opened last week: \n\n"
+        s += "".join(generate_issue_text(issue) for issue in new)
+        s += "\n---------------------------------------------------\n\n"
+    if len(changed) > 0:
+        s += "The following issues and pull requests were updated last week: \n\n"
+        s += "".join(generate_issue_text(issue) for issue in changed)
+        s += "\n---------------------------------------------------\n\n"
+    s += (
+        "All issues and pull requests with the label 'topic: feature'\n"
+        "can be viewed under the following URL:\n\n"
+    )
+    s += ISSUES_URL
+    return s
+
+
+def generate_issue_text(issue: Issue) -> str:
+    s = f"#{issue.number:<5} "
+    if issue.pull_request:
+        s += "[PR] "
+    s += f"{issue.title}\n"
+    s += f"       opened by @{issue.user}\n"
+    s += f"       {issue.url}\n"
+    return s
+
+
+if __name__ == "__main__":
+    main()
diff --git a/test-requirements.txt b/test-requirements.txt
new file mode 100644
index 0000000..658ae0a
--- /dev/null
+++ b/test-requirements.txt
@@ -0,0 +1,3 @@
+flake8
+flake8-bugbear
+flake8-pyi
diff --git a/typing_extensions/CHANGELOG b/typing_extensions/CHANGELOG
new file mode 100644
index 0000000..a9a5980
--- /dev/null
+++ b/typing_extensions/CHANGELOG
@@ -0,0 +1,71 @@
+# Unreleased
+
+- Add `typing.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 --git a/typing_extensions/LICENSE b/typing_extensions/LICENSE
new file mode 100644
index 0000000..583f9f6
--- /dev/null
+++ b/typing_extensions/LICENSE
@@ -0,0 +1,254 @@
+A. HISTORY OF THE SOFTWARE
+==========================
+
+Python was created in the early 1990s by Guido van Rossum at Stichting
+Mathematisch Centrum (CWI, see http://www.cwi.nl) in the Netherlands
+as a successor of a language called ABC.  Guido remains Python's
+principal author, although it includes many contributions from others.
+
+In 1995, Guido continued his work on Python at the Corporation for
+National Research Initiatives (CNRI, see http://www.cnri.reston.va.us)
+in Reston, Virginia where he released several versions of the
+software.
+
+In May 2000, Guido and the Python core development team moved to
+BeOpen.com to form the BeOpen PythonLabs team.  In October of the same
+year, the PythonLabs team moved to Digital Creations (now Zope
+Corporation, see http://www.zope.com).  In 2001, the Python Software
+Foundation (PSF, see http://www.python.org/psf/) was formed, a
+non-profit organization created specifically to own Python-related
+Intellectual Property.  Zope Corporation is a sponsoring member of
+the PSF.
+
+All Python releases are Open Source (see http://www.opensource.org for
+the Open Source Definition).  Historically, most, but not all, Python
+releases have also been GPL-compatible; the table below summarizes
+the various releases.
+
+    Release         Derived     Year        Owner       GPL-
+                    from                                compatible? (1)
+
+    0.9.0 thru 1.2              1991-1995   CWI         yes
+    1.3 thru 1.5.2  1.2         1995-1999   CNRI        yes
+    1.6             1.5.2       2000        CNRI        no
+    2.0             1.6         2000        BeOpen.com  no
+    1.6.1           1.6         2001        CNRI        yes (2)
+    2.1             2.0+1.6.1   2001        PSF         no
+    2.0.1           2.0+1.6.1   2001        PSF         yes
+    2.1.1           2.1+2.0.1   2001        PSF         yes
+    2.1.2           2.1.1       2002        PSF         yes
+    2.1.3           2.1.2       2002        PSF         yes
+    2.2 and above   2.1.1       2001-now    PSF         yes
+
+Footnotes:
+
+(1) GPL-compatible doesn't mean that we're distributing Python under
+    the GPL.  All Python licenses, unlike the GPL, let you distribute
+    a modified version without making your changes open source.  The
+    GPL-compatible licenses make it possible to combine Python with
+    other software that is released under the GPL; the others don't.
+
+(2) According to Richard Stallman, 1.6.1 is not GPL-compatible,
+    because its license has a choice of law clause.  According to
+    CNRI, however, Stallman's lawyer has told CNRI's lawyer that 1.6.1
+    is "not incompatible" with the GPL.
+
+Thanks to the many outside volunteers who have worked under Guido's
+direction to make these releases possible.
+
+
+B. TERMS AND CONDITIONS FOR ACCESSING OR OTHERWISE USING PYTHON
+===============================================================
+
+PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
+--------------------------------------------
+
+1. This LICENSE AGREEMENT is between the Python Software Foundation
+("PSF"), and the Individual or Organization ("Licensee") accessing and
+otherwise using this software ("Python") in source or binary form and
+its associated documentation.
+
+2. Subject to the terms and conditions of this License Agreement, PSF hereby
+grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce,
+analyze, test, perform and/or display publicly, prepare derivative works,
+distribute, and otherwise use Python alone or in any derivative version,
+provided, however, that PSF's License Agreement and PSF's notice of copyright,
+i.e., "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+2011, 2012, 2013, 2014 Python Software Foundation; All Rights Reserved" are
+retained in Python alone or in any derivative version prepared by Licensee.
+
+3. In the event Licensee prepares a derivative work that is based on
+or incorporates Python or any part thereof, and wants to make
+the derivative work available to others as provided herein, then
+Licensee hereby agrees to include in any such work a brief summary of
+the changes made to Python.
+
+4. PSF is making Python available to Licensee on an "AS IS"
+basis.  PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
+IMPLIED.  BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND
+DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
+FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT
+INFRINGE ANY THIRD PARTY RIGHTS.
+
+5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
+FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
+A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON,
+OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
+
+6. This License Agreement will automatically terminate upon a material
+breach of its terms and conditions.
+
+7. Nothing in this License Agreement shall be deemed to create any
+relationship of agency, partnership, or joint venture between PSF and
+Licensee.  This License Agreement does not grant permission to use PSF
+trademarks or trade name in a trademark sense to endorse or promote
+products or services of Licensee, or any third party.
+
+8. By copying, installing or otherwise using Python, Licensee
+agrees to be bound by the terms and conditions of this License
+Agreement.
+
+
+BEOPEN.COM LICENSE AGREEMENT FOR PYTHON 2.0
+-------------------------------------------
+
+BEOPEN PYTHON OPEN SOURCE LICENSE AGREEMENT VERSION 1
+
+1. This LICENSE AGREEMENT is between BeOpen.com ("BeOpen"), having an
+office at 160 Saratoga Avenue, Santa Clara, CA 95051, and the
+Individual or Organization ("Licensee") accessing and otherwise using
+this software in source or binary form and its associated
+documentation ("the Software").
+
+2. Subject to the terms and conditions of this BeOpen Python License
+Agreement, BeOpen hereby grants Licensee a non-exclusive,
+royalty-free, world-wide license to reproduce, analyze, test, perform
+and/or display publicly, prepare derivative works, distribute, and
+otherwise use the Software alone or in any derivative version,
+provided, however, that the BeOpen Python License is retained in the
+Software, alone or in any derivative version prepared by Licensee.
+
+3. BeOpen is making the Software available to Licensee on an "AS IS"
+basis.  BEOPEN MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
+IMPLIED.  BY WAY OF EXAMPLE, BUT NOT LIMITATION, BEOPEN MAKES NO AND
+DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
+FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE WILL NOT
+INFRINGE ANY THIRD PARTY RIGHTS.
+
+4. BEOPEN SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF THE
+SOFTWARE FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS
+AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THE SOFTWARE, OR ANY
+DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
+
+5. This License Agreement will automatically terminate upon a material
+breach of its terms and conditions.
+
+6. This License Agreement shall be governed by and interpreted in all
+respects by the law of the State of California, excluding conflict of
+law provisions.  Nothing in this License Agreement shall be deemed to
+create any relationship of agency, partnership, or joint venture
+between BeOpen and Licensee.  This License Agreement does not grant
+permission to use BeOpen trademarks or trade names in a trademark
+sense to endorse or promote products or services of Licensee, or any
+third party.  As an exception, the "BeOpen Python" logos available at
+http://www.pythonlabs.com/logos.html may be used according to the
+permissions granted on that web page.
+
+7. By copying, installing or otherwise using the software, Licensee
+agrees to be bound by the terms and conditions of this License
+Agreement.
+
+
+CNRI LICENSE AGREEMENT FOR PYTHON 1.6.1
+---------------------------------------
+
+1. This LICENSE AGREEMENT is between the Corporation for National
+Research Initiatives, having an office at 1895 Preston White Drive,
+Reston, VA 20191 ("CNRI"), and the Individual or Organization
+("Licensee") accessing and otherwise using Python 1.6.1 software in
+source or binary form and its associated documentation.
+
+2. Subject to the terms and conditions of this License Agreement, CNRI
+hereby grants Licensee a nonexclusive, royalty-free, world-wide
+license to reproduce, analyze, test, perform and/or display publicly,
+prepare derivative works, distribute, and otherwise use Python 1.6.1
+alone or in any derivative version, provided, however, that CNRI's
+License Agreement and CNRI's notice of copyright, i.e., "Copyright (c)
+1995-2001 Corporation for National Research Initiatives; All Rights
+Reserved" are retained in Python 1.6.1 alone or in any derivative
+version prepared by Licensee.  Alternately, in lieu of CNRI's License
+Agreement, Licensee may substitute the following text (omitting the
+quotes): "Python 1.6.1 is made available subject to the terms and
+conditions in CNRI's License Agreement.  This Agreement together with
+Python 1.6.1 may be located on the Internet using the following
+unique, persistent identifier (known as a handle): 1895.22/1013.  This
+Agreement may also be obtained from a proxy server on the Internet
+using the following URL: http://hdl.handle.net/1895.22/1013".
+
+3. In the event Licensee prepares a derivative work that is based on
+or incorporates Python 1.6.1 or any part thereof, and wants to make
+the derivative work available to others as provided herein, then
+Licensee hereby agrees to include in any such work a brief summary of
+the changes made to Python 1.6.1.
+
+4. CNRI is making Python 1.6.1 available to Licensee on an "AS IS"
+basis.  CNRI MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
+IMPLIED.  BY WAY OF EXAMPLE, BUT NOT LIMITATION, CNRI MAKES NO AND
+DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
+FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 1.6.1 WILL NOT
+INFRINGE ANY THIRD PARTY RIGHTS.
+
+5. CNRI SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
+1.6.1 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
+A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 1.6.1,
+OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
+
+6. This License Agreement will automatically terminate upon a material
+breach of its terms and conditions.
+
+7. This License Agreement shall be governed by the federal
+intellectual property law of the United States, including without
+limitation the federal copyright law, and, to the extent such
+U.S. federal law does not apply, by the law of the Commonwealth of
+Virginia, excluding Virginia's conflict of law provisions.
+Notwithstanding the foregoing, with regard to derivative works based
+on Python 1.6.1 that incorporate non-separable material that was
+previously distributed under the GNU General Public License (GPL), the
+law of the Commonwealth of Virginia shall govern this License
+Agreement only as to issues arising under or with respect to
+Paragraphs 4, 5, and 7 of this License Agreement.  Nothing in this
+License Agreement shall be deemed to create any relationship of
+agency, partnership, or joint venture between CNRI and Licensee.  This
+License Agreement does not grant permission to use CNRI trademarks or
+trade name in a trademark sense to endorse or promote products or
+services of Licensee, or any third party.
+
+8. By clicking on the "ACCEPT" button where indicated, or by copying,
+installing or otherwise using Python 1.6.1, Licensee agrees to be
+bound by the terms and conditions of this License Agreement.
+
+        ACCEPT
+
+
+CWI LICENSE AGREEMENT FOR PYTHON 0.9.0 THROUGH 1.2
+--------------------------------------------------
+
+Copyright (c) 1991 - 1995, Stichting Mathematisch Centrum Amsterdam,
+The Netherlands.  All rights reserved.
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Stichting Mathematisch
+Centrum or CWI not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
+THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
+FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
diff --git a/typing_extensions/README.rst b/typing_extensions/README.rst
new file mode 100644
index 0000000..9abed04
--- /dev/null
+++ b/typing_extensions/README.rst
@@ -0,0 +1,146 @@
+=================
+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``
+  - ``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.
+
+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 --git a/typing_extensions/pyproject.toml b/typing_extensions/pyproject.toml
new file mode 100644
index 0000000..fbd0180
--- /dev/null
+++ b/typing_extensions/pyproject.toml
@@ -0,0 +1,58 @@
+# Build system requirements.
+[build-system]
+requires = ["flit_core >=3.4,<4"]
+build-backend = "flit_core.buildapi"
+
+# Project metadata
+[project]
+name = "typing_extensions"
+version = "4.1.1"
+description = "Backported and Experimental Type Hints for Python 3.6+"
+readme = "README.rst"
+requires-python = ">=3.7"
+urls.Home = "https://github.com/python/typing/blob/master/typing_extensions/README.rst"
+license.file = "LICENSE"
+keywords = [
+    "annotations",
+    "backport",
+    "checker",
+    "checking",
+    "function",
+    "hinting",
+    "hints",
+    "type",
+    "typechecking",
+    "typehinting",
+    "typehints",
+    "typing"
+]
+# Classifiers list: https://pypi.org/classifiers/
+classifiers = [
+    "Development Status :: 3 - Alpha",
+    "Environment :: Console",
+    "Intended Audience :: Developers",
+    "License :: OSI Approved :: Python Software Foundation License",
+    "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"
+]
+
+# Project metadata -- authors. Flit stores this as a list of dicts, so it can't
+# be inline above.
+[[project.authors]]
+name = "Guido van Rossum, Jukka Lehtosalo, Łukasz Langa, Michael Lee"
+email = "levkivskyi@gmail.com"
+
+[tool.flit.sdist]
+include = [
+    "CHANGELOG",
+    "README.rst",
+    "*/test*.py"
+]
+exclude = []
diff --git a/typing_extensions/src/test_typing_extensions.py b/typing_extensions/src/test_typing_extensions.py
new file mode 100644
index 0000000..b8fe5e3
--- /dev/null
+++ b/typing_extensions/src/test_typing_extensions.py
@@ -0,0 +1,2779 @@
+import sys
+import os
+import abc
+import contextlib
+import collections
+import collections.abc
+from functools import lru_cache
+import inspect
+import pickle
+import subprocess
+import types
+from unittest import TestCase, main, skipUnless, skipIf
+from test import ann_module, ann_module2, ann_module3
+import typing
+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 no_type_check
+import typing_extensions
+from typing_extensions import NoReturn, ClassVar, Final, IntVar, Literal, Type, NewType, TypedDict, Self
+from typing_extensions import TypeAlias, ParamSpec, Concatenate, ParamSpecArgs, ParamSpecKwargs, TypeGuard
+from typing_extensions import Awaitable, AsyncIterator, AsyncContextManager, Required, NotRequired
+from typing_extensions import Protocol, runtime, runtime_checkable, Annotated, overload, final, is_typeddict
+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
+
+# 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_10_0 = sys.version_info[:3] >= (3, 10, 0)
+TYPING_3_11_0 = sys.version_info[:3] >= (3, 11, 0)
+
+
+class BaseTestCase(TestCase):
+    def assertIsSubclass(self, cls, class_or_tuple, msg=None):
+        if not issubclass(cls, class_or_tuple):
+            message = f'{cls!r} is not a subclass of {repr(class_or_tuple)}'
+            if msg is not None:
+                message += f' : {msg}'
+            raise self.failureException(message)
+
+    def assertNotIsSubclass(self, cls, class_or_tuple, msg=None):
+        if issubclass(cls, class_or_tuple):
+            message = f'{cls!r} is a subclass of {repr(class_or_tuple)}'
+            if msg is not None:
+                message += f' : {msg}'
+            raise self.failureException(message)
+
+
+class Employee:
+    pass
+
+
+class BottomTypeTestsMixin:
+    bottom_type: ClassVar[Any]
+
+    def test_equality(self):
+        self.assertEqual(self.bottom_type, self.bottom_type)
+        self.assertIs(self.bottom_type, self.bottom_type)
+        self.assertNotEqual(self.bottom_type, None)
+
+    def test_get_origin(self):
+        self.assertIs(get_origin(self.bottom_type), None)
+
+    def test_instance_type_error(self):
+        with self.assertRaises(TypeError):
+            isinstance(42, self.bottom_type)
+
+    def test_subclass_type_error(self):
+        with self.assertRaises(TypeError):
+            issubclass(Employee, self.bottom_type)
+        with self.assertRaises(TypeError):
+            issubclass(NoReturn, self.bottom_type)
+
+    def test_not_generic(self):
+        with self.assertRaises(TypeError):
+            self.bottom_type[int]
+
+    def test_cannot_subclass(self):
+        with self.assertRaises(TypeError):
+            class A(self.bottom_type):
+                pass
+        with self.assertRaises(TypeError):
+            class A(type(self.bottom_type)):
+                pass
+
+    def test_cannot_instantiate(self):
+        with self.assertRaises(TypeError):
+            self.bottom_type()
+        with self.assertRaises(TypeError):
+            type(self.bottom_type)()
+
+    def test_pickle(self):
+        for proto in range(pickle.HIGHEST_PROTOCOL):
+            pickled = pickle.dumps(self.bottom_type, protocol=proto)
+            self.assertIs(self.bottom_type, pickle.loads(pickled))
+
+
+class NoReturnTests(BottomTypeTestsMixin, BaseTestCase):
+    bottom_type = NoReturn
+
+    def test_repr(self):
+        if hasattr(typing, 'NoReturn'):
+            self.assertEqual(repr(NoReturn), 'typing.NoReturn')
+        else:
+            self.assertEqual(repr(NoReturn), 'typing_extensions.NoReturn')
+
+    def test_get_type_hints(self):
+        def some(arg: NoReturn) -> NoReturn: ...
+        def some_str(arg: 'NoReturn') -> 'typing.NoReturn': ...
+
+        expected = {'arg': NoReturn, 'return': NoReturn}
+        targets = [some]
+
+        # On 3.7.0 and 3.7.1, https://github.com/python/cpython/pull/10772
+        # wasn't applied yet and NoReturn fails _type_check.
+        if not ((3, 7, 0) <= sys.version_info < (3, 7, 2)):
+            targets.append(some_str)
+        for target in targets:
+            with self.subTest(target=target):
+                self.assertEqual(gth(target), expected)
+
+    def test_not_equality(self):
+        self.assertNotEqual(NoReturn, Never)
+        self.assertNotEqual(Never, NoReturn)
+
+
+class NeverTests(BottomTypeTestsMixin, BaseTestCase):
+    bottom_type = Never
+
+    def test_repr(self):
+        if hasattr(typing, 'Never'):
+            self.assertEqual(repr(Never), 'typing.Never')
+        else:
+            self.assertEqual(repr(Never), 'typing_extensions.Never')
+
+    def test_get_type_hints(self):
+        def some(arg: Never) -> Never: ...
+        def some_str(arg: 'Never') -> 'typing_extensions.Never': ...
+
+        expected = {'arg': Never, 'return': Never}
+        for target in [some, some_str]:
+            with self.subTest(target=target):
+                self.assertEqual(gth(target), expected)
+
+
+class AssertNeverTests(BaseTestCase):
+    def test_exception(self):
+        with self.assertRaises(AssertionError):
+            assert_never(None)
+
+
+class ClassVarTests(BaseTestCase):
+
+    def test_basics(self):
+        with self.assertRaises(TypeError):
+            ClassVar[1]
+        with self.assertRaises(TypeError):
+            ClassVar[int, str]
+        with self.assertRaises(TypeError):
+            ClassVar[int][str]
+
+    def test_repr(self):
+        if hasattr(typing, 'ClassVar'):
+            mod_name = 'typing'
+        else:
+            mod_name = 'typing_extensions'
+        self.assertEqual(repr(ClassVar), mod_name + '.ClassVar')
+        cv = ClassVar[int]
+        self.assertEqual(repr(cv), mod_name + '.ClassVar[int]')
+        cv = ClassVar[Employee]
+        self.assertEqual(repr(cv), mod_name + f'.ClassVar[{__name__}.Employee]')
+
+    def test_cannot_subclass(self):
+        with self.assertRaises(TypeError):
+            class C(type(ClassVar)):
+                pass
+        with self.assertRaises(TypeError):
+            class C(type(ClassVar[int])):
+                pass
+
+    def test_cannot_init(self):
+        with self.assertRaises(TypeError):
+            ClassVar()
+        with self.assertRaises(TypeError):
+            type(ClassVar)()
+        with self.assertRaises(TypeError):
+            type(ClassVar[Optional[int]])()
+
+    def test_no_isinstance(self):
+        with self.assertRaises(TypeError):
+            isinstance(1, ClassVar[int])
+        with self.assertRaises(TypeError):
+            issubclass(int, ClassVar)
+
+
+class FinalTests(BaseTestCase):
+
+    def test_basics(self):
+        with self.assertRaises(TypeError):
+            Final[1]
+        with self.assertRaises(TypeError):
+            Final[int, str]
+        with self.assertRaises(TypeError):
+            Final[int][str]
+
+    def test_repr(self):
+        if hasattr(typing, 'Final') and sys.version_info[:2] >= (3, 7):
+            mod_name = 'typing'
+        else:
+            mod_name = 'typing_extensions'
+        self.assertEqual(repr(Final), mod_name + '.Final')
+        cv = Final[int]
+        self.assertEqual(repr(cv), mod_name + '.Final[int]')
+        cv = Final[Employee]
+        self.assertEqual(repr(cv), mod_name + f'.Final[{__name__}.Employee]')
+
+    def test_cannot_subclass(self):
+        with self.assertRaises(TypeError):
+            class C(type(Final)):
+                pass
+        with self.assertRaises(TypeError):
+            class C(type(Final[int])):
+                pass
+
+    def test_cannot_init(self):
+        with self.assertRaises(TypeError):
+            Final()
+        with self.assertRaises(TypeError):
+            type(Final)()
+        with self.assertRaises(TypeError):
+            type(Final[Optional[int]])()
+
+    def test_no_isinstance(self):
+        with self.assertRaises(TypeError):
+            isinstance(1, Final[int])
+        with self.assertRaises(TypeError):
+            issubclass(int, Final)
+
+
+class RequiredTests(BaseTestCase):
+
+    def test_basics(self):
+        with self.assertRaises(TypeError):
+            Required[1]
+        with self.assertRaises(TypeError):
+            Required[int, str]
+        with self.assertRaises(TypeError):
+            Required[int][str]
+
+    def test_repr(self):
+        if hasattr(typing, 'Required'):
+            mod_name = 'typing'
+        else:
+            mod_name = 'typing_extensions'
+        self.assertEqual(repr(Required), mod_name + '.Required')
+        cv = Required[int]
+        self.assertEqual(repr(cv), mod_name + '.Required[int]')
+        cv = Required[Employee]
+        self.assertEqual(repr(cv), mod_name + '.Required[%s.Employee]' % __name__)
+
+    def test_cannot_subclass(self):
+        with self.assertRaises(TypeError):
+            class C(type(Required)):
+                pass
+        with self.assertRaises(TypeError):
+            class C(type(Required[int])):
+                pass
+
+    def test_cannot_init(self):
+        with self.assertRaises(TypeError):
+            Required()
+        with self.assertRaises(TypeError):
+            type(Required)()
+        with self.assertRaises(TypeError):
+            type(Required[Optional[int]])()
+
+    def test_no_isinstance(self):
+        with self.assertRaises(TypeError):
+            isinstance(1, Required[int])
+        with self.assertRaises(TypeError):
+            issubclass(int, Required)
+
+
+class NotRequiredTests(BaseTestCase):
+
+    def test_basics(self):
+        with self.assertRaises(TypeError):
+            NotRequired[1]
+        with self.assertRaises(TypeError):
+            NotRequired[int, str]
+        with self.assertRaises(TypeError):
+            NotRequired[int][str]
+
+    def test_repr(self):
+        if hasattr(typing, 'NotRequired'):
+            mod_name = 'typing'
+        else:
+            mod_name = 'typing_extensions'
+        self.assertEqual(repr(NotRequired), mod_name + '.NotRequired')
+        cv = NotRequired[int]
+        self.assertEqual(repr(cv), mod_name + '.NotRequired[int]')
+        cv = NotRequired[Employee]
+        self.assertEqual(repr(cv), mod_name + '.NotRequired[%s.Employee]' % __name__)
+
+    def test_cannot_subclass(self):
+        with self.assertRaises(TypeError):
+            class C(type(NotRequired)):
+                pass
+        with self.assertRaises(TypeError):
+            class C(type(NotRequired[int])):
+                pass
+
+    def test_cannot_init(self):
+        with self.assertRaises(TypeError):
+            NotRequired()
+        with self.assertRaises(TypeError):
+            type(NotRequired)()
+        with self.assertRaises(TypeError):
+            type(NotRequired[Optional[int]])()
+
+    def test_no_isinstance(self):
+        with self.assertRaises(TypeError):
+            isinstance(1, NotRequired[int])
+        with self.assertRaises(TypeError):
+            issubclass(int, NotRequired)
+
+
+class IntVarTests(BaseTestCase):
+    def test_valid(self):
+        T_ints = IntVar("T_ints")  # noqa
+
+    def test_invalid(self):
+        with self.assertRaises(TypeError):
+            T_ints = IntVar("T_ints", int)
+        with self.assertRaises(TypeError):
+            T_ints = IntVar("T_ints", bound=int)
+        with self.assertRaises(TypeError):
+            T_ints = IntVar("T_ints", covariant=True)  # noqa
+
+
+class LiteralTests(BaseTestCase):
+    def test_basics(self):
+        Literal[1]
+        Literal[1, 2, 3]
+        Literal["x", "y", "z"]
+        Literal[None]
+
+    def test_illegal_parameters_do_not_raise_runtime_errors(self):
+        # Type checkers should reject these types, but we do not
+        # raise errors at runtime to maintain maximum flexibility
+        Literal[int]
+        Literal[Literal[1, 2], Literal[4, 5]]
+        Literal[3j + 2, ..., ()]
+        Literal[b"foo", u"bar"]
+        Literal[{"foo": 3, "bar": 4}]
+        Literal[T]
+
+    def test_literals_inside_other_types(self):
+        List[Literal[1, 2, 3]]
+        List[Literal[("foo", "bar", "baz")]]
+
+    def test_repr(self):
+        if hasattr(typing, 'Literal'):
+            mod_name = 'typing'
+        else:
+            mod_name = 'typing_extensions'
+        self.assertEqual(repr(Literal[1]), mod_name + ".Literal[1]")
+        self.assertEqual(repr(Literal[1, True, "foo"]), mod_name + ".Literal[1, True, 'foo']")
+        self.assertEqual(repr(Literal[int]), mod_name + ".Literal[int]")
+        self.assertEqual(repr(Literal), mod_name + ".Literal")
+        self.assertEqual(repr(Literal[None]), mod_name + ".Literal[None]")
+
+    def test_cannot_init(self):
+        with self.assertRaises(TypeError):
+            Literal()
+        with self.assertRaises(TypeError):
+            Literal[1]()
+        with self.assertRaises(TypeError):
+            type(Literal)()
+        with self.assertRaises(TypeError):
+            type(Literal[1])()
+
+    def test_no_isinstance_or_issubclass(self):
+        with self.assertRaises(TypeError):
+            isinstance(1, Literal[1])
+        with self.assertRaises(TypeError):
+            isinstance(int, Literal[1])
+        with self.assertRaises(TypeError):
+            issubclass(1, Literal[1])
+        with self.assertRaises(TypeError):
+            issubclass(int, Literal[1])
+
+    def test_no_subclassing(self):
+        with self.assertRaises(TypeError):
+            class Foo(Literal[1]): pass
+        with self.assertRaises(TypeError):
+            class Bar(Literal): pass
+
+    def test_no_multiple_subscripts(self):
+        with self.assertRaises(TypeError):
+            Literal[1][1]
+
+
+class OverloadTests(BaseTestCase):
+
+    def test_overload_fails(self):
+        with self.assertRaises(RuntimeError):
+
+            @overload
+            def blah():
+                pass
+
+            blah()
+
+    def test_overload_succeeds(self):
+        @overload
+        def blah():
+            pass
+
+        def blah():
+            pass
+
+        blah()
+
+
+class AssertTypeTests(BaseTestCase):
+
+    def test_basics(self):
+        arg = 42
+        self.assertIs(assert_type(arg, int), arg)
+        self.assertIs(assert_type(arg, Union[str, float]), arg)
+        self.assertIs(assert_type(arg, AnyStr), arg)
+        self.assertIs(assert_type(arg, None), arg)
+
+    def test_errors(self):
+        # Bogus calls are not expected to fail.
+        arg = 42
+        self.assertIs(assert_type(arg, 42), arg)
+        self.assertIs(assert_type(arg, 'hello'), arg)
+
+
+T_a = TypeVar('T_a')
+
+class AwaitableWrapper(Awaitable[T_a]):
+
+    def __init__(self, value):
+        self.value = value
+
+    def __await__(self) -> typing.Iterator[T_a]:
+        yield
+        return self.value
+
+class AsyncIteratorWrapper(AsyncIterator[T_a]):
+
+    def __init__(self, value: Iterable[T_a]):
+        self.value = value
+
+    def __aiter__(self) -> AsyncIterator[T_a]:
+        return self
+
+    async def __anext__(self) -> T_a:
+        data = await self.value
+        if data:
+            return data
+        else:
+            raise StopAsyncIteration
+
+class ACM:
+    async def __aenter__(self) -> int:
+        return 42
+
+    async def __aexit__(self, etype, eval, tb):
+        return None
+
+
+
+class A:
+    y: float
+class B(A):
+    x: ClassVar[Optional['B']] = None
+    y: int
+    b: int
+class CSub(B):
+    z: ClassVar['CSub'] = B()
+class G(Generic[T]):
+    lst: ClassVar[List[T]] = []
+
+class Loop:
+    attr: Final['Loop']
+
+class NoneAndForward:
+    parent: 'NoneAndForward'
+    meaning: None
+
+class XRepr(NamedTuple):
+    x: int
+    y: int = 1
+
+    def __str__(self):
+        return f'{self.x} -> {self.y}'
+
+    def __add__(self, other):
+        return 0
+
+@runtime
+class HasCallProtocol(Protocol):
+    __call__: typing.Callable
+
+
+async def g_with(am: AsyncContextManager[int]):
+    x: int
+    async with am as x:
+        return x
+
+try:
+    g_with(ACM()).send(None)
+except StopIteration as e:
+    assert e.args[0] == 42
+
+Label = TypedDict('Label', [('label', str)])
+
+class Point2D(TypedDict):
+    x: int
+    y: int
+
+class Point2Dor3D(Point2D, total=False):
+    z: int
+
+class LabelPoint2D(Point2D, Label): ...
+
+class Options(TypedDict, total=False):
+    log_level: int
+    log_path: str
+
+class BaseAnimal(TypedDict):
+    name: str
+
+class Animal(BaseAnimal, total=False):
+    voice: str
+    tail: bool
+
+class Cat(Animal):
+    fur_color: str
+
+class TotalMovie(TypedDict):
+    title: str
+    year: NotRequired[int]
+
+class NontotalMovie(TypedDict, total=False):
+    title: Required[str]
+    year: int
+
+class AnnotatedMovie(TypedDict):
+    title: Annotated[Required[str], "foobar"]
+    year: NotRequired[Annotated[int, 2000]]
+
+
+gth = get_type_hints
+
+
+class GetTypeHintTests(BaseTestCase):
+    def test_get_type_hints_modules(self):
+        ann_module_type_hints = {1: 2, 'f': Tuple[int, int], 'x': int, 'y': str}
+        if (TYPING_3_11_0
+                or (TYPING_3_10_0 and sys.version_info.releaselevel in {'candidate', 'final'})):
+            # More tests were added in 3.10rc1.
+            ann_module_type_hints['u'] = int | float
+        self.assertEqual(gth(ann_module), ann_module_type_hints)
+        self.assertEqual(gth(ann_module2), {})
+        self.assertEqual(gth(ann_module3), {})
+
+    def test_get_type_hints_classes(self):
+        self.assertEqual(gth(ann_module.C, ann_module.__dict__),
+                         {'y': Optional[ann_module.C]})
+        self.assertIsInstance(gth(ann_module.j_class), dict)
+        self.assertEqual(gth(ann_module.M), {'123': 123, 'o': type})
+        self.assertEqual(gth(ann_module.D),
+                         {'j': str, 'k': str, 'y': Optional[ann_module.C]})
+        self.assertEqual(gth(ann_module.Y), {'z': int})
+        self.assertEqual(gth(ann_module.h_class),
+                         {'y': Optional[ann_module.C]})
+        self.assertEqual(gth(ann_module.S), {'x': str, 'y': str})
+        self.assertEqual(gth(ann_module.foo), {'x': int})
+        self.assertEqual(gth(NoneAndForward, globals()),
+                         {'parent': NoneAndForward, 'meaning': type(None)})
+
+    def test_respect_no_type_check(self):
+        @no_type_check
+        class NoTpCheck:
+            class Inn:
+                def __init__(self, x: 'not a type'): ...  # noqa
+        self.assertTrue(NoTpCheck.__no_type_check__)
+        self.assertTrue(NoTpCheck.Inn.__init__.__no_type_check__)
+        self.assertEqual(gth(ann_module2.NTC.meth), {})
+        class ABase(Generic[T]):
+            def meth(x: int): ...
+        @no_type_check
+        class Der(ABase): ...
+        self.assertEqual(gth(ABase.meth), {'x': int})
+
+    def test_get_type_hints_ClassVar(self):
+        self.assertEqual(gth(ann_module2.CV, ann_module2.__dict__),
+                         {'var': ClassVar[ann_module2.CV]})
+        self.assertEqual(gth(B, globals()),
+                         {'y': int, 'x': ClassVar[Optional[B]], 'b': int})
+        self.assertEqual(gth(CSub, globals()),
+                         {'z': ClassVar[CSub], 'y': int, 'b': int,
+                          'x': ClassVar[Optional[B]]})
+        self.assertEqual(gth(G), {'lst': ClassVar[List[T]]})
+
+    def test_final_forward_ref(self):
+        self.assertEqual(gth(Loop, globals())['attr'], Final[Loop])
+        self.assertNotEqual(gth(Loop, globals())['attr'], Final[int])
+        self.assertNotEqual(gth(Loop, globals())['attr'], Final)
+
+
+class GetUtilitiesTestCase(TestCase):
+    def test_get_origin(self):
+        T = TypeVar('T')
+        P = ParamSpec('P')
+        Ts = TypeVarTuple('Ts')
+        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)
+        self.assertIs(get_origin(Required[int]), Required)
+        self.assertIs(get_origin(NotRequired[int]), NotRequired)
+        self.assertIs(get_origin(Unpack[Ts]), Unpack)
+        self.assertIs(get_origin(Unpack), None)
+
+    def test_get_args(self):
+        T = TypeVar('T')
+        Ts = TypeVarTuple('Ts')
+        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))
+        self.assertEqual(get_args(Required[int]), (int,))
+        self.assertEqual(get_args(NotRequired[int]), (int,))
+        self.assertEqual(get_args(Unpack[Ts]), (Ts,))
+        self.assertEqual(get_args(Unpack), ())
+
+
+class CollectionsAbcTests(BaseTestCase):
+
+    def test_isinstance_collections(self):
+        self.assertNotIsInstance(1, collections.abc.Mapping)
+        self.assertNotIsInstance(1, collections.abc.Iterable)
+        self.assertNotIsInstance(1, collections.abc.Container)
+        self.assertNotIsInstance(1, collections.abc.Sized)
+        with self.assertRaises(TypeError):
+            isinstance(collections.deque(), typing_extensions.Deque[int])
+        with self.assertRaises(TypeError):
+            issubclass(collections.Counter, typing_extensions.Counter[str])
+
+    def test_awaitable(self):
+        ns = {}
+        exec(
+            "async def foo() -> typing_extensions.Awaitable[int]:\n"
+            "    return await AwaitableWrapper(42)\n",
+            globals(), ns)
+        foo = ns['foo']
+        g = foo()
+        self.assertIsInstance(g, typing_extensions.Awaitable)
+        self.assertNotIsInstance(foo, typing_extensions.Awaitable)
+        g.send(None)  # Run foo() till completion, to avoid warning.
+
+    def test_coroutine(self):
+        ns = {}
+        exec(
+            "async def foo():\n"
+            "    return\n",
+            globals(), ns)
+        foo = ns['foo']
+        g = foo()
+        self.assertIsInstance(g, typing_extensions.Coroutine)
+        with self.assertRaises(TypeError):
+            isinstance(g, typing_extensions.Coroutine[int])
+        self.assertNotIsInstance(foo, typing_extensions.Coroutine)
+        try:
+            g.send(None)
+        except StopIteration:
+            pass
+
+    def test_async_iterable(self):
+        base_it = range(10)  # type: Iterator[int]
+        it = AsyncIteratorWrapper(base_it)
+        self.assertIsInstance(it, typing_extensions.AsyncIterable)
+        self.assertIsInstance(it, typing_extensions.AsyncIterable)
+        self.assertNotIsInstance(42, typing_extensions.AsyncIterable)
+
+    def test_async_iterator(self):
+        base_it = range(10)  # type: Iterator[int]
+        it = AsyncIteratorWrapper(base_it)
+        self.assertIsInstance(it, typing_extensions.AsyncIterator)
+        self.assertNotIsInstance(42, typing_extensions.AsyncIterator)
+
+    def test_deque(self):
+        self.assertIsSubclass(collections.deque, typing_extensions.Deque)
+        class MyDeque(typing_extensions.Deque[int]): ...
+        self.assertIsInstance(MyDeque(), collections.deque)
+
+    def test_counter(self):
+        self.assertIsSubclass(collections.Counter, typing_extensions.Counter)
+
+    def test_defaultdict_instantiation(self):
+        self.assertIs(
+            type(typing_extensions.DefaultDict()),
+            collections.defaultdict)
+        self.assertIs(
+            type(typing_extensions.DefaultDict[KT, VT]()),
+            collections.defaultdict)
+        self.assertIs(
+            type(typing_extensions.DefaultDict[str, int]()),
+            collections.defaultdict)
+
+    def test_defaultdict_subclass(self):
+
+        class MyDefDict(typing_extensions.DefaultDict[str, int]):
+            pass
+
+        dd = MyDefDict()
+        self.assertIsInstance(dd, MyDefDict)
+
+        self.assertIsSubclass(MyDefDict, collections.defaultdict)
+        self.assertNotIsSubclass(collections.defaultdict, MyDefDict)
+
+    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)
+        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)
+        self.assertIs(type(typing_extensions.ChainMap[str, int]()), collections.ChainMap)
+        class CM(typing_extensions.ChainMap[KT, VT]): ...
+        self.assertIs(type(CM[int, str]()), CM)
+
+    def test_chainmap_subclass(self):
+
+        class MyChainMap(typing_extensions.ChainMap[str, int]):
+            pass
+
+        cm = MyChainMap()
+        self.assertIsInstance(cm, MyChainMap)
+
+        self.assertIsSubclass(MyChainMap, collections.ChainMap)
+        self.assertNotIsSubclass(collections.ChainMap, MyChainMap)
+
+    def test_deque_instantiation(self):
+        self.assertIs(type(typing_extensions.Deque()), collections.deque)
+        self.assertIs(type(typing_extensions.Deque[T]()), collections.deque)
+        self.assertIs(type(typing_extensions.Deque[int]()), collections.deque)
+        class D(typing_extensions.Deque[T]): ...
+        self.assertIs(type(D[int]()), D)
+
+    def test_counter_instantiation(self):
+        self.assertIs(type(typing_extensions.Counter()), collections.Counter)
+        self.assertIs(type(typing_extensions.Counter[T]()), collections.Counter)
+        self.assertIs(type(typing_extensions.Counter[int]()), collections.Counter)
+        class C(typing_extensions.Counter[T]): ...
+        self.assertIs(type(C[int]()), C)
+        self.assertEqual(C.__bases__, (collections.Counter, typing.Generic))
+
+    def test_counter_subclass_instantiation(self):
+
+        class MyCounter(typing_extensions.Counter[int]):
+            pass
+
+        d = MyCounter()
+        self.assertIsInstance(d, MyCounter)
+        self.assertIsInstance(d, collections.Counter)
+        self.assertIsInstance(d, typing_extensions.Counter)
+
+    def test_async_generator(self):
+        ns = {}
+        exec("async def f():\n"
+             "    yield 42\n", globals(), ns)
+        g = ns['f']()
+        self.assertIsSubclass(type(g), typing_extensions.AsyncGenerator)
+
+    def test_no_async_generator_instantiation(self):
+        with self.assertRaises(TypeError):
+            typing_extensions.AsyncGenerator()
+        with self.assertRaises(TypeError):
+            typing_extensions.AsyncGenerator[T, T]()
+        with self.assertRaises(TypeError):
+            typing_extensions.AsyncGenerator[int, int]()
+
+    def test_subclassing_async_generator(self):
+        class G(typing_extensions.AsyncGenerator[int, int]):
+            def asend(self, value):
+                pass
+            def athrow(self, typ, val=None, tb=None):
+                pass
+
+        ns = {}
+        exec('async def g(): yield 0', globals(), ns)
+        g = ns['g']
+        self.assertIsSubclass(G, typing_extensions.AsyncGenerator)
+        self.assertIsSubclass(G, typing_extensions.AsyncIterable)
+        self.assertIsSubclass(G, collections.abc.AsyncGenerator)
+        self.assertIsSubclass(G, collections.abc.AsyncIterable)
+        self.assertNotIsSubclass(type(g), G)
+
+        instance = G()
+        self.assertIsInstance(instance, typing_extensions.AsyncGenerator)
+        self.assertIsInstance(instance, typing_extensions.AsyncIterable)
+        self.assertIsInstance(instance, collections.abc.AsyncGenerator)
+        self.assertIsInstance(instance, collections.abc.AsyncIterable)
+        self.assertNotIsInstance(type(g), G)
+        self.assertNotIsInstance(g, G)
+
+
+class OtherABCTests(BaseTestCase):
+
+    def test_contextmanager(self):
+        @contextlib.contextmanager
+        def manager():
+            yield 42
+
+        cm = manager()
+        self.assertIsInstance(cm, typing_extensions.ContextManager)
+        self.assertNotIsInstance(42, typing_extensions.ContextManager)
+
+    def test_async_contextmanager(self):
+        class NotACM:
+            pass
+        self.assertIsInstance(ACM(), typing_extensions.AsyncContextManager)
+        self.assertNotIsInstance(NotACM(), typing_extensions.AsyncContextManager)
+        @contextlib.contextmanager
+        def manager():
+            yield 42
+
+        cm = manager()
+        self.assertNotIsInstance(cm, typing_extensions.AsyncContextManager)
+        self.assertEqual(typing_extensions.AsyncContextManager[int].__args__, (int,))
+        with self.assertRaises(TypeError):
+            isinstance(42, typing_extensions.AsyncContextManager[int])
+        with self.assertRaises(TypeError):
+            typing_extensions.AsyncContextManager[int, str]
+
+
+class TypeTests(BaseTestCase):
+
+    def test_type_basic(self):
+
+        class User: pass
+        class BasicUser(User): pass
+        class ProUser(User): pass
+
+        def new_user(user_class: Type[User]) -> User:
+            return user_class()
+
+        new_user(BasicUser)
+
+    def test_type_typevar(self):
+
+        class User: pass
+        class BasicUser(User): pass
+        class ProUser(User): pass
+
+        U = TypeVar('U', bound=User)
+
+        def new_user(user_class: Type[U]) -> U:
+            return user_class()
+
+        new_user(BasicUser)
+
+    def test_type_optional(self):
+        A = Optional[Type[BaseException]]
+
+        def foo(a: A) -> Optional[BaseException]:
+            if a is None:
+                return None
+            else:
+                return a()
+
+        assert isinstance(foo(KeyboardInterrupt), KeyboardInterrupt)
+        assert foo(None) is None
+
+
+class NewTypeTests(BaseTestCase):
+
+    def test_basic(self):
+        UserId = NewType('UserId', int)
+        UserName = NewType('UserName', str)
+        self.assertIsInstance(UserId(5), int)
+        self.assertIsInstance(UserName('Joe'), str)
+        self.assertEqual(UserId(5) + 1, 6)
+
+    def test_errors(self):
+        UserId = NewType('UserId', int)
+        UserName = NewType('UserName', str)
+        with self.assertRaises(TypeError):
+            issubclass(UserId, int)
+        with self.assertRaises(TypeError):
+            class D(UserName):
+                pass
+
+
+class Coordinate(Protocol):
+    x: int
+    y: int
+
+@runtime
+class Point(Coordinate, Protocol):
+    label: str
+
+class MyPoint:
+    x: int
+    y: int
+    label: str
+
+class XAxis(Protocol):
+    x: int
+
+class YAxis(Protocol):
+    y: int
+
+@runtime
+class Position(XAxis, YAxis, Protocol):
+    pass
+
+@runtime
+class Proto(Protocol):
+    attr: int
+
+    def meth(self, arg: str) -> int:
+        ...
+
+class Concrete(Proto):
+    pass
+
+class Other:
+    attr: int = 1
+
+    def meth(self, arg: str) -> int:
+        if arg == 'this':
+            return 1
+        return 0
+
+class NT(NamedTuple):
+    x: int
+    y: int
+
+
+class ProtocolTests(BaseTestCase):
+
+    def test_basic_protocol(self):
+        @runtime
+        class P(Protocol):
+            def meth(self):
+                pass
+        class C: pass
+        class D:
+            def meth(self):
+                pass
+        def f():
+            pass
+        self.assertIsSubclass(D, P)
+        self.assertIsInstance(D(), P)
+        self.assertNotIsSubclass(C, P)
+        self.assertNotIsInstance(C(), P)
+        self.assertNotIsSubclass(types.FunctionType, P)
+        self.assertNotIsInstance(f, P)
+
+    def test_everything_implements_empty_protocol(self):
+        @runtime
+        class Empty(Protocol): pass
+        class C: pass
+        def f():
+            pass
+        for thing in (object, type, tuple, C, types.FunctionType):
+            self.assertIsSubclass(thing, Empty)
+        for thing in (object(), 1, (), typing, f):
+            self.assertIsInstance(thing, Empty)
+
+    def test_function_implements_protocol(self):
+        def f():
+            pass
+        self.assertIsInstance(f, HasCallProtocol)
+
+    def test_no_inheritance_from_nominal(self):
+        class C: pass
+        class BP(Protocol): pass
+        with self.assertRaises(TypeError):
+            class P(C, Protocol):
+                pass
+        with self.assertRaises(TypeError):
+            class P(Protocol, C):
+                pass
+        with self.assertRaises(TypeError):
+            class P(BP, C, Protocol):
+                pass
+        class D(BP, C): pass
+        class E(C, BP): pass
+        self.assertNotIsInstance(D(), E)
+        self.assertNotIsInstance(E(), D)
+
+    def test_no_instantiation(self):
+        class P(Protocol): pass
+        with self.assertRaises(TypeError):
+            P()
+        class C(P): pass
+        self.assertIsInstance(C(), C)
+        T = TypeVar('T')
+        class PG(Protocol[T]): pass
+        with self.assertRaises(TypeError):
+            PG()
+        with self.assertRaises(TypeError):
+            PG[int]()
+        with self.assertRaises(TypeError):
+            PG[T]()
+        class CG(PG[T]): pass
+        self.assertIsInstance(CG[int](), CG)
+
+    def test_cannot_instantiate_abstract(self):
+        @runtime
+        class P(Protocol):
+            @abc.abstractmethod
+            def ameth(self) -> int:
+                raise NotImplementedError
+        class B(P):
+            pass
+        class C(B):
+            def ameth(self) -> int:
+                return 26
+        with self.assertRaises(TypeError):
+            B()
+        self.assertIsInstance(C(), P)
+
+    def test_subprotocols_extending(self):
+        class P1(Protocol):
+            def meth1(self):
+                pass
+        @runtime
+        class P2(P1, Protocol):
+            def meth2(self):
+                pass
+        class C:
+            def meth1(self):
+                pass
+            def meth2(self):
+                pass
+        class C1:
+            def meth1(self):
+                pass
+        class C2:
+            def meth2(self):
+                pass
+        self.assertNotIsInstance(C1(), P2)
+        self.assertNotIsInstance(C2(), P2)
+        self.assertNotIsSubclass(C1, P2)
+        self.assertNotIsSubclass(C2, P2)
+        self.assertIsInstance(C(), P2)
+        self.assertIsSubclass(C, P2)
+
+    def test_subprotocols_merging(self):
+        class P1(Protocol):
+            def meth1(self):
+                pass
+        class P2(Protocol):
+            def meth2(self):
+                pass
+        @runtime
+        class P(P1, P2, Protocol):
+            pass
+        class C:
+            def meth1(self):
+                pass
+            def meth2(self):
+                pass
+        class C1:
+            def meth1(self):
+                pass
+        class C2:
+            def meth2(self):
+                pass
+        self.assertNotIsInstance(C1(), P)
+        self.assertNotIsInstance(C2(), P)
+        self.assertNotIsSubclass(C1, P)
+        self.assertNotIsSubclass(C2, P)
+        self.assertIsInstance(C(), P)
+        self.assertIsSubclass(C, P)
+
+    def test_protocols_issubclass(self):
+        T = TypeVar('T')
+        @runtime
+        class P(Protocol):
+            def x(self): ...
+        @runtime
+        class PG(Protocol[T]):
+            def x(self): ...
+        class BadP(Protocol):
+            def x(self): ...
+        class BadPG(Protocol[T]):
+            def x(self): ...
+        class C:
+            def x(self): ...
+        self.assertIsSubclass(C, P)
+        self.assertIsSubclass(C, PG)
+        self.assertIsSubclass(BadP, PG)
+        with self.assertRaises(TypeError):
+            issubclass(C, PG[T])
+        with self.assertRaises(TypeError):
+            issubclass(C, PG[C])
+        with self.assertRaises(TypeError):
+            issubclass(C, BadP)
+        with self.assertRaises(TypeError):
+            issubclass(C, BadPG)
+        with self.assertRaises(TypeError):
+            issubclass(P, PG[T])
+        with self.assertRaises(TypeError):
+            issubclass(PG, PG[int])
+
+    def test_protocols_issubclass_non_callable(self):
+        class C:
+            x = 1
+        @runtime
+        class PNonCall(Protocol):
+            x = 1
+        with self.assertRaises(TypeError):
+            issubclass(C, PNonCall)
+        self.assertIsInstance(C(), PNonCall)
+        PNonCall.register(C)
+        with self.assertRaises(TypeError):
+            issubclass(C, PNonCall)
+        self.assertIsInstance(C(), PNonCall)
+        # check that non-protocol subclasses are not affected
+        class D(PNonCall): ...
+        self.assertNotIsSubclass(C, D)
+        self.assertNotIsInstance(C(), D)
+        D.register(C)
+        self.assertIsSubclass(C, D)
+        self.assertIsInstance(C(), D)
+        with self.assertRaises(TypeError):
+            issubclass(D, PNonCall)
+
+    def test_protocols_isinstance(self):
+        T = TypeVar('T')
+        @runtime
+        class P(Protocol):
+            def meth(x): ...
+        @runtime
+        class PG(Protocol[T]):
+            def meth(x): ...
+        class BadP(Protocol):
+            def meth(x): ...
+        class BadPG(Protocol[T]):
+            def meth(x): ...
+        class C:
+            def meth(x): ...
+        self.assertIsInstance(C(), P)
+        self.assertIsInstance(C(), PG)
+        with self.assertRaises(TypeError):
+            isinstance(C(), PG[T])
+        with self.assertRaises(TypeError):
+            isinstance(C(), PG[C])
+        with self.assertRaises(TypeError):
+            isinstance(C(), BadP)
+        with self.assertRaises(TypeError):
+            isinstance(C(), BadPG)
+
+    def test_protocols_isinstance_py36(self):
+        class APoint:
+            def __init__(self, x, y, label):
+                self.x = x
+                self.y = y
+                self.label = label
+        class BPoint:
+            label = 'B'
+            def __init__(self, x, y):
+                self.x = x
+                self.y = y
+        class C:
+            def __init__(self, attr):
+                self.attr = attr
+            def meth(self, arg):
+                return 0
+        class Bad: pass
+        self.assertIsInstance(APoint(1, 2, 'A'), Point)
+        self.assertIsInstance(BPoint(1, 2), Point)
+        self.assertNotIsInstance(MyPoint(), Point)
+        self.assertIsInstance(BPoint(1, 2), Position)
+        self.assertIsInstance(Other(), Proto)
+        self.assertIsInstance(Concrete(), Proto)
+        self.assertIsInstance(C(42), Proto)
+        self.assertNotIsInstance(Bad(), Proto)
+        self.assertNotIsInstance(Bad(), Point)
+        self.assertNotIsInstance(Bad(), Position)
+        self.assertNotIsInstance(Bad(), Concrete)
+        self.assertNotIsInstance(Other(), Concrete)
+        self.assertIsInstance(NT(1, 2), Position)
+
+    def test_protocols_isinstance_init(self):
+        T = TypeVar('T')
+        @runtime
+        class P(Protocol):
+            x = 1
+        @runtime
+        class PG(Protocol[T]):
+            x = 1
+        class C:
+            def __init__(self, x):
+                self.x = x
+        self.assertIsInstance(C(1), P)
+        self.assertIsInstance(C(1), PG)
+
+    def test_protocols_support_register(self):
+        @runtime
+        class P(Protocol):
+            x = 1
+        class PM(Protocol):
+            def meth(self): pass
+        class D(PM): pass
+        class C: pass
+        D.register(C)
+        P.register(C)
+        self.assertIsInstance(C(), P)
+        self.assertIsInstance(C(), D)
+
+    def test_none_on_non_callable_doesnt_block_implementation(self):
+        @runtime
+        class P(Protocol):
+            x = 1
+        class A:
+            x = 1
+        class B(A):
+            x = None
+        class C:
+            def __init__(self):
+                self.x = None
+        self.assertIsInstance(B(), P)
+        self.assertIsInstance(C(), P)
+
+    def test_none_on_callable_blocks_implementation(self):
+        @runtime
+        class P(Protocol):
+            def x(self): ...
+        class A:
+            def x(self): ...
+        class B(A):
+            x = None
+        class C:
+            def __init__(self):
+                self.x = None
+        self.assertNotIsInstance(B(), P)
+        self.assertNotIsInstance(C(), P)
+
+    def test_non_protocol_subclasses(self):
+        class P(Protocol):
+            x = 1
+        @runtime
+        class PR(Protocol):
+            def meth(self): pass
+        class NonP(P):
+            x = 1
+        class NonPR(PR): pass
+        class C:
+            x = 1
+        class D:
+            def meth(self): pass
+        self.assertNotIsInstance(C(), NonP)
+        self.assertNotIsInstance(D(), NonPR)
+        self.assertNotIsSubclass(C, NonP)
+        self.assertNotIsSubclass(D, NonPR)
+        self.assertIsInstance(NonPR(), PR)
+        self.assertIsSubclass(NonPR, PR)
+
+    def test_custom_subclasshook(self):
+        class P(Protocol):
+            x = 1
+        class OKClass: pass
+        class BadClass:
+            x = 1
+        class C(P):
+            @classmethod
+            def __subclasshook__(cls, other):
+                return other.__name__.startswith("OK")
+        self.assertIsInstance(OKClass(), C)
+        self.assertNotIsInstance(BadClass(), C)
+        self.assertIsSubclass(OKClass, C)
+        self.assertNotIsSubclass(BadClass, C)
+
+    def test_issubclass_fails_correctly(self):
+        @runtime
+        class P(Protocol):
+            x = 1
+        class C: pass
+        with self.assertRaises(TypeError):
+            issubclass(C(), P)
+
+    def test_defining_generic_protocols(self):
+        T = TypeVar('T')
+        S = TypeVar('S')
+        @runtime
+        class PR(Protocol[T, S]):
+            def meth(self): pass
+        class P(PR[int, T], Protocol[T]):
+            y = 1
+        with self.assertRaises(TypeError):
+            issubclass(PR[int, T], PR)
+        with self.assertRaises(TypeError):
+            issubclass(P[str], PR)
+        with self.assertRaises(TypeError):
+            PR[int]
+        with self.assertRaises(TypeError):
+            P[int, str]
+        if not TYPING_3_10_0:
+            with self.assertRaises(TypeError):
+                PR[int, 1]
+            with self.assertRaises(TypeError):
+                PR[int, ClassVar]
+        class C(PR[int, T]): pass
+        self.assertIsInstance(C[str](), C)
+
+    def test_defining_generic_protocols_old_style(self):
+        T = TypeVar('T')
+        S = TypeVar('S')
+        @runtime
+        class PR(Protocol, Generic[T, S]):
+            def meth(self): pass
+        class P(PR[int, str], Protocol):
+            y = 1
+        with self.assertRaises(TypeError):
+            self.assertIsSubclass(PR[int, str], PR)
+        self.assertIsSubclass(P, PR)
+        with self.assertRaises(TypeError):
+            PR[int]
+        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):
+            def bar(self, x: T) -> str: ...
+        @runtime
+        class PSub(P1[str], Protocol):
+            x = 1
+        class Test:
+            x = 1
+            def bar(self, x: str) -> str:
+                return x
+        self.assertIsInstance(Test(), PSub)
+        if not TYPING_3_10_0:
+            with self.assertRaises(TypeError):
+                PR[int, ClassVar]
+
+    def test_init_called(self):
+        T = TypeVar('T')
+        class P(Protocol[T]): pass
+        class C(P[T]):
+            def __init__(self):
+                self.test = 'OK'
+        self.assertEqual(C[int]().test, 'OK')
+
+    def test_protocols_bad_subscripts(self):
+        T = TypeVar('T')
+        S = TypeVar('S')
+        with self.assertRaises(TypeError):
+            class P(Protocol[T, T]): pass
+        with self.assertRaises(TypeError):
+            class P(Protocol[int]): pass
+        with self.assertRaises(TypeError):
+            class P(Protocol[T], Protocol[S]): pass
+        with self.assertRaises(TypeError):
+            class P(typing.Mapping[T, S], Protocol[T]): pass
+
+    def test_generic_protocols_repr(self):
+        T = TypeVar('T')
+        S = TypeVar('S')
+        class P(Protocol[T, S]): pass
+        self.assertTrue(repr(P[T, S]).endswith('P[~T, ~S]'))
+        self.assertTrue(repr(P[int, str]).endswith('P[int, str]'))
+
+    def test_generic_protocols_eq(self):
+        T = TypeVar('T')
+        S = TypeVar('S')
+        class P(Protocol[T, S]): pass
+        self.assertEqual(P, P)
+        self.assertEqual(P[int, T], P[int, T])
+        self.assertEqual(P[T, T][Tuple[T, S]][int, str],
+                         P[Tuple[int, str], Tuple[int, str]])
+
+    def test_generic_protocols_special_from_generic(self):
+        T = TypeVar('T')
+        class P(Protocol[T]): pass
+        self.assertEqual(P.__parameters__, (T,))
+        self.assertEqual(P[int].__parameters__, ())
+        self.assertEqual(P[int].__args__, (int,))
+        self.assertIs(P[int].__origin__, P)
+
+    def test_generic_protocols_special_from_protocol(self):
+        @runtime
+        class PR(Protocol):
+            x = 1
+        class P(Protocol):
+            def meth(self):
+                pass
+        T = TypeVar('T')
+        class PG(Protocol[T]):
+            x = 1
+            def meth(self):
+                pass
+        self.assertTrue(P._is_protocol)
+        self.assertTrue(PR._is_protocol)
+        self.assertTrue(PG._is_protocol)
+        if hasattr(typing, 'Protocol'):
+            self.assertFalse(P._is_runtime_protocol)
+        else:
+            with self.assertRaises(AttributeError):
+                self.assertFalse(P._is_runtime_protocol)
+        self.assertTrue(PR._is_runtime_protocol)
+        self.assertTrue(PG[int]._is_protocol)
+        self.assertEqual(typing_extensions._get_protocol_attrs(P), {'meth'})
+        self.assertEqual(typing_extensions._get_protocol_attrs(PR), {'x'})
+        self.assertEqual(frozenset(typing_extensions._get_protocol_attrs(PG)),
+                         frozenset({'x', 'meth'}))
+
+    def test_no_runtime_deco_on_nominal(self):
+        with self.assertRaises(TypeError):
+            @runtime
+            class C: pass
+        class Proto(Protocol):
+            x = 1
+        with self.assertRaises(TypeError):
+            @runtime
+            class Concrete(Proto):
+                pass
+
+    def test_none_treated_correctly(self):
+        @runtime
+        class P(Protocol):
+            x = None  # type: int
+        class B(object): pass
+        self.assertNotIsInstance(B(), P)
+        class C:
+            x = 1
+        class D:
+            x = None
+        self.assertIsInstance(C(), P)
+        self.assertIsInstance(D(), P)
+        class CI:
+            def __init__(self):
+                self.x = 1
+        class DI:
+            def __init__(self):
+                self.x = None
+        self.assertIsInstance(C(), P)
+        self.assertIsInstance(D(), P)
+
+    def test_protocols_in_unions(self):
+        class P(Protocol):
+            x = None  # type: int
+        Alias = typing.Union[typing.Iterable, P]
+        Alias2 = typing.Union[P, typing.Iterable]
+        self.assertEqual(Alias, Alias2)
+
+    def test_protocols_pickleable(self):
+        global P, CP  # pickle wants to reference the class by name
+        T = TypeVar('T')
+
+        @runtime
+        class P(Protocol[T]):
+            x = 1
+        class CP(P[int]):
+            pass
+
+        c = CP()
+        c.foo = 42
+        c.bar = 'abc'
+        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
+            z = pickle.dumps(c, proto)
+            x = pickle.loads(z)
+            self.assertEqual(x.foo, 42)
+            self.assertEqual(x.bar, 'abc')
+            self.assertEqual(x.x, 1)
+            self.assertEqual(x.__dict__, {'foo': 42, 'bar': 'abc'})
+            s = pickle.dumps(P)
+            D = pickle.loads(s)
+            class E:
+                x = 1
+            self.assertIsInstance(E(), D)
+
+    def test_collections_protocols_allowed(self):
+        @runtime_checkable
+        class Custom(collections.abc.Iterable, Protocol):
+            def close(self): pass
+
+        class A: ...
+        class B:
+            def __iter__(self):
+                return []
+            def close(self):
+                return 0
+
+        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):
+
+    def test_basics_iterable_syntax(self):
+        Emp = TypedDict('Emp', {'name': str, 'id': int})
+        self.assertIsSubclass(Emp, dict)
+        self.assertIsSubclass(Emp, typing.MutableMapping)
+        self.assertNotIsSubclass(Emp, collections.abc.Sequence)
+        jim = Emp(name='Jim', id=1)
+        self.assertIs(type(jim), dict)
+        self.assertEqual(jim['name'], 'Jim')
+        self.assertEqual(jim['id'], 1)
+        self.assertEqual(Emp.__name__, 'Emp')
+        self.assertEqual(Emp.__module__, __name__)
+        self.assertEqual(Emp.__bases__, (dict,))
+        self.assertEqual(Emp.__annotations__, {'name': str, 'id': int})
+        self.assertEqual(Emp.__total__, True)
+
+    def test_basics_keywords_syntax(self):
+        Emp = TypedDict('Emp', name=str, id=int)
+        self.assertIsSubclass(Emp, dict)
+        self.assertIsSubclass(Emp, typing.MutableMapping)
+        self.assertNotIsSubclass(Emp, collections.abc.Sequence)
+        jim = Emp(name='Jim', id=1)
+        self.assertIs(type(jim), dict)
+        self.assertEqual(jim['name'], 'Jim')
+        self.assertEqual(jim['id'], 1)
+        self.assertEqual(Emp.__name__, 'Emp')
+        self.assertEqual(Emp.__module__, __name__)
+        self.assertEqual(Emp.__bases__, (dict,))
+        self.assertEqual(Emp.__annotations__, {'name': str, 'id': int})
+        self.assertEqual(Emp.__total__, True)
+
+    def test_typeddict_special_keyword_names(self):
+        TD = TypedDict("TD", cls=type, self=object, typename=str, _typename=int,
+                       fields=list, _fields=dict)
+        self.assertEqual(TD.__name__, 'TD')
+        self.assertEqual(TD.__annotations__, {'cls': type, 'self': object, 'typename': str,
+                                              '_typename': int, 'fields': list, '_fields': dict})
+        a = TD(cls=str, self=42, typename='foo', _typename=53,
+               fields=[('bar', tuple)], _fields={'baz', set})
+        self.assertEqual(a['cls'], str)
+        self.assertEqual(a['self'], 42)
+        self.assertEqual(a['typename'], 'foo')
+        self.assertEqual(a['_typename'], 53)
+        self.assertEqual(a['fields'], [('bar', tuple)])
+        self.assertEqual(a['_fields'], {'baz', set})
+
+    @skipIf(hasattr(typing, 'TypedDict'), "Should be tested by upstream")
+    def test_typeddict_create_errors(self):
+        with self.assertRaises(TypeError):
+            TypedDict.__new__()
+        with self.assertRaises(TypeError):
+            TypedDict()
+        with self.assertRaises(TypeError):
+            TypedDict('Emp', [('name', str)], None)
+
+        with self.assertWarns(DeprecationWarning):
+            Emp = TypedDict(_typename='Emp', name=str, id=int)
+        self.assertEqual(Emp.__name__, 'Emp')
+        self.assertEqual(Emp.__annotations__, {'name': str, 'id': int})
+
+        with self.assertWarns(DeprecationWarning):
+            Emp = TypedDict('Emp', _fields={'name': str, 'id': int})
+        self.assertEqual(Emp.__name__, 'Emp')
+        self.assertEqual(Emp.__annotations__, {'name': str, 'id': int})
+
+    def test_typeddict_errors(self):
+        Emp = TypedDict('Emp', {'name': str, 'id': int})
+        if hasattr(typing, "Required"):
+            self.assertEqual(TypedDict.__module__, 'typing')
+        else:
+            self.assertEqual(TypedDict.__module__, 'typing_extensions')
+        jim = Emp(name='Jim', id=1)
+        with self.assertRaises(TypeError):
+            isinstance({}, Emp)
+        with self.assertRaises(TypeError):
+            isinstance(jim, Emp)
+        with self.assertRaises(TypeError):
+            issubclass(dict, Emp)
+        with self.assertRaises(TypeError):
+            TypedDict('Hi', x=1)
+        with self.assertRaises(TypeError):
+            TypedDict('Hi', [('x', int), ('y', 1)])
+        with self.assertRaises(TypeError):
+            TypedDict('Hi', [('x', int)], y=int)
+
+    def test_py36_class_syntax_usage(self):
+        self.assertEqual(LabelPoint2D.__name__, 'LabelPoint2D')
+        self.assertEqual(LabelPoint2D.__module__, __name__)
+        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)
+        not_origin = Point2D(x=0, y=1)
+        self.assertEqual(not_origin['x'], 0)
+        self.assertEqual(not_origin['y'], 1)
+        other = LabelPoint2D(x=0, y=1, label='hi')
+        self.assertEqual(other['label'], 'hi')
+
+    def test_pickle(self):
+        global EmpD  # pickle wants to reference the class by name
+        EmpD = TypedDict('EmpD', name=str, id=int)
+        jane = EmpD({'name': 'jane', 'id': 37})
+        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
+            z = pickle.dumps(jane, proto)
+            jane2 = pickle.loads(z)
+            self.assertEqual(jane2, jane)
+            self.assertEqual(jane2, {'name': 'jane', 'id': 37})
+            ZZ = pickle.dumps(EmpD, proto)
+            EmpDnew = pickle.loads(ZZ)
+            self.assertEqual(EmpDnew({'name': 'jane', 'id': 37}), jane)
+
+    def test_optional(self):
+        EmpD = TypedDict('EmpD', name=str, id=int)
+
+        self.assertEqual(typing.Optional[EmpD], typing.Union[None, EmpD])
+        self.assertNotEqual(typing.List[EmpD], typing.Tuple[EmpD])
+
+    def test_total(self):
+        D = TypedDict('D', {'x': int}, total=False)
+        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'})
+
+        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'})
+
+    def test_optional_keys(self):
+        assert Point2Dor3D.__required_keys__ == frozenset(['x', 'y'])
+        assert Point2Dor3D.__optional_keys__ == frozenset(['z'])
+
+    def test_required_notrequired_keys(self):
+        assert NontotalMovie.__required_keys__ == frozenset({'title'})
+        assert NontotalMovie.__optional_keys__ == frozenset({'year'})
+
+        assert TotalMovie.__required_keys__ == frozenset({'title'})
+        assert TotalMovie.__optional_keys__ == frozenset({'year'})
+
+
+    def test_keys_inheritance(self):
+        assert BaseAnimal.__required_keys__ == frozenset(['name'])
+        assert BaseAnimal.__optional_keys__ == frozenset([])
+        assert get_type_hints(BaseAnimal) == {'name': str}
+
+        assert Animal.__required_keys__ == frozenset(['name'])
+        assert Animal.__optional_keys__ == frozenset(['tail', 'voice'])
+        assert get_type_hints(Animal) == {
+            'name': str,
+            'tail': bool,
+            'voice': str,
+        }
+
+        assert Cat.__required_keys__ == frozenset(['name', 'fur_color'])
+        assert Cat.__optional_keys__ == frozenset(['tail', 'voice'])
+        assert get_type_hints(Cat) == {
+            'fur_color': str,
+            'name': str,
+            'tail': bool,
+            'voice': str,
+        }
+
+    def test_is_typeddict(self):
+        assert is_typeddict(Point2D) is True
+        assert is_typeddict(Point2Dor3D) is True
+        assert is_typeddict(Union[str, int]) is False
+        # classes, not instances
+        assert is_typeddict(Point2D()) is False
+
+    @skipUnless(TYPING_3_8_0, "Python 3.8+ required")
+    def test_is_typeddict_against_typeddict_from_typing(self):
+        Point = typing.TypedDict('Point', {'x': int, 'y': int})
+
+        class PointDict2D(typing.TypedDict):
+            x: int
+            y: int
+
+        class PointDict3D(PointDict2D, total=False):
+            z: int
+
+        assert is_typeddict(Point) is True
+        assert is_typeddict(PointDict2D) is True
+        assert is_typeddict(PointDict3D) is True
+
+
+class AnnotatedTests(BaseTestCase):
+
+    def test_repr(self):
+        if hasattr(typing, 'Annotated'):
+            mod_name = 'typing'
+        else:
+            mod_name = "typing_extensions"
+        self.assertEqual(
+            repr(Annotated[int, 4, 5]),
+            mod_name + ".Annotated[int, 4, 5]"
+        )
+        self.assertEqual(
+            repr(Annotated[List[int], 4, 5]),
+            mod_name + ".Annotated[typing.List[int], 4, 5]"
+        )
+
+    def test_flatten(self):
+        A = Annotated[Annotated[int, 4], 5]
+        self.assertEqual(A, Annotated[int, 4, 5])
+        self.assertEqual(A.__metadata__, (4, 5))
+        self.assertEqual(A.__origin__, int)
+
+    def test_specialize(self):
+        L = Annotated[List[T], "my decoration"]
+        LI = Annotated[List[int], "my decoration"]
+        self.assertEqual(L[int], Annotated[List[int], "my decoration"])
+        self.assertEqual(L[int].__metadata__, ("my decoration",))
+        self.assertEqual(L[int].__origin__, List[int])
+        with self.assertRaises(TypeError):
+            LI[int]
+        with self.assertRaises(TypeError):
+            L[int, float]
+
+    def test_hash_eq(self):
+        self.assertEqual(len({Annotated[int, 4, 5], Annotated[int, 4, 5]}), 1)
+        self.assertNotEqual(Annotated[int, 4, 5], Annotated[int, 5, 4])
+        self.assertNotEqual(Annotated[int, 4, 5], Annotated[str, 4, 5])
+        self.assertNotEqual(Annotated[int, 4], Annotated[int, 4, 4])
+        self.assertEqual(
+            {Annotated[int, 4, 5], Annotated[int, 4, 5], Annotated[T, 4, 5]},
+            {Annotated[int, 4, 5], Annotated[T, 4, 5]}
+        )
+
+    def test_instantiate(self):
+        class C:
+            classvar = 4
+
+            def __init__(self, x):
+                self.x = x
+
+            def __eq__(self, other):
+                if not isinstance(other, C):
+                    return NotImplemented
+                return other.x == self.x
+
+        A = Annotated[C, "a decoration"]
+        a = A(5)
+        c = C(5)
+        self.assertEqual(a, c)
+        self.assertEqual(a.x, c.x)
+        self.assertEqual(a.classvar, c.classvar)
+
+    def test_instantiate_generic(self):
+        MyCount = Annotated[typing_extensions.Counter[T], "my decoration"]
+        self.assertEqual(MyCount([4, 4, 5]), {4: 2, 5: 1})
+        self.assertEqual(MyCount[int]([4, 4, 5]), {4: 2, 5: 1})
+
+    def test_cannot_instantiate_forward(self):
+        A = Annotated["int", (5, 6)]
+        with self.assertRaises(TypeError):
+            A(5)
+
+    def test_cannot_instantiate_type_var(self):
+        A = Annotated[T, (5, 6)]
+        with self.assertRaises(TypeError):
+            A(5)
+
+    def test_cannot_getattr_typevar(self):
+        with self.assertRaises(AttributeError):
+            Annotated[T, (5, 7)].x
+
+    def test_attr_passthrough(self):
+        class C:
+            classvar = 4
+
+        A = Annotated[C, "a decoration"]
+        self.assertEqual(A.classvar, 4)
+        A.x = 5
+        self.assertEqual(C.x, 5)
+
+    @skipIf(sys.version_info[:2] in ((3, 9), (3, 10)), "Waiting for bpo-46491 bugfix.")
+    def test_special_form_containment(self):
+        class C:
+            classvar: Annotated[ClassVar[int], "a decoration"] = 4
+            const: Annotated[Final[int], "Const"] = 4
+
+        if sys.version_info[:2] >= (3, 7):
+            self.assertEqual(get_type_hints(C, globals())["classvar"], ClassVar[int])
+            self.assertEqual(get_type_hints(C, globals())["const"], Final[int])
+        else:
+            self.assertEqual(
+                get_type_hints(C, globals())["classvar"],
+                Annotated[ClassVar[int], "a decoration"]
+            )
+            self.assertEqual(
+                get_type_hints(C, globals())["const"], Annotated[Final[int], "Const"]
+            )
+
+    def test_hash_eq(self):
+        self.assertEqual(len({Annotated[int, 4, 5], Annotated[int, 4, 5]}), 1)
+        self.assertNotEqual(Annotated[int, 4, 5], Annotated[int, 5, 4])
+        self.assertNotEqual(Annotated[int, 4, 5], Annotated[str, 4, 5])
+        self.assertNotEqual(Annotated[int, 4], Annotated[int, 4, 4])
+        self.assertEqual(
+            {Annotated[int, 4, 5], Annotated[int, 4, 5], Annotated[T, 4, 5]},
+            {Annotated[int, 4, 5], Annotated[T, 4, 5]}
+        )
+
+    def test_cannot_subclass(self):
+        with self.assertRaisesRegex(TypeError, "Cannot subclass .*Annotated"):
+            class C(Annotated):
+                pass
+
+    def test_cannot_check_instance(self):
+        with self.assertRaises(TypeError):
+            isinstance(5, Annotated[int, "positive"])
+
+    def test_cannot_check_subclass(self):
+        with self.assertRaises(TypeError):
+            issubclass(int, Annotated[int, "positive"])
+
+    def test_pickle(self):
+        samples = [typing.Any, typing.Union[int, str],
+                   typing.Optional[str], Tuple[int, ...],
+                   typing.Callable[[str], bytes],
+                   Self, LiteralString, Never]
+
+        for t in samples:
+            x = Annotated[t, "a"]
+
+            for prot in range(pickle.HIGHEST_PROTOCOL + 1):
+                with self.subTest(protocol=prot, type=t):
+                    pickled = pickle.dumps(x, prot)
+                    restored = pickle.loads(pickled)
+                    self.assertEqual(x, restored)
+
+        global _Annotated_test_G
+
+        class _Annotated_test_G(Generic[T]):
+            x = 1
+
+        G = Annotated[_Annotated_test_G[int], "A decoration"]
+        G.foo = 42
+        G.bar = 'abc'
+
+        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
+            z = pickle.dumps(G, proto)
+            x = pickle.loads(z)
+            self.assertEqual(x.foo, 42)
+            self.assertEqual(x.bar, 'abc')
+            self.assertEqual(x.x, 1)
+
+    def test_subst(self):
+        dec = "a decoration"
+        dec2 = "another decoration"
+
+        S = Annotated[T, dec2]
+        self.assertEqual(S[int], Annotated[int, dec2])
+
+        self.assertEqual(S[Annotated[int, dec]], Annotated[int, dec, dec2])
+        L = Annotated[List[T], dec]
+
+        self.assertEqual(L[int], Annotated[List[int], dec])
+        with self.assertRaises(TypeError):
+            L[int, int]
+
+        self.assertEqual(S[L[int]], Annotated[List[int], dec, dec2])
+
+        D = Annotated[Dict[KT, VT], dec]
+        self.assertEqual(D[str, int], Annotated[Dict[str, int], dec])
+        with self.assertRaises(TypeError):
+            D[int]
+
+        It = Annotated[int, dec]
+        with self.assertRaises(TypeError):
+            It[None]
+
+        LI = L[int]
+        with self.assertRaises(TypeError):
+            LI[None]
+
+    def test_annotated_in_other_types(self):
+        X = List[Annotated[T, 5]]
+        self.assertEqual(X[int], List[Annotated[int, 5]])
+
+
+class GetTypeHintsTests(BaseTestCase):
+    def test_get_type_hints(self):
+        def foobar(x: List['X']): ...
+        X = Annotated[int, (1, 10)]
+        self.assertEqual(
+            get_type_hints(foobar, globals(), locals()),
+            {'x': List[int]}
+        )
+        self.assertEqual(
+            get_type_hints(foobar, globals(), locals(), include_extras=True),
+            {'x': List[Annotated[int, (1, 10)]]}
+        )
+        BA = Tuple[Annotated[T, (1, 0)], ...]
+        def barfoo(x: BA): ...
+        self.assertEqual(get_type_hints(barfoo, globals(), locals())['x'], Tuple[T, ...])
+        self.assertIs(
+            get_type_hints(barfoo, globals(), locals(), include_extras=True)['x'],
+            BA
+        )
+        def barfoo2(x: typing.Callable[..., Annotated[List[T], "const"]],
+                    y: typing.Union[int, Annotated[T, "mutable"]]): ...
+        self.assertEqual(
+            get_type_hints(barfoo2, globals(), locals()),
+            {'x': typing.Callable[..., List[T]], 'y': typing.Union[int, T]}
+        )
+        BA2 = typing.Callable[..., List[T]]
+        def barfoo3(x: BA2): ...
+        self.assertIs(
+            get_type_hints(barfoo3, globals(), locals(), include_extras=True)["x"],
+            BA2
+        )
+
+    def test_get_type_hints_refs(self):
+
+        Const = Annotated[T, "Const"]
+
+        class MySet(Generic[T]):
+
+            def __ior__(self, other: "Const[MySet[T]]") -> "MySet[T]":
+                ...
+
+            def __iand__(self, other: Const["MySet[T]"]) -> "MySet[T]":
+                ...
+
+        self.assertEqual(
+            get_type_hints(MySet.__iand__, globals(), locals()),
+            {'other': MySet[T], 'return': MySet[T]}
+        )
+
+        self.assertEqual(
+            get_type_hints(MySet.__iand__, globals(), locals(), include_extras=True),
+            {'other': Const[MySet[T]], 'return': MySet[T]}
+        )
+
+        self.assertEqual(
+            get_type_hints(MySet.__ior__, globals(), locals()),
+            {'other': MySet[T], 'return': MySet[T]}
+        )
+
+    def test_get_type_hints_typeddict(self):
+        assert get_type_hints(TotalMovie) == {'title': str, 'year': int}
+        assert get_type_hints(TotalMovie, include_extras=True) == {
+            'title': str,
+            'year': NotRequired[int],
+        }
+
+        assert get_type_hints(AnnotatedMovie) == {'title': str, 'year': int}
+        assert get_type_hints(AnnotatedMovie, include_extras=True) == {
+            'title': Annotated[Required[str], "foobar"],
+            'year': NotRequired[Annotated[int, 2000]],
+        }
+
+
+class TypeAliasTests(BaseTestCase):
+    def test_canonical_usage_with_variable_annotation(self):
+        ns = {}
+        exec('Alias: TypeAlias = Employee', globals(), ns)
+
+    def test_canonical_usage_with_type_comment(self):
+        Alias = Employee  # type: TypeAlias
+
+    def test_cannot_instantiate(self):
+        with self.assertRaises(TypeError):
+            TypeAlias()
+
+    def test_no_isinstance(self):
+        with self.assertRaises(TypeError):
+            isinstance(42, TypeAlias)
+
+    def test_no_issubclass(self):
+        with self.assertRaises(TypeError):
+            issubclass(Employee, TypeAlias)
+
+        with self.assertRaises(TypeError):
+            issubclass(TypeAlias, Employee)
+
+    def test_cannot_subclass(self):
+        with self.assertRaises(TypeError):
+            class C(TypeAlias):
+                pass
+
+        with self.assertRaises(TypeError):
+            class C(type(TypeAlias)):
+                pass
+
+    def test_repr(self):
+        if hasattr(typing, 'TypeAlias'):
+            self.assertEqual(repr(TypeAlias), 'typing.TypeAlias')
+        else:
+            self.assertEqual(repr(TypeAlias), 'typing_extensions.TypeAlias')
+
+    def test_cannot_subscript(self):
+        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]
+        self.assertEqual(C1.__args__, (P, int))
+        self.assertEqual(C1.__parameters__, (P,))
+        C2 = typing.Callable[P, T]
+        self.assertEqual(C2.__args__, (P, T))
+        self.assertEqual(C2.__parameters__, (P, T))
+
+
+        # Test collections.abc.Callable too.
+        if sys.version_info[:2] >= (3, 9):
+            # Note: no tests for Callable.__parameters__ here
+            # because types.GenericAlias Callable is hardcoded to search
+            # for tp_name "TypeVar" in C.  This was changed in 3.10.
+            C3 = collections.abc.Callable[P, int]
+            self.assertEqual(C3.__args__, (P, int))
+            C4 = collections.abc.Callable[P, T]
+            self.assertEqual(C4.__args__, (P, T))
+
+        # ParamSpec instances should also have args and kwargs attributes.
+        # Note: not in dir(P) because of __class__ hacks
+        self.assertTrue(hasattr(P, 'args'))
+        self.assertTrue(hasattr(P, 'kwargs'))
+
+    @skipIf((3, 10, 0) <= sys.version_info[:3] <= (3, 10, 2), "Needs bpo-46676.")
+    def test_args_kwargs(self):
+        P = ParamSpec('P')
+        P_2 = ParamSpec('P_2')
+        # Note: not in dir(P) because of __class__ hacks
+        self.assertTrue(hasattr(P, 'args'))
+        self.assertTrue(hasattr(P, 'kwargs'))
+        self.assertIsInstance(P.args, ParamSpecArgs)
+        self.assertIsInstance(P.kwargs, ParamSpecKwargs)
+        self.assertIs(P.args.__origin__, P)
+        self.assertIs(P.kwargs.__origin__, P)
+        self.assertEqual(P.args, P.args)
+        self.assertEqual(P.kwargs, P.kwargs)
+        self.assertNotEqual(P.args, P_2.args)
+        self.assertNotEqual(P.kwargs, P_2.kwargs)
+        self.assertNotEqual(P.args, P.kwargs)
+        self.assertNotEqual(P.kwargs, P.args)
+        self.assertNotEqual(P.args, P_2.kwargs)
+        self.assertEqual(repr(P.args), "P.args")
+        self.assertEqual(repr(P.kwargs), "P.kwargs")
+
+    def test_user_generics(self):
+        T = TypeVar("T")
+        P = ParamSpec("P")
+        P_2 = ParamSpec("P_2")
+
+        class X(Generic[T, P]):
+            pass
+
+        G1 = X[int, P_2]
+        self.assertEqual(G1.__args__, (int, P_2))
+        self.assertEqual(G1.__parameters__, (P_2,))
+
+        G2 = X[int, Concatenate[int, P_2]]
+        self.assertEqual(G2.__args__, (int, Concatenate[int, P_2]))
+        self.assertEqual(G2.__parameters__, (P_2,))
+
+        # The following are some valid uses cases in PEP 612 that don't work:
+        # These do not work in 3.9, _type_check blocks the list and ellipsis.
+        # G3 = X[int, [int, bool]]
+        # G4 = X[int, ...]
+        # G5 = Z[[int, str, bool]]
+        # Not working because this is special-cased in 3.10.
+        # G6 = Z[int, str, bool]
+
+        class Z(Generic[P]):
+            pass
+
+    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(f'Pickle protocol {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 = Callable[Concatenate[int, P], int]
+        C2 = 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_invalid_uses(self):
+        P = ParamSpec('P')
+        T = TypeVar('T')
+
+        with self.assertRaisesRegex(
+            TypeError,
+            'Cannot take a Concatenate of no types',
+        ):
+            Concatenate[()]
+
+        with self.assertRaisesRegex(
+            TypeError,
+            'The last parameter to Concatenate should be a ParamSpec variable',
+        ):
+            Concatenate[P, T]
+
+        with self.assertRaisesRegex(
+            TypeError,
+            'each arg must be a type',
+        ):
+            Concatenate[1, P]
+
+    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), f'{mod_name}.TypeGuard')
+        cv = TypeGuard[int]
+        self.assertEqual(repr(cv), f'{mod_name}.TypeGuard[int]')
+        cv = TypeGuard[Employee]
+        self.assertEqual(repr(cv), f'{mod_name}.TypeGuard[{__name__}.Employee]')
+        cv = TypeGuard[Tuple[int]]
+        self.assertEqual(repr(cv), f'{mod_name}.TypeGuard[typing.Tuple[int]]')
+
+    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 LiteralStringTests(BaseTestCase):
+    def test_basics(self):
+        class Foo:
+            def bar(self) -> LiteralString: ...
+            def baz(self) -> "LiteralString": ...
+
+        self.assertEqual(gth(Foo.bar), {'return': LiteralString})
+        self.assertEqual(gth(Foo.baz), {'return': LiteralString})
+
+    def test_get_origin(self):
+        self.assertIsNone(get_origin(LiteralString))
+
+    def test_repr(self):
+        if hasattr(typing, 'LiteralString'):
+            mod_name = 'typing'
+        else:
+            mod_name = 'typing_extensions'
+        self.assertEqual(repr(LiteralString), '{}.LiteralString'.format(mod_name))
+
+    def test_cannot_subscript(self):
+        with self.assertRaises(TypeError):
+            LiteralString[int]
+
+    def test_cannot_subclass(self):
+        with self.assertRaises(TypeError):
+            class C(type(LiteralString)):
+                pass
+        with self.assertRaises(TypeError):
+            class C(LiteralString):
+                pass
+
+    def test_cannot_init(self):
+        with self.assertRaises(TypeError):
+            LiteralString()
+        with self.assertRaises(TypeError):
+            type(LiteralString)()
+
+    def test_no_isinstance(self):
+        with self.assertRaises(TypeError):
+            isinstance(1, LiteralString)
+        with self.assertRaises(TypeError):
+            issubclass(int, LiteralString)
+
+    def test_alias(self):
+        StringTuple = Tuple[LiteralString, LiteralString]
+        class Alias:
+            def return_tuple(self) -> StringTuple:
+                return ("foo", "pep" + "675")
+
+    def test_typevar(self):
+        StrT = TypeVar("StrT", bound=LiteralString)
+        self.assertIs(StrT.__bound__, LiteralString)
+
+    def test_pickle(self):
+        for proto in range(pickle.HIGHEST_PROTOCOL):
+            pickled = pickle.dumps(LiteralString, protocol=proto)
+            self.assertIs(LiteralString, pickle.loads(pickled))
+
+
+class SelfTests(BaseTestCase):
+    def test_basics(self):
+        class Foo:
+            def bar(self) -> Self: ...
+
+        self.assertEqual(gth(Foo.bar), {'return': Self})
+
+    def test_repr(self):
+        if hasattr(typing, 'Self'):
+            mod_name = 'typing'
+        else:
+            mod_name = 'typing_extensions'
+        self.assertEqual(repr(Self), '{}.Self'.format(mod_name))
+
+    def test_cannot_subscript(self):
+        with self.assertRaises(TypeError):
+            Self[int]
+
+    def test_cannot_subclass(self):
+        with self.assertRaises(TypeError):
+            class C(type(Self)):
+                pass
+
+    def test_cannot_init(self):
+        with self.assertRaises(TypeError):
+            Self()
+        with self.assertRaises(TypeError):
+            type(Self)()
+
+    def test_no_isinstance(self):
+        with self.assertRaises(TypeError):
+            isinstance(1, Self)
+        with self.assertRaises(TypeError):
+            issubclass(int, Self)
+
+    def test_alias(self):
+        TupleSelf = Tuple[Self, Self]
+        class Alias:
+            def return_tuple(self) -> TupleSelf:
+                return (self, self)
+
+    def test_pickle(self):
+        for proto in range(pickle.HIGHEST_PROTOCOL):
+            pickled = pickle.dumps(Self, protocol=proto)
+            self.assertIs(Self, pickle.loads(pickled))
+
+
+class UnpackTests(BaseTestCase):
+    def test_basic_plain(self):
+        Ts = TypeVarTuple('Ts')
+        self.assertEqual(Unpack[Ts], Unpack[Ts])
+        with self.assertRaises(TypeError):
+            Unpack()
+
+    def test_repr(self):
+        Ts = TypeVarTuple('Ts')
+        self.assertEqual(repr(Unpack[Ts]), 'typing_extensions.Unpack[Ts]')
+
+    def test_cannot_subclass_vars(self):
+        with self.assertRaises(TypeError):
+            class V(Unpack[TypeVarTuple('Ts')]):
+                pass
+
+    def test_tuple(self):
+        Ts = TypeVarTuple('Ts')
+        Tuple[Unpack[Ts]]
+
+    def test_union(self):
+        Xs = TypeVarTuple('Xs')
+        Ys = TypeVarTuple('Ys')
+        self.assertEqual(
+            Union[Unpack[Xs]],
+            Unpack[Xs]
+        )
+        self.assertNotEqual(
+            Union[Unpack[Xs]],
+            Union[Unpack[Xs], Unpack[Ys]]
+        )
+        self.assertEqual(
+            Union[Unpack[Xs], Unpack[Xs]],
+            Unpack[Xs]
+        )
+        self.assertNotEqual(
+            Union[Unpack[Xs], int],
+            Union[Unpack[Xs]]
+        )
+        self.assertNotEqual(
+            Union[Unpack[Xs], int],
+            Union[int]
+        )
+        self.assertEqual(
+            Union[Unpack[Xs], int].__args__,
+            (Unpack[Xs], int)
+        )
+        self.assertEqual(
+            Union[Unpack[Xs], int].__parameters__,
+            (Xs,)
+        )
+        self.assertIs(
+            Union[Unpack[Xs], int].__origin__,
+            Union
+        )
+
+    def test_concatenation(self):
+        Xs = TypeVarTuple('Xs')
+        self.assertEqual(Tuple[int, Unpack[Xs]].__args__, (int, Unpack[Xs]))
+        self.assertEqual(Tuple[Unpack[Xs], int].__args__, (Unpack[Xs], int))
+        self.assertEqual(Tuple[int, Unpack[Xs], str].__args__,
+                         (int, Unpack[Xs], str))
+        class C(Generic[Unpack[Xs]]): pass
+        self.assertEqual(C[int, Unpack[Xs]].__args__, (int, Unpack[Xs]))
+        self.assertEqual(C[Unpack[Xs], int].__args__, (Unpack[Xs], int))
+        self.assertEqual(C[int, Unpack[Xs], str].__args__,
+                         (int, Unpack[Xs], str))
+
+    def test_class(self):
+        Ts = TypeVarTuple('Ts')
+
+        class C(Generic[Unpack[Ts]]): pass
+        self.assertEqual(C[int].__args__, (int,))
+        self.assertEqual(C[int, str].__args__, (int, str))
+
+        with self.assertRaises(TypeError):
+            class C(Generic[Unpack[Ts], int]): pass
+
+        T1 = TypeVar('T')
+        T2 = TypeVar('T')
+        class C(Generic[T1, T2, Unpack[Ts]]): pass
+        self.assertEqual(C[int, str].__args__, (int, str))
+        self.assertEqual(C[int, str, float].__args__, (int, str, float))
+        self.assertEqual(C[int, str, float, bool].__args__, (int, str, float, bool))
+        with self.assertRaises(TypeError):
+            C[int]
+
+
+class TypeVarTupleTests(BaseTestCase):
+
+    def test_basic_plain(self):
+        Ts = TypeVarTuple('Ts')
+        self.assertEqual(Ts, Ts)
+        self.assertIsInstance(Ts, TypeVarTuple)
+        Xs = TypeVarTuple('Xs')
+        Ys = TypeVarTuple('Ys')
+        self.assertNotEqual(Xs, Ys)
+
+    def test_repr(self):
+        Ts = TypeVarTuple('Ts')
+        self.assertEqual(repr(Ts), 'Ts')
+
+    def test_no_redefinition(self):
+        self.assertNotEqual(TypeVarTuple('Ts'), TypeVarTuple('Ts'))
+
+    def test_cannot_subclass_vars(self):
+        with self.assertRaises(TypeError):
+            class V(TypeVarTuple('Ts')):
+                pass
+
+    def test_cannot_subclass_var_itself(self):
+        with self.assertRaises(TypeError):
+            class V(TypeVarTuple):
+                pass
+
+    def test_cannot_instantiate_vars(self):
+        Ts = TypeVarTuple('Ts')
+        with self.assertRaises(TypeError):
+            Ts()
+
+    def test_tuple(self):
+        Ts = TypeVarTuple('Ts')
+        # Not legal at type checking time but we can't really check against it.
+        Tuple[Ts]
+
+    def test_args_and_parameters(self):
+        Ts = TypeVarTuple('Ts')
+
+        t = Tuple[tuple(Ts)]
+        self.assertEqual(t.__args__, (Ts.__unpacked__,))
+        self.assertEqual(t.__parameters__, (Ts,))
+
+
+class FinalDecoratorTests(BaseTestCase):
+    def test_final_unmodified(self):
+        def func(x): ...
+        self.assertIs(func, final(func))
+
+    def test_dunder_final(self):
+        @final
+        def func(): ...
+        @final
+        class Cls: ...
+        self.assertIs(True, func.__final__)
+        self.assertIs(True, Cls.__final__)
+
+        class Wrapper:
+            __slots__ = ("func",)
+            def __init__(self, func):
+                self.func = func
+            def __call__(self, *args, **kwargs):
+                return self.func(*args, **kwargs)
+
+        # Check that no error is thrown if the attribute
+        # is not writable.
+        @final
+        @Wrapper
+        def wrapped(): ...
+        self.assertIsInstance(wrapped, Wrapper)
+        self.assertIs(False, hasattr(wrapped, "__final__"))
+
+        class Meta(type):
+            @property
+            def __final__(self): return "can't set me"
+        @final
+        class WithMeta(metaclass=Meta): ...
+        self.assertEqual(WithMeta.__final__, "can't set me")
+
+        # Builtin classes throw TypeError if you try to set an
+        # attribute.
+        final(int)
+        self.assertIs(False, hasattr(int, "__final__"))
+
+        # Make sure it works with common builtin decorators
+        class Methods:
+            @final
+            @classmethod
+            def clsmethod(cls): ...
+
+            @final
+            @staticmethod
+            def stmethod(): ...
+
+            # The other order doesn't work because property objects
+            # don't allow attribute assignment.
+            @property
+            @final
+            def prop(self): ...
+
+            @final
+            @lru_cache()  # noqa: B019
+            def cached(self): ...
+
+        # Use getattr_static because the descriptor returns the
+        # underlying function, which doesn't have __final__.
+        self.assertIs(
+            True,
+            inspect.getattr_static(Methods, "clsmethod").__final__
+        )
+        self.assertIs(
+            True,
+            inspect.getattr_static(Methods, "stmethod").__final__
+        )
+        self.assertIs(True, Methods.prop.fget.__final__)
+        self.assertIs(True, Methods.cached.__final__)
+
+
+class RevealTypeTests(BaseTestCase):
+    def test_reveal_type(self):
+        obj = object()
+        self.assertIs(obj, reveal_type(obj))
+
+
+class DataclassTransformTests(BaseTestCase):
+    def test_decorator(self):
+        def create_model(*, frozen: bool = False, kw_only: bool = True):
+            return lambda cls: cls
+
+        decorated = dataclass_transform(kw_only_default=True, order_default=False)(create_model)
+
+        class CustomerModel:
+            id: int
+
+        self.assertIs(decorated, create_model)
+        self.assertEqual(
+            decorated.__dataclass_transform__,
+            {
+                "eq_default": True,
+                "order_default": False,
+                "kw_only_default": True,
+                "field_descriptors": (),
+            }
+        )
+        self.assertIs(
+            decorated(frozen=True, kw_only=False)(CustomerModel),
+            CustomerModel
+        )
+
+    def test_base_class(self):
+        class ModelBase:
+            def __init_subclass__(cls, *, frozen: bool = False): ...
+
+        Decorated = dataclass_transform(eq_default=True, order_default=True)(ModelBase)
+
+        class CustomerModel(Decorated, frozen=True):
+            id: int
+
+        self.assertIs(Decorated, ModelBase)
+        self.assertEqual(
+            Decorated.__dataclass_transform__,
+            {
+                "eq_default": True,
+                "order_default": True,
+                "kw_only_default": False,
+                "field_descriptors": (),
+            }
+        )
+        self.assertIsSubclass(CustomerModel, Decorated)
+
+    def test_metaclass(self):
+        class Field: ...
+
+        class ModelMeta(type):
+            def __new__(
+                cls, name, bases, namespace, *, init: bool = True,
+            ):
+                return super().__new__(cls, name, bases, namespace)
+
+        Decorated = dataclass_transform(
+            order_default=True, field_descriptors=(Field,)
+        )(ModelMeta)
+
+        class ModelBase(metaclass=Decorated): ...
+
+        class CustomerModel(ModelBase, init=False):
+            id: int
+
+        self.assertIs(Decorated, ModelMeta)
+        self.assertEqual(
+            Decorated.__dataclass_transform__,
+            {
+                "eq_default": True,
+                "order_default": True,
+                "kw_only_default": False,
+                "field_descriptors": (Field,),
+            }
+        )
+        self.assertIsInstance(CustomerModel, Decorated)
+
+
+class AllTests(BaseTestCase):
+
+    def test_typing_extensions_includes_standard(self):
+        a = typing_extensions.__all__
+        self.assertIn('ClassVar', a)
+        self.assertIn('Type', a)
+        self.assertIn('ChainMap', a)
+        self.assertIn('ContextManager', a)
+        self.assertIn('Counter', a)
+        self.assertIn('DefaultDict', a)
+        self.assertIn('Deque', a)
+        self.assertIn('NewType', a)
+        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)
+
+        self.assertIn('Annotated', a)
+        self.assertIn('get_type_hints', a)
+
+        self.assertIn('Awaitable', a)
+        self.assertIn('AsyncIterator', a)
+        self.assertIn('AsyncIterable', a)
+        self.assertIn('Coroutine', a)
+        self.assertIn('AsyncContextManager', a)
+
+        self.assertIn('AsyncGenerator', a)
+
+        self.assertIn('Protocol', a)
+        self.assertIn('runtime', a)
+
+        # Check that all objects in `__all__` are present in the module
+        for name in a:
+            self.assertTrue(hasattr(typing_extensions, name))
+
+    def test_typing_extensions_defers_when_possible(self):
+        exclude = {
+            'overload',
+            'Text',
+            'TypedDict',
+            'TYPE_CHECKING',
+            'Final',
+            'get_type_hints',
+            'is_typeddict',
+        }
+        if sys.version_info < (3, 10):
+            exclude |= {'get_args', 'get_origin'}
+        if sys.version_info < (3, 11):
+            exclude.add('final')
+        for item in typing_extensions.__all__:
+            if item not in exclude and hasattr(typing, item):
+                self.assertIs(
+                    getattr(typing_extensions, item),
+                    getattr(typing, item))
+
+    def test_typing_extensions_compiles_with_opt(self):
+        file_path = os.path.join(os.path.dirname(os.path.realpath(__file__)),
+                                 'typing_extensions.py')
+        try:
+            subprocess.check_output(f'{sys.executable} -OO {file_path}',
+                                    stderr=subprocess.STDOUT,
+                                    shell=True)
+        except subprocess.CalledProcessError:
+            self.fail('Module does not compile with optimize=2 (-OO flag).')
+
+
+
+if __name__ == '__main__':
+    main()
diff --git a/typing_extensions/src/typing_extensions.py b/typing_extensions/src/typing_extensions.py
new file mode 100644
index 0000000..5698a76
--- /dev/null
+++ b/typing_extensions/src/typing_extensions.py
@@ -0,0 +1,1882 @@
+import abc
+import collections
+import collections.abc
+import operator
+import sys
+import types as _types
+import typing
+
+
+# Please keep __all__ alphabetized within each category.
+__all__ = [
+    # Super-special typing primitives.
+    'ClassVar',
+    'Concatenate',
+    'Final',
+    'LiteralString',
+    'ParamSpec',
+    'Self',
+    'Type',
+    'TypeVarTuple',
+    'Unpack',
+
+    # ABCs (from collections.abc).
+    'Awaitable',
+    'AsyncIterator',
+    'AsyncIterable',
+    'Coroutine',
+    'AsyncGenerator',
+    'AsyncContextManager',
+    'ChainMap',
+
+    # Concrete collection types.
+    'ContextManager',
+    'Counter',
+    'Deque',
+    'DefaultDict',
+    'OrderedDict',
+    'TypedDict',
+
+    # Structural checks, a.k.a. protocols.
+    'SupportsIndex',
+
+    # One-off things.
+    'Annotated',
+    'assert_never',
+    'dataclass_transform',
+    'final',
+    'get_args',
+    'get_origin',
+    'get_type_hints',
+    'IntVar',
+    'is_typeddict',
+    'Literal',
+    'NewType',
+    'overload',
+    'Protocol',
+    'reveal_type',
+    'runtime',
+    'runtime_checkable',
+    'Text',
+    'TypeAlias',
+    'TypeGuard',
+    'TYPE_CHECKING',
+    'Never',
+    'NoReturn',
+    'Required',
+    'NotRequired',
+]
+
+# for backward compatibility
+PEP_560 = True
+GenericMeta = type
+
+# The functions below are modified copies of typing internal helpers.
+# They are needed by _ProtocolMeta and they provide support for PEP 646.
+
+_marker = object()
+
+
+def _check_generic(cls, parameters, elen=_marker):
+    """Check correct count for parameters of a generic cls (internal helper).
+    This gives a nice error message in case of count mismatch.
+    """
+    if not elen:
+        raise TypeError(f"{cls} is not a generic class")
+    if elen is _marker:
+        if not hasattr(cls, "__parameters__") or not cls.__parameters__:
+            raise TypeError(f"{cls} is not a generic class")
+        elen = len(cls.__parameters__)
+    alen = len(parameters)
+    if alen != elen:
+        if hasattr(cls, "__parameters__"):
+            parameters = [p for p in cls.__parameters__ if not _is_unpack(p)]
+            num_tv_tuples = sum(isinstance(p, TypeVarTuple) for p in parameters)
+            if (num_tv_tuples > 0) and (alen >= elen - num_tv_tuples):
+                return
+        raise TypeError(f"Too {'many' if alen > elen else 'few'} parameters for {cls};"
+                        f" actual {alen}, expected {elen}")
+
+
+if sys.version_info >= (3, 10):
+    def _should_collect_from_parameters(t):
+        return isinstance(
+            t, (typing._GenericAlias, _types.GenericAlias, _types.UnionType)
+        )
+elif sys.version_info >= (3, 9):
+    def _should_collect_from_parameters(t):
+        return isinstance(t, (typing._GenericAlias, _types.GenericAlias))
+else:
+    def _should_collect_from_parameters(t):
+        return isinstance(t, typing._GenericAlias) and not t._special
+
+
+def _collect_type_vars(types, typevar_types=None):
+    """Collect all type variable contained in types in order of
+    first appearance (lexicographic order). For example::
+
+        _collect_type_vars((T, List[S, T])) == (T, S)
+    """
+    if typevar_types is None:
+        typevar_types = typing.TypeVar
+    tvars = []
+    for t in types:
+        if (
+            isinstance(t, typevar_types) and
+            t not in tvars and
+            not _is_unpack(t)
+        ):
+            tvars.append(t)
+        if _should_collect_from_parameters(t):
+            tvars.extend([t for t in t.__parameters__ if t not in tvars])
+    return tuple(tvars)
+
+
+NoReturn = typing.NoReturn
+
+# Some unconstrained type variables.  These are used by the container types.
+# (These are not for export.)
+T = typing.TypeVar('T')  # Any type.
+KT = typing.TypeVar('KT')  # Key type.
+VT = typing.TypeVar('VT')  # Value type.
+T_co = typing.TypeVar('T_co', covariant=True)  # Any type covariant containers.
+T_contra = typing.TypeVar('T_contra', contravariant=True)  # Ditto contravariant.
+
+ClassVar = typing.ClassVar
+
+# On older versions of typing there is an internal class named "Final".
+# 3.8+
+if hasattr(typing, 'Final') and sys.version_info[:2] >= (3, 7):
+    Final = typing.Final
+# 3.7
+else:
+    class _FinalForm(typing._SpecialForm, _root=True):
+
+        def __repr__(self):
+            return 'typing_extensions.' + self._name
+
+        def __getitem__(self, parameters):
+            item = typing._type_check(parameters,
+                                      f'{self._name} accepts only single type')
+            return typing._GenericAlias(self, (item,))
+
+    Final = _FinalForm('Final',
+                       doc="""A special typing construct to indicate that a name
+                       cannot be re-assigned or overridden in a subclass.
+                       For example:
+
+                           MAX_SIZE: Final = 9000
+                           MAX_SIZE += 1  # Error reported by type checker
+
+                           class Connection:
+                               TIMEOUT: Final[int] = 10
+                           class FastConnector(Connection):
+                               TIMEOUT = 1  # Error reported by type checker
+
+                       There is no runtime checking of these properties.""")
+
+if sys.version_info >= (3, 11):
+    final = typing.final
+else:
+    # @final exists in 3.8+, but we backport it for all versions
+    # before 3.11 to keep support for the __final__ attribute.
+    # See https://bugs.python.org/issue46342
+    def final(f):
+        """This decorator can be used to indicate to type checkers that
+        the decorated method cannot be overridden, and decorated class
+        cannot be subclassed. For example:
+
+            class Base:
+                @final
+                def done(self) -> None:
+                    ...
+            class Sub(Base):
+                def done(self) -> None:  # Error reported by type checker
+                    ...
+            @final
+            class Leaf:
+                ...
+            class Other(Leaf):  # Error reported by type checker
+                ...
+
+        There is no runtime checking of these properties. The decorator
+        sets the ``__final__`` attribute to ``True`` on the decorated object
+        to allow runtime introspection.
+        """
+        try:
+            f.__final__ = True
+        except (AttributeError, TypeError):
+            # Skip the attribute silently if it is not writable.
+            # AttributeError happens if the object has __slots__ or a
+            # read-only property, TypeError if it's a builtin class.
+            pass
+        return f
+
+
+def IntVar(name):
+    return typing.TypeVar(name)
+
+
+# 3.8+:
+if hasattr(typing, 'Literal'):
+    Literal = typing.Literal
+# 3.7:
+else:
+    class _LiteralForm(typing._SpecialForm, _root=True):
+
+        def __repr__(self):
+            return 'typing_extensions.' + self._name
+
+        def __getitem__(self, parameters):
+            return typing._GenericAlias(self, parameters)
+
+    Literal = _LiteralForm('Literal',
+                           doc="""A type that can be used to indicate to type checkers
+                           that the corresponding value has a value literally equivalent
+                           to the provided parameter. For example:
+
+                               var: Literal[4] = 4
+
+                           The type checker understands that 'var' is literally equal to
+                           the value 4 and no other value.
+
+                           Literal[...] cannot be subclassed. There is no runtime
+                           checking verifying that the parameter is actually a value
+                           instead of a type.""")
+
+
+_overload_dummy = typing._overload_dummy  # noqa
+overload = typing.overload
+
+
+# This is not a real generic class.  Don't use outside annotations.
+Type = typing.Type
+
+# Various ABCs mimicking those in collections.abc.
+# A few are simply re-exported for completeness.
+
+
+Awaitable = typing.Awaitable
+Coroutine = typing.Coroutine
+AsyncIterable = typing.AsyncIterable
+AsyncIterator = typing.AsyncIterator
+Deque = typing.Deque
+ContextManager = typing.ContextManager
+AsyncContextManager = typing.AsyncContextManager
+DefaultDict = typing.DefaultDict
+
+# 3.7.2+
+if hasattr(typing, 'OrderedDict'):
+    OrderedDict = typing.OrderedDict
+# 3.7.0-3.7.2
+else:
+    OrderedDict = typing._alias(collections.OrderedDict, (KT, VT))
+
+Counter = typing.Counter
+ChainMap = typing.ChainMap
+AsyncGenerator = typing.AsyncGenerator
+NewType = typing.NewType
+Text = typing.Text
+TYPE_CHECKING = typing.TYPE_CHECKING
+
+
+_PROTO_WHITELIST = ['Callable', 'Awaitable',
+                    'Iterable', 'Iterator', 'AsyncIterable', 'AsyncIterator',
+                    'Hashable', 'Sized', 'Container', 'Collection', 'Reversible',
+                    'ContextManager', 'AsyncContextManager']
+
+
+def _get_protocol_attrs(cls):
+    attrs = set()
+    for base in cls.__mro__[:-1]:  # without object
+        if base.__name__ in ('Protocol', 'Generic'):
+            continue
+        annotations = getattr(base, '__annotations__', {})
+        for attr in list(base.__dict__.keys()) + list(annotations.keys()):
+            if (not attr.startswith('_abc_') and attr not in (
+                    '__abstractmethods__', '__annotations__', '__weakref__',
+                    '_is_protocol', '_is_runtime_protocol', '__dict__',
+                    '__args__', '__slots__',
+                    '__next_in_mro__', '__parameters__', '__origin__',
+                    '__orig_bases__', '__extra__', '__tree_hash__',
+                    '__doc__', '__subclasshook__', '__init__', '__new__',
+                    '__module__', '_MutableMapping__marker', '_gorg')):
+                attrs.add(attr)
+    return attrs
+
+
+def _is_callable_members_only(cls):
+    return all(callable(getattr(cls, attr, None)) for attr in _get_protocol_attrs(cls))
+
+
+# 3.8+
+if hasattr(typing, 'Protocol'):
+    Protocol = typing.Protocol
+# 3.7
+else:
+
+    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__.
+        def __instancecheck__(cls, instance):
+            # We need this method for situations where attributes are
+            # assigned in __init__.
+            if ((not getattr(cls, '_is_protocol', False) or
+                 _is_callable_members_only(cls)) and
+                    issubclass(instance.__class__, cls)):
+                return True
+            if cls._is_protocol:
+                if all(hasattr(instance, attr) and
+                       (not callable(getattr(cls, attr, None)) or
+                        getattr(instance, attr) is not None)
+                       for attr in _get_protocol_attrs(cls)):
+                    return True
+            return super().__instancecheck__(instance)
+
+    class Protocol(metaclass=_ProtocolMeta):
+        # There is quite a lot of overlapping code with typing.Generic.
+        # Unfortunately it is hard to avoid this while these live in two different
+        # modules. The duplicated code will be removed when Protocol is moved to typing.
+        """Base class for protocol classes. Protocol classes are defined as::
+
+            class Proto(Protocol):
+                def meth(self) -> int:
+                    ...
+
+        Such classes are primarily used with static type checkers that recognize
+        structural subtyping (static duck-typing), for example::
+
+            class C:
+                def meth(self) -> int:
+                    return 0
+
+            def func(x: Proto) -> int:
+                return x.meth()
+
+            func(C())  # Passes static type check
+
+        See PEP 544 for details. Protocol classes decorated with
+        @typing_extensions.runtime act as simple-minded runtime protocol that checks
+        only the presence of given attributes, ignoring their type signatures.
+
+        Protocol classes can be generic, they are defined as::
+
+            class GenProto(Protocol[T]):
+                def meth(self) -> T:
+                    ...
+        """
+        __slots__ = ()
+        _is_protocol = True
+
+        def __new__(cls, *args, **kwds):
+            if cls is Protocol:
+                raise TypeError("Type Protocol cannot be instantiated; "
+                                "it can only be used as a base class")
+            return super().__new__(cls)
+
+        @typing._tp_cache
+        def __class_getitem__(cls, params):
+            if not isinstance(params, tuple):
+                params = (params,)
+            if not params and cls is not typing.Tuple:
+                raise TypeError(
+                    f"Parameter list to {cls.__qualname__}[...] cannot be empty")
+            msg = "Parameters to generic types must be types."
+            params = tuple(typing._type_check(p, msg) for p in params)  # noqa
+            if cls is Protocol:
+                # Generic can only be subscripted with unique type variables.
+                if not all(isinstance(p, typing.TypeVar) for p in params):
+                    i = 0
+                    while isinstance(params[i], typing.TypeVar):
+                        i += 1
+                    raise TypeError(
+                        "Parameters to Protocol[...] must all be type variables."
+                        f" Parameter {i + 1} is {params[i]}")
+                if len(set(params)) != len(params):
+                    raise TypeError(
+                        "Parameters to Protocol[...] must all be unique")
+            else:
+                # Subscripting a regular Generic subclass.
+                _check_generic(cls, params, len(cls.__parameters__))
+            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)
+
+            # Determine if this is a protocol or a concrete subclass.
+            if not cls.__dict__.get('_is_protocol', None):
+                cls._is_protocol = any(b is Protocol for b in cls.__bases__)
+
+            # Set (or override) the protocol subclass hook.
+            def _proto_hook(other):
+                if not cls.__dict__.get('_is_protocol', None):
+                    return NotImplemented
+                if not getattr(cls, '_is_runtime_protocol', False):
+                    if sys._getframe(2).f_globals['__name__'] in ['abc', 'functools']:
+                        return NotImplemented
+                    raise TypeError("Instance and class checks can only be used with"
+                                    " @runtime protocols")
+                if not _is_callable_members_only(cls):
+                    if sys._getframe(2).f_globals['__name__'] in ['abc', 'functools']:
+                        return NotImplemented
+                    raise TypeError("Protocols with non-method members"
+                                    " don't support issubclass()")
+                if not isinstance(other, type):
+                    # Same error as for issubclass(1, int)
+                    raise TypeError('issubclass() arg 1 must be a class')
+                for attr in _get_protocol_attrs(cls):
+                    for base in other.__mro__:
+                        if attr in base.__dict__:
+                            if base.__dict__[attr] is None:
+                                return NotImplemented
+                            break
+                        annotations = getattr(base, '__annotations__', {})
+                        if (isinstance(annotations, typing.Mapping) and
+                                attr in annotations and
+                                isinstance(other, _ProtocolMeta) and
+                                other._is_protocol):
+                            break
+                    else:
+                        return NotImplemented
+                return True
+            if '__subclasshook__' not in cls.__dict__:
+                cls.__subclasshook__ = _proto_hook
+
+            # We have nothing more to do for non-protocols.
+            if not cls._is_protocol:
+                return
+
+            # Check consistency of bases.
+            for base in cls.__bases__:
+                if not (base in (object, typing.Generic) or
+                        base.__module__ == 'collections.abc' and
+                        base.__name__ in _PROTO_WHITELIST or
+                        isinstance(base, _ProtocolMeta) and base._is_protocol):
+                    raise TypeError('Protocols can only inherit from other'
+                                    f' protocols, got {repr(base)}')
+            cls.__init__ = _no_init
+
+
+# 3.8+
+if hasattr(typing, 'runtime_checkable'):
+    runtime_checkable = typing.runtime_checkable
+# 3.7
+else:
+    def runtime_checkable(cls):
+        """Mark a protocol class as a runtime protocol, so that it
+        can be used with isinstance() and issubclass(). Raise TypeError
+        if applied to a non-protocol class.
+
+        This allows a simple-minded structural check very similar to the
+        one-offs in collections.abc such as Hashable.
+        """
+        if not isinstance(cls, _ProtocolMeta) or not cls._is_protocol:
+            raise TypeError('@runtime_checkable can be only applied to protocol classes,'
+                            f' got {cls!r}')
+        cls._is_runtime_protocol = True
+        return cls
+
+
+# Exists for backwards compatibility.
+runtime = runtime_checkable
+
+
+# 3.8+
+if hasattr(typing, 'SupportsIndex'):
+    SupportsIndex = typing.SupportsIndex
+# 3.7
+else:
+    @runtime_checkable
+    class SupportsIndex(Protocol):
+        __slots__ = ()
+
+        @abc.abstractmethod
+        def __index__(self) -> int:
+            pass
+
+
+if hasattr(typing, "Required"):
+    # 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
+    # The standard library TypedDict below Python 3.11 does not store runtime
+    # information about optional and required keys when using Required or NotRequired.
+    TypedDict = typing.TypedDict
+    _TypedDictMeta = typing._TypedDictMeta
+    is_typeddict = typing.is_typeddict
+else:
+    def _check_fails(cls, other):
+        try:
+            if sys._getframe(1).f_globals['__name__'] not in ['abc',
+                                                              'functools',
+                                                              'typing']:
+                # Typed dicts are only for static structural subtyping.
+                raise TypeError('TypedDict does not support instance and class checks')
+        except (AttributeError, ValueError):
+            pass
+        return False
+
+    def _dict_new(*args, **kwargs):
+        if not args:
+            raise TypeError('TypedDict.__new__(): not enough arguments')
+        _, args = args[0], args[1:]  # allow the "cls" keyword be passed
+        return dict(*args, **kwargs)
+
+    _dict_new.__text_signature__ = '($cls, _typename, _fields=None, /, **kwargs)'
+
+    def _typeddict_new(*args, total=True, **kwargs):
+        if not args:
+            raise TypeError('TypedDict.__new__(): not enough arguments')
+        _, args = args[0], args[1:]  # allow the "cls" keyword be passed
+        if args:
+            typename, args = args[0], args[1:]  # allow the "_typename" keyword be passed
+        elif '_typename' in kwargs:
+            typename = kwargs.pop('_typename')
+            import warnings
+            warnings.warn("Passing '_typename' as keyword argument is deprecated",
+                          DeprecationWarning, stacklevel=2)
+        else:
+            raise TypeError("TypedDict.__new__() missing 1 required positional "
+                            "argument: '_typename'")
+        if args:
+            try:
+                fields, = args  # allow the "_fields" keyword be passed
+            except ValueError:
+                raise TypeError('TypedDict.__new__() takes from 2 to 3 '
+                                f'positional arguments but {len(args) + 2} '
+                                'were given')
+        elif '_fields' in kwargs and len(kwargs) == 1:
+            fields = kwargs.pop('_fields')
+            import warnings
+            warnings.warn("Passing '_fields' as keyword argument is deprecated",
+                          DeprecationWarning, stacklevel=2)
+        else:
+            fields = None
+
+        if fields is None:
+            fields = kwargs
+        elif kwargs:
+            raise TypeError("TypedDict takes either a dict or keyword arguments,"
+                            " but not both")
+
+        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, total=total)
+
+    _typeddict_new.__text_signature__ = ('($cls, _typename, _fields=None,'
+                                         ' /, *, total=True, **kwargs)')
+
+    class _TypedDictMeta(type):
+        def __init__(cls, name, bases, ns, total=True):
+            super().__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,
+            # or via _typeddict_new when TypedDict is instantiated. This way
+            # TypedDict supports all three syntaxes described in its docstring.
+            # Subclasses and instances of TypedDict return actual dictionaries
+            # via _dict_new.
+            ns['__new__'] = _typeddict_new if name == 'TypedDict' else _dict_new
+            tp_dict = super().__new__(cls, name, (dict,), ns)
+
+            annotations = {}
+            own_annotations = ns.get('__annotations__', {})
+            msg = "TypedDict('Name', {f0: t0, f1: t1, ...}); each t must be a type"
+            own_annotations = {
+                n: typing._type_check(tp, msg) for n, tp in own_annotations.items()
+            }
+            required_keys = set()
+            optional_keys = set()
+
+            for base in bases:
+                annotations.update(base.__dict__.get('__annotations__', {}))
+                required_keys.update(base.__dict__.get('__required_keys__', ()))
+                optional_keys.update(base.__dict__.get('__optional_keys__', ()))
+
+            annotations.update(own_annotations)
+            for annotation_key, annotation_type in own_annotations.items():
+                annotation_origin = get_origin(annotation_type)
+                if annotation_origin is Annotated:
+                    annotation_args = get_args(annotation_type)
+                    if annotation_args:
+                        annotation_type = annotation_args[0]
+                        annotation_origin = get_origin(annotation_type)
+
+                if annotation_origin is Required:
+                    required_keys.add(annotation_key)
+                elif annotation_origin is NotRequired:
+                    optional_keys.add(annotation_key)
+                elif total:
+                    required_keys.add(annotation_key)
+                else:
+                    optional_keys.add(annotation_key)
+
+            tp_dict.__annotations__ = annotations
+            tp_dict.__required_keys__ = frozenset(required_keys)
+            tp_dict.__optional_keys__ = frozenset(optional_keys)
+            if not hasattr(tp_dict, '__total__'):
+                tp_dict.__total__ = total
+            return tp_dict
+
+        __instancecheck__ = __subclasscheck__ = _check_fails
+
+    TypedDict = _TypedDictMeta('TypedDict', (dict,), {})
+    TypedDict.__module__ = __name__
+    TypedDict.__doc__ = \
+        """A simple typed name space. At runtime it is equivalent to a plain dict.
+
+        TypedDict creates a dictionary type that expects all of its
+        instances to have a certain set of keys, with each key
+        associated with a value of a consistent type. This expectation
+        is not checked at runtime but is only enforced by type checkers.
+        Usage::
+
+            class Point2D(TypedDict):
+                x: int
+                y: int
+                label: str
+
+            a: Point2D = {'x': 1, 'y': 2, 'label': 'good'}  # OK
+            b: Point2D = {'z': 3, 'label': 'bad'}           # Fails type check
+
+            assert Point2D(x=1, y=2, label='first') == dict(x=1, y=2, label='first')
+
+        The type info can be accessed via the Point2D.__annotations__ dict, and
+        the Point2D.__required_keys__ and Point2D.__optional_keys__ frozensets.
+        TypedDict supports two additional equivalent forms::
+
+            Point2D = TypedDict('Point2D', x=int, y=int, label=str)
+            Point2D = TypedDict('Point2D', {'x': int, 'y': int, 'label': str})
+
+        The class syntax is only supported in Python 3.6+, while two other
+        syntax forms work for Python 2.7 and 3.2+
+        """
+
+    if hasattr(typing, "_TypedDictMeta"):
+        _TYPEDDICT_TYPES = (typing._TypedDictMeta, _TypedDictMeta)
+    else:
+        _TYPEDDICT_TYPES = (_TypedDictMeta,)
+
+    def is_typeddict(tp):
+        """Check if an annotation is a TypedDict class
+
+        For example::
+            class Film(TypedDict):
+                title: str
+                year: int
+
+            is_typeddict(Film)  # => True
+            is_typeddict(Union[list, str])  # => False
+        """
+        return isinstance(tp, tuple(_TYPEDDICT_TYPES))
+
+
+if hasattr(typing, "assert_type"):
+    assert_type = typing.assert_type
+
+else:
+    def assert_type(__val, __typ):
+        """Assert (to the type checker) that the value is of the given type.
+
+        When the type checker encounters a call to assert_type(), it
+        emits an error if the value is not of the specified type::
+
+            def greet(name: str) -> None:
+                assert_type(name, str)  # ok
+                assert_type(name, int)  # type checker error
+
+        At runtime this returns the first argument unchanged and otherwise
+        does nothing.
+        """
+        return __val
+
+
+if hasattr(typing, "Required"):
+    get_type_hints = typing.get_type_hints
+else:
+    import functools
+    import types
+
+    # replaces _strip_annotations()
+    def _strip_extras(t):
+        """Strips Annotated, Required and NotRequired from a given type."""
+        if isinstance(t, _AnnotatedAlias):
+            return _strip_extras(t.__origin__)
+        if hasattr(t, "__origin__") and t.__origin__ in (Required, NotRequired):
+            return _strip_extras(t.__args__[0])
+        if isinstance(t, typing._GenericAlias):
+            stripped_args = tuple(_strip_extras(a) for a in t.__args__)
+            if stripped_args == t.__args__:
+                return t
+            return t.copy_with(stripped_args)
+        if hasattr(types, "GenericAlias") and isinstance(t, types.GenericAlias):
+            stripped_args = tuple(_strip_extras(a) for a in t.__args__)
+            if stripped_args == t.__args__:
+                return t
+            return types.GenericAlias(t.__origin__, stripped_args)
+        if hasattr(types, "UnionType") and isinstance(t, types.UnionType):
+            stripped_args = tuple(_strip_extras(a) for a in t.__args__)
+            if stripped_args == t.__args__:
+                return t
+            return functools.reduce(operator.or_, stripped_args)
+
+        return t
+
+    def get_type_hints(obj, globalns=None, localns=None, include_extras=False):
+        """Return type hints for an object.
+
+        This is often the same as obj.__annotations__, but it handles
+        forward references encoded as string literals, adds Optional[t] if a
+        default value equal to None is set and recursively replaces all
+        'Annotated[T, ...]', 'Required[T]' or 'NotRequired[T]' with 'T'
+        (unless 'include_extras=True').
+
+        The argument may be a module, class, method, or function. The annotations
+        are returned as a dictionary. For classes, annotations include also
+        inherited members.
+
+        TypeError is raised if the argument is not of a type that can contain
+        annotations, and an empty dictionary is returned if no annotations are
+        present.
+
+        BEWARE -- the behavior of globalns and localns is counterintuitive
+        (unless you are familiar with how eval() and exec() work).  The
+        search order is locals first, then globals.
+
+        - If no dict arguments are passed, an attempt is made to use the
+          globals from obj (or the respective module's globals for classes),
+          and these are also used as the locals.  If the object does not appear
+          to have globals, an empty dictionary is used.
+
+        - If one dict argument is passed, it is used for both globals and
+          locals.
+
+        - If two dict arguments are passed, they specify globals and
+          locals, respectively.
+        """
+        if hasattr(typing, "Annotated"):
+            hint = typing.get_type_hints(
+                obj, globalns=globalns, localns=localns, include_extras=True
+            )
+        else:
+            hint = typing.get_type_hints(obj, globalns=globalns, localns=localns)
+        if include_extras:
+            return hint
+        return {k: _strip_extras(t) for k, t in hint.items()}
+
+
+# Python 3.9+ has PEP 593 (Annotated)
+if hasattr(typing, 'Annotated'):
+    Annotated = typing.Annotated
+    # Not exported and not a public API, but needed for get_origin() and get_args()
+    # to work.
+    _AnnotatedAlias = typing._AnnotatedAlias
+# 3.7-3.8
+else:
+    class _AnnotatedAlias(typing._GenericAlias, _root=True):
+        """Runtime representation of an annotated type.
+
+        At its core 'Annotated[t, dec1, dec2, ...]' is an alias for the type 't'
+        with extra annotations. The alias behaves like a normal typing alias,
+        instantiating is the same as instantiating the underlying type, binding
+        it to types is also the same.
+        """
+        def __init__(self, origin, metadata):
+            if isinstance(origin, _AnnotatedAlias):
+                metadata = origin.__metadata__ + metadata
+                origin = origin.__origin__
+            super().__init__(origin, origin)
+            self.__metadata__ = metadata
+
+        def copy_with(self, params):
+            assert len(params) == 1
+            new_type = params[0]
+            return _AnnotatedAlias(new_type, self.__metadata__)
+
+        def __repr__(self):
+            return (f"typing_extensions.Annotated[{typing._type_repr(self.__origin__)}, "
+                    f"{', '.join(repr(a) for a in self.__metadata__)}]")
+
+        def __reduce__(self):
+            return operator.getitem, (
+                Annotated, (self.__origin__,) + self.__metadata__
+            )
+
+        def __eq__(self, other):
+            if not isinstance(other, _AnnotatedAlias):
+                return NotImplemented
+            if self.__origin__ != other.__origin__:
+                return False
+            return self.__metadata__ == other.__metadata__
+
+        def __hash__(self):
+            return hash((self.__origin__, self.__metadata__))
+
+    class Annotated:
+        """Add context specific metadata to a type.
+
+        Example: Annotated[int, runtime_check.Unsigned] indicates to the
+        hypothetical runtime_check module that this type is an unsigned int.
+        Every other consumer of this type can ignore this metadata and treat
+        this type as int.
+
+        The first argument to Annotated must be a valid type (and will be in
+        the __origin__ field), the remaining arguments are kept as a tuple in
+        the __extra__ field.
+
+        Details:
+
+        - It's an error to call `Annotated` with less than two arguments.
+        - Nested Annotated are flattened::
+
+            Annotated[Annotated[T, Ann1, Ann2], Ann3] == Annotated[T, Ann1, Ann2, Ann3]
+
+        - Instantiating an annotated type is equivalent to instantiating the
+        underlying type::
+
+            Annotated[C, Ann1](5) == C(5)
+
+        - Annotated can be used as a generic type alias::
+
+            Optimized = Annotated[T, runtime.Optimize()]
+            Optimized[int] == Annotated[int, runtime.Optimize()]
+
+            OptimizedList = Annotated[List[T], runtime.Optimize()]
+            OptimizedList[int] == Annotated[List[int], runtime.Optimize()]
+        """
+
+        __slots__ = ()
+
+        def __new__(cls, *args, **kwargs):
+            raise TypeError("Type Annotated cannot be instantiated.")
+
+        @typing._tp_cache
+        def __class_getitem__(cls, params):
+            if not isinstance(params, tuple) or len(params) < 2:
+                raise TypeError("Annotated[...] should be used "
+                                "with at least two arguments (a type and an "
+                                "annotation).")
+            allowed_special_forms = (ClassVar, Final)
+            if get_origin(params[0]) in allowed_special_forms:
+                origin = params[0]
+            else:
+                msg = "Annotated[t, ...]: t must be a type."
+                origin = typing._type_check(params[0], msg)
+            metadata = tuple(params[1:])
+            return _AnnotatedAlias(origin, metadata)
+
+        def __init_subclass__(cls, *args, **kwargs):
+            raise TypeError(
+                f"Cannot subclass {cls.__module__}.Annotated"
+            )
+
+# Python 3.8 has get_origin() and get_args() but those implementations aren't
+# Annotated-aware, so we can't use those. Python 3.9's versions don't support
+# ParamSpecArgs and ParamSpecKwargs, so only Python 3.10's versions will do.
+if sys.version_info[:2] >= (3, 10):
+    get_origin = typing.get_origin
+    get_args = typing.get_args
+# 3.7-3.9
+else:
+    try:
+        # 3.9+
+        from typing import _BaseGenericAlias
+    except ImportError:
+        _BaseGenericAlias = typing._GenericAlias
+    try:
+        # 3.9+
+        from typing import GenericAlias
+    except ImportError:
+        GenericAlias = typing._GenericAlias
+
+    def get_origin(tp):
+        """Get the unsubscripted version of a type.
+
+        This supports generic types, Callable, Tuple, Union, Literal, Final, ClassVar
+        and Annotated. Return None for unsupported types. Examples::
+
+            get_origin(Literal[42]) is Literal
+            get_origin(int) is None
+            get_origin(ClassVar[int]) is ClassVar
+            get_origin(Generic) is Generic
+            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, (typing._GenericAlias, GenericAlias, _BaseGenericAlias,
+                           ParamSpecArgs, ParamSpecKwargs)):
+            return tp.__origin__
+        if tp is typing.Generic:
+            return typing.Generic
+        return None
+
+    def get_args(tp):
+        """Get type arguments with all substitutions performed.
+
+        For unions, basic simplifications used by Union constructor are performed.
+        Examples::
+            get_args(Dict[str, int]) == (str, int)
+            get_args(int) == ()
+            get_args(Union[int, Union[T, int], str][int]) == (int, str)
+            get_args(Union[int, Tuple[T, int]][str]) == (int, Tuple[str, int])
+            get_args(Callable[[], T][int]) == ([], int)
+        """
+        if isinstance(tp, _AnnotatedAlias):
+            return (tp.__origin__,) + tp.__metadata__
+        if isinstance(tp, (typing._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])
+            return res
+        return ()
+
+
+# 3.10+
+if hasattr(typing, 'TypeAlias'):
+    TypeAlias = typing.TypeAlias
+# 3.9
+elif sys.version_info[:2] >= (3, 9):
+    class _TypeAliasForm(typing._SpecialForm, _root=True):
+        def __repr__(self):
+            return 'typing_extensions.' + self._name
+
+    @_TypeAliasForm
+    def TypeAlias(self, parameters):
+        """Special marker indicating that an assignment should
+        be recognized as a proper type alias definition by type
+        checkers.
+
+        For example::
+
+            Predicate: TypeAlias = Callable[..., bool]
+
+        It's invalid when used anywhere except as in the example above.
+        """
+        raise TypeError(f"{self} is not subscriptable")
+# 3.7-3.8
+else:
+    class _TypeAliasForm(typing._SpecialForm, _root=True):
+        def __repr__(self):
+            return 'typing_extensions.' + self._name
+
+    TypeAlias = _TypeAliasForm('TypeAlias',
+                               doc="""Special marker indicating that an assignment should
+                               be recognized as a proper type alias definition by type
+                               checkers.
+
+                               For example::
+
+                                   Predicate: TypeAlias = Callable[..., bool]
+
+                               It's invalid when used anywhere except as in the example
+                               above.""")
+
+
+# Python 3.10+ has PEP 612
+if hasattr(typing, 'ParamSpecArgs'):
+    ParamSpecArgs = typing.ParamSpecArgs
+    ParamSpecKwargs = typing.ParamSpecKwargs
+# 3.7-3.9
+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 f"{self.__origin__.__name__}.args"
+
+        def __eq__(self, other):
+            if not isinstance(other, ParamSpecArgs):
+                return NotImplemented
+            return self.__origin__ == other.__origin__
+
+    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 f"{self.__origin__.__name__}.kwargs"
+
+        def __eq__(self, other):
+            if not isinstance(other, ParamSpecKwargs):
+                return NotImplemented
+            return self.__origin__ == other.__origin__
+
+# 3.10+
+if hasattr(typing, 'ParamSpec'):
+    ParamSpec = typing.ParamSpec
+# 3.7-3.9
+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.
+        """
+
+        # Trick Generic __parameters__.
+        __class__ = typing.TypeVar
+
+        @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
+
+
+# 3.7-3.9
+if not hasattr(typing, 'Concatenate'):
+    # Inherits from list as a workaround for Callable checks in Python < 3.9.2.
+    class _ConcatenateGenericAlias(list):
+
+        # Trick Generic into looking into this for __parameters__.
+        __class__ = typing._GenericAlias
+
+        # Flag in 3.8.
+        _special = False
+
+        def __init__(self, origin, args):
+            super().__init__(args)
+            self.__origin__ = origin
+            self.__args__ = args
+
+        def __repr__(self):
+            _type_repr = typing._type_repr
+            return (f'{_type_repr(self.__origin__)}'
+                    f'[{", ".join(_type_repr(arg) for arg in self.__args__)}]')
+
+        def __hash__(self):
+            return hash((self.__origin__, self.__args__))
+
+        # Hack to get typing._type_check to pass in Generic.
+        def __call__(self, *args, **kwargs):
+            pass
+
+        @property
+        def __parameters__(self):
+            return tuple(
+                tp for tp in self.__args__ if isinstance(tp, (typing.TypeVar, ParamSpec))
+            )
+
+
+# 3.7-3.9
+@typing._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)
+
+
+# 3.10+
+if hasattr(typing, 'Concatenate'):
+    Concatenate = typing.Concatenate
+    _ConcatenateGenericAlias = typing._ConcatenateGenericAlias # noqa
+# 3.9
+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)
+# 3.7-8
+else:
+    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.
+        """)
+
+# 3.10+
+if hasattr(typing, 'TypeGuard'):
+    TypeGuard = typing.TypeGuard
+# 3.9
+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, f'{self} accepts only single type.')
+        return typing._GenericAlias(self, (item,))
+# 3.7-3.8
+else:
+    class _TypeGuardForm(typing._SpecialForm, _root=True):
+
+        def __repr__(self):
+            return 'typing_extensions.' + self._name
+
+        def __getitem__(self, parameters):
+            item = typing._type_check(parameters,
+                                      f'{self._name} accepts only a single type')
+            return typing._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).
+        """)
+
+
+# Vendored from cpython typing._SpecialFrom
+class _SpecialForm(typing._Final, _root=True):
+    __slots__ = ('_name', '__doc__', '_getitem')
+
+    def __init__(self, getitem):
+        self._getitem = getitem
+        self._name = getitem.__name__
+        self.__doc__ = getitem.__doc__
+
+    def __getattr__(self, item):
+        if item in {'__name__', '__qualname__'}:
+            return self._name
+
+        raise AttributeError(item)
+
+    def __mro_entries__(self, bases):
+        raise TypeError(f"Cannot subclass {self!r}")
+
+    def __repr__(self):
+        return f'typing_extensions.{self._name}'
+
+    def __reduce__(self):
+        return self._name
+
+    def __call__(self, *args, **kwds):
+        raise TypeError(f"Cannot instantiate {self!r}")
+
+    def __or__(self, other):
+        return typing.Union[self, other]
+
+    def __ror__(self, other):
+        return typing.Union[other, self]
+
+    def __instancecheck__(self, obj):
+        raise TypeError(f"{self} cannot be used with isinstance()")
+
+    def __subclasscheck__(self, cls):
+        raise TypeError(f"{self} cannot be used with issubclass()")
+
+    @typing._tp_cache
+    def __getitem__(self, parameters):
+        return self._getitem(self, parameters)
+
+
+if hasattr(typing, "LiteralString"):
+    LiteralString = typing.LiteralString
+else:
+    @_SpecialForm
+    def LiteralString(self, params):
+        """Represents an arbitrary literal string.
+
+        Example::
+
+          from typing_extensions import LiteralString
+
+          def query(sql: LiteralString) -> ...:
+              ...
+
+          query("SELECT * FROM table")  # ok
+          query(f"SELECT * FROM {input()}")  # not ok
+
+        See PEP 675 for details.
+
+        """
+        raise TypeError(f"{self} is not subscriptable")
+
+
+if hasattr(typing, "Self"):
+    Self = typing.Self
+else:
+    @_SpecialForm
+    def Self(self, params):
+        """Used to spell the type of "self" in classes.
+
+        Example::
+
+          from typing import Self
+
+          class ReturnsSelf:
+              def parse(self, data: bytes) -> Self:
+                  ...
+                  return self
+
+        """
+
+        raise TypeError(f"{self} is not subscriptable")
+
+
+if hasattr(typing, "Never"):
+    Never = typing.Never
+else:
+    @_SpecialForm
+    def Never(self, params):
+        """The bottom type, a type that has no members.
+
+        This can be used to define a function that should never be
+        called, or a function that never returns::
+
+            from typing_extensions import Never
+
+            def never_call_me(arg: Never) -> None:
+                pass
+
+            def int_or_str(arg: int | str) -> None:
+                never_call_me(arg)  # type checker error
+                match arg:
+                    case int():
+                        print("It's an int")
+                    case str():
+                        print("It's a str")
+                    case _:
+                        never_call_me(arg)  # ok, arg is of type Never
+
+        """
+
+        raise TypeError(f"{self} is not subscriptable")
+
+
+if hasattr(typing, 'Required'):
+    Required = typing.Required
+    NotRequired = typing.NotRequired
+elif sys.version_info[:2] >= (3, 9):
+    class _ExtensionsSpecialForm(typing._SpecialForm, _root=True):
+        def __repr__(self):
+            return 'typing_extensions.' + self._name
+
+    @_ExtensionsSpecialForm
+    def Required(self, parameters):
+        """A special typing construct to mark a key of a total=False TypedDict
+        as required. For example:
+
+            class Movie(TypedDict, total=False):
+                title: Required[str]
+                year: int
+
+            m = Movie(
+                title='The Matrix',  # typechecker error if key is omitted
+                year=1999,
+            )
+
+        There is no runtime checking that a required key is actually provided
+        when instantiating a related TypedDict.
+        """
+        item = typing._type_check(parameters, f'{self._name} accepts only single type')
+        return typing._GenericAlias(self, (item,))
+
+    @_ExtensionsSpecialForm
+    def NotRequired(self, parameters):
+        """A special typing construct to mark a key of a TypedDict as
+        potentially missing. For example:
+
+            class Movie(TypedDict):
+                title: str
+                year: NotRequired[int]
+
+            m = Movie(
+                title='The Matrix',  # typechecker error if key is omitted
+                year=1999,
+            )
+        """
+        item = typing._type_check(parameters, f'{self._name} accepts only single type')
+        return typing._GenericAlias(self, (item,))
+
+else:
+    class _RequiredForm(typing._SpecialForm, _root=True):
+        def __repr__(self):
+            return 'typing_extensions.' + self._name
+
+        def __getitem__(self, parameters):
+            item = typing._type_check(parameters,
+                                      '{} accepts only single type'.format(self._name))
+            return typing._GenericAlias(self, (item,))
+
+    Required = _RequiredForm(
+        'Required',
+        doc="""A special typing construct to mark a key of a total=False TypedDict
+        as required. For example:
+
+            class Movie(TypedDict, total=False):
+                title: Required[str]
+                year: int
+
+            m = Movie(
+                title='The Matrix',  # typechecker error if key is omitted
+                year=1999,
+            )
+
+        There is no runtime checking that a required key is actually provided
+        when instantiating a related TypedDict.
+        """)
+    NotRequired = _RequiredForm(
+        'NotRequired',
+        doc="""A special typing construct to mark a key of a TypedDict as
+        potentially missing. For example:
+
+            class Movie(TypedDict):
+                title: str
+                year: NotRequired[int]
+
+            m = Movie(
+                title='The Matrix',  # typechecker error if key is omitted
+                year=1999,
+            )
+        """)
+
+
+if sys.version_info[:2] >= (3, 9):
+    class _UnpackSpecialForm(typing._SpecialForm, _root=True):
+        def __repr__(self):
+            return 'typing_extensions.' + self._name
+
+    class _UnpackAlias(typing._GenericAlias, _root=True):
+        __class__ = typing.TypeVar
+
+    @_UnpackSpecialForm
+    def Unpack(self, parameters):
+        """A special typing construct to unpack a variadic type. For example:
+
+            Shape = TypeVarTuple('Shape')
+            Batch = NewType('Batch', int)
+
+            def add_batch_axis(
+                x: Array[Unpack[Shape]]
+            ) -> Array[Batch, Unpack[Shape]]: ...
+
+        """
+        item = typing._type_check(parameters, f'{self._name} accepts only single type')
+        return _UnpackAlias(self, (item,))
+
+    def _is_unpack(obj):
+        return isinstance(obj, _UnpackAlias)
+
+else:
+    class _UnpackAlias(typing._GenericAlias, _root=True):
+        __class__ = typing.TypeVar
+
+    class _UnpackForm(typing._SpecialForm, _root=True):
+        def __repr__(self):
+            return 'typing_extensions.' + self._name
+
+        def __getitem__(self, parameters):
+            item = typing._type_check(parameters,
+                                      f'{self._name} accepts only single type')
+            return _UnpackAlias(self, (item,))
+
+    Unpack = _UnpackForm(
+        'Unpack',
+        doc="""A special typing construct to unpack a variadic type. For example:
+
+            Shape = TypeVarTuple('Shape')
+            Batch = NewType('Batch', int)
+
+            def add_batch_axis(
+                x: Array[Unpack[Shape]]
+            ) -> Array[Batch, Unpack[Shape]]: ...
+
+        """)
+
+    def _is_unpack(obj):
+        return isinstance(obj, _UnpackAlias)
+
+
+class TypeVarTuple:
+    """Type variable tuple.
+
+    Usage::
+
+        Ts = TypeVarTuple('Ts')
+
+    In the same way that a normal type variable is a stand-in for a single
+    type such as ``int``, a type variable *tuple* is a stand-in for a *tuple* type such as
+    ``Tuple[int, str]``.
+
+    Type variable tuples can be used in ``Generic`` declarations.
+    Consider the following example::
+
+        class Array(Generic[*Ts]): ...
+
+    The ``Ts`` type variable tuple here behaves like ``tuple[T1, T2]``,
+    where ``T1`` and ``T2`` are type variables. To use these type variables
+    as type parameters of ``Array``, we must *unpack* the type variable tuple using
+    the star operator: ``*Ts``. The signature of ``Array`` then behaves
+    as if we had simply written ``class Array(Generic[T1, T2]): ...``.
+    In contrast to ``Generic[T1, T2]``, however, ``Generic[*Shape]`` allows
+    us to parameterise the class with an *arbitrary* number of type parameters.
+
+    Type variable tuples can be used anywhere a normal ``TypeVar`` can.
+    This includes class definitions, as shown above, as well as function
+    signatures and variable annotations::
+
+        class Array(Generic[*Ts]):
+
+            def __init__(self, shape: Tuple[*Ts]):
+                self._shape: Tuple[*Ts] = shape
+
+            def get_shape(self) -> Tuple[*Ts]:
+                return self._shape
+
+        shape = (Height(480), Width(640))
+        x: Array[Height, Width] = Array(shape)
+        y = abs(x)  # Inferred type is Array[Height, Width]
+        z = x + x   #        ...    is Array[Height, Width]
+        x.get_shape()  #     ...    is tuple[Height, Width]
+
+    """
+
+    # Trick Generic __parameters__.
+    __class__ = typing.TypeVar
+
+    def __iter__(self):
+        yield self.__unpacked__
+
+    def __init__(self, name):
+        self.__name__ = name
+
+        # 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
+
+        self.__unpacked__ = Unpack[self]
+
+    def __repr__(self):
+        return self.__name__
+
+    def __hash__(self):
+        return object.__hash__(self)
+
+    def __eq__(self, other):
+        return self is other
+
+    def __reduce__(self):
+        return self.__name__
+
+    def __init_subclass__(self, *args, **kwds):
+        if '_root' not in kwds:
+            raise TypeError("Cannot subclass special typing classes")
+
+
+if hasattr(typing, "reveal_type"):
+    reveal_type = typing.reveal_type
+else:
+    def reveal_type(__obj: T) -> T:
+        """Reveal the inferred type of a variable.
+
+        When a static type checker encounters a call to ``reveal_type()``,
+        it will emit the inferred type of the argument::
+
+            x: int = 1
+            reveal_type(x)
+
+        Running a static type checker (e.g., ``mypy``) on this example
+        will produce output similar to 'Revealed type is "builtins.int"'.
+
+        At runtime, the function prints the runtime type of the
+        argument and returns it unchanged.
+
+        """
+        print(f"Runtime type is {type(__obj).__name__!r}", file=sys.stderr)
+        return __obj
+
+
+if hasattr(typing, "assert_never"):
+    assert_never = typing.assert_never
+else:
+    def assert_never(__arg: Never) -> Never:
+        """Assert to the type checker that a line of code is unreachable.
+
+        Example::
+
+            def int_or_str(arg: int | str) -> None:
+                match arg:
+                    case int():
+                        print("It's an int")
+                    case str():
+                        print("It's a str")
+                    case _:
+                        assert_never(arg)
+
+        If a type checker finds that a call to assert_never() is
+        reachable, it will emit an error.
+
+        At runtime, this throws an exception when called.
+
+        """
+        raise AssertionError("Expected code to be unreachable")
+
+
+if hasattr(typing, 'dataclass_transform'):
+    dataclass_transform = typing.dataclass_transform
+else:
+    def dataclass_transform(
+        *,
+        eq_default: bool = True,
+        order_default: bool = False,
+        kw_only_default: bool = False,
+        field_descriptors: typing.Tuple[
+            typing.Union[typing.Type[typing.Any], typing.Callable[..., typing.Any]],
+            ...
+        ] = (),
+    ) -> typing.Callable[[T], T]:
+        """Decorator that marks a function, class, or metaclass as providing
+        dataclass-like behavior.
+
+        Example:
+
+            from typing_extensions import dataclass_transform
+
+            _T = TypeVar("_T")
+
+            # Used on a decorator function
+            @dataclass_transform()
+            def create_model(cls: type[_T]) -> type[_T]:
+                ...
+                return cls
+
+            @create_model
+            class CustomerModel:
+                id: int
+                name: str
+
+            # Used on a base class
+            @dataclass_transform()
+            class ModelBase: ...
+
+            class CustomerModel(ModelBase):
+                id: int
+                name: str
+
+            # Used on a metaclass
+            @dataclass_transform()
+            class ModelMeta(type): ...
+
+            class ModelBase(metaclass=ModelMeta): ...
+
+            class CustomerModel(ModelBase):
+                id: int
+                name: str
+
+        Each of the ``CustomerModel`` classes defined in this example will now
+        behave similarly to a dataclass created with the ``@dataclasses.dataclass``
+        decorator. For example, the type checker will synthesize an ``__init__``
+        method.
+
+        The arguments to this decorator can be used to customize this behavior:
+        - ``eq_default`` indicates whether the ``eq`` parameter is assumed to be
+          True or False if it is omitted by the caller.
+        - ``order_default`` indicates whether the ``order`` parameter is
+          assumed to be True or False if it is omitted by the caller.
+        - ``kw_only_default`` indicates whether the ``kw_only`` parameter is
+          assumed to be True or False if it is omitted by the caller.
+        - ``field_descriptors`` specifies a static list of supported classes
+          or functions, that describe fields, similar to ``dataclasses.field()``.
+
+        At runtime, this decorator records its arguments in the
+        ``__dataclass_transform__`` attribute on the decorated object.
+
+        See PEP 681 for details.
+
+        """
+        def decorator(cls_or_fn):
+            cls_or_fn.__dataclass_transform__ = {
+                "eq_default": eq_default,
+                "order_default": order_default,
+                "kw_only_default": kw_only_default,
+                "field_descriptors": field_descriptors,
+            }
+            return cls_or_fn
+        return decorator
+
+
+# We have to do some monkey patching to deal with the dual nature of
+# Unpack/TypeVarTuple:
+# - We want Unpack to be a kind of TypeVar so it gets accepted in
+#   Generic[Unpack[Ts]]
+# - We want it to *not* be treated as a TypeVar for the purposes of
+#   counting generic parameters, so that when we subscript a generic,
+#   the runtime doesn't try to substitute the Unpack with the subscripted type.
+if not hasattr(typing, "TypeVarTuple"):
+    typing._collect_type_vars = _collect_type_vars
+    typing._check_generic = _check_generic
diff --git a/typing_extensions/tox.ini b/typing_extensions/tox.ini
new file mode 100644
index 0000000..0886936
--- /dev/null
+++ b/typing_extensions/tox.ini
@@ -0,0 +1,7 @@
+[tox]
+isolated_build = True
+envlist = py36, py37, py38, py39, py310
+
+[testenv]
+changedir = src
+commands = python -m unittest discover