Permalink
Cannot retrieve contributors at this time
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
216 lines (185 sloc)
7.84 KB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
import glob | |
import os | |
import os.path | |
import sys | |
if sys.version_info < (3, 6, 0): | |
sys.stderr.write("ERROR: You need Python 3.6 or later to use mypy.\n") | |
exit(1) | |
# we'll import stuff from the source tree, let's ensure is on the sys path | |
sys.path.insert(0, os.path.dirname(os.path.realpath(__file__))) | |
# This requires setuptools when building; setuptools is not needed | |
# when installing from a wheel file (though it is still needed for | |
# alternative forms of installing, as suggested by README.md). | |
from setuptools import setup, find_packages | |
from setuptools.command.build_py import build_py | |
from mypy.version import __version__ as version | |
description = 'Optional static typing for Python' | |
long_description = ''' | |
Mypy -- Optional Static Typing for Python | |
========================================= | |
Add type annotations to your Python programs, and use mypy to type | |
check them. Mypy is essentially a Python linter on steroids, and it | |
can catch many programming errors by analyzing your program, without | |
actually having to run it. Mypy has a powerful type system with | |
features such as type inference, gradual typing, generics and union | |
types. | |
'''.lstrip() | |
def find_package_data(base, globs, root='mypy'): | |
"""Find all interesting data files, for setup(package_data=) | |
Arguments: | |
root: The directory to search in. | |
globs: A list of glob patterns to accept files. | |
""" | |
rv_dirs = [root for root, dirs, files in os.walk(base)] | |
rv = [] | |
for rv_dir in rv_dirs: | |
files = [] | |
for pat in globs: | |
files += glob.glob(os.path.join(rv_dir, pat)) | |
if not files: | |
continue | |
rv.extend([os.path.relpath(f, root) for f in files]) | |
return rv | |
class CustomPythonBuild(build_py): | |
def pin_version(self): | |
path = os.path.join(self.build_lib, 'mypy') | |
self.mkpath(path) | |
with open(os.path.join(path, 'version.py'), 'w') as stream: | |
stream.write('__version__ = "{}"\n'.format(version)) | |
def run(self): | |
self.execute(self.pin_version, ()) | |
build_py.run(self) | |
cmdclass = {'build_py': CustomPythonBuild} | |
package_data = ['py.typed'] | |
package_data += find_package_data(os.path.join('mypy', 'typeshed'), ['*.py', '*.pyi']) | |
package_data += [os.path.join('mypy', 'typeshed', 'stdlib', 'VERSIONS')] | |
package_data += find_package_data(os.path.join('mypy', 'xml'), ['*.xsd', '*.xslt', '*.css']) | |
USE_MYPYC = False | |
# To compile with mypyc, a mypyc checkout must be present on the PYTHONPATH | |
if len(sys.argv) > 1 and sys.argv[1] == '--use-mypyc': | |
sys.argv.pop(1) | |
USE_MYPYC = True | |
if os.getenv('MYPY_USE_MYPYC', None) == '1': | |
USE_MYPYC = True | |
if USE_MYPYC: | |
MYPYC_BLACKLIST = tuple(os.path.join('mypy', x) for x in ( | |
# Need to be runnable as scripts | |
'__main__.py', | |
'pyinfo.py', | |
os.path.join('dmypy', '__main__.py'), | |
# Uses __getattr__/__setattr__ | |
'split_namespace.py', | |
# Lies to mypy about code reachability | |
'bogus_type.py', | |
# We don't populate __file__ properly at the top level or something? | |
# Also I think there would be problems with how we generate version.py. | |
'version.py', | |
# Skip these to reduce the size of the build | |
'stubtest.py', | |
'stubgenc.py', | |
'stubdoc.py', | |
'stubutil.py', | |
)) + ( | |
# Don't want to grab this accidentally | |
os.path.join('mypyc', 'lib-rt', 'setup.py'), | |
# Uses __file__ at top level https://github.com/mypyc/mypyc/issues/700 | |
os.path.join('mypyc', '__main__.py'), | |
) | |
everything = ( | |
[os.path.join('mypy', x) for x in find_package_data('mypy', ['*.py'])] + | |
[os.path.join('mypyc', x) for x in find_package_data('mypyc', ['*.py'], root='mypyc')]) | |
# Start with all the .py files | |
all_real_pys = [x for x in everything | |
if not x.startswith(os.path.join('mypy', 'typeshed') + os.sep)] | |
# Strip out anything in our blacklist | |
mypyc_targets = [x for x in all_real_pys if x not in MYPYC_BLACKLIST] | |
# Strip out any test code | |
mypyc_targets = [x for x in mypyc_targets | |
if not x.startswith((os.path.join('mypy', 'test') + os.sep, | |
os.path.join('mypyc', 'test') + os.sep, | |
os.path.join('mypyc', 'doc') + os.sep, | |
os.path.join('mypyc', 'test-data') + os.sep, | |
))] | |
# ... and add back in the one test module we need | |
mypyc_targets.append(os.path.join('mypy', 'test', 'visitors.py')) | |
# The targets come out of file system apis in an unspecified | |
# order. Sort them so that the mypyc output is deterministic. | |
mypyc_targets.sort() | |
use_other_mypyc = os.getenv('ALTERNATE_MYPYC_PATH', None) | |
if use_other_mypyc: | |
# This bit is super unfortunate: we want to use a different | |
# mypy/mypyc version, but we've already imported parts, so we | |
# remove the modules that we've imported already, which will | |
# let the right versions be imported by mypyc. | |
del sys.modules['mypy'] | |
del sys.modules['mypy.version'] | |
del sys.modules['mypy.git'] | |
sys.path.insert(0, use_other_mypyc) | |
from mypyc.build import mypycify | |
opt_level = os.getenv('MYPYC_OPT_LEVEL', '3') | |
debug_level = os.getenv('MYPYC_DEBUG_LEVEL', '1') | |
force_multifile = os.getenv('MYPYC_MULTI_FILE', '') == '1' | |
ext_modules = mypycify( | |
mypyc_targets + ['--config-file=mypy_bootstrap.ini'], | |
opt_level=opt_level, | |
debug_level=debug_level, | |
# Use multi-file compilation mode on windows because without it | |
# our Appveyor builds run out of memory sometimes. | |
multi_file=sys.platform == 'win32' or force_multifile, | |
) | |
else: | |
ext_modules = [] | |
classifiers = [ | |
'Development Status :: 4 - Beta', | |
'Environment :: Console', | |
'Intended Audience :: Developers', | |
'License :: OSI Approved :: MIT License', | |
'Programming Language :: Python :: 3', | |
'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', | |
] | |
setup(name='mypy', | |
version=version, | |
description=description, | |
long_description=long_description, | |
author='Jukka Lehtosalo', | |
author_email='jukka.lehtosalo@iki.fi', | |
url='http://www.mypy-lang.org/', | |
license='MIT License', | |
py_modules=[], | |
ext_modules=ext_modules, | |
packages=find_packages(), | |
package_data={'mypy': package_data}, | |
entry_points={'console_scripts': ['mypy=mypy.__main__:console_entry', | |
'stubgen=mypy.stubgen:main', | |
'stubtest=mypy.stubtest:main', | |
'dmypy=mypy.dmypy.client:console_entry', | |
'mypyc=mypyc.__main__:main', | |
]}, | |
classifiers=classifiers, | |
cmdclass=cmdclass, | |
# When changing this, also update mypy-requirements.txt. | |
install_requires=["typed_ast >= 1.4.0, < 2; python_version<'3.8'", | |
'typing_extensions>=3.10', | |
'mypy_extensions >= 0.4.3', | |
"tomli>=1.1.0; python_version<'3.11'", | |
], | |
# Same here. | |
extras_require={ | |
'dmypy': 'psutil >= 4.0', | |
'python2': 'typed_ast >= 1.4.0, < 2', | |
'reports': 'lxml' | |
}, | |
python_requires=">=3.6", | |
include_package_data=True, | |
project_urls={ | |
'News': 'http://mypy-lang.org/news.html', | |
'Documentation': 'https://mypy.readthedocs.io/en/stable/introduction.html', | |
'Repository': 'https://github.com/python/mypy', | |
}, | |
) |