mirror of
https://github.com/pre-commit/pre-commit.git
synced 2026-02-17 08:14:42 +04:00
Merge pull request #2602 from pre-commit/mypy-modules-as-protocols
use modules as protocols
This commit is contained in:
commit
d33df92add
3 changed files with 60 additions and 70 deletions
|
|
@ -1,7 +1,6 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from typing import Callable
|
from typing import Protocol
|
||||||
from typing import NamedTuple
|
|
||||||
from typing import Sequence
|
from typing import Sequence
|
||||||
|
|
||||||
from pre_commit.hook import Hook
|
from pre_commit.hook import Hook
|
||||||
|
|
@ -27,44 +26,61 @@ from pre_commit.languages import system
|
||||||
from pre_commit.prefix import Prefix
|
from pre_commit.prefix import Prefix
|
||||||
|
|
||||||
|
|
||||||
class Language(NamedTuple):
|
class Language(Protocol):
|
||||||
name: str
|
|
||||||
# Use `None` for no installation / environment
|
# Use `None` for no installation / environment
|
||||||
ENVIRONMENT_DIR: str | None
|
@property
|
||||||
|
def ENVIRONMENT_DIR(self) -> str | None: ...
|
||||||
# return a value to replace `'default` for `language_version`
|
# return a value to replace `'default` for `language_version`
|
||||||
get_default_version: Callable[[], str]
|
def get_default_version(self) -> str: ...
|
||||||
|
|
||||||
# return whether the environment is healthy (or should be rebuilt)
|
# return whether the environment is healthy (or should be rebuilt)
|
||||||
health_check: Callable[[Prefix, str], str | None]
|
def health_check(
|
||||||
|
self,
|
||||||
|
prefix: Prefix,
|
||||||
|
language_version: str,
|
||||||
|
) -> str | None:
|
||||||
|
...
|
||||||
|
|
||||||
# install a repository for the given language and language_version
|
# install a repository for the given language and language_version
|
||||||
install_environment: Callable[[Prefix, str, Sequence[str]], None]
|
def install_environment(
|
||||||
|
self,
|
||||||
|
prefix: Prefix,
|
||||||
|
version: str,
|
||||||
|
additional_dependencies: Sequence[str],
|
||||||
|
) -> None:
|
||||||
|
...
|
||||||
|
|
||||||
# execute a hook and return the exit code and output
|
# execute a hook and return the exit code and output
|
||||||
run_hook: Callable[[Hook, Sequence[str], bool], tuple[int, bytes]]
|
def run_hook(
|
||||||
|
self,
|
||||||
|
hook: Hook,
|
||||||
|
file_args: Sequence[str],
|
||||||
|
color: bool,
|
||||||
|
) -> tuple[int, bytes]:
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
# TODO: back to modules + Protocol: https://github.com/python/mypy/issues/5018
|
languages: dict[str, Language] = {
|
||||||
languages = {
|
'conda': conda,
|
||||||
# BEGIN GENERATED (testing/gen-languages-all)
|
'coursier': coursier,
|
||||||
'conda': Language(name='conda', ENVIRONMENT_DIR=conda.ENVIRONMENT_DIR, get_default_version=conda.get_default_version, health_check=conda.health_check, install_environment=conda.install_environment, run_hook=conda.run_hook), # noqa: E501
|
'dart': dart,
|
||||||
'coursier': Language(name='coursier', ENVIRONMENT_DIR=coursier.ENVIRONMENT_DIR, get_default_version=coursier.get_default_version, health_check=coursier.health_check, install_environment=coursier.install_environment, run_hook=coursier.run_hook), # noqa: E501
|
'docker': docker,
|
||||||
'dart': Language(name='dart', ENVIRONMENT_DIR=dart.ENVIRONMENT_DIR, get_default_version=dart.get_default_version, health_check=dart.health_check, install_environment=dart.install_environment, run_hook=dart.run_hook), # noqa: E501
|
'docker_image': docker_image,
|
||||||
'docker': Language(name='docker', ENVIRONMENT_DIR=docker.ENVIRONMENT_DIR, get_default_version=docker.get_default_version, health_check=docker.health_check, install_environment=docker.install_environment, run_hook=docker.run_hook), # noqa: E501
|
'dotnet': dotnet,
|
||||||
'docker_image': Language(name='docker_image', ENVIRONMENT_DIR=docker_image.ENVIRONMENT_DIR, get_default_version=docker_image.get_default_version, health_check=docker_image.health_check, install_environment=docker_image.install_environment, run_hook=docker_image.run_hook), # noqa: E501
|
'fail': fail,
|
||||||
'dotnet': Language(name='dotnet', ENVIRONMENT_DIR=dotnet.ENVIRONMENT_DIR, get_default_version=dotnet.get_default_version, health_check=dotnet.health_check, install_environment=dotnet.install_environment, run_hook=dotnet.run_hook), # noqa: E501
|
'golang': golang,
|
||||||
'fail': Language(name='fail', ENVIRONMENT_DIR=fail.ENVIRONMENT_DIR, get_default_version=fail.get_default_version, health_check=fail.health_check, install_environment=fail.install_environment, run_hook=fail.run_hook), # noqa: E501
|
'lua': lua,
|
||||||
'golang': Language(name='golang', ENVIRONMENT_DIR=golang.ENVIRONMENT_DIR, get_default_version=golang.get_default_version, health_check=golang.health_check, install_environment=golang.install_environment, run_hook=golang.run_hook), # noqa: E501
|
'node': node,
|
||||||
'lua': Language(name='lua', ENVIRONMENT_DIR=lua.ENVIRONMENT_DIR, get_default_version=lua.get_default_version, health_check=lua.health_check, install_environment=lua.install_environment, run_hook=lua.run_hook), # noqa: E501
|
'perl': perl,
|
||||||
'node': Language(name='node', ENVIRONMENT_DIR=node.ENVIRONMENT_DIR, get_default_version=node.get_default_version, health_check=node.health_check, install_environment=node.install_environment, run_hook=node.run_hook), # noqa: E501
|
'pygrep': pygrep,
|
||||||
'perl': Language(name='perl', ENVIRONMENT_DIR=perl.ENVIRONMENT_DIR, get_default_version=perl.get_default_version, health_check=perl.health_check, install_environment=perl.install_environment, run_hook=perl.run_hook), # noqa: E501
|
'python': python,
|
||||||
'pygrep': Language(name='pygrep', ENVIRONMENT_DIR=pygrep.ENVIRONMENT_DIR, get_default_version=pygrep.get_default_version, health_check=pygrep.health_check, install_environment=pygrep.install_environment, run_hook=pygrep.run_hook), # noqa: E501
|
'r': r,
|
||||||
'python': Language(name='python', ENVIRONMENT_DIR=python.ENVIRONMENT_DIR, get_default_version=python.get_default_version, health_check=python.health_check, install_environment=python.install_environment, run_hook=python.run_hook), # noqa: E501
|
'ruby': ruby,
|
||||||
'r': Language(name='r', ENVIRONMENT_DIR=r.ENVIRONMENT_DIR, get_default_version=r.get_default_version, health_check=r.health_check, install_environment=r.install_environment, run_hook=r.run_hook), # noqa: E501
|
'rust': rust,
|
||||||
'ruby': Language(name='ruby', ENVIRONMENT_DIR=ruby.ENVIRONMENT_DIR, get_default_version=ruby.get_default_version, health_check=ruby.health_check, install_environment=ruby.install_environment, run_hook=ruby.run_hook), # noqa: E501
|
'script': script,
|
||||||
'rust': Language(name='rust', ENVIRONMENT_DIR=rust.ENVIRONMENT_DIR, get_default_version=rust.get_default_version, health_check=rust.health_check, install_environment=rust.install_environment, run_hook=rust.run_hook), # noqa: E501
|
'swift': swift,
|
||||||
'script': Language(name='script', ENVIRONMENT_DIR=script.ENVIRONMENT_DIR, get_default_version=script.get_default_version, health_check=script.health_check, install_environment=script.install_environment, run_hook=script.run_hook), # noqa: E501
|
'system': system,
|
||||||
'swift': Language(name='swift', ENVIRONMENT_DIR=swift.ENVIRONMENT_DIR, get_default_version=swift.get_default_version, health_check=swift.health_check, install_environment=swift.install_environment, run_hook=swift.run_hook), # noqa: E501
|
# TODO: fully deprecate `python_venv`
|
||||||
'system': Language(name='system', ENVIRONMENT_DIR=system.ENVIRONMENT_DIR, get_default_version=system.get_default_version, health_check=system.health_check, install_environment=system.install_environment, run_hook=system.run_hook), # noqa: E501
|
'python_venv': python,
|
||||||
# END GENERATED
|
|
||||||
}
|
}
|
||||||
# TODO: fully deprecate `python_venv`
|
|
||||||
languages['python_venv'] = languages['python']
|
|
||||||
all_languages = sorted(languages)
|
all_languages = sorted(languages)
|
||||||
|
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
#!/usr/bin/env python3
|
|
||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
import sys
|
|
||||||
|
|
||||||
LANGUAGES = (
|
|
||||||
'conda', 'coursier', 'dart', 'docker', 'docker_image', 'dotnet', 'fail',
|
|
||||||
'golang', 'lua', 'node', 'perl', 'pygrep', 'python', 'r', 'ruby', 'rust',
|
|
||||||
'script', 'swift', 'system',
|
|
||||||
)
|
|
||||||
FIELDS = (
|
|
||||||
'ENVIRONMENT_DIR', 'get_default_version', 'health_check',
|
|
||||||
'install_environment', 'run_hook',
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def main() -> int:
|
|
||||||
print(f' # BEGIN GENERATED ({sys.argv[0]})')
|
|
||||||
for lang in LANGUAGES:
|
|
||||||
parts = [f' {lang!r}: Language(name={lang!r}']
|
|
||||||
for k in FIELDS:
|
|
||||||
parts.append(f', {k}={lang}.{k}')
|
|
||||||
parts.append('), # noqa: E501')
|
|
||||||
print(''.join(parts))
|
|
||||||
print(' # END GENERATED')
|
|
||||||
return 0
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
raise SystemExit(main())
|
|
||||||
|
|
@ -133,9 +133,11 @@ def test_python_hook(tempdir_factory, store):
|
||||||
def test_python_hook_default_version(tempdir_factory, store):
|
def test_python_hook_default_version(tempdir_factory, store):
|
||||||
# make sure that this continues to work for platforms where default
|
# make sure that this continues to work for platforms where default
|
||||||
# language detection does not work
|
# language detection does not work
|
||||||
returns_default = mock.Mock(return_value=C.DEFAULT)
|
with mock.patch.object(
|
||||||
lang = languages['python']._replace(get_default_version=returns_default)
|
python,
|
||||||
with mock.patch.dict(languages, python=lang):
|
'get_default_version',
|
||||||
|
return_value=C.DEFAULT,
|
||||||
|
):
|
||||||
test_python_hook(tempdir_factory, store)
|
test_python_hook(tempdir_factory, store)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -247,9 +249,11 @@ def test_run_a_node_hook(tempdir_factory, store):
|
||||||
def test_run_a_node_hook_default_version(tempdir_factory, store):
|
def test_run_a_node_hook_default_version(tempdir_factory, store):
|
||||||
# make sure that this continues to work for platforms where node is not
|
# make sure that this continues to work for platforms where node is not
|
||||||
# installed at the system
|
# installed at the system
|
||||||
returns_default = mock.Mock(return_value=C.DEFAULT)
|
with mock.patch.object(
|
||||||
lang = languages['node']._replace(get_default_version=returns_default)
|
node,
|
||||||
with mock.patch.dict(languages, node=lang):
|
'get_default_version',
|
||||||
|
return_value=C.DEFAULT,
|
||||||
|
):
|
||||||
test_run_a_node_hook(tempdir_factory, store)
|
test_run_a_node_hook(tempdir_factory, store)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue