Replace yapf with black
This commit is contained in:
2
.github/workflows/tests.yml
vendored
2
.github/workflows/tests.yml
vendored
@@ -1,6 +1,6 @@
|
|||||||
name: Tests
|
name: Tests
|
||||||
|
|
||||||
on: [push, pull_request]
|
on: [pull_request]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
|
|||||||
639
poetry.lock
generated
639
poetry.lock
generated
@@ -1,59 +1,104 @@
|
|||||||
[[package]]
|
[[package]]
|
||||||
|
name = "appdirs"
|
||||||
|
version = "1.4.4"
|
||||||
|
description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
|
||||||
category = "dev"
|
category = "dev"
|
||||||
description = "Atomic file writes."
|
|
||||||
name = "atomicwrites"
|
|
||||||
optional = false
|
|
||||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
|
||||||
version = "1.3.0"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
category = "dev"
|
|
||||||
description = "Classes Without Boilerplate"
|
|
||||||
name = "attrs"
|
|
||||||
optional = false
|
|
||||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
|
||||||
version = "19.3.0"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
category = "dev"
|
|
||||||
description = "Cross-platform colored terminal text."
|
|
||||||
marker = "sys_platform == \"win32\""
|
|
||||||
name = "colorama"
|
|
||||||
optional = false
|
|
||||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
|
||||||
version = "0.4.1"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
category = "dev"
|
|
||||||
description = "Code coverage measurement for Python"
|
|
||||||
name = "coverage"
|
|
||||||
optional = false
|
|
||||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4"
|
|
||||||
version = "5.0"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
category = "dev"
|
|
||||||
description = "Discover and load entry points from installed packages."
|
|
||||||
name = "entrypoints"
|
|
||||||
optional = false
|
|
||||||
python-versions = ">=2.7"
|
|
||||||
version = "0.3"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
category = "dev"
|
|
||||||
description = "A platform independent file lock."
|
|
||||||
name = "filelock"
|
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "*"
|
python-versions = "*"
|
||||||
version = "3.0.12"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
name = "atomicwrites"
|
||||||
|
version = "1.3.0"
|
||||||
|
description = "Atomic file writes."
|
||||||
category = "dev"
|
category = "dev"
|
||||||
description = "the modular source code checker: pep8, pyflakes and co"
|
|
||||||
name = "flake8"
|
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "attrs"
|
||||||
|
version = "19.3.0"
|
||||||
|
description = "Classes Without Boilerplate"
|
||||||
|
category = "dev"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||||
|
|
||||||
|
[package.extras]
|
||||||
|
azure-pipelines = ["coverage", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface", "pytest-azurepipelines"]
|
||||||
|
dev = ["coverage", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface", "sphinx", "pre-commit"]
|
||||||
|
docs = ["sphinx", "zope.interface"]
|
||||||
|
tests = ["coverage", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface"]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "black"
|
||||||
|
version = "19.10b0"
|
||||||
|
description = "The uncompromising code formatter."
|
||||||
|
category = "dev"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.6"
|
||||||
|
|
||||||
|
[package.extras]
|
||||||
|
d = ["aiohttp (>=3.3.2)", "aiohttp-cors"]
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
appdirs = "*"
|
||||||
|
attrs = ">=18.1.0"
|
||||||
|
click = ">=6.5"
|
||||||
|
pathspec = ">=0.6,<1"
|
||||||
|
regex = "*"
|
||||||
|
toml = ">=0.9.4"
|
||||||
|
typed-ast = ">=1.4.0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "click"
|
||||||
|
version = "7.1.2"
|
||||||
|
description = "Composable command line interface toolkit"
|
||||||
|
category = "dev"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "colorama"
|
||||||
|
version = "0.4.1"
|
||||||
|
description = "Cross-platform colored terminal text."
|
||||||
|
category = "dev"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||||
|
marker = "sys_platform == \"win32\""
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "coverage"
|
||||||
|
version = "5.0"
|
||||||
|
description = "Code coverage measurement for Python"
|
||||||
|
category = "dev"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4"
|
||||||
|
|
||||||
|
[package.extras]
|
||||||
|
toml = ["toml"]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "entrypoints"
|
||||||
|
version = "0.3"
|
||||||
|
description = "Discover and load entry points from installed packages."
|
||||||
|
category = "dev"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=2.7"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "filelock"
|
||||||
|
version = "3.0.12"
|
||||||
|
description = "A platform independent file lock."
|
||||||
|
category = "dev"
|
||||||
|
optional = false
|
||||||
|
python-versions = "*"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "flake8"
|
||||||
version = "3.7.8"
|
version = "3.7.8"
|
||||||
|
description = "the modular source code checker: pep8, pyflakes and co"
|
||||||
|
category = "dev"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
entrypoints = ">=0.3.0,<0.4.0"
|
entrypoints = ">=0.3.0,<0.4.0"
|
||||||
@@ -62,48 +107,61 @@ pycodestyle = ">=2.5.0,<2.6.0"
|
|||||||
pyflakes = ">=2.1.0,<2.2.0"
|
pyflakes = ">=2.1.0,<2.2.0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "dev"
|
|
||||||
description = "Read metadata from Python packages"
|
|
||||||
marker = "python_version < \"3.8\""
|
|
||||||
name = "importlib-metadata"
|
name = "importlib-metadata"
|
||||||
|
version = "0.23"
|
||||||
|
description = "Read metadata from Python packages"
|
||||||
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=2.7,!=3.0,!=3.1,!=3.2,!=3.3"
|
python-versions = ">=2.7,!=3.0,!=3.1,!=3.2,!=3.3"
|
||||||
version = "0.23"
|
marker = "python_version < \"3.8\""
|
||||||
|
|
||||||
|
[package.extras]
|
||||||
|
docs = ["sphinx", "rst.linker"]
|
||||||
|
testing = ["packaging", "importlib-resources"]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
zipp = ">=0.5"
|
zipp = ">=0.5"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "dev"
|
|
||||||
description = "A Python utility / library to sort Python imports."
|
|
||||||
name = "isort"
|
name = "isort"
|
||||||
|
version = "4.3.21"
|
||||||
|
description = "A Python utility / library to sort Python imports."
|
||||||
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||||
version = "4.3.21"
|
|
||||||
|
[package.extras]
|
||||||
|
pipfile = ["pipreqs", "requirementslib"]
|
||||||
|
pyproject = ["toml"]
|
||||||
|
requirements = ["pipreqs", "pip-api"]
|
||||||
|
xdg_home = ["appdirs (>=1.4.0)"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "dev"
|
|
||||||
description = "McCabe checker, plugin for flake8"
|
|
||||||
name = "mccabe"
|
name = "mccabe"
|
||||||
|
version = "0.6.1"
|
||||||
|
description = "McCabe checker, plugin for flake8"
|
||||||
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "*"
|
python-versions = "*"
|
||||||
version = "0.6.1"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "dev"
|
|
||||||
description = "More routines for operating on iterables, beyond itertools"
|
|
||||||
name = "more-itertools"
|
name = "more-itertools"
|
||||||
|
version = "7.2.0"
|
||||||
|
description = "More routines for operating on iterables, beyond itertools"
|
||||||
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.4"
|
python-versions = ">=3.4"
|
||||||
version = "7.2.0"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "dev"
|
|
||||||
description = "Optional static typing for Python"
|
|
||||||
name = "mypy"
|
name = "mypy"
|
||||||
|
version = "0.740"
|
||||||
|
description = "Optional static typing for Python"
|
||||||
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.5"
|
python-versions = ">=3.5"
|
||||||
version = "0.740"
|
|
||||||
|
[package.extras]
|
||||||
|
dmypy = ["psutil (>=4.0)"]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
mypy-extensions = ">=0.4.0,<0.5.0"
|
mypy-extensions = ">=0.4.0,<0.5.0"
|
||||||
@@ -111,85 +169,104 @@ typed-ast = ">=1.4.0,<1.5.0"
|
|||||||
typing-extensions = ">=3.7.4"
|
typing-extensions = ">=3.7.4"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "dev"
|
|
||||||
description = "Experimental type system extensions for programs checked with the mypy typechecker."
|
|
||||||
name = "mypy-extensions"
|
name = "mypy-extensions"
|
||||||
|
version = "0.4.3"
|
||||||
|
description = "Experimental type system extensions for programs checked with the mypy typechecker."
|
||||||
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "*"
|
python-versions = "*"
|
||||||
version = "0.4.3"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "dev"
|
|
||||||
description = "Core utilities for Python packages"
|
|
||||||
name = "packaging"
|
name = "packaging"
|
||||||
|
version = "19.2"
|
||||||
|
description = "Core utilities for Python packages"
|
||||||
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||||
version = "19.2"
|
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
pyparsing = ">=2.0.2"
|
pyparsing = ">=2.0.2"
|
||||||
six = "*"
|
six = "*"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
name = "pathspec"
|
||||||
|
version = "0.8.0"
|
||||||
|
description = "Utility library for gitignore style pattern matching of file paths."
|
||||||
category = "dev"
|
category = "dev"
|
||||||
description = "plugin and hook calling mechanisms for python"
|
optional = false
|
||||||
|
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
name = "pluggy"
|
name = "pluggy"
|
||||||
|
version = "0.13.0"
|
||||||
|
description = "plugin and hook calling mechanisms for python"
|
||||||
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||||
version = "0.13.0"
|
|
||||||
|
[package.extras]
|
||||||
|
dev = ["pre-commit", "tox"]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
[package.dependencies.importlib-metadata]
|
[package.dependencies.importlib-metadata]
|
||||||
python = "<3.8"
|
|
||||||
version = ">=0.12"
|
version = ">=0.12"
|
||||||
|
python = "<3.8"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "dev"
|
|
||||||
description = "library with cross-python path, ini-parsing, io, code, log facilities"
|
|
||||||
name = "py"
|
name = "py"
|
||||||
optional = false
|
|
||||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
|
||||||
version = "1.8.0"
|
version = "1.8.0"
|
||||||
|
description = "library with cross-python path, ini-parsing, io, code, log facilities"
|
||||||
|
category = "dev"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "dev"
|
|
||||||
description = "Python style guide checker"
|
|
||||||
name = "pycodestyle"
|
name = "pycodestyle"
|
||||||
optional = false
|
|
||||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
|
||||||
version = "2.5.0"
|
version = "2.5.0"
|
||||||
|
description = "Python style guide checker"
|
||||||
[[package]]
|
category = "dev"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pyflakes"
|
||||||
|
version = "2.1.1"
|
||||||
|
description = "passive checker of Python programs"
|
||||||
category = "dev"
|
category = "dev"
|
||||||
description = "passive checker of Python programs"
|
|
||||||
name = "pyflakes"
|
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||||
version = "2.1.1"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "main"
|
|
||||||
description = "a pythonic generic language server (pronounced like \"pie glass\")."
|
|
||||||
name = "pygls"
|
name = "pygls"
|
||||||
|
version = "0.8.1"
|
||||||
|
description = "a pythonic generic language server (pronounced like \"pie glass\")."
|
||||||
|
category = "main"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "*"
|
python-versions = "*"
|
||||||
version = "0.8.1"
|
|
||||||
|
[package.extras]
|
||||||
|
dev = ["bandit (1.6.0)", "flake8 (3.7.7)"]
|
||||||
|
docs = ["sphinx (2.0.1)", "sphinx-rtd-theme (0.4.3)"]
|
||||||
|
test = ["mock (3.0.5)", "pytest (4.5.0)", "pytest-asyncio (0.10.0)"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "main"
|
|
||||||
description = "Python parsing module"
|
|
||||||
name = "pyparsing"
|
name = "pyparsing"
|
||||||
|
version = "2.4.2"
|
||||||
|
description = "Python parsing module"
|
||||||
|
category = "main"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
|
python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
|
||||||
version = "2.4.2"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "dev"
|
|
||||||
description = "pytest: simple powerful testing with Python"
|
|
||||||
name = "pytest"
|
name = "pytest"
|
||||||
|
version = "5.2.1"
|
||||||
|
description = "pytest: simple powerful testing with Python"
|
||||||
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.5"
|
python-versions = ">=3.5"
|
||||||
version = "5.2.1"
|
|
||||||
|
[package.extras]
|
||||||
|
testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
atomicwrites = ">=1.0"
|
atomicwrites = ">=1.0"
|
||||||
@@ -202,55 +279,70 @@ py = ">=1.5.0"
|
|||||||
wcwidth = "*"
|
wcwidth = "*"
|
||||||
|
|
||||||
[package.dependencies.importlib-metadata]
|
[package.dependencies.importlib-metadata]
|
||||||
python = "<3.8"
|
|
||||||
version = ">=0.12"
|
version = ">=0.12"
|
||||||
|
python = "<3.8"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "dev"
|
|
||||||
description = "Pytest plugin for measuring coverage."
|
|
||||||
name = "pytest-cov"
|
name = "pytest-cov"
|
||||||
|
version = "2.8.1"
|
||||||
|
description = "Pytest plugin for measuring coverage."
|
||||||
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||||
version = "2.8.1"
|
|
||||||
|
[package.extras]
|
||||||
|
testing = ["fields", "hunter", "process-tests (2.0.2)", "six", "virtualenv"]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
coverage = ">=4.4"
|
coverage = ">=4.4"
|
||||||
pytest = ">=3.6"
|
pytest = ">=3.6"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "dev"
|
|
||||||
description = "pytest plugin for test data directories and files"
|
|
||||||
name = "pytest-datadir"
|
name = "pytest-datadir"
|
||||||
|
version = "1.3.1"
|
||||||
|
description = "pytest plugin for test data directories and files"
|
||||||
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||||
version = "1.3.1"
|
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
pytest = ">=2.7.0"
|
pytest = ">=2.7.0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
name = "regex"
|
||||||
|
version = "2020.7.14"
|
||||||
|
description = "Alternative regular expression module, to replace re."
|
||||||
category = "dev"
|
category = "dev"
|
||||||
description = "Python 2 and 3 compatibility utilities"
|
|
||||||
name = "six"
|
|
||||||
optional = false
|
|
||||||
python-versions = ">=2.6, !=3.0.*, !=3.1.*"
|
|
||||||
version = "1.12.0"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
category = "dev"
|
|
||||||
description = "Python Library for Tom's Obvious, Minimal Language"
|
|
||||||
name = "toml"
|
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "*"
|
python-versions = "*"
|
||||||
version = "0.10.0"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
name = "six"
|
||||||
|
version = "1.12.0"
|
||||||
|
description = "Python 2 and 3 compatibility utilities"
|
||||||
category = "dev"
|
category = "dev"
|
||||||
description = "tox is a generic virtualenv management and test command line tool"
|
optional = false
|
||||||
|
python-versions = ">=2.6, !=3.0.*, !=3.1.*"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml"
|
||||||
|
version = "0.10.0"
|
||||||
|
description = "Python Library for Tom's Obvious, Minimal Language"
|
||||||
|
category = "dev"
|
||||||
|
optional = false
|
||||||
|
python-versions = "*"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
name = "tox"
|
name = "tox"
|
||||||
|
version = "3.14.0"
|
||||||
|
description = "tox is a generic virtualenv management and test command line tool"
|
||||||
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||||
version = "3.14.0"
|
|
||||||
|
[package.extras]
|
||||||
|
docs = ["sphinx (>=2.0.0,<3)", "towncrier (>=18.5.0)", "pygments-github-lexers (>=0.0.5)", "sphinxcontrib-autoprogram (>=0.1.5)"]
|
||||||
|
testing = ["freezegun (>=0.3.11,<1)", "pathlib2 (>=2.3.3,<3)", "pytest (>=4.0.0,<6)", "pytest-cov (>=2.5.1,<3)", "pytest-mock (>=1.10.0,<2)", "pytest-xdist (>=1.22.2,<2)", "pytest-randomly (>=1.2.3,<2)", "flaky (>=3.4.0,<4)", "psutil (>=5.6.1,<6)"]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
filelock = ">=3.0.0,<4"
|
filelock = ">=3.0.0,<4"
|
||||||
@@ -262,107 +354,304 @@ toml = ">=0.9.4"
|
|||||||
virtualenv = ">=14.0.0"
|
virtualenv = ">=14.0.0"
|
||||||
|
|
||||||
[package.dependencies.importlib-metadata]
|
[package.dependencies.importlib-metadata]
|
||||||
python = "<3.8"
|
|
||||||
version = ">=0.12,<1"
|
version = ">=0.12,<1"
|
||||||
|
python = "<3.8"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "dev"
|
|
||||||
description = "a fork of Python 2 and 3 ast modules with type comment support"
|
|
||||||
name = "typed-ast"
|
name = "typed-ast"
|
||||||
optional = false
|
|
||||||
python-versions = "*"
|
|
||||||
version = "1.4.0"
|
version = "1.4.0"
|
||||||
|
description = "a fork of Python 2 and 3 ast modules with type comment support"
|
||||||
|
category = "dev"
|
||||||
|
optional = false
|
||||||
|
python-versions = "*"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "dev"
|
|
||||||
description = "Type Hints for Python"
|
|
||||||
name = "typing"
|
name = "typing"
|
||||||
|
version = "3.7.4.1"
|
||||||
|
description = "Type Hints for Python"
|
||||||
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "*"
|
python-versions = "*"
|
||||||
version = "3.7.4.1"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "dev"
|
|
||||||
description = "Backported and Experimental Type Hints for Python 3.5+"
|
|
||||||
name = "typing-extensions"
|
name = "typing-extensions"
|
||||||
|
version = "3.7.4"
|
||||||
|
description = "Backported and Experimental Type Hints for Python 3.5+"
|
||||||
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "*"
|
python-versions = "*"
|
||||||
version = "3.7.4"
|
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
typing = ">=3.7.4"
|
typing = ">=3.7.4"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "dev"
|
|
||||||
description = "Virtual Python Environment builder"
|
|
||||||
name = "virtualenv"
|
name = "virtualenv"
|
||||||
|
version = "16.7.7"
|
||||||
|
description = "Virtual Python Environment builder"
|
||||||
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7"
|
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7"
|
||||||
version = "16.7.7"
|
|
||||||
|
[package.extras]
|
||||||
|
docs = ["sphinx (>=1.8.0,<2)", "towncrier (>=18.5.0)", "sphinx-rtd-theme (>=0.4.2,<1)"]
|
||||||
|
testing = ["pytest (>=4.0.0,<5)", "coverage (>=4.5.0,<5)", "pytest-timeout (>=1.3.0,<2)", "six (>=1.10.0,<2)", "pytest-xdist", "pytest-localserver", "pypiserver", "mock", "xonsh"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "dev"
|
|
||||||
description = "Measures number of Terminal column cells of wide-character codes"
|
|
||||||
name = "wcwidth"
|
name = "wcwidth"
|
||||||
optional = false
|
|
||||||
python-versions = "*"
|
|
||||||
version = "0.1.7"
|
version = "0.1.7"
|
||||||
|
description = "Measures number of Terminal column cells of wide-character codes"
|
||||||
[[package]]
|
|
||||||
category = "dev"
|
category = "dev"
|
||||||
description = "A formatter for Python code."
|
|
||||||
name = "yapf"
|
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "*"
|
python-versions = "*"
|
||||||
version = "0.28.0"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "dev"
|
|
||||||
description = "Backport of pathlib-compatible object wrapper for zip files"
|
|
||||||
marker = "python_version < \"3.8\""
|
|
||||||
name = "zipp"
|
name = "zipp"
|
||||||
|
version = "0.6.0"
|
||||||
|
description = "Backport of pathlib-compatible object wrapper for zip files"
|
||||||
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=2.7"
|
python-versions = ">=2.7"
|
||||||
version = "0.6.0"
|
marker = "python_version < \"3.8\""
|
||||||
|
|
||||||
|
[package.extras]
|
||||||
|
docs = ["sphinx", "jaraco.packaging (>=3.2)", "rst.linker (>=1.9)"]
|
||||||
|
testing = ["pathlib2", "contextlib2", "unittest2"]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
more-itertools = "*"
|
more-itertools = "*"
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
content-hash = "284b539e6199a16441b6196fcbc38a374c886e328ae0c5e8bf07d0aaa47b0670"
|
lock-version = "1.0"
|
||||||
python-versions = "^3.6"
|
python-versions = "^3.6"
|
||||||
|
content-hash = "2a838d1a4c2f23e2510f2a83e999f268cddf10788031e911324496d6af70a1cc"
|
||||||
|
|
||||||
[metadata.hashes]
|
[metadata.files]
|
||||||
atomicwrites = ["03472c30eb2c5d1ba9227e4c2ca66ab8287fbfbbda3888aa93dc2e28fc6811b4", "75a9445bac02d8d058d5e1fe689654ba5a6556a1dfd8ce6ec55a0ed79866cfa6"]
|
appdirs = [
|
||||||
attrs = ["08a96c641c3a74e44eb59afb61a24f2cb9f4d7188748e76ba4bb5edfa3cb7d1c", "f7b7ce16570fe9965acd6d30101a28f62fb4a7f9e926b3bbc9b61f8b04247e72"]
|
{file = "appdirs-1.4.4-py2.py3-none-any.whl", hash = "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128"},
|
||||||
colorama = ["05eed71e2e327246ad6b38c540c4a3117230b19679b875190486ddd2d721422d", "f8ac84de7840f5b9c4e3347b3c1eaa50f7e49c2b07596221daec5edaabbd7c48"]
|
{file = "appdirs-1.4.4.tar.gz", hash = "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41"},
|
||||||
coverage = ["0cd13a6e98c37b510a2d34c8281d5e1a226aaf9b65b7d770ef03c63169965351", "1a4b6b6a2a3a6612e6361130c2cc3dc4378d8c221752b96167ccbad94b47f3cd", "2ee55e6dba516ddf6f484aa83ccabbb0adf45a18892204c23486938d12258cde", "3be5338a2eb4ef03c57f20917e1d12a1fd10e3853fed060b6d6b677cb3745898", "44b783b02db03c4777d8cf71bae19eadc171a6f2a96777d916b2c30a1eb3d070", "475bf7c4252af0a56e1abba9606f1e54127cdf122063095c75ab04f6f99cf45e", "47c81ee687eafc2f1db7f03fbe99aab81330565ebc62fb3b61edfc2216a550c8", "4a7f8e72b18f2aca288ff02255ce32cc830bc04d993efbc87abf6beddc9e56c0", "50197163a22fd17f79086e087a787883b3ec9280a509807daf158dfc2a7ded02", "56b13000acf891f700f5067512b804d1ec8c301d627486c678b903859d07f798", "79388ae29c896299b3567965dbcd93255f175c17c6c7bca38614d12718c47466", "79fd5d3d62238c4f583b75d48d53cdae759fe04d4fb18fe8b371d88ad2b6f8be", "7fe3e2fde2bf1d7ce25ebcd2d3de3650b8d60d9a73ce6dcef36e20191291613d", "81042a24f67b96e4287774014fa27220d8a4d91af1043389e4d73892efc89ac6", "81326f1095c53111f8afc95da281e1414185f4a538609a77ca50bdfa39a6c207", "8873dc0d8f42142ea9f20c27bbdc485190fff93823c6795be661703369e5877d", "88d2cbcb0a112f47eef71eb95460b6995da18e6f8ca50c264585abc2c473154b", "91f2491aeab9599956c45a77c5666d323efdec790bfe23fcceafcd91105d585a", "979daa8655ae5a51e8e7a24e7d34e250ae8309fd9719490df92cbb2fe2b0422b", "9c871b006c878a890c6e44a5b2f3c6291335324b298c904dc0402ee92ee1f0be", "a6d092545e5af53e960465f652e00efbf5357adad177b2630d63978d85e46a72", "b5ed7837b923d1d71c4f587ae1539ccd96bfd6be9788f507dbe94dab5febbb5d", "ba259f68250f16d2444cbbfaddaa0bb20e1560a4fdaad50bece25c199e6af864", "be1d89614c6b6c36d7578496dc8625123bda2ff44f224cf8b1c45b810ee7383f", "c1b030a79749aa8d1f1486885040114ee56933b15ccfc90049ba266e4aa2139f", "c95bb147fab76f2ecde332d972d8f4138b8f2daee6c466af4ff3b4f29bd4c19e", "d52c1c2d7e856cecc05aa0526453cb14574f821b7f413cc279b9514750d795c1", "d609a6d564ad3d327e9509846c2c47f170456344521462b469e5cb39e48ba31c", "e1bad043c12fb58e8c7d92b3d7f2f49977dcb80a08a6d1e7a5114a11bf819fca", "e5a675f6829c53c87d79117a8eb656cc4a5f8918185a32fc93ba09778e90f6db", "fec32646b98baf4a22fdceb08703965bd16dea09051fbeb31a04b5b6e72b846c"]
|
]
|
||||||
entrypoints = ["589f874b313739ad35be6e0cd7efde2a4e9b6fea91edcc34e58ecbb8dbe56d19", "c70dd71abe5a8c85e55e12c19bd91ccfeec11a6e99044204511f9ed547d48451"]
|
atomicwrites = [
|
||||||
filelock = ["18d82244ee114f543149c66a6e0c14e9c4f8a1044b5cdaadd0f82159d6a6ff59", "929b7d63ec5b7d6b71b0fa5ac14e030b3f70b75747cef1b10da9b879fef15836"]
|
{file = "atomicwrites-1.3.0-py2.py3-none-any.whl", hash = "sha256:03472c30eb2c5d1ba9227e4c2ca66ab8287fbfbbda3888aa93dc2e28fc6811b4"},
|
||||||
flake8 = ["19241c1cbc971b9962473e4438a2ca19749a7dd002dd1a946eaba171b4114548", "8e9dfa3cecb2400b3738a42c54c3043e821682b9c840b0448c0503f781130696"]
|
{file = "atomicwrites-1.3.0.tar.gz", hash = "sha256:75a9445bac02d8d058d5e1fe689654ba5a6556a1dfd8ce6ec55a0ed79866cfa6"},
|
||||||
importlib-metadata = ["aa18d7378b00b40847790e7c27e11673d7fed219354109d0e7b9e5b25dc3ad26", "d5f18a79777f3aa179c145737780282e27b508fc8fd688cb17c7a813e8bd39af"]
|
]
|
||||||
isort = ["54da7e92468955c4fceacd0c86bd0ec997b0e1ee80d97f67c35a78b719dccab1", "6e811fcb295968434526407adb8796944f1988c5b65e8139058f2014cbe100fd"]
|
attrs = [
|
||||||
mccabe = ["ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42", "dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"]
|
{file = "attrs-19.3.0-py2.py3-none-any.whl", hash = "sha256:08a96c641c3a74e44eb59afb61a24f2cb9f4d7188748e76ba4bb5edfa3cb7d1c"},
|
||||||
more-itertools = ["409cd48d4db7052af495b09dec721011634af3753ae1ef92d2b32f73a745f832", "92b8c4b06dac4f0611c0729b2f2ede52b2e1bac1ab48f089c7ddc12e26bb60c4"]
|
{file = "attrs-19.3.0.tar.gz", hash = "sha256:f7b7ce16570fe9965acd6d30101a28f62fb4a7f9e926b3bbc9b61f8b04247e72"},
|
||||||
mypy = ["1521c186a3d200c399bd5573c828ea2db1362af7209b2adb1bb8532cea2fb36f", "31a046ab040a84a0fc38bc93694876398e62bc9f35eca8ccbf6418b7297f4c00", "3b1a411909c84b2ae9b8283b58b48541654b918e8513c20a400bb946aa9111ae", "48c8bc99380575deb39f5d3400ebb6a8a1cb5cc669bbba4d3bb30f904e0a0e7d", "540c9caa57a22d0d5d3c69047cc9dd0094d49782603eb03069821b41f9e970e9", "672e418425d957e276c291930a3921b4a6413204f53fe7c37cad7bc57b9a3391", "6ed3b9b3fdc7193ea7aca6f3c20549b377a56f28769783a8f27191903a54170f", "9371290aa2cad5ad133e4cdc43892778efd13293406f7340b9ffe99d5ec7c1d9", "ace6ac1d0f87d4072f05b5468a084a45b4eda970e4d26704f201e06d47ab2990", "b428f883d2b3fe1d052c630642cc6afddd07d5cd7873da948644508be3b9d4a7", "d5bf0e6ec8ba346a2cf35cb55bf4adfddbc6b6576fcc9e10863daa523e418dbb", "d7574e283f83c08501607586b3167728c58e8442947e027d2d4c7dcd6d82f453", "dc889c84241a857c263a2b1cd1121507db7d5b5f5e87e77147097230f374d10b", "f4748697b349f373002656bf32fede706a0e713d67bfdcf04edf39b1f61d46eb"]
|
]
|
||||||
mypy-extensions = ["090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d", "2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"]
|
black = [
|
||||||
packaging = ["28b924174df7a2fa32c1953825ff29c61e2f5e082343165438812f00d3a7fc47", "d9551545c6d761f3def1677baf08ab2a3ca17c56879e70fecba2fc4dde4ed108"]
|
{file = "black-19.10b0-py36-none-any.whl", hash = "sha256:1b30e59be925fafc1ee4565e5e08abef6b03fe455102883820fe5ee2e4734e0b"},
|
||||||
pluggy = ["0db4b7601aae1d35b4a033282da476845aa19185c1e6964b25cf324b5e4ec3e6", "fa5fa1622fa6dd5c030e9cad086fa19ef6a0cf6d7a2d12318e10cb49d6d68f34"]
|
{file = "black-19.10b0.tar.gz", hash = "sha256:c2edb73a08e9e0e6f65a0e6af18b059b8b1cdd5bef997d7a0b181df93dc81539"},
|
||||||
py = ["64f65755aee5b381cea27766a3a147c3f15b9b6b9ac88676de66ba2ae36793fa", "dc639b046a6e2cff5bbe40194ad65936d6ba360b52b3c3fe1d08a82dd50b5e53"]
|
]
|
||||||
pycodestyle = ["95a2219d12372f05704562a14ec30bc76b05a5b297b21a5dfe3f6fac3491ae56", "e40a936c9a450ad81df37f549d676d127b1b66000a6c500caa2b085bc0ca976c"]
|
click = [
|
||||||
pyflakes = ["17dbeb2e3f4d772725c777fabc446d5634d1038f234e77343108ce445ea69ce0", "d976835886f8c5b31d47970ed689944a0262b5f3afa00a5a7b4dc81e5449f8a2"]
|
{file = "click-7.1.2-py2.py3-none-any.whl", hash = "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc"},
|
||||||
pygls = ["3ee878a828b7bc0873a2ea44208d6846a91aa7dbbbdc052e7fe8cc689f6644fa", "780fd0c5ae95ad02ecaf70b071e43ff8ced8384b7d6bed19311a7b431d26fb88"]
|
{file = "click-7.1.2.tar.gz", hash = "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a"},
|
||||||
pyparsing = ["6f98a7b9397e206d78cc01df10131398f1c8b8510a2f4d97d9abd82e1aacdd80", "d9338df12903bbf5d65a0e4e87c2161968b10d2e489652bb47001d82a9b028b4"]
|
]
|
||||||
pytest = ["7e4800063ccfc306a53c461442526c5571e1462f61583506ce97e4da6a1d88c8", "ca563435f4941d0cb34767301c27bc65c510cb82e90b9ecf9cb52dc2c63caaa0"]
|
colorama = [
|
||||||
pytest-cov = ["cc6742d8bac45070217169f5f72ceee1e0e55b0221f54bcf24845972d3a47f2b", "cdbdef4f870408ebdbfeb44e63e07eb18bb4619fae852f6e760645fa36172626"]
|
{file = "colorama-0.4.1-py2.py3-none-any.whl", hash = "sha256:f8ac84de7840f5b9c4e3347b3c1eaa50f7e49c2b07596221daec5edaabbd7c48"},
|
||||||
pytest-datadir = ["1847ed0efe0bc54cac40ab3fba6d651c2f03d18dd01f2a582979604d32e7621e", "d3af1e738df87515ee509d6135780f25a15959766d9c2b2dbe02bf4fb979cb18"]
|
{file = "colorama-0.4.1.tar.gz", hash = "sha256:05eed71e2e327246ad6b38c540c4a3117230b19679b875190486ddd2d721422d"},
|
||||||
six = ["3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c", "d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73"]
|
]
|
||||||
toml = ["229f81c57791a41d65e399fc06bf0848bab550a9dfd5ed66df18ce5f05e73d5c", "235682dd292d5899d361a811df37e04a8828a5b1da3115886b73cf81ebc9100e", "f1db651f9657708513243e61e6cc67d101a39bad662eaa9b5546f789338e07a3"]
|
coverage = [
|
||||||
tox = ["0bc216b6a2e6afe764476b4a07edf2c1dab99ed82bb146a1130b2e828f5bff5e", "c4f6b319c20ba4913dbfe71ebfd14ff95d1853c4231493608182f66e566ecfe1"]
|
{file = "coverage-5.0-cp27-cp27m-macosx_10_12_x86_64.whl", hash = "sha256:9c871b006c878a890c6e44a5b2f3c6291335324b298c904dc0402ee92ee1f0be"},
|
||||||
typed-ast = ["1170afa46a3799e18b4c977777ce137bb53c7485379d9706af8a59f2ea1aa161", "18511a0b3e7922276346bcb47e2ef9f38fb90fd31cb9223eed42c85d1312344e", "262c247a82d005e43b5b7f69aff746370538e176131c32dda9cb0f324d27141e", "2b907eb046d049bcd9892e3076c7a6456c93a25bebfe554e931620c90e6a25b0", "354c16e5babd09f5cb0ee000d54cfa38401d8b8891eefa878ac772f827181a3c", "48e5b1e71f25cfdef98b013263a88d7145879fbb2d5185f2a0c79fa7ebbeae47", "4e0b70c6fc4d010f8107726af5fd37921b666f5b31d9331f0bd24ad9a088e631", "630968c5cdee51a11c05a30453f8cd65e0cc1d2ad0d9192819df9978984529f4", "66480f95b8167c9c5c5c87f32cf437d585937970f3fc24386f313a4c97b44e34", "71211d26ffd12d63a83e079ff258ac9d56a1376a25bc80b1cdcdf601b855b90b", "7954560051331d003b4e2b3eb822d9dd2e376fa4f6d98fee32f452f52dd6ebb2", "838997f4310012cf2e1ad3803bce2f3402e9ffb71ded61b5ee22617b3a7f6b6e", "95bd11af7eafc16e829af2d3df510cecfd4387f6453355188342c3e79a2ec87a", "bc6c7d3fa1325a0c6613512a093bc2a2a15aeec350451cbdf9e1d4bffe3e3233", "cc34a6f5b426748a507dd5d1de4c1978f2eb5626d51326e43280941206c209e1", "d755f03c1e4a51e9b24d899561fec4ccaf51f210d52abdf8c07ee2849b212a36", "d7c45933b1bdfaf9f36c579671fec15d25b06c8398f113dab64c18ed1adda01d", "d896919306dd0aa22d0132f62a1b78d11aaf4c9fc5b3410d3c666b818191630a", "fdc1c9bbf79510b76408840e009ed65958feba92a88833cdceecff93ae8fff66", "ffde2fbfad571af120fcbfbbc61c72469e72f550d676c3342492a9dfdefb8f12"]
|
{file = "coverage-5.0-cp27-cp27m-macosx_10_13_intel.whl", hash = "sha256:e5a675f6829c53c87d79117a8eb656cc4a5f8918185a32fc93ba09778e90f6db"},
|
||||||
typing = ["91dfe6f3f706ee8cc32d38edbbf304e9b7583fb37108fef38229617f8b3eba23", "c8cabb5ab8945cd2f54917be357d134db9cc1eb039e59d1606dc1e60cb1d9d36", "f38d83c5a7a7086543a0f649564d661859c5146a85775ab90c0d2f93ffaa9714"]
|
{file = "coverage-5.0-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:81326f1095c53111f8afc95da281e1414185f4a538609a77ca50bdfa39a6c207"},
|
||||||
typing-extensions = ["2ed632b30bb54fc3941c382decfd0ee4148f5c591651c9272473fea2c6397d95", "b1edbbf0652660e32ae780ac9433f4231e7339c7f9a8057d0f042fcbcea49b87", "d8179012ec2c620d3791ca6fe2bf7979d979acdbef1fca0bc56b37411db682ed"]
|
{file = "coverage-5.0-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:8873dc0d8f42142ea9f20c27bbdc485190fff93823c6795be661703369e5877d"},
|
||||||
virtualenv = ["11cb4608930d5fd3afb545ecf8db83fa50e1f96fc4fca80c94b07d2c83146589", "d257bb3773e48cac60e475a19b608996c73f4d333b3ba2e4e57d5ac6134e0136"]
|
{file = "coverage-5.0-cp27-cp27m-win32.whl", hash = "sha256:44b783b02db03c4777d8cf71bae19eadc171a6f2a96777d916b2c30a1eb3d070"},
|
||||||
wcwidth = ["3df37372226d6e63e1b1e1eda15c594bca98a22d33a23832a90998faa96bc65e", "f4ebe71925af7b40a864553f761ed559b43544f8f71746c2d756c7fe788ade7c"]
|
{file = "coverage-5.0-cp27-cp27m-win_amd64.whl", hash = "sha256:d52c1c2d7e856cecc05aa0526453cb14574f821b7f413cc279b9514750d795c1"},
|
||||||
yapf = ["02ace10a00fa2e36c7ebd1df2ead91dbfbd7989686dc4ccbdc549e95d19f5780", "6f94b6a176a7c114cfa6bad86d40f259bbe0f10cf2fa7f2f4b3596fc5802a41b"]
|
{file = "coverage-5.0-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:ba259f68250f16d2444cbbfaddaa0bb20e1560a4fdaad50bece25c199e6af864"},
|
||||||
zipp = ["3718b1cbcd963c7d4c5511a8240812904164b7f381b647143a89d3b98f9bcd8e", "f06903e9f1f43b12d371004b4ac7b06ab39a44adc747266928ae6debfa7b3335"]
|
{file = "coverage-5.0-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:475bf7c4252af0a56e1abba9606f1e54127cdf122063095c75ab04f6f99cf45e"},
|
||||||
|
{file = "coverage-5.0-cp35-cp35m-macosx_10_12_x86_64.whl", hash = "sha256:91f2491aeab9599956c45a77c5666d323efdec790bfe23fcceafcd91105d585a"},
|
||||||
|
{file = "coverage-5.0-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:979daa8655ae5a51e8e7a24e7d34e250ae8309fd9719490df92cbb2fe2b0422b"},
|
||||||
|
{file = "coverage-5.0-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:1a4b6b6a2a3a6612e6361130c2cc3dc4378d8c221752b96167ccbad94b47f3cd"},
|
||||||
|
{file = "coverage-5.0-cp35-cp35m-win32.whl", hash = "sha256:56b13000acf891f700f5067512b804d1ec8c301d627486c678b903859d07f798"},
|
||||||
|
{file = "coverage-5.0-cp35-cp35m-win_amd64.whl", hash = "sha256:81042a24f67b96e4287774014fa27220d8a4d91af1043389e4d73892efc89ac6"},
|
||||||
|
{file = "coverage-5.0-cp36-cp36m-macosx_10_13_x86_64.whl", hash = "sha256:fec32646b98baf4a22fdceb08703965bd16dea09051fbeb31a04b5b6e72b846c"},
|
||||||
|
{file = "coverage-5.0-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:7fe3e2fde2bf1d7ce25ebcd2d3de3650b8d60d9a73ce6dcef36e20191291613d"},
|
||||||
|
{file = "coverage-5.0-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:be1d89614c6b6c36d7578496dc8625123bda2ff44f224cf8b1c45b810ee7383f"},
|
||||||
|
{file = "coverage-5.0-cp36-cp36m-win32.whl", hash = "sha256:47c81ee687eafc2f1db7f03fbe99aab81330565ebc62fb3b61edfc2216a550c8"},
|
||||||
|
{file = "coverage-5.0-cp36-cp36m-win_amd64.whl", hash = "sha256:3be5338a2eb4ef03c57f20917e1d12a1fd10e3853fed060b6d6b677cb3745898"},
|
||||||
|
{file = "coverage-5.0-cp37-cp37m-macosx_10_13_x86_64.whl", hash = "sha256:79388ae29c896299b3567965dbcd93255f175c17c6c7bca38614d12718c47466"},
|
||||||
|
{file = "coverage-5.0-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:4a7f8e72b18f2aca288ff02255ce32cc830bc04d993efbc87abf6beddc9e56c0"},
|
||||||
|
{file = "coverage-5.0-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:d609a6d564ad3d327e9509846c2c47f170456344521462b469e5cb39e48ba31c"},
|
||||||
|
{file = "coverage-5.0-cp37-cp37m-win32.whl", hash = "sha256:50197163a22fd17f79086e087a787883b3ec9280a509807daf158dfc2a7ded02"},
|
||||||
|
{file = "coverage-5.0-cp37-cp37m-win_amd64.whl", hash = "sha256:b5ed7837b923d1d71c4f587ae1539ccd96bfd6be9788f507dbe94dab5febbb5d"},
|
||||||
|
{file = "coverage-5.0-cp38-cp38-macosx_10_13_x86_64.whl", hash = "sha256:c95bb147fab76f2ecde332d972d8f4138b8f2daee6c466af4ff3b4f29bd4c19e"},
|
||||||
|
{file = "coverage-5.0-cp38-cp38-manylinux1_i686.whl", hash = "sha256:0cd13a6e98c37b510a2d34c8281d5e1a226aaf9b65b7d770ef03c63169965351"},
|
||||||
|
{file = "coverage-5.0-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:88d2cbcb0a112f47eef71eb95460b6995da18e6f8ca50c264585abc2c473154b"},
|
||||||
|
{file = "coverage-5.0-cp38-cp38m-win32.whl", hash = "sha256:2ee55e6dba516ddf6f484aa83ccabbb0adf45a18892204c23486938d12258cde"},
|
||||||
|
{file = "coverage-5.0-cp38-cp38m-win_amd64.whl", hash = "sha256:a6d092545e5af53e960465f652e00efbf5357adad177b2630d63978d85e46a72"},
|
||||||
|
{file = "coverage-5.0-cp39-cp39m-win32.whl", hash = "sha256:79fd5d3d62238c4f583b75d48d53cdae759fe04d4fb18fe8b371d88ad2b6f8be"},
|
||||||
|
{file = "coverage-5.0-cp39-cp39m-win_amd64.whl", hash = "sha256:c1b030a79749aa8d1f1486885040114ee56933b15ccfc90049ba266e4aa2139f"},
|
||||||
|
{file = "coverage-5.0.tar.gz", hash = "sha256:e1bad043c12fb58e8c7d92b3d7f2f49977dcb80a08a6d1e7a5114a11bf819fca"},
|
||||||
|
]
|
||||||
|
entrypoints = [
|
||||||
|
{file = "entrypoints-0.3-py2.py3-none-any.whl", hash = "sha256:589f874b313739ad35be6e0cd7efde2a4e9b6fea91edcc34e58ecbb8dbe56d19"},
|
||||||
|
{file = "entrypoints-0.3.tar.gz", hash = "sha256:c70dd71abe5a8c85e55e12c19bd91ccfeec11a6e99044204511f9ed547d48451"},
|
||||||
|
]
|
||||||
|
filelock = [
|
||||||
|
{file = "filelock-3.0.12-py3-none-any.whl", hash = "sha256:929b7d63ec5b7d6b71b0fa5ac14e030b3f70b75747cef1b10da9b879fef15836"},
|
||||||
|
{file = "filelock-3.0.12.tar.gz", hash = "sha256:18d82244ee114f543149c66a6e0c14e9c4f8a1044b5cdaadd0f82159d6a6ff59"},
|
||||||
|
]
|
||||||
|
flake8 = [
|
||||||
|
{file = "flake8-3.7.8-py2.py3-none-any.whl", hash = "sha256:8e9dfa3cecb2400b3738a42c54c3043e821682b9c840b0448c0503f781130696"},
|
||||||
|
{file = "flake8-3.7.8.tar.gz", hash = "sha256:19241c1cbc971b9962473e4438a2ca19749a7dd002dd1a946eaba171b4114548"},
|
||||||
|
]
|
||||||
|
importlib-metadata = [
|
||||||
|
{file = "importlib_metadata-0.23-py2.py3-none-any.whl", hash = "sha256:d5f18a79777f3aa179c145737780282e27b508fc8fd688cb17c7a813e8bd39af"},
|
||||||
|
{file = "importlib_metadata-0.23.tar.gz", hash = "sha256:aa18d7378b00b40847790e7c27e11673d7fed219354109d0e7b9e5b25dc3ad26"},
|
||||||
|
]
|
||||||
|
isort = [
|
||||||
|
{file = "isort-4.3.21-py2.py3-none-any.whl", hash = "sha256:6e811fcb295968434526407adb8796944f1988c5b65e8139058f2014cbe100fd"},
|
||||||
|
{file = "isort-4.3.21.tar.gz", hash = "sha256:54da7e92468955c4fceacd0c86bd0ec997b0e1ee80d97f67c35a78b719dccab1"},
|
||||||
|
]
|
||||||
|
mccabe = [
|
||||||
|
{file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"},
|
||||||
|
{file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"},
|
||||||
|
]
|
||||||
|
more-itertools = [
|
||||||
|
{file = "more-itertools-7.2.0.tar.gz", hash = "sha256:409cd48d4db7052af495b09dec721011634af3753ae1ef92d2b32f73a745f832"},
|
||||||
|
{file = "more_itertools-7.2.0-py3-none-any.whl", hash = "sha256:92b8c4b06dac4f0611c0729b2f2ede52b2e1bac1ab48f089c7ddc12e26bb60c4"},
|
||||||
|
]
|
||||||
|
mypy = [
|
||||||
|
{file = "mypy-0.740-cp35-cp35m-macosx_10_6_x86_64.whl", hash = "sha256:9371290aa2cad5ad133e4cdc43892778efd13293406f7340b9ffe99d5ec7c1d9"},
|
||||||
|
{file = "mypy-0.740-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:b428f883d2b3fe1d052c630642cc6afddd07d5cd7873da948644508be3b9d4a7"},
|
||||||
|
{file = "mypy-0.740-cp35-cp35m-win_amd64.whl", hash = "sha256:ace6ac1d0f87d4072f05b5468a084a45b4eda970e4d26704f201e06d47ab2990"},
|
||||||
|
{file = "mypy-0.740-cp36-cp36m-macosx_10_6_x86_64.whl", hash = "sha256:d7574e283f83c08501607586b3167728c58e8442947e027d2d4c7dcd6d82f453"},
|
||||||
|
{file = "mypy-0.740-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:d5bf0e6ec8ba346a2cf35cb55bf4adfddbc6b6576fcc9e10863daa523e418dbb"},
|
||||||
|
{file = "mypy-0.740-cp36-cp36m-win_amd64.whl", hash = "sha256:1521c186a3d200c399bd5573c828ea2db1362af7209b2adb1bb8532cea2fb36f"},
|
||||||
|
{file = "mypy-0.740-cp37-cp37m-macosx_10_6_x86_64.whl", hash = "sha256:dc889c84241a857c263a2b1cd1121507db7d5b5f5e87e77147097230f374d10b"},
|
||||||
|
{file = "mypy-0.740-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:6ed3b9b3fdc7193ea7aca6f3c20549b377a56f28769783a8f27191903a54170f"},
|
||||||
|
{file = "mypy-0.740-cp37-cp37m-win_amd64.whl", hash = "sha256:31a046ab040a84a0fc38bc93694876398e62bc9f35eca8ccbf6418b7297f4c00"},
|
||||||
|
{file = "mypy-0.740-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:672e418425d957e276c291930a3921b4a6413204f53fe7c37cad7bc57b9a3391"},
|
||||||
|
{file = "mypy-0.740-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:3b1a411909c84b2ae9b8283b58b48541654b918e8513c20a400bb946aa9111ae"},
|
||||||
|
{file = "mypy-0.740-cp38-cp38-win_amd64.whl", hash = "sha256:540c9caa57a22d0d5d3c69047cc9dd0094d49782603eb03069821b41f9e970e9"},
|
||||||
|
{file = "mypy-0.740-py3-none-any.whl", hash = "sha256:f4748697b349f373002656bf32fede706a0e713d67bfdcf04edf39b1f61d46eb"},
|
||||||
|
{file = "mypy-0.740.tar.gz", hash = "sha256:48c8bc99380575deb39f5d3400ebb6a8a1cb5cc669bbba4d3bb30f904e0a0e7d"},
|
||||||
|
]
|
||||||
|
mypy-extensions = [
|
||||||
|
{file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"},
|
||||||
|
{file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"},
|
||||||
|
]
|
||||||
|
packaging = [
|
||||||
|
{file = "packaging-19.2-py2.py3-none-any.whl", hash = "sha256:d9551545c6d761f3def1677baf08ab2a3ca17c56879e70fecba2fc4dde4ed108"},
|
||||||
|
{file = "packaging-19.2.tar.gz", hash = "sha256:28b924174df7a2fa32c1953825ff29c61e2f5e082343165438812f00d3a7fc47"},
|
||||||
|
]
|
||||||
|
pathspec = [
|
||||||
|
{file = "pathspec-0.8.0-py2.py3-none-any.whl", hash = "sha256:7d91249d21749788d07a2d0f94147accd8f845507400749ea19c1ec9054a12b0"},
|
||||||
|
{file = "pathspec-0.8.0.tar.gz", hash = "sha256:da45173eb3a6f2a5a487efba21f050af2b41948be6ab52b6a1e3ff22bb8b7061"},
|
||||||
|
]
|
||||||
|
pluggy = [
|
||||||
|
{file = "pluggy-0.13.0-py2.py3-none-any.whl", hash = "sha256:0db4b7601aae1d35b4a033282da476845aa19185c1e6964b25cf324b5e4ec3e6"},
|
||||||
|
{file = "pluggy-0.13.0.tar.gz", hash = "sha256:fa5fa1622fa6dd5c030e9cad086fa19ef6a0cf6d7a2d12318e10cb49d6d68f34"},
|
||||||
|
]
|
||||||
|
py = [
|
||||||
|
{file = "py-1.8.0-py2.py3-none-any.whl", hash = "sha256:64f65755aee5b381cea27766a3a147c3f15b9b6b9ac88676de66ba2ae36793fa"},
|
||||||
|
{file = "py-1.8.0.tar.gz", hash = "sha256:dc639b046a6e2cff5bbe40194ad65936d6ba360b52b3c3fe1d08a82dd50b5e53"},
|
||||||
|
]
|
||||||
|
pycodestyle = [
|
||||||
|
{file = "pycodestyle-2.5.0-py2.py3-none-any.whl", hash = "sha256:95a2219d12372f05704562a14ec30bc76b05a5b297b21a5dfe3f6fac3491ae56"},
|
||||||
|
{file = "pycodestyle-2.5.0.tar.gz", hash = "sha256:e40a936c9a450ad81df37f549d676d127b1b66000a6c500caa2b085bc0ca976c"},
|
||||||
|
]
|
||||||
|
pyflakes = [
|
||||||
|
{file = "pyflakes-2.1.1-py2.py3-none-any.whl", hash = "sha256:17dbeb2e3f4d772725c777fabc446d5634d1038f234e77343108ce445ea69ce0"},
|
||||||
|
{file = "pyflakes-2.1.1.tar.gz", hash = "sha256:d976835886f8c5b31d47970ed689944a0262b5f3afa00a5a7b4dc81e5449f8a2"},
|
||||||
|
]
|
||||||
|
pygls = [
|
||||||
|
{file = "pygls-0.8.1-py3-none-any.whl", hash = "sha256:3ee878a828b7bc0873a2ea44208d6846a91aa7dbbbdc052e7fe8cc689f6644fa"},
|
||||||
|
{file = "pygls-0.8.1.tar.gz", hash = "sha256:780fd0c5ae95ad02ecaf70b071e43ff8ced8384b7d6bed19311a7b431d26fb88"},
|
||||||
|
]
|
||||||
|
pyparsing = [
|
||||||
|
{file = "pyparsing-2.4.2-py2.py3-none-any.whl", hash = "sha256:d9338df12903bbf5d65a0e4e87c2161968b10d2e489652bb47001d82a9b028b4"},
|
||||||
|
{file = "pyparsing-2.4.2.tar.gz", hash = "sha256:6f98a7b9397e206d78cc01df10131398f1c8b8510a2f4d97d9abd82e1aacdd80"},
|
||||||
|
]
|
||||||
|
pytest = [
|
||||||
|
{file = "pytest-5.2.1-py3-none-any.whl", hash = "sha256:7e4800063ccfc306a53c461442526c5571e1462f61583506ce97e4da6a1d88c8"},
|
||||||
|
{file = "pytest-5.2.1.tar.gz", hash = "sha256:ca563435f4941d0cb34767301c27bc65c510cb82e90b9ecf9cb52dc2c63caaa0"},
|
||||||
|
]
|
||||||
|
pytest-cov = [
|
||||||
|
{file = "pytest-cov-2.8.1.tar.gz", hash = "sha256:cc6742d8bac45070217169f5f72ceee1e0e55b0221f54bcf24845972d3a47f2b"},
|
||||||
|
{file = "pytest_cov-2.8.1-py2.py3-none-any.whl", hash = "sha256:cdbdef4f870408ebdbfeb44e63e07eb18bb4619fae852f6e760645fa36172626"},
|
||||||
|
]
|
||||||
|
pytest-datadir = [
|
||||||
|
{file = "pytest-datadir-1.3.1.tar.gz", hash = "sha256:d3af1e738df87515ee509d6135780f25a15959766d9c2b2dbe02bf4fb979cb18"},
|
||||||
|
{file = "pytest_datadir-1.3.1-py2.py3-none-any.whl", hash = "sha256:1847ed0efe0bc54cac40ab3fba6d651c2f03d18dd01f2a582979604d32e7621e"},
|
||||||
|
]
|
||||||
|
regex = [
|
||||||
|
{file = "regex-2020.7.14-cp27-cp27m-win32.whl", hash = "sha256:e46d13f38cfcbb79bfdb2964b0fe12561fe633caf964a77a5f8d4e45fe5d2ef7"},
|
||||||
|
{file = "regex-2020.7.14-cp27-cp27m-win_amd64.whl", hash = "sha256:6961548bba529cac7c07af2fd4d527c5b91bb8fe18995fed6044ac22b3d14644"},
|
||||||
|
{file = "regex-2020.7.14-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:c50a724d136ec10d920661f1442e4a8b010a4fe5aebd65e0c2241ea41dbe93dc"},
|
||||||
|
{file = "regex-2020.7.14-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:8a51f2c6d1f884e98846a0a9021ff6861bdb98457879f412fdc2b42d14494067"},
|
||||||
|
{file = "regex-2020.7.14-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:9c568495e35599625f7b999774e29e8d6b01a6fb684d77dee1f56d41b11b40cd"},
|
||||||
|
{file = "regex-2020.7.14-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:51178c738d559a2d1071ce0b0f56e57eb315bcf8f7d4cf127674b533e3101f88"},
|
||||||
|
{file = "regex-2020.7.14-cp36-cp36m-win32.whl", hash = "sha256:9eddaafb3c48e0900690c1727fba226c4804b8e6127ea409689c3bb492d06de4"},
|
||||||
|
{file = "regex-2020.7.14-cp36-cp36m-win_amd64.whl", hash = "sha256:14a53646369157baa0499513f96091eb70382eb50b2c82393d17d7ec81b7b85f"},
|
||||||
|
{file = "regex-2020.7.14-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:1269fef3167bb52631ad4fa7dd27bf635d5a0790b8e6222065d42e91bede4162"},
|
||||||
|
{file = "regex-2020.7.14-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:d0a5095d52b90ff38592bbdc2644f17c6d495762edf47d876049cfd2968fbccf"},
|
||||||
|
{file = "regex-2020.7.14-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:4c037fd14c5f4e308b8370b447b469ca10e69427966527edcab07f52d88388f7"},
|
||||||
|
{file = "regex-2020.7.14-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:bc3d98f621898b4a9bc7fecc00513eec8f40b5b83913d74ccb445f037d58cd89"},
|
||||||
|
{file = "regex-2020.7.14-cp37-cp37m-win32.whl", hash = "sha256:46bac5ca10fb748d6c55843a931855e2727a7a22584f302dd9bb1506e69f83f6"},
|
||||||
|
{file = "regex-2020.7.14-cp37-cp37m-win_amd64.whl", hash = "sha256:0dc64ee3f33cd7899f79a8d788abfbec168410be356ed9bd30bbd3f0a23a7204"},
|
||||||
|
{file = "regex-2020.7.14-cp38-cp38-manylinux1_i686.whl", hash = "sha256:5ea81ea3dbd6767873c611687141ec7b06ed8bab43f68fad5b7be184a920dc99"},
|
||||||
|
{file = "regex-2020.7.14-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:bbb332d45b32df41200380fff14712cb6093b61bd142272a10b16778c418e98e"},
|
||||||
|
{file = "regex-2020.7.14-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:c11d6033115dc4887c456565303f540c44197f4fc1a2bfb192224a301534888e"},
|
||||||
|
{file = "regex-2020.7.14-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:75aaa27aa521a182824d89e5ab0a1d16ca207318a6b65042b046053cfc8ed07a"},
|
||||||
|
{file = "regex-2020.7.14-cp38-cp38-win32.whl", hash = "sha256:d6cff2276e502b86a25fd10c2a96973fdb45c7a977dca2138d661417f3728341"},
|
||||||
|
{file = "regex-2020.7.14-cp38-cp38-win_amd64.whl", hash = "sha256:7a2dd66d2d4df34fa82c9dc85657c5e019b87932019947faece7983f2089a840"},
|
||||||
|
{file = "regex-2020.7.14.tar.gz", hash = "sha256:3a3af27a8d23143c49a3420efe5b3f8cf1a48c6fc8bc6856b03f638abc1833bb"},
|
||||||
|
]
|
||||||
|
six = [
|
||||||
|
{file = "six-1.12.0-py2.py3-none-any.whl", hash = "sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c"},
|
||||||
|
{file = "six-1.12.0.tar.gz", hash = "sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73"},
|
||||||
|
]
|
||||||
|
toml = [
|
||||||
|
{file = "toml-0.10.0-py2.7.egg", hash = "sha256:f1db651f9657708513243e61e6cc67d101a39bad662eaa9b5546f789338e07a3"},
|
||||||
|
{file = "toml-0.10.0-py2.py3-none-any.whl", hash = "sha256:235682dd292d5899d361a811df37e04a8828a5b1da3115886b73cf81ebc9100e"},
|
||||||
|
{file = "toml-0.10.0.tar.gz", hash = "sha256:229f81c57791a41d65e399fc06bf0848bab550a9dfd5ed66df18ce5f05e73d5c"},
|
||||||
|
]
|
||||||
|
tox = [
|
||||||
|
{file = "tox-3.14.0-py2.py3-none-any.whl", hash = "sha256:0bc216b6a2e6afe764476b4a07edf2c1dab99ed82bb146a1130b2e828f5bff5e"},
|
||||||
|
{file = "tox-3.14.0.tar.gz", hash = "sha256:c4f6b319c20ba4913dbfe71ebfd14ff95d1853c4231493608182f66e566ecfe1"},
|
||||||
|
]
|
||||||
|
typed-ast = [
|
||||||
|
{file = "typed_ast-1.4.0-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:262c247a82d005e43b5b7f69aff746370538e176131c32dda9cb0f324d27141e"},
|
||||||
|
{file = "typed_ast-1.4.0-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:71211d26ffd12d63a83e079ff258ac9d56a1376a25bc80b1cdcdf601b855b90b"},
|
||||||
|
{file = "typed_ast-1.4.0-cp35-cp35m-win32.whl", hash = "sha256:630968c5cdee51a11c05a30453f8cd65e0cc1d2ad0d9192819df9978984529f4"},
|
||||||
|
{file = "typed_ast-1.4.0-cp35-cp35m-win_amd64.whl", hash = "sha256:ffde2fbfad571af120fcbfbbc61c72469e72f550d676c3342492a9dfdefb8f12"},
|
||||||
|
{file = "typed_ast-1.4.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:4e0b70c6fc4d010f8107726af5fd37921b666f5b31d9331f0bd24ad9a088e631"},
|
||||||
|
{file = "typed_ast-1.4.0-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:bc6c7d3fa1325a0c6613512a093bc2a2a15aeec350451cbdf9e1d4bffe3e3233"},
|
||||||
|
{file = "typed_ast-1.4.0-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:cc34a6f5b426748a507dd5d1de4c1978f2eb5626d51326e43280941206c209e1"},
|
||||||
|
{file = "typed_ast-1.4.0-cp36-cp36m-win32.whl", hash = "sha256:d896919306dd0aa22d0132f62a1b78d11aaf4c9fc5b3410d3c666b818191630a"},
|
||||||
|
{file = "typed_ast-1.4.0-cp36-cp36m-win_amd64.whl", hash = "sha256:354c16e5babd09f5cb0ee000d54cfa38401d8b8891eefa878ac772f827181a3c"},
|
||||||
|
{file = "typed_ast-1.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:95bd11af7eafc16e829af2d3df510cecfd4387f6453355188342c3e79a2ec87a"},
|
||||||
|
{file = "typed_ast-1.4.0-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:18511a0b3e7922276346bcb47e2ef9f38fb90fd31cb9223eed42c85d1312344e"},
|
||||||
|
{file = "typed_ast-1.4.0-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:d7c45933b1bdfaf9f36c579671fec15d25b06c8398f113dab64c18ed1adda01d"},
|
||||||
|
{file = "typed_ast-1.4.0-cp37-cp37m-win32.whl", hash = "sha256:d755f03c1e4a51e9b24d899561fec4ccaf51f210d52abdf8c07ee2849b212a36"},
|
||||||
|
{file = "typed_ast-1.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:2b907eb046d049bcd9892e3076c7a6456c93a25bebfe554e931620c90e6a25b0"},
|
||||||
|
{file = "typed_ast-1.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:fdc1c9bbf79510b76408840e009ed65958feba92a88833cdceecff93ae8fff66"},
|
||||||
|
{file = "typed_ast-1.4.0-cp38-cp38-manylinux1_i686.whl", hash = "sha256:7954560051331d003b4e2b3eb822d9dd2e376fa4f6d98fee32f452f52dd6ebb2"},
|
||||||
|
{file = "typed_ast-1.4.0-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:48e5b1e71f25cfdef98b013263a88d7145879fbb2d5185f2a0c79fa7ebbeae47"},
|
||||||
|
{file = "typed_ast-1.4.0-cp38-cp38-win32.whl", hash = "sha256:1170afa46a3799e18b4c977777ce137bb53c7485379d9706af8a59f2ea1aa161"},
|
||||||
|
{file = "typed_ast-1.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:838997f4310012cf2e1ad3803bce2f3402e9ffb71ded61b5ee22617b3a7f6b6e"},
|
||||||
|
{file = "typed_ast-1.4.0.tar.gz", hash = "sha256:66480f95b8167c9c5c5c87f32cf437d585937970f3fc24386f313a4c97b44e34"},
|
||||||
|
]
|
||||||
|
typing = [
|
||||||
|
{file = "typing-3.7.4.1-py2-none-any.whl", hash = "sha256:c8cabb5ab8945cd2f54917be357d134db9cc1eb039e59d1606dc1e60cb1d9d36"},
|
||||||
|
{file = "typing-3.7.4.1-py3-none-any.whl", hash = "sha256:f38d83c5a7a7086543a0f649564d661859c5146a85775ab90c0d2f93ffaa9714"},
|
||||||
|
{file = "typing-3.7.4.1.tar.gz", hash = "sha256:91dfe6f3f706ee8cc32d38edbbf304e9b7583fb37108fef38229617f8b3eba23"},
|
||||||
|
]
|
||||||
|
typing-extensions = [
|
||||||
|
{file = "typing_extensions-3.7.4-py2-none-any.whl", hash = "sha256:b1edbbf0652660e32ae780ac9433f4231e7339c7f9a8057d0f042fcbcea49b87"},
|
||||||
|
{file = "typing_extensions-3.7.4-py3-none-any.whl", hash = "sha256:d8179012ec2c620d3791ca6fe2bf7979d979acdbef1fca0bc56b37411db682ed"},
|
||||||
|
{file = "typing_extensions-3.7.4.tar.gz", hash = "sha256:2ed632b30bb54fc3941c382decfd0ee4148f5c591651c9272473fea2c6397d95"},
|
||||||
|
]
|
||||||
|
virtualenv = [
|
||||||
|
{file = "virtualenv-16.7.7-py2.py3-none-any.whl", hash = "sha256:11cb4608930d5fd3afb545ecf8db83fa50e1f96fc4fca80c94b07d2c83146589"},
|
||||||
|
{file = "virtualenv-16.7.7.tar.gz", hash = "sha256:d257bb3773e48cac60e475a19b608996c73f4d333b3ba2e4e57d5ac6134e0136"},
|
||||||
|
]
|
||||||
|
wcwidth = [
|
||||||
|
{file = "wcwidth-0.1.7-py2.py3-none-any.whl", hash = "sha256:f4ebe71925af7b40a864553f761ed559b43544f8f71746c2d756c7fe788ade7c"},
|
||||||
|
{file = "wcwidth-0.1.7.tar.gz", hash = "sha256:3df37372226d6e63e1b1e1eda15c594bca98a22d33a23832a90998faa96bc65e"},
|
||||||
|
]
|
||||||
|
zipp = [
|
||||||
|
{file = "zipp-0.6.0-py2.py3-none-any.whl", hash = "sha256:f06903e9f1f43b12d371004b4ac7b06ab39a44adc747266928ae6debfa7b3335"},
|
||||||
|
{file = "zipp-0.6.0.tar.gz", hash = "sha256:3718b1cbcd963c7d4c5511a8240812904164b7f381b647143a89d3b98f9bcd8e"},
|
||||||
|
]
|
||||||
|
|||||||
@@ -26,11 +26,11 @@ pyparsing = "^2.4"
|
|||||||
flake8 = "^3.7"
|
flake8 = "^3.7"
|
||||||
mypy = "^0.740.0"
|
mypy = "^0.740.0"
|
||||||
pytest = "^5.2"
|
pytest = "^5.2"
|
||||||
yapf = "^0.28.0"
|
|
||||||
pytest-datadir = "^1.3"
|
pytest-datadir = "^1.3"
|
||||||
tox = "^3.14"
|
tox = "^3.14"
|
||||||
isort = "^4.3"
|
isort = "^4.3"
|
||||||
pytest-cov = "^2.8"
|
pytest-cov = "^2.8"
|
||||||
|
black = "^19.10b0"
|
||||||
|
|
||||||
[tool.poetry.scripts]
|
[tool.poetry.scripts]
|
||||||
cmake-format = "cmake_language_server.formatter:main"
|
cmake-format = "cmake_language_server.formatter:main"
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
__version__ = '0.1.2'
|
__version__ = "0.1.2"
|
||||||
|
|||||||
@@ -12,10 +12,10 @@ logger = logging.getLogger(__name__)
|
|||||||
|
|
||||||
def _tidy_doc(doc: str) -> str:
|
def _tidy_doc(doc: str) -> str:
|
||||||
doc = doc.strip()
|
doc = doc.strip()
|
||||||
doc = re.sub(r':.+?:`(.+?)`', r'\1', doc)
|
doc = re.sub(r":.+?:`(.+?)`", r"\1", doc)
|
||||||
doc = re.sub(r'``([^`]+)``', r'`\1`', doc)
|
doc = re.sub(r"``([^`]+)``", r"`\1`", doc)
|
||||||
doc = doc.replace('\n', ' ')
|
doc = doc.replace("\n", " ")
|
||||||
doc = doc.replace('. ', '. ')
|
doc = doc.replace(". ", ". ")
|
||||||
return doc
|
return doc
|
||||||
|
|
||||||
|
|
||||||
@@ -49,78 +49,82 @@ class API(object):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
self.query_json.parent.mkdir(parents=True, exist_ok=True)
|
self.query_json.parent.mkdir(parents=True, exist_ok=True)
|
||||||
with self.query_json.open('w') as fp:
|
with self.query_json.open("w") as fp:
|
||||||
fp.write('''\
|
fp.write(
|
||||||
|
"""\
|
||||||
{
|
{
|
||||||
"requests": [
|
"requests": [
|
||||||
{"kind": "codemodel", "version": 2},
|
{"kind": "codemodel", "version": 2},
|
||||||
{"kind": "cache", "version": 2},
|
{"kind": "cache", "version": 2},
|
||||||
{"kind": "cmakeFiles", "version": 1}
|
{"kind": "cmakeFiles", "version": 1}
|
||||||
]
|
]
|
||||||
}''')
|
}"""
|
||||||
|
)
|
||||||
|
|
||||||
proc = subprocess.run([self._cmake, str(self._build)],
|
proc = subprocess.run(
|
||||||
stdout=subprocess.PIPE,
|
[self._cmake, str(self._build)],
|
||||||
stderr=subprocess.PIPE,
|
stdout=subprocess.PIPE,
|
||||||
encoding='utf-8',
|
stderr=subprocess.PIPE,
|
||||||
universal_newlines=True)
|
encoding="utf-8",
|
||||||
|
universal_newlines=True,
|
||||||
|
)
|
||||||
self.query_json.unlink()
|
self.query_json.unlink()
|
||||||
self.query_json.parent.rmdir()
|
self.query_json.parent.rmdir()
|
||||||
if proc.returncode != 0:
|
if proc.returncode != 0:
|
||||||
logging.error(
|
logging.error(f"cmake exited with {proc.returncode}: {proc.stderr}")
|
||||||
f'cmake exited with {proc.returncode}: {proc.stderr}')
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def read_reply(self) -> bool:
|
def read_reply(self) -> bool:
|
||||||
reply = self._build / '.cmake' / 'api' / 'v1' / 'reply'
|
reply = self._build / ".cmake" / "api" / "v1" / "reply"
|
||||||
indices = sorted(reply.glob('index-*.json'))
|
indices = sorted(reply.glob("index-*.json"))
|
||||||
if not indices:
|
if not indices:
|
||||||
logger.error('no reply')
|
logger.error("no reply")
|
||||||
return False
|
return False
|
||||||
with indices[-1].open() as fp:
|
with indices[-1].open() as fp:
|
||||||
index = json.load(fp)
|
index = json.load(fp)
|
||||||
try:
|
try:
|
||||||
responses = index['reply'][f'client-{self._uuid}']['query.json'][
|
responses = index["reply"][f"client-{self._uuid}"]["query.json"][
|
||||||
'responses']
|
"responses"
|
||||||
|
]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
logger.error('no rensponse')
|
logger.error("no rensponse")
|
||||||
return False
|
return False
|
||||||
for response in responses:
|
for response in responses:
|
||||||
if response['kind'] == 'codemodel':
|
if response["kind"] == "codemodel":
|
||||||
self._read_codemodel(reply / response['jsonFile'])
|
self._read_codemodel(reply / response["jsonFile"])
|
||||||
elif response['kind'] == 'cache':
|
elif response["kind"] == "cache":
|
||||||
self._read_cache(reply / response['jsonFile'])
|
self._read_cache(reply / response["jsonFile"])
|
||||||
elif response['kind'] == 'cmakeFiles':
|
elif response["kind"] == "cmakeFiles":
|
||||||
self._read_cmake_files(reply / response['jsonFile'])
|
self._read_cmake_files(reply / response["jsonFile"])
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def _read_codemodel(self, codemodelpath: Path):
|
def _read_codemodel(self, codemodelpath: Path):
|
||||||
with (codemodelpath).open() as fp:
|
with (codemodelpath).open() as fp:
|
||||||
codemodel = json.load(fp)
|
codemodel = json.load(fp)
|
||||||
config = codemodel['configurations'][0]
|
config = codemodel["configurations"][0]
|
||||||
self._targets[:] = [x['name'] for x in config['targets']]
|
self._targets[:] = [x["name"] for x in config["targets"]]
|
||||||
|
|
||||||
def _read_cache(self, cachepath: Path):
|
def _read_cache(self, cachepath: Path):
|
||||||
with cachepath.open() as fp:
|
with cachepath.open() as fp:
|
||||||
cache = json.load(fp)
|
cache = json.load(fp)
|
||||||
self._cached_variables.clear()
|
self._cached_variables.clear()
|
||||||
for entry in cache['entries']:
|
for entry in cache["entries"]:
|
||||||
name = entry['name']
|
name = entry["name"]
|
||||||
value = self._truncate_variable(entry['value'])
|
value = self._truncate_variable(entry["value"])
|
||||||
properties = {x['name']: x['value'] for x in entry['properties']}
|
properties = {x["name"]: x["value"] for x in entry["properties"]}
|
||||||
helpstring = properties.get('HELPSTRING', '')
|
helpstring = properties.get("HELPSTRING", "")
|
||||||
doc = []
|
doc = []
|
||||||
if helpstring:
|
if helpstring:
|
||||||
doc.append(helpstring)
|
doc.append(helpstring)
|
||||||
if value:
|
if value:
|
||||||
doc.append(f'`{value}`')
|
doc.append(f"`{value}`")
|
||||||
self._cached_variables[name] = '\n\n'.join(doc)
|
self._cached_variables[name] = "\n\n".join(doc)
|
||||||
|
|
||||||
def _read_cmake_files(self, jsonpath: Path):
|
def _read_cmake_files(self, jsonpath: Path):
|
||||||
'''inspect generated list files'''
|
"""inspect generated list files"""
|
||||||
|
|
||||||
if not self._builtin_variables or self._generated_list_parsed:
|
if not self._builtin_variables or self._generated_list_parsed:
|
||||||
return
|
return
|
||||||
@@ -130,44 +134,46 @@ class API(object):
|
|||||||
|
|
||||||
# inspect generated list files
|
# inspect generated list files
|
||||||
with tempfile.TemporaryDirectory() as tmpdirname:
|
with tempfile.TemporaryDirectory() as tmpdirname:
|
||||||
tmplist = Path(tmpdirname) / 'dump.cmake'
|
tmplist = Path(tmpdirname) / "dump.cmake"
|
||||||
with tmplist.open('w') as fp:
|
with tmplist.open("w") as fp:
|
||||||
for listfile in cmake_files['inputs']:
|
for listfile in cmake_files["inputs"]:
|
||||||
if not listfile.get('isGenerated', False):
|
if not listfile.get("isGenerated", False):
|
||||||
continue
|
continue
|
||||||
path = listfile['path']
|
path = listfile["path"]
|
||||||
fp.write(f'include({path})\n')
|
fp.write(f"include({path})\n")
|
||||||
fp.write('''
|
fp.write(
|
||||||
|
"""
|
||||||
get_cmake_property(variables VARIABLES)
|
get_cmake_property(variables VARIABLES)
|
||||||
foreach (variable ${variables})
|
foreach (variable ${variables})
|
||||||
message("${variable}=${${variable}}")
|
message("${variable}=${${variable}}")
|
||||||
endforeach()
|
endforeach()
|
||||||
''')
|
"""
|
||||||
|
)
|
||||||
p = subprocess.run(
|
p = subprocess.run(
|
||||||
[self._cmake, '-P', str(tmplist)],
|
[self._cmake, "-P", str(tmplist)],
|
||||||
stdout=subprocess.PIPE,
|
stdout=subprocess.PIPE,
|
||||||
stderr=subprocess.PIPE,
|
stderr=subprocess.PIPE,
|
||||||
cwd=cmake_files['paths']['source'],
|
cwd=cmake_files["paths"]["source"],
|
||||||
encoding='utf-8',
|
encoding="utf-8",
|
||||||
universal_newlines=True)
|
universal_newlines=True,
|
||||||
|
)
|
||||||
if p.returncode != 0:
|
if p.returncode != 0:
|
||||||
return
|
return
|
||||||
|
|
||||||
for line in p.stderr.split('\n'):
|
for line in p.stderr.split("\n"):
|
||||||
line = line.strip()
|
line = line.strip()
|
||||||
if not line:
|
if not line:
|
||||||
continue
|
continue
|
||||||
k, v = line.split('=', 1)
|
k, v = line.split("=", 1)
|
||||||
if k.startswith('CMAKE_ARG'):
|
if k.startswith("CMAKE_ARG"):
|
||||||
continue
|
continue
|
||||||
v = self._truncate_variable(v)
|
v = self._truncate_variable(v)
|
||||||
if k in self._builtin_variables:
|
if k in self._builtin_variables:
|
||||||
self._builtin_variables[k] += f'\n\n`{v}`'
|
self._builtin_variables[k] += f"\n\n`{v}`"
|
||||||
else:
|
else:
|
||||||
for pattern, doc in self._builtin_variable_template.items(
|
for pattern, doc in self._builtin_variable_template.items():
|
||||||
):
|
|
||||||
if pattern.fullmatch(k):
|
if pattern.fullmatch(k):
|
||||||
self._builtin_variables[k] = f'{doc}\n\n`{v}`'
|
self._builtin_variables[k] = f"{doc}\n\n`{v}`"
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
# ignore variable with no document
|
# ignore variable with no document
|
||||||
@@ -177,12 +183,19 @@ endforeach()
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def query_json(self) -> Path:
|
def query_json(self) -> Path:
|
||||||
return (self._build / '.cmake' / 'api' / 'v1' / 'query' /
|
return (
|
||||||
f'client-{self._uuid}' / 'query.json')
|
self._build
|
||||||
|
/ ".cmake"
|
||||||
|
/ "api"
|
||||||
|
/ "v1"
|
||||||
|
/ "query"
|
||||||
|
/ f"client-{self._uuid}"
|
||||||
|
/ "query.json"
|
||||||
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def cmake_cache(self) -> Path:
|
def cmake_cache(self) -> Path:
|
||||||
return self._build / 'CMakeCache.txt'
|
return self._build / "CMakeCache.txt"
|
||||||
|
|
||||||
def parse_doc(self) -> None:
|
def parse_doc(self) -> None:
|
||||||
self._parse_commands()
|
self._parse_commands()
|
||||||
@@ -190,81 +203,95 @@ endforeach()
|
|||||||
self._parse_modules()
|
self._parse_modules()
|
||||||
|
|
||||||
def _parse_commands(self) -> None:
|
def _parse_commands(self) -> None:
|
||||||
p = subprocess.run([self._cmake, '--help-commands'],
|
p = subprocess.run(
|
||||||
stdout=subprocess.PIPE,
|
[self._cmake, "--help-commands"],
|
||||||
encoding='utf-8',
|
stdout=subprocess.PIPE,
|
||||||
universal_newlines=True)
|
encoding="utf-8",
|
||||||
|
universal_newlines=True,
|
||||||
|
)
|
||||||
|
|
||||||
if p.returncode != 0:
|
if p.returncode != 0:
|
||||||
return
|
return
|
||||||
|
|
||||||
matches = re.finditer(
|
matches = re.finditer(
|
||||||
r'''
|
r"""
|
||||||
(?P<command>.+)\n
|
(?P<command>.+)\n
|
||||||
-+\n+?
|
-+\n+?
|
||||||
[\s\S]*?
|
[\s\S]*?
|
||||||
(?P<signature>(?P=command)\s*\([^)]*\))
|
(?P<signature>(?P=command)\s*\([^)]*\))
|
||||||
''', p.stdout, re.VERBOSE)
|
""",
|
||||||
|
p.stdout,
|
||||||
|
re.VERBOSE,
|
||||||
|
)
|
||||||
self._builtin_commands.clear()
|
self._builtin_commands.clear()
|
||||||
for match in matches:
|
for match in matches:
|
||||||
command = match.group('command')
|
command = match.group("command")
|
||||||
signature = match.group('signature')
|
signature = match.group("signature")
|
||||||
signature = re.sub(r'^ ', r'', signature, flags=re.MULTILINE)
|
signature = re.sub(r"^ ", r"", signature, flags=re.MULTILINE)
|
||||||
self._builtin_commands[
|
self._builtin_commands[command] = "```cmake\n" + signature + "\n```"
|
||||||
command] = '```cmake\n' + signature + '\n```'
|
|
||||||
|
|
||||||
def _parse_variables(self) -> None:
|
def _parse_variables(self) -> None:
|
||||||
p = subprocess.run([self._cmake, '--help-variables'],
|
p = subprocess.run(
|
||||||
stdout=subprocess.PIPE,
|
[self._cmake, "--help-variables"],
|
||||||
encoding='utf-8',
|
stdout=subprocess.PIPE,
|
||||||
universal_newlines=True)
|
encoding="utf-8",
|
||||||
|
universal_newlines=True,
|
||||||
|
)
|
||||||
|
|
||||||
if p.returncode != 0:
|
if p.returncode != 0:
|
||||||
return
|
return
|
||||||
|
|
||||||
matches = re.finditer(
|
matches = re.finditer(
|
||||||
r'''
|
r"""
|
||||||
(?P<variable>.+)\n
|
(?P<variable>.+)\n
|
||||||
-+\n\n
|
-+\n\n
|
||||||
(?P<doc>[\s\S]+?)(?:\n\n|$)
|
(?P<doc>[\s\S]+?)(?:\n\n|$)
|
||||||
''', p.stdout, re.VERBOSE)
|
""",
|
||||||
|
p.stdout,
|
||||||
|
re.VERBOSE,
|
||||||
|
)
|
||||||
self._builtin_variables.clear()
|
self._builtin_variables.clear()
|
||||||
for match in matches:
|
for match in matches:
|
||||||
variable = match.group('variable')
|
variable = match.group("variable")
|
||||||
doc = _tidy_doc(match.group('doc'))
|
doc = _tidy_doc(match.group("doc"))
|
||||||
if variable == 'CMAKE_MATCH_<n>':
|
if variable == "CMAKE_MATCH_<n>":
|
||||||
for i in range(10):
|
for i in range(10):
|
||||||
self._builtin_variables[f'CMAKE_MATCH_{i}'] = doc
|
self._builtin_variables[f"CMAKE_MATCH_{i}"] = doc
|
||||||
elif '<' in variable:
|
elif "<" in variable:
|
||||||
variable = re.sub(r'<[^>]+>', r'[^_]+', variable)
|
variable = re.sub(r"<[^>]+>", r"[^_]+", variable)
|
||||||
pattern = re.compile(variable)
|
pattern = re.compile(variable)
|
||||||
self._builtin_variable_template[pattern] = doc
|
self._builtin_variable_template[pattern] = doc
|
||||||
else:
|
else:
|
||||||
self._builtin_variables[variable] = doc
|
self._builtin_variables[variable] = doc
|
||||||
|
|
||||||
def _parse_modules(self) -> None:
|
def _parse_modules(self) -> None:
|
||||||
p = subprocess.run([self._cmake, '--help-modules'],
|
p = subprocess.run(
|
||||||
stdout=subprocess.PIPE,
|
[self._cmake, "--help-modules"],
|
||||||
encoding='utf-8',
|
stdout=subprocess.PIPE,
|
||||||
universal_newlines=True)
|
encoding="utf-8",
|
||||||
|
universal_newlines=True,
|
||||||
|
)
|
||||||
|
|
||||||
if p.returncode != 0:
|
if p.returncode != 0:
|
||||||
return
|
return
|
||||||
|
|
||||||
matches = re.finditer(
|
matches = re.finditer(
|
||||||
r'''
|
r"""
|
||||||
(?P<module>.+)\n
|
(?P<module>.+)\n
|
||||||
-+\n+?
|
-+\n+?
|
||||||
(?:(?P<header>\w[\w\s]+)\n\^+\n+?)?
|
(?:(?P<header>\w[\w\s]+)\n\^+\n+?)?
|
||||||
(?P<doc>.(?:.|\n)+?\n\n)
|
(?P<doc>.(?:.|\n)+?\n\n)
|
||||||
''', p.stdout + '\n\n', re.VERBOSE)
|
""",
|
||||||
|
p.stdout + "\n\n",
|
||||||
|
re.VERBOSE,
|
||||||
|
)
|
||||||
self._builtin_modules.clear()
|
self._builtin_modules.clear()
|
||||||
for match in matches:
|
for match in matches:
|
||||||
module = match.group('module')
|
module = match.group("module")
|
||||||
header = match.group('header')
|
header = match.group("header")
|
||||||
doc = _tidy_doc(match.group('doc'))
|
doc = _tidy_doc(match.group("doc"))
|
||||||
if header is not None and header != 'Overview':
|
if header is not None and header != "Overview":
|
||||||
doc = ''
|
doc = ""
|
||||||
self._builtin_modules[module] = doc
|
self._builtin_modules[module] = doc
|
||||||
|
|
||||||
def get_command_doc(self, command: str) -> Optional[str]:
|
def get_command_doc(self, command: str) -> Optional[str]:
|
||||||
@@ -281,28 +308,27 @@ endforeach()
|
|||||||
return self._builtin_variables.get(variable)
|
return self._builtin_variables.get(variable)
|
||||||
|
|
||||||
def search_variable(self, variable: str) -> List[str]:
|
def search_variable(self, variable: str) -> List[str]:
|
||||||
cached = frozenset(x for x in self._cached_variables
|
cached = frozenset(x for x in self._cached_variables if x.startswith(variable))
|
||||||
if x.startswith(variable))
|
builtin = frozenset(
|
||||||
builtin = frozenset(x for x in self._builtin_variables
|
x for x in self._builtin_variables if x.startswith(variable)
|
||||||
if x.startswith(variable))
|
)
|
||||||
return list(cached | builtin)
|
return list(cached | builtin)
|
||||||
|
|
||||||
def get_module_doc(self, module: str, package: bool) -> Optional[str]:
|
def get_module_doc(self, module: str, package: bool) -> Optional[str]:
|
||||||
if package:
|
if package:
|
||||||
return self._builtin_modules.get('Find' + module)
|
return self._builtin_modules.get("Find" + module)
|
||||||
|
|
||||||
return self._builtin_modules.get(module)
|
return self._builtin_modules.get(module)
|
||||||
|
|
||||||
def search_module(self, module: str, package: bool) -> List[str]:
|
def search_module(self, module: str, package: bool) -> List[str]:
|
||||||
if package:
|
if package:
|
||||||
module = 'Find' + module
|
module = "Find" + module
|
||||||
return [
|
return [x[4:] for x in self._builtin_modules if x.startswith(module)]
|
||||||
x[4:] for x in self._builtin_modules if x.startswith(module)
|
|
||||||
]
|
|
||||||
|
|
||||||
return [
|
return [
|
||||||
x for x in self._builtin_modules
|
x
|
||||||
if x.startswith(module) and not x.startswith('Find')
|
for x in self._builtin_modules
|
||||||
|
if x.startswith(module) and not x.startswith("Find")
|
||||||
]
|
]
|
||||||
|
|
||||||
def search_target(self, target: str) -> List[str]:
|
def search_target(self, target: str) -> List[str]:
|
||||||
@@ -310,4 +336,4 @@ endforeach()
|
|||||||
|
|
||||||
def _truncate_variable(self, v: str) -> str:
|
def _truncate_variable(self, v: str) -> str:
|
||||||
width = 70
|
width = 70
|
||||||
return v[:width] + (v[width:] and '...')
|
return v[:width] + (v[width:] and "...")
|
||||||
|
|||||||
@@ -7,39 +7,51 @@ class Formatter(object):
|
|||||||
indnt: str
|
indnt: str
|
||||||
lower_identifier: bool
|
lower_identifier: bool
|
||||||
|
|
||||||
def __init__(self, indent=' ', lower_identifier=True):
|
def __init__(self, indent=" ", lower_identifier=True):
|
||||||
self.indent = indent
|
self.indent = indent
|
||||||
self.lower_identifier = lower_identifier
|
self.lower_identifier = lower_identifier
|
||||||
|
|
||||||
def format(self, tokens: TokenList) -> str:
|
def format(self, tokens: TokenList) -> str:
|
||||||
cmds: List[str] = ['']
|
cmds: List[str] = [""]
|
||||||
indnet_level = 0
|
indnet_level = 0
|
||||||
for token in tokens:
|
for token in tokens:
|
||||||
if isinstance(token, tuple):
|
if isinstance(token, tuple):
|
||||||
raw_identifier = token[0]
|
raw_identifier = token[0]
|
||||||
identifier = raw_identifier.lower()
|
identifier = raw_identifier.lower()
|
||||||
if identifier in ('elseif', 'else', 'endif', 'endforeach',
|
if identifier in (
|
||||||
'endwhile', 'endmacro', 'endfunction'):
|
"elseif",
|
||||||
|
"else",
|
||||||
|
"endif",
|
||||||
|
"endforeach",
|
||||||
|
"endwhile",
|
||||||
|
"endmacro",
|
||||||
|
"endfunction",
|
||||||
|
):
|
||||||
if indnet_level > 0:
|
if indnet_level > 0:
|
||||||
indnet_level -= 1
|
indnet_level -= 1
|
||||||
cmds[-1] = self.indent * indnet_level
|
cmds[-1] = self.indent * indnet_level
|
||||||
cmds[-1] += (identifier
|
cmds[-1] += identifier if self.lower_identifier else raw_identifier
|
||||||
if self.lower_identifier else raw_identifier)
|
|
||||||
args = self._format_args(token[1])
|
args = self._format_args(token[1])
|
||||||
if len(args) < 2:
|
if len(args) < 2:
|
||||||
cmds[-1] += '(' + ''.join(args) + ')'
|
cmds[-1] += "(" + "".join(args) + ")"
|
||||||
else:
|
else:
|
||||||
cmds[-1] += '(\n'
|
cmds[-1] += "(\n"
|
||||||
for arg in args:
|
for arg in args:
|
||||||
cmds[-1] += self.indent * (indnet_level +
|
cmds[-1] += self.indent * (indnet_level + 1) + arg + "\n"
|
||||||
1) + arg + '\n'
|
cmds[-1] += self.indent * indnet_level + ")"
|
||||||
cmds[-1] += self.indent * indnet_level + ')'
|
if identifier in (
|
||||||
if identifier in ('if', 'elseif', 'else', 'foreach', 'while',
|
"if",
|
||||||
'macro', 'function'):
|
"elseif",
|
||||||
|
"else",
|
||||||
|
"foreach",
|
||||||
|
"while",
|
||||||
|
"macro",
|
||||||
|
"function",
|
||||||
|
):
|
||||||
indnet_level += 1
|
indnet_level += 1
|
||||||
elif token == '\n':
|
elif token == "\n":
|
||||||
cmds.append('')
|
cmds.append("")
|
||||||
elif token[0] == '#':
|
elif token[0] == "#":
|
||||||
if cmds[-1]:
|
if cmds[-1]:
|
||||||
cmds[-1] += token
|
cmds[-1] += token
|
||||||
else:
|
else:
|
||||||
@@ -48,70 +60,67 @@ class Formatter(object):
|
|||||||
cmds[-1] += token
|
cmds[-1] += token
|
||||||
|
|
||||||
cmds = self._strip_line(cmds)
|
cmds = self._strip_line(cmds)
|
||||||
return '\n'.join(cmds) + '\n'
|
return "\n".join(cmds) + "\n"
|
||||||
|
|
||||||
def _format_args(self, args: List[str]) -> List[str]:
|
def _format_args(self, args: List[str]) -> List[str]:
|
||||||
lines = ['']
|
lines = [""]
|
||||||
for i in range(len(args)):
|
for i in range(len(args)):
|
||||||
arg = args[i]
|
arg = args[i]
|
||||||
if arg[0] == '#':
|
if arg[0] == "#":
|
||||||
lines[-1] += arg
|
lines[-1] += arg
|
||||||
elif arg[0] == '\n':
|
elif arg[0] == "\n":
|
||||||
lines.append('')
|
lines.append("")
|
||||||
elif arg.isspace():
|
elif arg.isspace():
|
||||||
if lines[-1]:
|
if lines[-1]:
|
||||||
if i + 1 < len(args) and args[i + 1][0] == '#':
|
if i + 1 < len(args) and args[i + 1][0] == "#":
|
||||||
lines[-1] += arg
|
lines[-1] += arg
|
||||||
else:
|
else:
|
||||||
lines[-1] += ' '
|
lines[-1] += " "
|
||||||
else:
|
else:
|
||||||
lines[-1] += arg
|
lines[-1] += arg
|
||||||
|
|
||||||
return self._strip_line(lines)
|
return self._strip_line(lines)
|
||||||
|
|
||||||
def _strip_line(self, lines: List[str]) -> List[str]:
|
def _strip_line(self, lines: List[str]) -> List[str]:
|
||||||
'''Delete empty lines at the start/end of the input'''
|
"""Delete empty lines at the start/end of the input"""
|
||||||
|
|
||||||
ret: List[str] = []
|
ret: List[str] = []
|
||||||
for line in lines:
|
for line in lines:
|
||||||
line = line.rstrip()
|
line = line.rstrip()
|
||||||
if line != '' or len(ret) > 0:
|
if line != "" or len(ret) > 0:
|
||||||
ret.append(line)
|
ret.append(line)
|
||||||
while ret and ret[-1] == '':
|
while ret and ret[-1] == "":
|
||||||
del ret[-1]
|
del ret[-1]
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
def main(args: List[str] = None):
|
def main(args: List[str] = None):
|
||||||
|
import sys
|
||||||
from argparse import ArgumentParser
|
from argparse import ArgumentParser
|
||||||
from difflib import unified_diff
|
from difflib import unified_diff
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
import sys
|
|
||||||
from . import __version__
|
from . import __version__
|
||||||
from .parser import ListParser
|
from .parser import ListParser
|
||||||
|
|
||||||
parser = ArgumentParser(
|
parser = ArgumentParser(
|
||||||
description='Format CMake list files.',
|
description="Format CMake list files.",
|
||||||
epilog='''
|
epilog="""
|
||||||
If no arguments are specified, it formats the code from
|
If no arguments are specified, it formats the code from
|
||||||
standard input and writes the result to the standard output.''',
|
standard input and writes the result to the standard output.""",
|
||||||
)
|
)
|
||||||
parser.add_argument('lists', type=Path, nargs='*', help='CMake list files')
|
parser.add_argument("lists", type=Path, nargs="*", help="CMake list files")
|
||||||
group = parser.add_mutually_exclusive_group()
|
group = parser.add_mutually_exclusive_group()
|
||||||
group.add_argument('-i',
|
group.add_argument("-i", "--inplace", action="store_true", help="inplace edit")
|
||||||
'--inplace',
|
group.add_argument("-d", "--diff", action="store_true", help="show diff")
|
||||||
action='store_true',
|
parser.add_argument(
|
||||||
help='inplace edit')
|
"--version", action="version", version=f"%(prog)s {__version__}"
|
||||||
group.add_argument('-d', '--diff', action='store_true', help='show diff')
|
)
|
||||||
parser.add_argument('--version',
|
|
||||||
action='version',
|
|
||||||
version=f'%(prog)s {__version__}')
|
|
||||||
|
|
||||||
args = parser.parse_args(args)
|
args = parser.parse_args(args)
|
||||||
|
|
||||||
if not args.lists and args.inplace:
|
if not args.lists and args.inplace:
|
||||||
print('error: cannot use -i when no arguments are specified.',
|
print("error: cannot use -i when no arguments are specified.", file=sys.stderr)
|
||||||
file=sys.stderr)
|
|
||||||
return
|
return
|
||||||
if not args.lists:
|
if not args.lists:
|
||||||
args.lists.append(None)
|
args.lists.append(None)
|
||||||
@@ -120,7 +129,7 @@ def main(args: List[str] = None):
|
|||||||
formatter = Formatter()
|
formatter = Formatter()
|
||||||
for listpath in args.lists:
|
for listpath in args.lists:
|
||||||
if listpath is None:
|
if listpath is None:
|
||||||
listpath = '(stdin)'
|
listpath = "(stdin)"
|
||||||
content = sys.stdin.read()
|
content = sys.stdin.read()
|
||||||
else:
|
else:
|
||||||
with listpath.open() as fp:
|
with listpath.open() as fp:
|
||||||
@@ -130,14 +139,18 @@ def main(args: List[str] = None):
|
|||||||
|
|
||||||
if args.inplace:
|
if args.inplace:
|
||||||
if not remain:
|
if not remain:
|
||||||
with listpath.open('w') as fp:
|
with listpath.open("w") as fp:
|
||||||
fp.write(formatted)
|
fp.write(formatted)
|
||||||
elif args.diff:
|
elif args.diff:
|
||||||
diff = unified_diff(content.splitlines(True),
|
diff = unified_diff(
|
||||||
formatted.splitlines(True), str(listpath),
|
content.splitlines(True),
|
||||||
str(listpath), '(before formatting)',
|
formatted.splitlines(True),
|
||||||
'(after formatting)')
|
str(listpath),
|
||||||
diffstr = ''.join(diff)
|
str(listpath),
|
||||||
print(diffstr, end='')
|
"(before formatting)",
|
||||||
|
"(after formatting)",
|
||||||
|
)
|
||||||
|
diffstr = "".join(diff)
|
||||||
|
print(diffstr, end="")
|
||||||
else:
|
else:
|
||||||
print(formatted, end='')
|
print(formatted, end="")
|
||||||
|
|||||||
@@ -11,8 +11,8 @@ class ListParser(object):
|
|||||||
_parser: pp.ParserElement
|
_parser: pp.ParserElement
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
newline = '\n'
|
newline = "\n"
|
||||||
space_plus = pp.Regex('[ \t]+')
|
space_plus = pp.Regex("[ \t]+")
|
||||||
space_star = pp.Optional(space_plus)
|
space_star = pp.Optional(space_plus)
|
||||||
|
|
||||||
quoted_element = pp.Regex(r'[^\\"]|\\[^A-Za-z0-9]|\\[trn]')
|
quoted_element = pp.Regex(r'[^\\"]|\\[^A-Za-z0-9]|\\[trn]')
|
||||||
@@ -22,10 +22,10 @@ class ListParser(object):
|
|||||||
|
|
||||||
def action_bracket_open(tokens: pp.ParseResults):
|
def action_bracket_open(tokens: pp.ParseResults):
|
||||||
nonlocal bracket_content
|
nonlocal bracket_content
|
||||||
marker = ']' + '=' * (len(tokens[0]) - 2) + ']'
|
marker = "]" + "=" * (len(tokens[0]) - 2) + "]"
|
||||||
bracket_content <<= pp.SkipTo(marker, include=True)
|
bracket_content <<= pp.SkipTo(marker, include=True)
|
||||||
|
|
||||||
bracket_open = pp.Regex(r'\[=*\[').setParseAction(action_bracket_open)
|
bracket_open = pp.Regex(r"\[=*\[").setParseAction(action_bracket_open)
|
||||||
bracket_argument = pp.Combine(bracket_open + bracket_content)
|
bracket_argument = pp.Combine(bracket_open + bracket_content)
|
||||||
|
|
||||||
unquoted_element = pp.Regex(r'[^\s()#"\\]|\\[^A-Za-z0-9]|\\[trn]')
|
unquoted_element = pp.Regex(r'[^\s()#"\\]|\\[^A-Za-z0-9]|\\[trn]')
|
||||||
@@ -33,25 +33,29 @@ class ListParser(object):
|
|||||||
|
|
||||||
argument = bracket_argument | quoted_argument | unquoted_argument
|
argument = bracket_argument | quoted_argument | unquoted_argument
|
||||||
|
|
||||||
line_comment = pp.Combine('#' + ~bracket_open +
|
line_comment = pp.Combine("#" + ~bracket_open + pp.SkipTo(pp.LineEnd()))
|
||||||
pp.SkipTo(pp.LineEnd()))
|
bracket_comment = pp.Combine("#" + bracket_argument)
|
||||||
bracket_comment = pp.Combine('#' + bracket_argument)
|
line_ending = (
|
||||||
line_ending = (space_star +
|
space_star
|
||||||
pp.ZeroOrMore(bracket_comment + space_star) +
|
+ pp.ZeroOrMore(bracket_comment + space_star)
|
||||||
pp.Optional(line_comment) + (newline | pp.lineEnd))
|
+ pp.Optional(line_comment)
|
||||||
|
+ (newline | pp.lineEnd)
|
||||||
|
)
|
||||||
|
|
||||||
identifier = pp.Word(pp.alphas + '_', pp.alphanums + '_')
|
identifier = pp.Word(pp.alphas + "_", pp.alphanums + "_")
|
||||||
arguments = pp.Forward()
|
arguments = pp.Forward()
|
||||||
arguments << pp.ZeroOrMore(argument | line_ending | space_plus
|
arguments << pp.ZeroOrMore(
|
||||||
| '(' + arguments + ')').leaveWhitespace()
|
argument | line_ending | space_plus | "(" + arguments + ")"
|
||||||
|
).leaveWhitespace()
|
||||||
arguments = pp.Group(arguments)
|
arguments = pp.Group(arguments)
|
||||||
PAREN_L, PAREN_R = map(pp.Suppress, '()')
|
PAREN_L, PAREN_R = map(pp.Suppress, "()")
|
||||||
command_invocation = (
|
command_invocation = (
|
||||||
identifier + space_star.suppress() + PAREN_L + arguments +
|
identifier + space_star.suppress() + PAREN_L + arguments + PAREN_R
|
||||||
PAREN_R).setParseAction(lambda t: (t[0], t[1].asList()))
|
).setParseAction(lambda t: (t[0], t[1].asList()))
|
||||||
|
|
||||||
file_element = (space_star + command_invocation + line_ending
|
file_element = (
|
||||||
| line_ending).leaveWhitespace()
|
space_star + command_invocation + line_ending | line_ending
|
||||||
|
).leaveWhitespace()
|
||||||
file = pp.ZeroOrMore(file_element)
|
file = pp.ZeroOrMore(file_element)
|
||||||
|
|
||||||
self._parser = file
|
self._parser = file
|
||||||
|
|||||||
@@ -3,14 +3,31 @@ import re
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import List, Optional, Tuple
|
from typing import List, Optional, Tuple
|
||||||
|
|
||||||
from pygls.features import (COMPLETION, FORMATTING, HOVER, INITIALIZE,
|
from pygls.features import (
|
||||||
INITIALIZED, TEXT_DOCUMENT_DID_SAVE)
|
COMPLETION,
|
||||||
|
FORMATTING,
|
||||||
|
HOVER,
|
||||||
|
INITIALIZE,
|
||||||
|
INITIALIZED,
|
||||||
|
TEXT_DOCUMENT_DID_SAVE,
|
||||||
|
)
|
||||||
from pygls.server import LanguageServer
|
from pygls.server import LanguageServer
|
||||||
from pygls.types import (CompletionItem, CompletionItemKind, CompletionList,
|
from pygls.types import (
|
||||||
CompletionParams, CompletionTriggerKind,
|
CompletionItem,
|
||||||
DocumentFormattingParams, Hover, InitializeParams,
|
CompletionItemKind,
|
||||||
MarkupContent, MarkupKind, Position, Range,
|
CompletionList,
|
||||||
TextDocumentPositionParams, TextEdit)
|
CompletionParams,
|
||||||
|
CompletionTriggerKind,
|
||||||
|
DocumentFormattingParams,
|
||||||
|
Hover,
|
||||||
|
InitializeParams,
|
||||||
|
MarkupContent,
|
||||||
|
MarkupKind,
|
||||||
|
Position,
|
||||||
|
Range,
|
||||||
|
TextDocumentPositionParams,
|
||||||
|
TextEdit,
|
||||||
|
)
|
||||||
|
|
||||||
from .api import API
|
from .api import API
|
||||||
from .formatter import Formatter
|
from .formatter import Formatter
|
||||||
@@ -33,32 +50,34 @@ class CMakeLanguageServer(LanguageServer):
|
|||||||
def initialize(params: InitializeParams):
|
def initialize(params: InitializeParams):
|
||||||
opts = params.initializationOptions
|
opts = params.initializationOptions
|
||||||
|
|
||||||
cmake = getattr(opts, 'cmakeExecutable', 'cmake')
|
cmake = getattr(opts, "cmakeExecutable", "cmake")
|
||||||
builddir = getattr(opts, 'buildDirectory', '')
|
builddir = getattr(opts, "buildDirectory", "")
|
||||||
logging.info(f'cmakeExecutable={cmake}, buildDirectory={builddir}')
|
logging.info(f"cmakeExecutable={cmake}, buildDirectory={builddir}")
|
||||||
|
|
||||||
self._api = API(cmake, Path(builddir))
|
self._api = API(cmake, Path(builddir))
|
||||||
self._api.parse_doc()
|
self._api.parse_doc()
|
||||||
|
|
||||||
trigger_characters = ['{', '(']
|
trigger_characters = ["{", "("]
|
||||||
|
|
||||||
@self.feature(COMPLETION, trigger_characters=trigger_characters)
|
@self.feature(COMPLETION, trigger_characters=trigger_characters)
|
||||||
def completions(params: CompletionParams):
|
def completions(params: CompletionParams):
|
||||||
if (hasattr(params, 'context') and params.context.triggerKind ==
|
if (
|
||||||
CompletionTriggerKind.TriggerCharacter):
|
hasattr(params, "context")
|
||||||
token = ''
|
and params.context.triggerKind == CompletionTriggerKind.TriggerCharacter
|
||||||
|
):
|
||||||
|
token = ""
|
||||||
trigger = params.context.triggerCharacter
|
trigger = params.context.triggerCharacter
|
||||||
else:
|
else:
|
||||||
line = self._cursor_line(params.textDocument.uri,
|
line = self._cursor_line(params.textDocument.uri, params.position)
|
||||||
params.position)
|
|
||||||
idx = params.position.character - 1
|
idx = params.position.character - 1
|
||||||
if 0 <= idx < len(line) and line[idx] in trigger_characters:
|
if 0 <= idx < len(line) and line[idx] in trigger_characters:
|
||||||
token = ''
|
token = ""
|
||||||
trigger = line[idx]
|
trigger = line[idx]
|
||||||
else:
|
else:
|
||||||
word = self._cursor_word(params.textDocument.uri,
|
word = self._cursor_word(
|
||||||
params.position, False)
|
params.textDocument.uri, params.position, False
|
||||||
token = '' if word is None else word[0]
|
)
|
||||||
|
token = "" if word is None else word[0]
|
||||||
trigger = None
|
trigger = None
|
||||||
|
|
||||||
items: List[CompletionItem] = []
|
items: List[CompletionItem] = []
|
||||||
@@ -66,46 +85,60 @@ class CMakeLanguageServer(LanguageServer):
|
|||||||
if trigger is None:
|
if trigger is None:
|
||||||
commands = self._api.search_command(token)
|
commands = self._api.search_command(token)
|
||||||
items.extend(
|
items.extend(
|
||||||
CompletionItem(x,
|
CompletionItem(
|
||||||
CompletionItemKind.Function,
|
x,
|
||||||
documentation=self._api.get_command_doc(x),
|
CompletionItemKind.Function,
|
||||||
insert_text=x) for x in commands)
|
documentation=self._api.get_command_doc(x),
|
||||||
|
insert_text=x,
|
||||||
|
)
|
||||||
|
for x in commands
|
||||||
|
)
|
||||||
|
|
||||||
if trigger is None or trigger == '{':
|
if trigger is None or trigger == "{":
|
||||||
variables = self._api.search_variable(token)
|
variables = self._api.search_variable(token)
|
||||||
items.extend(
|
items.extend(
|
||||||
CompletionItem(x,
|
CompletionItem(
|
||||||
CompletionItemKind.Variable,
|
x,
|
||||||
documentation=self._api.get_variable_doc(x),
|
CompletionItemKind.Variable,
|
||||||
insert_text=x) for x in variables)
|
documentation=self._api.get_variable_doc(x),
|
||||||
|
insert_text=x,
|
||||||
|
)
|
||||||
|
for x in variables
|
||||||
|
)
|
||||||
|
|
||||||
if trigger is None:
|
if trigger is None:
|
||||||
targets = self._api.search_target(token)
|
targets = self._api.search_target(token)
|
||||||
items.extend(
|
items.extend(
|
||||||
CompletionItem(x, CompletionItemKind.Class, insert_text=x)
|
CompletionItem(x, CompletionItemKind.Class, insert_text=x)
|
||||||
for x in targets)
|
for x in targets
|
||||||
|
)
|
||||||
|
|
||||||
if trigger == '(':
|
if trigger == "(":
|
||||||
func = self._cursor_function(params.textDocument.uri,
|
func = self._cursor_function(params.textDocument.uri, params.position)
|
||||||
params.position)
|
|
||||||
if func is not None:
|
if func is not None:
|
||||||
func = func.lower()
|
func = func.lower()
|
||||||
if func == 'include':
|
if func == "include":
|
||||||
modules = self._api.search_module(token, False)
|
modules = self._api.search_module(token, False)
|
||||||
items.extend(
|
items.extend(
|
||||||
CompletionItem(x,
|
CompletionItem(
|
||||||
CompletionItemKind.Module,
|
x,
|
||||||
documentation=self._api.
|
CompletionItemKind.Module,
|
||||||
get_module_doc(x, False),
|
documentation=self._api.get_module_doc(x, False),
|
||||||
insert_text=x) for x in modules)
|
insert_text=x,
|
||||||
elif func == 'find_package':
|
)
|
||||||
|
for x in modules
|
||||||
|
)
|
||||||
|
elif func == "find_package":
|
||||||
modules = self._api.search_module(token, True)
|
modules = self._api.search_module(token, True)
|
||||||
items.extend(
|
items.extend(
|
||||||
CompletionItem(x,
|
CompletionItem(
|
||||||
CompletionItemKind.Module,
|
x,
|
||||||
documentation=self._api.
|
CompletionItemKind.Module,
|
||||||
get_module_doc(x, True),
|
documentation=self._api.get_module_doc(x, True),
|
||||||
insert_text=x) for x in modules)
|
insert_text=x,
|
||||||
|
)
|
||||||
|
for x in modules
|
||||||
|
)
|
||||||
|
|
||||||
return CompletionList(False, items)
|
return CompletionList(False, items)
|
||||||
|
|
||||||
@@ -115,20 +148,16 @@ class CMakeLanguageServer(LanguageServer):
|
|||||||
content = doc.source
|
content = doc.source
|
||||||
tokens, remain = self._parser.parse(content)
|
tokens, remain = self._parser.parse(content)
|
||||||
if remain:
|
if remain:
|
||||||
self.show_message('CMake parser failed')
|
self.show_message("CMake parser failed")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
formatted = Formatter().format(tokens)
|
formatted = Formatter().format(tokens)
|
||||||
lines = content.count('\n')
|
lines = content.count("\n")
|
||||||
return [
|
return [TextEdit(Range(Position(0, 0), Position(lines + 1, 0)), formatted)]
|
||||||
TextEdit(Range(Position(0, 0), Position(lines + 1, 0)),
|
|
||||||
formatted)
|
|
||||||
]
|
|
||||||
|
|
||||||
@self.feature(HOVER)
|
@self.feature(HOVER)
|
||||||
def hover(params: TextDocumentPositionParams):
|
def hover(params: TextDocumentPositionParams):
|
||||||
word = self._cursor_word(params.textDocument.uri, params.position,
|
word = self._cursor_word(params.textDocument.uri, params.position, True)
|
||||||
True)
|
|
||||||
if not word:
|
if not word:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@@ -154,43 +183,46 @@ class CMakeLanguageServer(LanguageServer):
|
|||||||
|
|
||||||
def _cursor_function(self, uri: str, position: Position) -> Optional[str]:
|
def _cursor_function(self, uri: str, position: Position) -> Optional[str]:
|
||||||
doc = self.workspace.get_document(uri)
|
doc = self.workspace.get_document(uri)
|
||||||
lines = doc.source.split('\n')[:position.line + 1]
|
lines = doc.source.split("\n")[: position.line + 1]
|
||||||
lines[-1] = lines[-1][:position.character - 1].strip()
|
lines[-1] = lines[-1][: position.character - 1].strip()
|
||||||
words = re.split(r'[\s\n()]+', '\n'.join(lines))
|
words = re.split(r"[\s\n()]+", "\n".join(lines))
|
||||||
return words[-1] if words else None
|
return words[-1] if words else None
|
||||||
|
|
||||||
def _cursor_line(self, uri: str, position: Position) -> str:
|
def _cursor_line(self, uri: str, position: Position) -> str:
|
||||||
doc = self.workspace.get_document(uri)
|
doc = self.workspace.get_document(uri)
|
||||||
content = doc.source
|
content = doc.source
|
||||||
line = content.split('\n')[position.line]
|
line = content.split("\n")[position.line]
|
||||||
return line
|
return line
|
||||||
|
|
||||||
def _cursor_word(self,
|
def _cursor_word(
|
||||||
uri: str,
|
self, uri: str, position: Position, include_all: bool = True
|
||||||
position: Position,
|
) -> Optional[Tuple[str, Range]]:
|
||||||
include_all: bool = True) -> Optional[Tuple[str, Range]]:
|
|
||||||
line = self._cursor_line(uri, position)
|
line = self._cursor_line(uri, position)
|
||||||
cursor = position.character
|
cursor = position.character
|
||||||
for m in re.finditer(r'\w+', line):
|
for m in re.finditer(r"\w+", line):
|
||||||
end = m.end() if include_all else cursor
|
end = m.end() if include_all else cursor
|
||||||
if m.start() <= cursor <= m.end():
|
if m.start() <= cursor <= m.end():
|
||||||
word = (line[m.start():end],
|
word = (
|
||||||
Range(Position(position.line, m.start()),
|
line[m.start() : end],
|
||||||
Position(position.line, end)))
|
Range(
|
||||||
|
Position(position.line, m.start()), Position(position.line, end)
|
||||||
|
),
|
||||||
|
)
|
||||||
return word
|
return word
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def main(args=None):
|
def main(args=None):
|
||||||
from argparse import ArgumentParser
|
from argparse import ArgumentParser
|
||||||
|
|
||||||
from . import __version__
|
from . import __version__
|
||||||
|
|
||||||
parser = ArgumentParser(description='CMake Language Server')
|
parser = ArgumentParser(description="CMake Language Server")
|
||||||
parser.add_argument('--version',
|
parser.add_argument(
|
||||||
action='version',
|
"--version", action="version", version=f"%(prog)s {__version__}"
|
||||||
version=f'%(prog)s {__version__}')
|
)
|
||||||
args = parser.parse_args(args)
|
args = parser.parse_args(args)
|
||||||
|
|
||||||
logging.basicConfig(level=logging.INFO)
|
logging.basicConfig(level=logging.INFO)
|
||||||
logging.getLogger('pygls').setLevel(logging.WARNING)
|
logging.getLogger("pygls").setLevel(logging.WARNING)
|
||||||
CMakeLanguageServer().start_io()
|
CMakeLanguageServer().start_io()
|
||||||
|
|||||||
@@ -14,18 +14,20 @@ from cmake_language_server.server import CMakeLanguageServer
|
|||||||
|
|
||||||
@pytest.fixture()
|
@pytest.fixture()
|
||||||
def cmake_build(shared_datadir):
|
def cmake_build(shared_datadir):
|
||||||
source = shared_datadir / 'cmake'
|
source = shared_datadir / "cmake"
|
||||||
build = source / 'build'
|
build = source / "build"
|
||||||
build.mkdir()
|
build.mkdir()
|
||||||
p = run(['cmake', str(source)],
|
p = run(
|
||||||
cwd=build,
|
["cmake", str(source)],
|
||||||
stdout=PIPE,
|
cwd=build,
|
||||||
stderr=PIPE,
|
stdout=PIPE,
|
||||||
universal_newlines=True)
|
stderr=PIPE,
|
||||||
|
universal_newlines=True,
|
||||||
|
)
|
||||||
if p.returncode != 0:
|
if p.returncode != 0:
|
||||||
logging.error('env:\n' + pprint.pformat(os.environ))
|
logging.error("env:\n" + pprint.pformat(os.environ))
|
||||||
logging.error('stdout:\n' + p.stdout)
|
logging.error("stdout:\n" + p.stdout)
|
||||||
logging.error('stderr:\n' + p.stderr)
|
logging.error("stderr:\n" + p.stderr)
|
||||||
raise RuntimeError("CMake failed")
|
raise RuntimeError("CMake failed")
|
||||||
yield build
|
yield build
|
||||||
|
|
||||||
@@ -40,7 +42,7 @@ def client_server():
|
|||||||
# disable `close()` to avoid error messages
|
# disable `close()` to avoid error messages
|
||||||
close = ls.loop.close
|
close = ls.loop.close
|
||||||
ls.loop.close = lambda: None
|
ls.loop.close = lambda: None
|
||||||
ls.start_io(os.fdopen(fdr, 'rb'), os.fdopen(fdw, 'wb'))
|
ls.start_io(os.fdopen(fdr, "rb"), os.fdopen(fdw, "wb"))
|
||||||
ls.loop.close = close
|
ls.loop.close = close
|
||||||
|
|
||||||
server = CMakeLanguageServer(asyncio.new_event_loop())
|
server = CMakeLanguageServer(asyncio.new_event_loop())
|
||||||
|
|||||||
@@ -4,109 +4,115 @@ from cmake_language_server.api import API
|
|||||||
|
|
||||||
|
|
||||||
def test_query_with_cache(cmake_build):
|
def test_query_with_cache(cmake_build):
|
||||||
api = API('cmake', cmake_build)
|
api = API("cmake", cmake_build)
|
||||||
assert api.query()
|
assert api.query()
|
||||||
|
|
||||||
query = cmake_build / '.cmake' / 'api' / 'v1' / 'query'
|
query = cmake_build / ".cmake" / "api" / "v1" / "query"
|
||||||
assert query.exists()
|
assert query.exists()
|
||||||
|
|
||||||
reply = cmake_build / '.cmake' / 'api' / 'v1' / 'reply'
|
reply = cmake_build / ".cmake" / "api" / "v1" / "reply"
|
||||||
assert reply.exists()
|
assert reply.exists()
|
||||||
|
|
||||||
|
|
||||||
def test_query_without_cache(cmake_build):
|
def test_query_without_cache(cmake_build):
|
||||||
api = API('cmake', cmake_build)
|
api = API("cmake", cmake_build)
|
||||||
(cmake_build / 'CMakeCache.txt').unlink()
|
(cmake_build / "CMakeCache.txt").unlink()
|
||||||
|
|
||||||
assert not api.query()
|
assert not api.query()
|
||||||
|
|
||||||
|
|
||||||
def test_read_variable(cmake_build):
|
def test_read_variable(cmake_build):
|
||||||
api = API('cmake', cmake_build)
|
api = API("cmake", cmake_build)
|
||||||
assert api.query()
|
assert api.query()
|
||||||
assert api.read_reply()
|
assert api.read_reply()
|
||||||
|
|
||||||
assert api.get_variable_doc('testproject_BINARY_DIR')
|
assert api.get_variable_doc("testproject_BINARY_DIR")
|
||||||
|
|
||||||
|
|
||||||
def test_read_cmake_files(cmake_build):
|
def test_read_cmake_files(cmake_build):
|
||||||
api = API('cmake', cmake_build)
|
api = API("cmake", cmake_build)
|
||||||
api.parse_doc()
|
api.parse_doc()
|
||||||
assert api.query()
|
assert api.query()
|
||||||
api.read_reply()
|
api.read_reply()
|
||||||
|
|
||||||
import platform
|
import platform
|
||||||
|
|
||||||
system = platform.system()
|
system = platform.system()
|
||||||
if system == 'Linux':
|
if system == "Linux":
|
||||||
assert 'GNU' in api.get_variable_doc('CMAKE_CXX_COMPILER_ID')
|
assert "GNU" in api.get_variable_doc("CMAKE_CXX_COMPILER_ID")
|
||||||
elif system == 'Windows':
|
elif system == "Windows":
|
||||||
assert 'MSVC' in api.get_variable_doc('CMAKE_CXX_COMPILER_ID')
|
assert "MSVC" in api.get_variable_doc("CMAKE_CXX_COMPILER_ID")
|
||||||
elif system == 'Darwin':
|
elif system == "Darwin":
|
||||||
assert 'Clang' in api.get_variable_doc('CMAKE_CXX_COMPILER_ID')
|
assert "Clang" in api.get_variable_doc("CMAKE_CXX_COMPILER_ID")
|
||||||
else:
|
else:
|
||||||
raise RuntimeError('Unexpected system')
|
raise RuntimeError("Unexpected system")
|
||||||
|
|
||||||
|
|
||||||
def test_parse_commands(cmake_build):
|
def test_parse_commands(cmake_build):
|
||||||
api = API('cmake', cmake_build)
|
api = API("cmake", cmake_build)
|
||||||
api.parse_doc()
|
api.parse_doc()
|
||||||
|
|
||||||
p = subprocess.run(['cmake', '--help-command-list'],
|
p = subprocess.run(
|
||||||
universal_newlines=True,
|
["cmake", "--help-command-list"],
|
||||||
stdout=subprocess.PIPE,
|
universal_newlines=True,
|
||||||
stderr=subprocess.PIPE)
|
stdout=subprocess.PIPE,
|
||||||
commands = p.stdout.strip().split('\n')
|
stderr=subprocess.PIPE,
|
||||||
|
)
|
||||||
|
commands = p.stdout.strip().split("\n")
|
||||||
|
|
||||||
for command in commands:
|
for command in commands:
|
||||||
assert api.get_command_doc(command) is not None, f'{command} not found'
|
assert api.get_command_doc(command) is not None, f"{command} not found"
|
||||||
|
|
||||||
assert 'break()' in api.get_command_doc('break')
|
assert "break()" in api.get_command_doc("break")
|
||||||
assert api.get_command_doc('not_existing_command') is None
|
assert api.get_command_doc("not_existing_command") is None
|
||||||
|
|
||||||
|
|
||||||
def test_parse_variables(cmake_build):
|
def test_parse_variables(cmake_build):
|
||||||
api = API('cmake', cmake_build)
|
api = API("cmake", cmake_build)
|
||||||
api.parse_doc()
|
api.parse_doc()
|
||||||
|
|
||||||
p = subprocess.run(['cmake', '--help-variable-list'],
|
p = subprocess.run(
|
||||||
universal_newlines=True,
|
["cmake", "--help-variable-list"],
|
||||||
stdout=subprocess.PIPE,
|
universal_newlines=True,
|
||||||
stderr=subprocess.PIPE)
|
stdout=subprocess.PIPE,
|
||||||
variables = p.stdout.strip().split('\n')
|
stderr=subprocess.PIPE,
|
||||||
|
)
|
||||||
|
variables = p.stdout.strip().split("\n")
|
||||||
|
|
||||||
for variable in variables:
|
for variable in variables:
|
||||||
if '<' in variable:
|
if "<" in variable:
|
||||||
continue
|
continue
|
||||||
assert api.get_variable_doc(
|
assert api.get_variable_doc(variable) is not None, f"{variable} not found"
|
||||||
variable) is not None, f'{variable} not found'
|
|
||||||
|
|
||||||
assert api.get_variable_doc('BUILD_SHARED_LIBS') is not None
|
assert api.get_variable_doc("BUILD_SHARED_LIBS") is not None
|
||||||
assert api.get_variable_doc('not_existing_variable') is None
|
assert api.get_variable_doc("not_existing_variable") is None
|
||||||
|
|
||||||
|
|
||||||
def test_parse_modules(cmake_build):
|
def test_parse_modules(cmake_build):
|
||||||
api = API('cmake', cmake_build)
|
api = API("cmake", cmake_build)
|
||||||
api.parse_doc()
|
api.parse_doc()
|
||||||
|
|
||||||
p = subprocess.run(['cmake', '--help-module-list'],
|
p = subprocess.run(
|
||||||
universal_newlines=True,
|
["cmake", "--help-module-list"],
|
||||||
stdout=subprocess.PIPE,
|
universal_newlines=True,
|
||||||
stderr=subprocess.PIPE)
|
stdout=subprocess.PIPE,
|
||||||
modules = p.stdout.strip().split('\n')
|
stderr=subprocess.PIPE,
|
||||||
|
)
|
||||||
|
modules = p.stdout.strip().split("\n")
|
||||||
|
|
||||||
for module in modules:
|
for module in modules:
|
||||||
if module.startswith('Find'):
|
if module.startswith("Find"):
|
||||||
assert api.get_module_doc(module[4:],
|
assert (
|
||||||
True) is not None, f'{module} not found'
|
api.get_module_doc(module[4:], True) is not None
|
||||||
|
), f"{module} not found"
|
||||||
else:
|
else:
|
||||||
assert api.get_module_doc(module,
|
assert api.get_module_doc(module, False) is not None, f"{module} not found"
|
||||||
False) is not None, f'{module} not found'
|
|
||||||
|
|
||||||
assert api.get_module_doc('GoogleTest', False) is not None
|
assert api.get_module_doc("GoogleTest", False) is not None
|
||||||
assert api.get_module_doc('GoogleTest', True) is None
|
assert api.get_module_doc("GoogleTest", True) is None
|
||||||
assert api.search_module('GoogleTest', False) == ['GoogleTest']
|
assert api.search_module("GoogleTest", False) == ["GoogleTest"]
|
||||||
assert api.search_module('GoogleTest', True) == []
|
assert api.search_module("GoogleTest", True) == []
|
||||||
assert api.get_module_doc('Boost', False) is None
|
assert api.get_module_doc("Boost", False) is None
|
||||||
assert api.get_module_doc('Boost', True) is not None
|
assert api.get_module_doc("Boost", True) is not None
|
||||||
assert api.search_module('Boost', False) == []
|
assert api.search_module("Boost", False) == []
|
||||||
assert api.search_module('Boost', True) == ['Boost']
|
assert api.search_module("Boost", True) == ["Boost"]
|
||||||
|
|||||||
@@ -15,50 +15,57 @@ def make_formatter_test(liststr: str, expect: str):
|
|||||||
return test
|
return test
|
||||||
|
|
||||||
|
|
||||||
test_command = make_formatter_test('a()', 'a()\n')
|
test_command = make_formatter_test("a()", "a()\n")
|
||||||
test_command_tolower = make_formatter_test('A()', 'a()\n')
|
test_command_tolower = make_formatter_test("A()", "a()\n")
|
||||||
test_remove_space = make_formatter_test('''
|
test_remove_space = make_formatter_test(
|
||||||
|
"""
|
||||||
#a
|
#a
|
||||||
b ( c ) # d
|
b ( c ) # d
|
||||||
''', '''\
|
""",
|
||||||
|
"""\
|
||||||
#a
|
#a
|
||||||
b(c) # d
|
b(c) # d
|
||||||
''')
|
""",
|
||||||
|
)
|
||||||
test_indent_if = make_formatter_test(
|
test_indent_if = make_formatter_test(
|
||||||
'''
|
"""
|
||||||
if()
|
if()
|
||||||
a() # a
|
a() # a
|
||||||
else()
|
else()
|
||||||
# b
|
# b
|
||||||
b()
|
b()
|
||||||
endif()
|
endif()
|
||||||
''', '''\
|
""",
|
||||||
|
"""\
|
||||||
if()
|
if()
|
||||||
a() # a
|
a() # a
|
||||||
else()
|
else()
|
||||||
# b
|
# b
|
||||||
b()
|
b()
|
||||||
endif()
|
endif()
|
||||||
''')
|
""",
|
||||||
|
)
|
||||||
test_indent_if_nested = make_formatter_test(
|
test_indent_if_nested = make_formatter_test(
|
||||||
'''
|
"""
|
||||||
if()
|
if()
|
||||||
if()
|
if()
|
||||||
a()
|
a()
|
||||||
b()
|
b()
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
''', '''\
|
""",
|
||||||
|
"""\
|
||||||
if()
|
if()
|
||||||
if()
|
if()
|
||||||
a()
|
a()
|
||||||
b()
|
b()
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
''')
|
""",
|
||||||
test_argument = make_formatter_test('a( b c d)', 'a(b c d)\n')
|
)
|
||||||
|
test_argument = make_formatter_test("a( b c d)", "a(b c d)\n")
|
||||||
test_argument_multiline = make_formatter_test(
|
test_argument_multiline = make_formatter_test(
|
||||||
'''
|
"""
|
||||||
if()
|
if()
|
||||||
a(b c
|
a(b c
|
||||||
d # e
|
d # e
|
||||||
@@ -66,7 +73,8 @@ f
|
|||||||
# g
|
# g
|
||||||
) # h
|
) # h
|
||||||
endif()
|
endif()
|
||||||
''', '''\
|
""",
|
||||||
|
"""\
|
||||||
if()
|
if()
|
||||||
a(
|
a(
|
||||||
b c
|
b c
|
||||||
@@ -75,7 +83,8 @@ if()
|
|||||||
# g
|
# g
|
||||||
) # h
|
) # h
|
||||||
endif()
|
endif()
|
||||||
''')
|
""",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@contextmanager
|
@contextmanager
|
||||||
@@ -87,70 +96,70 @@ def mock_stdin(buf: str):
|
|||||||
|
|
||||||
|
|
||||||
def test_main_stdin(capsys):
|
def test_main_stdin(capsys):
|
||||||
with mock_stdin(' a()'):
|
with mock_stdin(" a()"):
|
||||||
main([])
|
main([])
|
||||||
captured = capsys.readouterr()
|
captured = capsys.readouterr()
|
||||||
assert captured.out == 'a()\n'
|
assert captured.out == "a()\n"
|
||||||
assert captured.err == ''
|
assert captured.err == ""
|
||||||
|
|
||||||
|
|
||||||
def test_main_stdin_diff(capsys):
|
def test_main_stdin_diff(capsys):
|
||||||
with mock_stdin(' a()'):
|
with mock_stdin(" a()"):
|
||||||
main(['-d'])
|
main(["-d"])
|
||||||
captured = capsys.readouterr()
|
captured = capsys.readouterr()
|
||||||
assert '- a()' in captured.out
|
assert "- a()" in captured.out
|
||||||
assert '+a()' in captured.out
|
assert "+a()" in captured.out
|
||||||
assert captured.err == ''
|
assert captured.err == ""
|
||||||
|
|
||||||
|
|
||||||
def test_main_file_1(capsys, tmp_path):
|
def test_main_file_1(capsys, tmp_path):
|
||||||
testfile1 = tmp_path / 'list1.cmake'
|
testfile1 = tmp_path / "list1.cmake"
|
||||||
with testfile1.open('w') as fp:
|
with testfile1.open("w") as fp:
|
||||||
fp.write(' a()')
|
fp.write(" a()")
|
||||||
|
|
||||||
main([str(testfile1)])
|
main([str(testfile1)])
|
||||||
captured = capsys.readouterr()
|
captured = capsys.readouterr()
|
||||||
assert captured.out == 'a()\n'
|
assert captured.out == "a()\n"
|
||||||
assert captured.err == ''
|
assert captured.err == ""
|
||||||
|
|
||||||
|
|
||||||
def test_main_file_2(capsys, tmp_path):
|
def test_main_file_2(capsys, tmp_path):
|
||||||
testfile1 = tmp_path / 'list1.cmake'
|
testfile1 = tmp_path / "list1.cmake"
|
||||||
with testfile1.open('w') as fp:
|
with testfile1.open("w") as fp:
|
||||||
fp.write(' a()')
|
fp.write(" a()")
|
||||||
testfile2 = tmp_path / 'list2.cmake'
|
testfile2 = tmp_path / "list2.cmake"
|
||||||
with testfile2.open('w') as fp:
|
with testfile2.open("w") as fp:
|
||||||
fp.write(' b()')
|
fp.write(" b()")
|
||||||
|
|
||||||
main([str(testfile1), str(testfile2)])
|
main([str(testfile1), str(testfile2)])
|
||||||
captured = capsys.readouterr()
|
captured = capsys.readouterr()
|
||||||
assert captured.out == 'a()\nb()\n'
|
assert captured.out == "a()\nb()\n"
|
||||||
assert captured.err == ''
|
assert captured.err == ""
|
||||||
|
|
||||||
|
|
||||||
def test_main_inplace(capsys, tmp_path):
|
def test_main_inplace(capsys, tmp_path):
|
||||||
testfile1 = tmp_path / 'list1.cmake'
|
testfile1 = tmp_path / "list1.cmake"
|
||||||
with testfile1.open('w') as fp:
|
with testfile1.open("w") as fp:
|
||||||
fp.write(' a()')
|
fp.write(" a()")
|
||||||
|
|
||||||
main(['-i', str(testfile1)])
|
main(["-i", str(testfile1)])
|
||||||
captured = capsys.readouterr()
|
captured = capsys.readouterr()
|
||||||
assert captured.out == ''
|
assert captured.out == ""
|
||||||
assert captured.err == ''
|
assert captured.err == ""
|
||||||
|
|
||||||
with testfile1.open() as fp:
|
with testfile1.open() as fp:
|
||||||
content = fp.read()
|
content = fp.read()
|
||||||
assert content == 'a()\n'
|
assert content == "a()\n"
|
||||||
|
|
||||||
|
|
||||||
def test_main_diff(capsys, tmp_path):
|
def test_main_diff(capsys, tmp_path):
|
||||||
testfile1 = tmp_path / 'list1.cmake'
|
testfile1 = tmp_path / "list1.cmake"
|
||||||
with testfile1.open('w') as fp:
|
with testfile1.open("w") as fp:
|
||||||
fp.write(' a()')
|
fp.write(" a()")
|
||||||
|
|
||||||
main(['-d', str(testfile1)])
|
main(["-d", str(testfile1)])
|
||||||
captured = capsys.readouterr()
|
captured = capsys.readouterr()
|
||||||
assert str(testfile1) in captured.out
|
assert str(testfile1) in captured.out
|
||||||
assert '- a()' in captured.out
|
assert "- a()" in captured.out
|
||||||
assert '+a()' in captured.out
|
assert "+a()" in captured.out
|
||||||
assert captured.err == ''
|
assert captured.err == ""
|
||||||
|
|||||||
@@ -3,9 +3,9 @@ from typing import List
|
|||||||
from cmake_language_server.parser import ListParser, TokenType
|
from cmake_language_server.parser import ListParser, TokenType
|
||||||
|
|
||||||
|
|
||||||
def make_parser_test(liststr: str,
|
def make_parser_test(
|
||||||
expect_token: List[TokenType],
|
liststr: str, expect_token: List[TokenType], expect_remain: str = ""
|
||||||
expect_remain: str = ''):
|
):
|
||||||
def test():
|
def test():
|
||||||
actual_token, actual_remain = ListParser().parse(liststr)
|
actual_token, actual_remain = ListParser().parse(liststr)
|
||||||
assert actual_token == expect_token
|
assert actual_token == expect_token
|
||||||
@@ -14,51 +14,70 @@ def make_parser_test(liststr: str,
|
|||||||
return test
|
return test
|
||||||
|
|
||||||
|
|
||||||
test_command_no_args = make_parser_test('a()', [('a', [])])
|
test_command_no_args = make_parser_test("a()", [("a", [])])
|
||||||
test_command_space = make_parser_test(' a ()', [' ', ('a', [])])
|
test_command_space = make_parser_test(" a ()", [" ", ("a", [])])
|
||||||
test_command_arg = make_parser_test('a(b)', [('a', ['b'])])
|
test_command_arg = make_parser_test("a(b)", [("a", ["b"])])
|
||||||
test_command_arg_space = make_parser_test('a ( b )', [('a', ['b'])])
|
test_command_arg_space = make_parser_test("a ( b )", [("a", ["b"])])
|
||||||
test_command_arg_escape = make_parser_test(r'a(\n\")', [('a', [r'\n\"'])])
|
test_command_arg_escape = make_parser_test(r"a(\n\")", [("a", [r"\n\""])])
|
||||||
test_command_arg_paren = make_parser_test('a((b))', [('a', ['(', 'b', ')'])])
|
test_command_arg_paren = make_parser_test("a((b))", [("a", ["(", "b", ")"])])
|
||||||
test_command_arg_paren_paren = make_parser_test(
|
test_command_arg_paren_paren = make_parser_test(
|
||||||
'a(((b)))', [('a', ['(', '(', 'b', ')', ')'])])
|
"a(((b)))", [("a", ["(", "(", "b", ")", ")"])]
|
||||||
test_command_arg_quote = make_parser_test(r'a("b\"")', [('a', [r'"b\""'])])
|
)
|
||||||
test_command_arg_quote_cont = make_parser_test('a("\\\n")',
|
test_command_arg_quote = make_parser_test(r'a("b\"")', [("a", [r'"b\""'])])
|
||||||
[('a', ['"\\\n"'])])
|
test_command_arg_quote_cont = make_parser_test('a("\\\n")', [("a", ['"\\\n"'])])
|
||||||
test_command_arg_quo_multiline = make_parser_test('''a("b
|
test_command_arg_quo_multiline = make_parser_test(
|
||||||
|
"""a("b
|
||||||
c
|
c
|
||||||
")''', [('a', ['"b\nc\n"'])])
|
")""",
|
||||||
test_command_arg_bracket_0 = make_parser_test('a([[b]])', [('a', ['[[b]]'])])
|
[("a", ['"b\nc\n"'])],
|
||||||
test_command_arg_bracket_1 = make_parser_test('a([=[b]=])',
|
)
|
||||||
[('a', ['[=[b]=]'])])
|
test_command_arg_bracket_0 = make_parser_test("a([[b]])", [("a", ["[[b]]"])])
|
||||||
test_command_arg_space = make_parser_test('a ( b )', [('a', [' ', 'b', ' '])])
|
test_command_arg_bracket_1 = make_parser_test("a([=[b]=])", [("a", ["[=[b]=]"])])
|
||||||
test_command_arg_multi = make_parser_test('a(b c)', [('a', ['b', ' ', 'c'])])
|
test_command_arg_space = make_parser_test("a ( b )", [("a", [" ", "b", " "])])
|
||||||
test_command_multielement = make_parser_test('''a(
|
test_command_arg_multi = make_parser_test("a(b c)", [("a", ["b", " ", "c"])])
|
||||||
|
test_command_multielement = make_parser_test(
|
||||||
|
"""a(
|
||||||
b
|
b
|
||||||
c # c
|
c # c
|
||||||
)''', [('a', ['\n', ' ', 'b', '\n', ' ', 'c', ' ', '# c', '\n'])])
|
)""",
|
||||||
test_line_comment = make_parser_test('a() # b # c',
|
[("a", ["\n", " ", "b", "\n", " ", "c", " ", "# c", "\n"])],
|
||||||
[('a', []), ' ', '# b # c'])
|
)
|
||||||
test_bracket_comment = make_parser_test('#[[a]]#[[b]]', ['#[[a]]', '#[[b]]'])
|
test_line_comment = make_parser_test("a() # b # c", [("a", []), " ", "# b # c"])
|
||||||
test_bracket_comment_nested = make_parser_test('#[=[[[a]]]=]',
|
test_bracket_comment = make_parser_test("#[[a]]#[[b]]", ["#[[a]]", "#[[b]]"])
|
||||||
['#[=[[[a]]]=]'])
|
test_bracket_comment_nested = make_parser_test("#[=[[[a]]]=]", ["#[=[[[a]]]=]"])
|
||||||
test_bracket_comment_multiline = make_parser_test('#[[\na\nb\nc\n]]',
|
test_bracket_comment_multiline = make_parser_test(
|
||||||
['#[[\na\nb\nc\n]]'])
|
"#[[\na\nb\nc\n]]", ["#[[\na\nb\nc\n]]"]
|
||||||
test_if_block = make_parser_test('''if()
|
)
|
||||||
|
test_if_block = make_parser_test(
|
||||||
|
"""if()
|
||||||
a()
|
a()
|
||||||
else()
|
else()
|
||||||
b()
|
b()
|
||||||
endif()''', [('if', []), '\n', ' ', ('a', []), '\n', ('else', []), '\n', ' ',
|
endif()""",
|
||||||
('b', []), '\n', ('endif', [])])
|
[
|
||||||
|
("if", []),
|
||||||
|
"\n",
|
||||||
|
" ",
|
||||||
|
("a", []),
|
||||||
|
"\n",
|
||||||
|
("else", []),
|
||||||
|
"\n",
|
||||||
|
" ",
|
||||||
|
("b", []),
|
||||||
|
"\n",
|
||||||
|
("endif", []),
|
||||||
|
],
|
||||||
|
)
|
||||||
test_comment_multi_linecomment = make_parser_test(
|
test_comment_multi_linecomment = make_parser_test(
|
||||||
'''a()# a
|
"""a()# a
|
||||||
b() # b
|
b() # b
|
||||||
c() # c''', [('a', []), '# a', '\n', ('b', []), ' ', '# b', '\n',
|
c() # c""",
|
||||||
('c', []), ' ', '# c'])
|
[("a", []), "# a", "\n", ("b", []), " ", "# b", "\n", ("c", []), " ", "# c"],
|
||||||
|
)
|
||||||
|
|
||||||
test_incomplete_id = make_parser_test('a', [], 'a')
|
test_incomplete_id = make_parser_test("a", [], "a")
|
||||||
test_incomplete_command = make_parser_test('a(', [], 'a(')
|
test_incomplete_command = make_parser_test("a(", [], "a(")
|
||||||
test_incomplete_id_after_command = make_parser_test('a()\nb',
|
test_incomplete_id_after_command = make_parser_test("a()\nb", [("a", []), "\n"], "b")
|
||||||
[('a', []), '\n'], 'b')
|
|
||||||
test_incomplete_command_after_command = make_parser_test(
|
test_incomplete_command_after_command = make_parser_test(
|
||||||
'a()\nb(c', [('a', []), '\n'], 'b(c')
|
"a()\nb(c", [("a", []), "\n"], "b(c"
|
||||||
|
)
|
||||||
|
|||||||
@@ -2,14 +2,27 @@ from concurrent import futures
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
from pygls.features import (COMPLETION, FORMATTING, HOVER, INITIALIZE,
|
from pygls.features import (
|
||||||
TEXT_DOCUMENT_DID_OPEN)
|
COMPLETION,
|
||||||
|
FORMATTING,
|
||||||
|
HOVER,
|
||||||
|
INITIALIZE,
|
||||||
|
TEXT_DOCUMENT_DID_OPEN,
|
||||||
|
)
|
||||||
from pygls.server import LanguageServer
|
from pygls.server import LanguageServer
|
||||||
from pygls.types import (CompletionContext, CompletionParams,
|
from pygls.types import (
|
||||||
CompletionTriggerKind, DidOpenTextDocumentParams,
|
CompletionContext,
|
||||||
DocumentFormattingParams, FormattingOptions,
|
CompletionParams,
|
||||||
InitializeParams, Position, TextDocumentIdentifier,
|
CompletionTriggerKind,
|
||||||
TextDocumentItem, TextDocumentPositionParams)
|
DidOpenTextDocumentParams,
|
||||||
|
DocumentFormattingParams,
|
||||||
|
FormattingOptions,
|
||||||
|
InitializeParams,
|
||||||
|
Position,
|
||||||
|
TextDocumentIdentifier,
|
||||||
|
TextDocumentItem,
|
||||||
|
TextDocumentPositionParams,
|
||||||
|
)
|
||||||
|
|
||||||
CALL_TIMEOUT = 2
|
CALL_TIMEOUT = 2
|
||||||
|
|
||||||
@@ -21,8 +34,9 @@ def _init(client: LanguageServer, root: Path):
|
|||||||
client.lsp.send_request(
|
client.lsp.send_request(
|
||||||
INITIALIZE,
|
INITIALIZE,
|
||||||
InitializeParams(
|
InitializeParams(
|
||||||
process_id=1234, root_uri=root.as_uri(),
|
process_id=1234, root_uri=root.as_uri(), capabilities=None
|
||||||
capabilities=None)).result(timeout=CALL_TIMEOUT)
|
),
|
||||||
|
).result(timeout=CALL_TIMEOUT)
|
||||||
except futures.TimeoutError:
|
except futures.TimeoutError:
|
||||||
retry -= 1
|
retry -= 1
|
||||||
else:
|
else:
|
||||||
@@ -36,23 +50,24 @@ def _open(client: LanguageServer, path: Path, text: Optional[str] = None):
|
|||||||
|
|
||||||
client.lsp.notify(
|
client.lsp.notify(
|
||||||
TEXT_DOCUMENT_DID_OPEN,
|
TEXT_DOCUMENT_DID_OPEN,
|
||||||
DidOpenTextDocumentParams(
|
DidOpenTextDocumentParams(TextDocumentItem(path.as_uri(), "cmake", 1, text)),
|
||||||
TextDocumentItem(path.as_uri(), 'cmake', 1, text)))
|
)
|
||||||
|
|
||||||
|
|
||||||
def _test_completion(client_server, datadir, content: str,
|
def _test_completion(
|
||||||
context: Optional[CompletionContext]):
|
client_server, datadir, content: str, context: Optional[CompletionContext]
|
||||||
|
):
|
||||||
client, server = client_server
|
client, server = client_server
|
||||||
_init(client, datadir)
|
_init(client, datadir)
|
||||||
path = datadir / 'CMakeLists.txt'
|
path = datadir / "CMakeLists.txt"
|
||||||
_open(client, path, content)
|
_open(client, path, content)
|
||||||
params = CompletionParams(TextDocumentIdentifier(path.as_uri()),
|
params = CompletionParams(
|
||||||
Position(0, len(content)), context)
|
TextDocumentIdentifier(path.as_uri()), Position(0, len(content)), context
|
||||||
|
)
|
||||||
if context is None:
|
if context is None:
|
||||||
# some clients do not send context
|
# some clients do not send context
|
||||||
del params.context
|
del params.context
|
||||||
return client.lsp.send_request(COMPLETION,
|
return client.lsp.send_request(COMPLETION, params).result(timeout=CALL_TIMEOUT)
|
||||||
params).result(timeout=CALL_TIMEOUT)
|
|
||||||
|
|
||||||
|
|
||||||
def test_initialize(client_server, datadir):
|
def test_initialize(client_server, datadir):
|
||||||
@@ -65,72 +80,83 @@ def test_initialize(client_server, datadir):
|
|||||||
|
|
||||||
def test_completions_invoked(client_server, datadir):
|
def test_completions_invoked(client_server, datadir):
|
||||||
response = _test_completion(
|
response = _test_completion(
|
||||||
client_server, datadir, 'projec',
|
client_server,
|
||||||
CompletionContext(CompletionTriggerKind.Invoked))
|
datadir,
|
||||||
item = next(filter(lambda x: x.label == 'project', response.items), None)
|
"projec",
|
||||||
|
CompletionContext(CompletionTriggerKind.Invoked),
|
||||||
|
)
|
||||||
|
item = next(filter(lambda x: x.label == "project", response.items), None)
|
||||||
assert item is not None
|
assert item is not None
|
||||||
assert '<PROJECT-NAME>' in item.documentation
|
assert "<PROJECT-NAME>" in item.documentation
|
||||||
|
|
||||||
|
|
||||||
def test_completions_nocontext(client_server, datadir):
|
def test_completions_nocontext(client_server, datadir):
|
||||||
response = _test_completion(client_server, datadir, 'projec', None)
|
response = _test_completion(client_server, datadir, "projec", None)
|
||||||
item = next(filter(lambda x: x.label == 'project', response.items), None)
|
item = next(filter(lambda x: x.label == "project", response.items), None)
|
||||||
assert item is not None
|
assert item is not None
|
||||||
assert '<PROJECT-NAME>' in item.documentation
|
assert "<PROJECT-NAME>" in item.documentation
|
||||||
|
|
||||||
|
|
||||||
def test_completions_triggercharacter_variable(client_server, datadir):
|
def test_completions_triggercharacter_variable(client_server, datadir):
|
||||||
response = _test_completion(
|
response = _test_completion(
|
||||||
client_server, datadir, '${',
|
client_server,
|
||||||
CompletionContext(CompletionTriggerKind.TriggerCharacter, '{'))
|
datadir,
|
||||||
assert 'PROJECT_VERSION' in [x.label for x in response.items]
|
"${",
|
||||||
|
CompletionContext(CompletionTriggerKind.TriggerCharacter, "{"),
|
||||||
|
)
|
||||||
|
assert "PROJECT_VERSION" in [x.label for x in response.items]
|
||||||
|
|
||||||
response_nocontext = _test_completion(client_server, datadir, '${', None)
|
response_nocontext = _test_completion(client_server, datadir, "${", None)
|
||||||
assert response == response_nocontext
|
assert response == response_nocontext
|
||||||
|
|
||||||
|
|
||||||
def test_completions_triggercharacter_module(client_server, datadir):
|
def test_completions_triggercharacter_module(client_server, datadir):
|
||||||
response = _test_completion(
|
response = _test_completion(
|
||||||
client_server, datadir, 'include(',
|
client_server,
|
||||||
CompletionContext(CompletionTriggerKind.TriggerCharacter, '('))
|
datadir,
|
||||||
assert 'GoogleTest' in [x.label for x in response.items]
|
"include(",
|
||||||
|
CompletionContext(CompletionTriggerKind.TriggerCharacter, "("),
|
||||||
|
)
|
||||||
|
assert "GoogleTest" in [x.label for x in response.items]
|
||||||
|
|
||||||
response_nocontext = _test_completion(client_server, datadir, 'include(',
|
response_nocontext = _test_completion(client_server, datadir, "include(", None)
|
||||||
None)
|
|
||||||
assert response == response_nocontext
|
assert response == response_nocontext
|
||||||
|
|
||||||
|
|
||||||
def test_completions_triggercharacter_package(client_server, datadir):
|
def test_completions_triggercharacter_package(client_server, datadir):
|
||||||
response = _test_completion(
|
response = _test_completion(
|
||||||
client_server, datadir, 'find_package(',
|
client_server,
|
||||||
CompletionContext(CompletionTriggerKind.TriggerCharacter, '('))
|
datadir,
|
||||||
assert 'Boost' in [x.label for x in response.items]
|
"find_package(",
|
||||||
|
CompletionContext(CompletionTriggerKind.TriggerCharacter, "("),
|
||||||
|
)
|
||||||
|
assert "Boost" in [x.label for x in response.items]
|
||||||
|
|
||||||
response_nocontext = _test_completion(client_server, datadir,
|
response_nocontext = _test_completion(client_server, datadir, "find_package(", None)
|
||||||
'find_package(', None)
|
|
||||||
assert response == response_nocontext
|
assert response == response_nocontext
|
||||||
|
|
||||||
|
|
||||||
def test_formatting(client_server, datadir):
|
def test_formatting(client_server, datadir):
|
||||||
client, server = client_server
|
client, server = client_server
|
||||||
_init(client, datadir)
|
_init(client, datadir)
|
||||||
path = datadir / 'CMakeLists.txt'
|
path = datadir / "CMakeLists.txt"
|
||||||
_open(client, path, 'a ( b c ) ')
|
_open(client, path, "a ( b c ) ")
|
||||||
response = client.lsp.send_request(
|
response = client.lsp.send_request(
|
||||||
FORMATTING,
|
FORMATTING,
|
||||||
DocumentFormattingParams(TextDocumentIdentifier(path.as_uri()),
|
DocumentFormattingParams(
|
||||||
FormattingOptions(
|
TextDocumentIdentifier(path.as_uri()), FormattingOptions(2, True)
|
||||||
2, True))).result(timeout=CALL_TIMEOUT)
|
),
|
||||||
assert response[0].newText == 'a(b c)\n'
|
).result(timeout=CALL_TIMEOUT)
|
||||||
|
assert response[0].newText == "a(b c)\n"
|
||||||
|
|
||||||
|
|
||||||
def test_hover(client_server, datadir):
|
def test_hover(client_server, datadir):
|
||||||
client, server = client_server
|
client, server = client_server
|
||||||
_init(client, datadir)
|
_init(client, datadir)
|
||||||
path = datadir / 'CMakeLists.txt'
|
path = datadir / "CMakeLists.txt"
|
||||||
_open(client, path, 'project()')
|
_open(client, path, "project()")
|
||||||
response = client.lsp.send_request(
|
response = client.lsp.send_request(
|
||||||
HOVER,
|
HOVER,
|
||||||
TextDocumentPositionParams(TextDocumentIdentifier(path.as_uri()),
|
TextDocumentPositionParams(TextDocumentIdentifier(path.as_uri()), Position()),
|
||||||
Position())).result(timeout=CALL_TIMEOUT)
|
).result(timeout=CALL_TIMEOUT)
|
||||||
assert '<PROJECT-NAME>' in response.contents.value
|
assert "<PROJECT-NAME>" in response.contents.value
|
||||||
|
|||||||
14
tox.ini
14
tox.ini
@@ -1,3 +1,15 @@
|
|||||||
|
[isort]
|
||||||
|
multi_line_output = 3
|
||||||
|
include_trailing_comma = True
|
||||||
|
force_grid_wrap = 0
|
||||||
|
use_parentheses = True
|
||||||
|
ensure_newline_before_comments = True
|
||||||
|
line_length = 88
|
||||||
|
|
||||||
|
[flake8]
|
||||||
|
max-line-length = 88
|
||||||
|
extend-ignore = E203, W503
|
||||||
|
|
||||||
[tox]
|
[tox]
|
||||||
isolated_build = True
|
isolated_build = True
|
||||||
skipsdist = True
|
skipsdist = True
|
||||||
@@ -21,6 +33,6 @@ commands =
|
|||||||
[testenv:lint]
|
[testenv:lint]
|
||||||
commands =
|
commands =
|
||||||
poetry run isort -c -rc src tests
|
poetry run isort -c -rc src tests
|
||||||
poetry run yapf -d -r src tests
|
poetry run black --diff src tests
|
||||||
poetry run flake8 src tests
|
poetry run flake8 src tests
|
||||||
poetry run mypy src tests
|
poetry run mypy src tests
|
||||||
|
|||||||
Reference in New Issue
Block a user