Skip to content

Commit 591f737

Browse files
committed
Add typing_extensions subfolder
This pull request adds a 'typing_exensions' subproject to 'typing'. The 'typing_extensions' module backports any new additions to 'typing' for Python 3.5+ users who are using older versions of 'typing' that were bundled with their standard library (and so can't update to the latest versions). See python#435 for motivation and additional context.
1 parent 2b6932a commit 591f737

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+32286
-0
lines changed

typing_extensions/.gitignore

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
MANIFEST
2+
build/
3+
dist/
4+
.tox/
5+
.idea/
6+
.cache/
7+
__pycache__/
8+
.mypy_cache/
9+
tmp/
10+
*.swp
11+
*.pyc

typing_extensions/README.md

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
# Typing Extensions
2+
3+
The `typing_extensions` module contains backports of recent changes
4+
to the `typing` module that were not present in older versions of
5+
`typing`.
6+
7+
This module is intended to be used mainly by people who are using
8+
Python 3.5+, where the `typing` module is a part of the standard
9+
library and cannot be updated to the latest version on PyPi.
10+
11+
Users of other Python versions should continue to install and use
12+
use the `typing` module from PyPi instead of using this one, unless
13+
they are specifically writing code intended to be compatible with
14+
multiple versions of Python.
15+
16+
## Backported items
17+
18+
This module contains the following backported items:
19+
20+
### All Python versions:
21+
22+
- `ClassVar`
23+
- `Collection`
24+
- `ContextManager`
25+
- `Counter`
26+
- `DefaultDict`
27+
- `Deque`
28+
- `NewType`
29+
- `NoReturn`
30+
- `overload` (note that older versions of `typing` only let you use `overload` in stubs)
31+
- `Text`
32+
- `Type`
33+
- `TYPE_CHECKING`
34+
35+
### Python 3.3+ only:
36+
37+
- `ChainMap`
38+
39+
### Python 3.5+ only:
40+
41+
- `AsyncIterable`
42+
- `AsyncIterator`
43+
- `AsyncContextManager`
44+
- `Awaitable`
45+
- `Coroutine`
46+
47+
### Python 3.6+ only:
48+
49+
- `AsyncGenerator`
50+
51+
## Other Notes and Limitations
52+
53+
There are a few types who's interface was modified between different
54+
versions of typing. For example, `typing.Sequence` was modified to
55+
subclass `typing.Reversible` as of Python 3.5.3.
56+
57+
These changes are _not_ backported to prevent subtle compatibility
58+
issues when mixing the differing implementations of modified classes.
59+
60+
## Running tests
61+
62+
There are two different ways to test this module. The first is to simply run
63+
each individual Python interpreter against `test_typing_extensions.py` in the
64+
`src_py2` and `src_py3` folders.
65+
66+
However, because multiple versions of Python for each individual release
67+
can be onerous, you can instead run `run_tests.py` using a single Python
68+
interpreter. The `run_tests.py` file will essentially "modify" the standard
69+
library by changing `PYTHONPATH` to point to individual folders in the
70+
`test_data` repo.
71+
72+
Each individual folder contains a snapshot of the source code for the
73+
`collections`, `typing,` and `abc` modules for that given release, letting us
74+
test `typing` against those particular implementations.
75+
76+
`run_tests.py` will assume that you have Python 3.6.1 and a reasonably
77+
modern version of Python 2.7 installed on your system, aliased to
78+
`py -2.7` and `py -3.6` on Windows, and `python` and `python3` on Linux and
79+
Mac.

typing_extensions/run_tests.py

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
#!/usr/bin/env python
2+
3+
from typing import List, Iterator, Tuple
4+
from contextlib import contextmanager
5+
import glob
6+
import os
7+
import os.path
8+
import shutil
9+
import subprocess
10+
import sys
11+
import textwrap
12+
13+
CORE_FILES_2 = [
14+
"./src_py2/typing_extensions.py",
15+
"./src_py2/test_typing_extensions.py"
16+
]
17+
CORE_FILES_3 = [
18+
"./src_py3/typing_extensions.py",
19+
"./src_py3/test_typing_extensions.py"
20+
]
21+
TEST_DIR = "test_data"
22+
23+
if sys.platform.startswith('win32'):
24+
PYTHON2 = "py -2.7"
25+
PYTHON3 = "py -3.6"
26+
else:
27+
PYTHON2 = "python"
28+
PYTHON3 = "python3"
29+
30+
31+
def get_test_dirs() -> List[str]:
32+
"""Get all folders to test inside TEST_DIR."""
33+
return list(glob.glob(os.path.join(TEST_DIR, "*")))
34+
35+
36+
@contextmanager
37+
def temp_copy(src_files: List[str], dest_dir: str) -> Iterator[None]:
38+
"""
39+
A context manager that temporarily copies the given files to the
40+
given destination directory, and deletes those temp files upon
41+
exiting.
42+
"""
43+
# Copy
44+
for src_path in src_files:
45+
shutil.copy(src_path, dest_dir)
46+
47+
yield
48+
49+
# Delete
50+
for src_path in src_files:
51+
dst_path = os.path.join(dest_dir, os.path.basename(src_path))
52+
os.remove(dst_path)
53+
54+
55+
@contextmanager
56+
def change_directory(dir_path: str) -> Iterator[None]:
57+
"""
58+
A context manager that temporarily changes the working directory
59+
to the specified directory, and changes back to the original
60+
upon exiting.
61+
"""
62+
original = os.getcwd()
63+
os.chdir(dir_path)
64+
65+
yield
66+
67+
os.chdir(original)
68+
69+
70+
def run_shell(command: str) -> Tuple[bool, str]:
71+
env = os.environ.copy()
72+
env["PYTHONPATH"] = ":".join([os.getcwd(), env["PYTHONPATH"], env["PATH"]])
73+
out = subprocess.run(
74+
command,
75+
stdout=subprocess.PIPE,
76+
stderr=subprocess.STDOUT,
77+
shell=True,
78+
env=env)
79+
success = out.returncode == 0
80+
stdout = '' if out.stdout is None else out.stdout.decode('utf-8')
81+
return (success, stdout)
82+
83+
84+
def main() -> int:
85+
test_dirs = get_test_dirs()
86+
exit_code = 0
87+
for test_dir in test_dirs:
88+
_, version_number = test_dir.split('-')
89+
py2 = version_number.startswith("2")
90+
print("Testing Python {}".format(version_number))
91+
92+
core_files = CORE_FILES_2 if py2 else CORE_FILES_3
93+
python_exe = PYTHON2 if py2 else PYTHON3
94+
95+
with temp_copy(core_files, test_dir), change_directory(test_dir):
96+
success, output = run_shell("{} {} {}".format(
97+
python_exe,
98+
"test_typing_extensions.py",
99+
version_number))
100+
if success:
101+
print(" All tests passed!")
102+
else:
103+
print(textwrap.indent(output, " "))
104+
exit_code = 1
105+
return exit_code
106+
107+
108+
if __name__ == '__main__':
109+
sys.exit(main())
110+

typing_extensions/setup.py

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
#!/usr/bin/env python
2+
# coding: utf-8
3+
4+
import sys
5+
from distutils.core import setup
6+
7+
if sys.version_info < (2, 7, 0) or (3, 0, 0) <= sys.version_info < (3, 3, 0):
8+
sys.stderr.write('ERROR: You need Python 2.7 or 3.3+ '
9+
'to install the typing package.\n')
10+
exit(1)
11+
12+
version = '3.6.1'
13+
description = 'Type Hint backports for Python 3.5+'
14+
long_description = '''\
15+
Typing -- Type Hints for Python
16+
17+
This is a backport of the standard library typing module to Python
18+
versions 3.5+. The typing module has seen several changes since it was
19+
first added in Python 3.5.0, which means people who are using 3.5.0+
20+
but are unable to upgrade to the latest version of Python are unable
21+
to take advantage of some new features of the typing library, such as
22+
typing.Type or typing.Coroutine.
23+
24+
This module allows those users to use the latest additions to the typing
25+
module without worrying about naming conflicts with the standard library.
26+
Users of Python 2.7, 3.3, and 3.4 should install the typing module
27+
from pypi and use that directly, except when writing code that needs to
28+
be compatible across multiple versions of Python.
29+
'''
30+
31+
classifiers = [
32+
'Development Status :: 5 - Production/Stable',
33+
'Environment :: Console',
34+
'Intended Audience :: Developers',
35+
'License :: OSI Approved :: Python Software Foundation License',
36+
'Operating System :: OS Independent',
37+
'Programming Language :: Python :: 2.7',
38+
'Programming Language :: Python :: 3.3',
39+
'Programming Language :: Python :: 3.4',
40+
'Programming Language :: Python :: 3.5',
41+
'Programming Language :: Python :: 3.6',
42+
'Topic :: Software Development',
43+
]
44+
45+
if sys.version_info.major == 2:
46+
package_dir = 'src_py2'
47+
elif sys.version_info.major == 3:
48+
package_dir = 'src_py3'
49+
else:
50+
raise AssertionError()
51+
52+
install_requires = []
53+
if sys.version_info < (3, 5):
54+
install_requires.append('typing >= 3.6.1')
55+
56+
setup(name='typing_extensions',
57+
version=version,
58+
description=description,
59+
long_description=long_description,
60+
author='Guido van Rossum, Jukka Lehtosalo, Lukasz Langa, Michael Lee',
61+
author_email='[email protected]',
62+
# TODO: Change URL
63+
url='https://github.com/michael0x2a/typing_extensions',
64+
license='PSF',
65+
keywords='typing function annotations type hints hinting checking '
66+
'checker typehints typehinting typechecking backport',
67+
package_dir={'': package_dir},
68+
py_modules=['typing_extensions'],
69+
classifiers=classifiers,
70+
install_requires=install_requires,
71+
)

0 commit comments

Comments
 (0)