2

用 mypy 检查 Python 类型系统

 3 weeks ago
source link: https://zhiqiang.org/coding/mypy-check-python-typing.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

类型系统可以提前检查代码准确性,为中大型项目提供保障。所以现在大型编程语言都争先恐后地为程序添加类型系统。

1、安装 mypy

首先安装 mypy

sudo -E pip3 install mypy 

其次,大多数包都有配套的stub包,一般为{package}-stub。下面脚本可以为系统库一次性全部安装对应的 stub 库:

import os
import pkg_resources

installed_packages = list(pkg_resources.working_set)
installed_packages_list = sorted([f"{i.key}=={i.version}" for i in installed_packages])
installed_packages_list = [i.split('==')[0] for i in installed_packages_list]

installed_packages_list = [i for i in installed_packages_list if not i.endswith("-stubs")]

installed_stubs = []

# Try to install stubs for each package
for package_name in installed_packages_list:
    try:
        # Attempt to install the stubs package
        os.system(f"sudo -E pip3 install -U {package_name}-stubs")
        installed_stubs.append(package_name)
    except Exception as e:
        print(f"No stubs found for {package_name}: {e}")

print(f"系统一共安装了{len(installed_packages_list)}个库,"
       f"已安装{len(installed_stubs)}个类型库:{installed_stubs}")

2、配置 vim

直接在 linters 里为 python 添加 mypy 即可,可以和 pylint 同时使用:

Plug 'w0rp/ale'
let g:ale_linters = {'cpp': [], 'c': [], 'python': ['pylint', 'mypy', ], 'javascript': ['eslint', ], 'vue': ['eslint', ],  } 

3、配置 mypy

首先一个最重要的: mypy 不会自动使用 PYTHONPATH 的环境变量。所以自己的库需要手工添加到 MYPY 里。在你的~.bashrc或者~/.zshrc(根据你使用什么 bash 环境)添加环境变量:

export MYPYPATH=$HOME/your_local_path:/opt/other_path
# or
export MYPYPATH=$PYTHONPATH

其次,有些常用库不提供 stub , mypy 会有下面import-untyped类似的提示:

Skipping analyzing "rest_framework": module is installed, but missing library stubs or py.typed marker  [import-untyped]

这时候有两种方法,一种临时的方法是在该行代码后面添加注释取消检查:

import rest_framework # type: ignore

还有一种方法是对项目或者所有文件生效:将下面配置放在项目下的 pyproject.toml或者个人目录下的~/mypy.ini

[tool.mypy]
# The mypy configurations are set here
python_version = "3.8"
check_untyped_defs = true
ignore_missing_imports = false
warn_redundant_casts = true
warn_unused_ignores = true
warn_return_any = true

[tool.mypy-tensorflow.*]
ignore_missing_imports = true

下面这些库有类型库:

['absl-py', 'aiohttp-jinja2', 'aiohttp', 'aiosignal', 'alabaster', 'amqp', 'ansi2html', 'anyio', 'appdirs-stubs', 'appdirs', 'argcomplete', 'argon2-cffi', 'arrow', 'asgiref', 'astroid', 'asttokens', 'astunparse', 'async-generator', 'async-timeout', 'asyncssh', 'atomicwrites', 'attrs', 'automat', 'autopep8', 'babel', 'backcall', 'backports.zoneinfo', 'bcrypt', 'beautifulsoup4', 'billiard', 'binaryornot', 'black', 'bleach', 'blinker', 'bottle', 'brlapi', 'brotli', 'cached-property', 'cachetools', 'celery-stubs', 'celery', 'certifi', 'cffi', 'chardet', 'charset-normalizer', 'cheat', 'click-didyoumean', 'click-plugins', 'click-repl', 'click', 'clickhouse-connect', 'cloudpickle', 'colorama', 'coloredlogs', 'colorlog', 'comm', 'command-not-found', 'constantly', 'contourpy', 'cookiecutter', 'cppman', 'cryptography', 'cssselect', 'cupshelpers', 'cvxopt', 'cx-oracle', 'cycler', 'dataclasses-json', 'dataclasses', 'dbus-python', 'deap', 'debugpy', 'decorator', 'defer', 'defusedxml', 'diff-match-patch', 'dill', 'distro', 'django-appconf', 'django-celery-beat', 'django-celery-results', 'django-classy-tags', 'django-cors-headers', 'django-filter-stubs', 'django-filter', 'django-js-asset', 'django-model-utils', 'django-mptt', 'django-nyt', 'django-redirect-urls', 'django-sekizai', 'django-stubs-ext', 'django-stubs', 'django-timezone-field', 'django-widget-tweaks', 'django', 'djangorestframework-stubs', 'djangorestframework', 'dlib', 'dnspython', 'docker-compose', 'docker-stubs', 'docker', 'dockerpty', 'docopt', 'docstring-to-markdown', 'docutils-stubs', 'docutils', 'dolphindb', 'doxypypy', 'duplicity', 'editorconfig', 'entrypoints', 'et-xmlfile', 'exceptiongroup', 'executing', 'exifread', 'face-recognition-models', 'face-recognition', 'fasteners', 'feedgenerator', 'feedparser', 'filelock', 'flake8', 'flask', 'flatbuffers', 'fonttools', 'frozenlist', 'future', 'gast', 'ghp-import', 'glances', 'google-auth-oauthlib', 'google-auth', 'google-pasta', 'greenlet', 'grpcio', 'h11', 'h2', 'h5py', 'hpack', 'html5lib', 'httplib2', 'huggingface-hub', 'humanfriendly', 'hyperframe', 'hyperlink', 'icdiff', 'idna', 'imagesize', 'importlib-metadata', 'importlib-resources', 'imutils', 'incremental', 'inflection', 'influxdb', 'intervaltree', 'iotop', 'ipykernel', 'ipython-genutils', 'ipython', 'ipywidgets', 'isort', 'itchat', 'itemadapter', 'itemloaders', 'itsdangerous', 'jedi', 'jellyfish', 'jieba', 'jinja2-time', 'jinja2', 'jmespath', 'joblib', 'jsbeautifier', 'jsonschema', 'jupyter-client', 'jupyter-console', 'jupyter-core', 'jupyter', 'jupyterlab-pygments', 'keras-preprocessing', 'keras', 'keyring', 'kiwisolver', 'kombu', 'langchain', 'language-selector', 'lazr.uri', 'lazy-object-proxy', 'livereload', 'llama-index', 'lockfile', 'loguru', 'louis', 'lunr', 'lxml-stubs', 'lxml', 'lz4', 'macaroonbakery', 'mako', 'markdown-cjk-spacing', 'markdown-include', 'markdown-it-py', 'markdown', 'markupsafe', 'marshmallow-enum', 'marshmallow', 'matplotlib-inline', 'matplotlib', 'mccabe', 'mdurl', 'mergedeep', 'mistune', 'mkdocs-get-deps', 'mkdocs-mermaid2-plugin', 'mkdocs', 'monotonic', 'more-itertools', 'mosek', 'msgpack', 'multidict', 'mypy-extensions', 'mypy', 'nbclient', 'nbconvert', 'nbformat', 'nest-asyncio', 'netifaces', 'nltk', 'notebook', 'numpy', 'numpydoc', 'olefile', 'onboard', 'openai', 'openapi-schema-pydantic', 'opencv-python', 'openpyxl', 'openutilslitecitics', 'opt-einsum', 'ordered-set', 'outcome', 'packaging', 'padme', 'pandas-stubs', 'pandas', 'pandocfilters', 'paramiko', 'parsel', 'parso', 'pathlib', 'pathspec', 'pathtools', 'peewee', 'pelican', 'pexpect', 'pickleshare', 'pillow', 'pip', 'platformdirs', 'plot', 'pluggy', 'ply', 'poyo', 'priority', 'progressbar', 'prometheus-client', 'prompt-toolkit', 'protego', 'protobuf', 'psutil', 'psycopg2-binary', 'ptyprocess', 'pure-eval', 'pyasn1-modules', 'pyasn1', 'pycairo', 'pycodestyle', 'pycparser', 'pycrypto', 'pycryptodome', 'pycryptodomex', 'pycups', 'pycurl', 'pydantic', 'pydispatcher', 'pydocstyle', 'pyexif', 'pyflakes', 'pygments', 'pygobject', 'pyjwt', 'pylint-venv', 'pylint', 'pyls-black', 'pyls-spyder', 'pymacaroons', 'pymdown-extensions', 'pymssql', 'pymupdf', 'pymysql', 'pynacl', 'pyopenssl', 'pyparsing', 'pypdf2', 'pypinyin', 'pypng', 'pypyodbc', 'pyqrcode', 'pyqt5-sip', 'pyqt5', 'pyqtwebengine', 'pyrfc3339', 'pyrsistent', 'pysmi', 'pysnmp', 'pysocks', 'pystache', 'python-apt', 'python-crontab', 'python-dateutil', 'python-dotenv', 'python-gnupg', 'python-jsonrpc-server', 'python-language-server', 'python-lsp-black', 'python-lsp-jsonrpc', 'python-lsp-server', 'python-markdown-math', 'python-rapidjson', 'python-slugify', 'pytoolconfig', 'pytz', 'pyxdg', 'pyyaml-env-tag', 'pyyaml', 'pyzbar', 'pyzmq', 'qdarkstyle', 'qscintilla', 'qstylizer', 'qtawesome', 'qtconsole', 'qtpy', 'queuelib', 'rapidjson', 'regex', 'reportlab', 'requestium', 'requests-file', 'requests-oauthlib', 'requests-unixsocket', 'requests', 'rich', 'rope', 'rqdatac', 'rsa', 'rtree', 'ruff', 'scikit-learn', 'scipy', 'scrapy', 'screen-resolution-extra', 'seaborn', 'secretstorage', 'selenium', 'send2trash', 'service-identity', 'setuptools', 'simplejson', 'sip', 'six', 'sklearn', 'sniffio', 'snowballstemmer', 'socks', 'sorl-thumbnail', 'sortedcontainers', 'soupsieve', 'spark-parser',
'sphinx', 'sphinxcontrib-applehelp', 'sphinxcontrib-devhelp', 'sphinxcontrib-htmlhelp', 'sphinxcontrib-jsmath', 'sphinxcontrib-qthelp', 'sphinxcontrib-serializinghtml', 'spyder-kernels', 'spyder', 'sqlalchemy', 'sqlparse', 'ssh-import-id', 'stack-data', 'system-service', 'systemd-python', 'ta-lib', 'tailer', 'tenacity', 'tensorboard-data-server', 'tensorboard-plugin-wit', 'tensorboard', 'tensorflow-estimator', 'tensorflow-gpu', 'termcolor', 'terminado', 'testpath', 'text-unidecode', 'textdistance',
'texttable', 'threadpoolctl', 'three-merge', 'tinify', 'tinycss2', 'tinycss', 'tldextract', 'tokenizers', 'toml', 'tomli', 'tomlkit', 'torch-geometric', 'torch', 'torchvision', 'tornado', 'tqdm', 'traitlets', 'transformers', 'trio-websocket', 'trio', 'twisted', 'typed-ast', 'types-beautifulsoup4', 'types-cffi', 'types-html5lib', 'types-markdown', 'types-pillow', 'types-psutil', 'types-psycopg2', 'types-pymysql', 'types-pyopenssl', 'types-pytz', 'types-pyyaml', 'types-redis', 'types-requests', 'types-setuptools', 'types-six', 'types-tqdm', 'types-urllib3', 'typing-extensions', 'typing-inspect', 'typing', 'tzdata', 'tzlocal', 'ubuntu-drivers-common', 'ubuntu-make', 'ubuntu-pro-client', 'ufw', 'ujson', 'uncompyle6', 'unidecode', 'unity-scope-calculator', 'unity-scope-chromiumbookmarks', 'unity-scope-colourlovers', 'unity-scope-devhelp', 'unity-scope-manpages', 'unity-scope-texdoc', 'unity-scope-tomboy', 'unity-scope-virtualbox', 'unity-scope-yelp', 'unity-scope-zotero', 'urllib3', 'usb-creator',
'vine', 'vnpy', 'w3lib', 'wadllib', 'wand', 'watchdog', 'watchfiles', 'wcwidth', 'webdriver-manager', 'webencodings', 'websocket-client', 'websockets', 'werkzeug', 'whatthepatch', 'wheel', 'widgetsnbextension', 'wmi', 'wrapt', 'wsproto', 'wurlitzer', 'xdis', 'xkit', 'xlrd', 'xlsxwriter', 'yapf', 'yarl', 'zhconv', 'zipp', 'zope.interface', 'zstandard']

Q. E. D.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK