| 286 | |
| 287 | |
| 288 | def test_argcomplete(pytester: Pytester, monkeypatch: MonkeyPatch) -> None: |
| 289 | if sys.version_info >= (3, 11): |
| 290 | # New in Python 3.11, ignores utf-8 mode |
| 291 | encoding = locale.getencoding() |
| 292 | else: |
| 293 | encoding = locale.getpreferredencoding(False) |
| 294 | try: |
| 295 | bash_version = subprocess.run( |
| 296 | ["bash", "--version"], |
| 297 | stdout=subprocess.PIPE, |
| 298 | stderr=subprocess.DEVNULL, |
| 299 | check=True, |
| 300 | text=True, |
| 301 | encoding=encoding, |
| 302 | ).stdout |
| 303 | except (OSError, subprocess.CalledProcessError): |
| 304 | pytest.skip("bash is not available") |
| 305 | if "GNU bash" not in bash_version: |
| 306 | # See #7518. |
| 307 | pytest.skip("not a real bash") |
| 308 | |
| 309 | script = str(pytester.path.joinpath("test_argcomplete")) |
| 310 | |
| 311 | with open(str(script), "w", encoding="utf-8") as fp: |
| 312 | # redirect output from argcomplete to stdin and stderr is not trivial |
| 313 | # http://stackoverflow.com/q/12589419/1307905 |
| 314 | # so we use bash |
| 315 | fp.write( |
| 316 | f'COMP_WORDBREAKS="$COMP_WORDBREAKS" {shlex.quote(sys.executable)} -m pytest 8>&1 9>&2' |
| 317 | ) |
| 318 | # alternative would be extended Pytester.{run(),_run(),popen()} to be able |
| 319 | # to handle a keyword argument env that replaces os.environ in popen or |
| 320 | # extends the copy, advantage: could not forget to restore |
| 321 | monkeypatch.setenv("_ARGCOMPLETE", "1") |
| 322 | monkeypatch.setenv("_ARGCOMPLETE_IFS", "\x0b") |
| 323 | monkeypatch.setenv("COMP_WORDBREAKS", " \\t\\n\"\\'><=;|&(:") |
| 324 | |
| 325 | arg = "--fu" |
| 326 | monkeypatch.setenv("COMP_LINE", "pytest " + arg) |
| 327 | monkeypatch.setenv("COMP_POINT", str(len("pytest " + arg))) |
| 328 | result = pytester.run("bash", str(script), arg) |
| 329 | if result.ret == 255: |
| 330 | # argcomplete not found |
| 331 | pytest.skip("argcomplete not available") |
| 332 | elif not result.stdout.str(): |
| 333 | pytest.skip( |
| 334 | f"bash provided no output on stdout, argcomplete not available? (stderr={result.stderr.str()!r})" |
| 335 | ) |
| 336 | else: |
| 337 | result.stdout.fnmatch_lines(["--funcargs", "--fulltrace"]) |
| 338 | os.mkdir("test_argcomplete.d") |
| 339 | arg = "test_argc" |
| 340 | monkeypatch.setenv("COMP_LINE", "pytest " + arg) |
| 341 | monkeypatch.setenv("COMP_POINT", str(len("pytest " + arg))) |
| 342 | result = pytester.run("bash", str(script), arg) |
| 343 | result.stdout.fnmatch_lines(["test_argcomplete", "test_argcomplete.d/"]) |
| 344 | |
| 345 | |