Add shell completions by shtab
See #1992 pytest --print-completion bash | sudo tee /usr/share/bash-completion/completions/pytest pytest --print-completion tcsh | sudo tee /etc/profile.d/pytest.completion.csh pytest --print-completion zsh | sudo tee /usr/share/zsh/site-functions/_pytest
This commit is contained in:
parent
5bd41befa8
commit
5f673aca65
1
AUTHORS
1
AUTHORS
|
@ -365,6 +365,7 @@ Wil Cooley
|
||||||
William Lee
|
William Lee
|
||||||
Wim Glenn
|
Wim Glenn
|
||||||
Wouter van Ackooy
|
Wouter van Ackooy
|
||||||
|
Wu Zhenyu
|
||||||
Xixi Zhao
|
Xixi Zhao
|
||||||
Xuan Luong
|
Xuan Luong
|
||||||
Xuecong Liao
|
Xuecong Liao
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Added shell completions by shtab
|
|
@ -64,6 +64,8 @@ console_scripts =
|
||||||
py.test=pytest:console_main
|
py.test=pytest:console_main
|
||||||
|
|
||||||
[options.extras_require]
|
[options.extras_require]
|
||||||
|
completion =
|
||||||
|
shtab
|
||||||
testing =
|
testing =
|
||||||
argcomplete
|
argcomplete
|
||||||
hypothesis>=3.56
|
hypothesis>=3.56
|
||||||
|
@ -71,6 +73,7 @@ testing =
|
||||||
nose
|
nose
|
||||||
pygments>=2.7.2
|
pygments>=2.7.2
|
||||||
requests
|
requests
|
||||||
|
shtab
|
||||||
xmlschema
|
xmlschema
|
||||||
|
|
||||||
[options.package_data]
|
[options.package_data]
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
__all__ = ["__version__", "version_tuple"]
|
__all__ = ["__version__", "version_tuple", "shtab", "XML_FILE", "PREAMBLE"]
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from ._version import version as __version__, version_tuple
|
from ._version import version as __version__, version_tuple
|
||||||
|
@ -7,3 +7,24 @@ except ImportError: # pragma: no cover
|
||||||
# unknown only works because we do poor mans version compare
|
# unknown only works because we do poor mans version compare
|
||||||
__version__ = "unknown"
|
__version__ = "unknown"
|
||||||
version_tuple = (0, 0, "unknown") # type:ignore[assignment]
|
version_tuple = (0, 0, "unknown") # type:ignore[assignment]
|
||||||
|
|
||||||
|
try:
|
||||||
|
import shtab
|
||||||
|
except ImportError:
|
||||||
|
from . import _shtab as shtab
|
||||||
|
|
||||||
|
# https://github.com/iterative/shtab/blob/5358dda86e8ea98bf801a43a24ad73cd9f820c63/examples/customcomplete.py#L11-L22
|
||||||
|
XML_FILE = {
|
||||||
|
"bash": "_shtab_greeter_compgen_xml_files",
|
||||||
|
"zsh": "_files -g '*.xml'",
|
||||||
|
"tcsh": "f:*.xml",
|
||||||
|
}
|
||||||
|
PREAMBLE = {
|
||||||
|
"bash": """
|
||||||
|
# $1=COMP_WORDS[1]
|
||||||
|
_shtab_greeter_compgen_xml_files() {
|
||||||
|
compgen -d -- $1 # recurse into subdirs
|
||||||
|
compgen -f -X '!*?.xml' -- $1
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
"""A shim of shtab."""
|
||||||
|
from argparse import Action
|
||||||
|
from argparse import ArgumentParser
|
||||||
|
from typing import Any
|
||||||
|
from typing import Dict
|
||||||
|
from typing import List
|
||||||
|
|
||||||
|
FILE = None
|
||||||
|
DIRECTORY = DIR = None
|
||||||
|
|
||||||
|
|
||||||
|
def add_argument_to(parser: ArgumentParser, *args: List[Any], **kwargs: Dict[str, Any]):
|
||||||
|
Action.complete = None # type: ignore
|
||||||
|
return parser
|
|
@ -17,6 +17,8 @@ from typing import TYPE_CHECKING
|
||||||
from typing import Union
|
from typing import Union
|
||||||
|
|
||||||
import _pytest._io
|
import _pytest._io
|
||||||
|
from _pytest import PREAMBLE
|
||||||
|
from _pytest import shtab
|
||||||
from _pytest.compat import final
|
from _pytest.compat import final
|
||||||
from _pytest.config.exceptions import UsageError
|
from _pytest.config.exceptions import UsageError
|
||||||
from _pytest.deprecated import ARGUMENT_PERCENT_DEFAULT
|
from _pytest.deprecated import ARGUMENT_PERCENT_DEFAULT
|
||||||
|
@ -27,6 +29,7 @@ from _pytest.deprecated import check_ispytest
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from typing_extensions import Literal
|
from typing_extensions import Literal
|
||||||
|
|
||||||
|
|
||||||
FILE_OR_DIR = "file_or_dir"
|
FILE_OR_DIR = "file_or_dir"
|
||||||
|
|
||||||
|
|
||||||
|
@ -124,11 +127,19 @@ class Parser:
|
||||||
if group.options:
|
if group.options:
|
||||||
desc = group.description or group.name
|
desc = group.description or group.name
|
||||||
arggroup = optparser.add_argument_group(desc)
|
arggroup = optparser.add_argument_group(desc)
|
||||||
|
if group.name == "debugconfig":
|
||||||
|
shtab.add_argument_to(arggroup, preamble=PREAMBLE)
|
||||||
for option in group.options:
|
for option in group.options:
|
||||||
n = option.names()
|
n = option.names()
|
||||||
a = option.attrs()
|
a = option.attrs()
|
||||||
arggroup.add_argument(*n, **a)
|
complete = a.get("complete")
|
||||||
|
if complete:
|
||||||
|
del a["complete"] # type: ignore
|
||||||
|
action = arggroup.add_argument(*n, **a)
|
||||||
|
if complete:
|
||||||
|
action.complete = complete # type: ignore
|
||||||
file_or_dir_arg = optparser.add_argument(FILE_OR_DIR, nargs="*")
|
file_or_dir_arg = optparser.add_argument(FILE_OR_DIR, nargs="*")
|
||||||
|
file_or_dir_arg.complete = shtab.FILE # type: ignore
|
||||||
# bash like autocompletion for dirs (appending '/')
|
# bash like autocompletion for dirs (appending '/')
|
||||||
# Type ignored because typeshed doesn't know about argcomplete.
|
# Type ignored because typeshed doesn't know about argcomplete.
|
||||||
file_or_dir_arg.completer = filescompleter # type: ignore
|
file_or_dir_arg.completer = filescompleter # type: ignore
|
||||||
|
|
|
@ -7,6 +7,7 @@ from typing import Optional
|
||||||
from typing import Union
|
from typing import Union
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
from _pytest import shtab
|
||||||
from _pytest.config import Config
|
from _pytest.config import Config
|
||||||
from _pytest.config import ExitCode
|
from _pytest.config import ExitCode
|
||||||
from _pytest.config import PrintHelp
|
from _pytest.config import PrintHelp
|
||||||
|
@ -86,6 +87,7 @@ def pytest_addoption(parser: Parser) -> None:
|
||||||
help="Store internal tracing debug information in this log file. "
|
help="Store internal tracing debug information in this log file. "
|
||||||
"This file is opened with 'w' and truncated as a result, care advised. "
|
"This file is opened with 'w' and truncated as a result, care advised. "
|
||||||
"Default: pytestdebug.log.",
|
"Default: pytestdebug.log.",
|
||||||
|
complete=shtab.FILE,
|
||||||
)
|
)
|
||||||
group._addoption(
|
group._addoption(
|
||||||
"-o",
|
"-o",
|
||||||
|
|
|
@ -21,6 +21,7 @@ from typing import Tuple
|
||||||
from typing import Union
|
from typing import Union
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
from . import XML_FILE
|
||||||
from _pytest import nodes
|
from _pytest import nodes
|
||||||
from _pytest import timing
|
from _pytest import timing
|
||||||
from _pytest._code.code import ExceptionRepr
|
from _pytest._code.code import ExceptionRepr
|
||||||
|
@ -33,7 +34,6 @@ from _pytest.reports import TestReport
|
||||||
from _pytest.stash import StashKey
|
from _pytest.stash import StashKey
|
||||||
from _pytest.terminal import TerminalReporter
|
from _pytest.terminal import TerminalReporter
|
||||||
|
|
||||||
|
|
||||||
xml_key = StashKey["LogXML"]()
|
xml_key = StashKey["LogXML"]()
|
||||||
|
|
||||||
|
|
||||||
|
@ -390,6 +390,7 @@ def pytest_addoption(parser: Parser) -> None:
|
||||||
type=functools.partial(filename_arg, optname="--junitxml"),
|
type=functools.partial(filename_arg, optname="--junitxml"),
|
||||||
default=None,
|
default=None,
|
||||||
help="Create junit-xml style report file at given path",
|
help="Create junit-xml style report file at given path",
|
||||||
|
complete=XML_FILE,
|
||||||
)
|
)
|
||||||
group.addoption(
|
group.addoption(
|
||||||
"--junitprefix",
|
"--junitprefix",
|
||||||
|
|
|
@ -19,6 +19,7 @@ from typing import TypeVar
|
||||||
from typing import Union
|
from typing import Union
|
||||||
|
|
||||||
from _pytest import nodes
|
from _pytest import nodes
|
||||||
|
from _pytest import shtab
|
||||||
from _pytest._io import TerminalWriter
|
from _pytest._io import TerminalWriter
|
||||||
from _pytest.capture import CaptureManager
|
from _pytest.capture import CaptureManager
|
||||||
from _pytest.compat import final
|
from _pytest.compat import final
|
||||||
|
@ -35,6 +36,7 @@ from _pytest.main import Session
|
||||||
from _pytest.stash import StashKey
|
from _pytest.stash import StashKey
|
||||||
from _pytest.terminal import TerminalReporter
|
from _pytest.terminal import TerminalReporter
|
||||||
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
logging_StreamHandler = logging.StreamHandler[StringIO]
|
logging_StreamHandler = logging.StreamHandler[StringIO]
|
||||||
|
|
||||||
|
@ -272,6 +274,7 @@ def pytest_addoption(parser: Parser) -> None:
|
||||||
dest="log_file",
|
dest="log_file",
|
||||||
default=None,
|
default=None,
|
||||||
help="Path to a file when logging will be written to",
|
help="Path to a file when logging will be written to",
|
||||||
|
complete=shtab.FILE,
|
||||||
)
|
)
|
||||||
add_option_ini(
|
add_option_ini(
|
||||||
"--log-file-level",
|
"--log-file-level",
|
||||||
|
|
|
@ -23,6 +23,7 @@ import attr
|
||||||
|
|
||||||
import _pytest._code
|
import _pytest._code
|
||||||
from _pytest import nodes
|
from _pytest import nodes
|
||||||
|
from _pytest import shtab
|
||||||
from _pytest.compat import final
|
from _pytest.compat import final
|
||||||
from _pytest.compat import overload
|
from _pytest.compat import overload
|
||||||
from _pytest.config import Config
|
from _pytest.config import Config
|
||||||
|
@ -128,6 +129,7 @@ def pytest_addoption(parser: Parser) -> None:
|
||||||
dest="inifilename",
|
dest="inifilename",
|
||||||
help="Load configuration from `file` instead of trying to locate one of the "
|
help="Load configuration from `file` instead of trying to locate one of the "
|
||||||
"implicit configuration files",
|
"implicit configuration files",
|
||||||
|
complete=shtab.FILE,
|
||||||
)
|
)
|
||||||
group._addoption(
|
group._addoption(
|
||||||
"--continue-on-collection-errors",
|
"--continue-on-collection-errors",
|
||||||
|
@ -143,6 +145,7 @@ def pytest_addoption(parser: Parser) -> None:
|
||||||
help="Define root directory for tests. Can be relative path: 'root_dir', './root_dir', "
|
help="Define root directory for tests. Can be relative path: 'root_dir', './root_dir', "
|
||||||
"'root_dir/another_dir/'; absolute path: '/home/user/root_dir'; path with variables: "
|
"'root_dir/another_dir/'; absolute path: '/home/user/root_dir'; path with variables: "
|
||||||
"'$HOME/root_dir'.",
|
"'$HOME/root_dir'.",
|
||||||
|
complete=shtab.DIR,
|
||||||
)
|
)
|
||||||
|
|
||||||
group = parser.getgroup("collect", "collection")
|
group = parser.getgroup("collect", "collection")
|
||||||
|
@ -183,6 +186,7 @@ def pytest_addoption(parser: Parser) -> None:
|
||||||
metavar="dir",
|
metavar="dir",
|
||||||
type=functools.partial(directory_arg, optname="--confcutdir"),
|
type=functools.partial(directory_arg, optname="--confcutdir"),
|
||||||
help="Only load conftest.py's relative to specified dir",
|
help="Only load conftest.py's relative to specified dir",
|
||||||
|
complete=shtab.DIR,
|
||||||
)
|
)
|
||||||
group.addoption(
|
group.addoption(
|
||||||
"--noconftest",
|
"--noconftest",
|
||||||
|
@ -226,6 +230,7 @@ def pytest_addoption(parser: Parser) -> None:
|
||||||
"Base temporary directory for this test run. "
|
"Base temporary directory for this test run. "
|
||||||
"(Warning: this directory is removed if it exists.)"
|
"(Warning: this directory is removed if it exists.)"
|
||||||
),
|
),
|
||||||
|
complete=shtab.DIR,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue