test_argcomplete.py
Overview
The `test_argcomplete.py` file is a test utility module designed to validate and compare behaviors of file completion mechanisms similar to those used in shell environments, specifically Bash. It primarily tests various file completer implementations to ensure they produce consistent and expected autocompletion results for file and directory names.
The tests utilize subprocess calls to the Bash `compgen` builtin command to generate baseline completions and then compare these with Python-based completers (`FilesCompleter` and `FastFilesCompleter`). This file is particularly focused on verifying compatibility and correctness of autocompletion logic, excluding platform-specific issues (notably skipping tests on Windows and macOS).
Detailed Explanation
Functions
equal_with_bash(prefix, ffc, fc, out=None)
Compares the output of two file completion functions against each other, with one being a Python completer and the other based on Bash's `compgen`.
Parameters:
prefix(str): The initial string prefix for which completions are sought.ffc(callable): A Python completer function/class instance (e.g.,FastFilesCompleter).fc(callable): Another Python completer (e.g.,FilesCompleter) whose output is compared against.out(file-like, optional): An output stream for logging comparison details (default: None).
Returns:
bool:Trueif both completion sets are equal, False otherwise.
Usage Example:
result = equal_with_bash("data", FastFilesCompleter(), FilesCompleter(), out=sys.stdout) print(result) # True if completions matchImplementation Details:
Calls both completers with the same prefix.
Converts their outputs to sets and compares them.
Logs differences when output stream is provided.
Utility Functions
_wrapcall(*args, **kargs)
A helper function to run shell commands via `subprocess.check_output`, decode the output, and return lines as a list.
Parameters:
*args: Positional arguments forwarded tosubprocess.check_output.**kargs: Keyword arguments forwarded tosubprocess.check_output.
Returns:
list[str]: Lines of decoded output from the command, or empty list on failure.
Usage Example:
files = _wrapcall(["bash", "-c", "compgen -A file -- 'prefix'"])Implementation Detail:
Catches
subprocess.CalledProcessErrorand returns an empty list to avoid crashing on command failure.
Classes
FilesCompleter
A file and directory name completer that wraps Bash's `compgen` to provide filename completion based on a prefix, with optional filtering by allowed file extensions and directory inclusion.
Constructor:
FilesCompleter(allowednames=(), directories=True)Parameters:
allowednames(tupleorstr, optional): Allowed file extensions (e.g.,("py", "txt")). If a string is passed, it is treated as a single-element list.directories(bool, optional): Whether to include directory completions (default:True).
Methods:
__call__(prefix, **kwargs) -> list[str]Returns a list of completions matching the
prefix.Parameters:
prefix(str): The prefix string to complete.**kwargs: Additional ignored keyword arguments for compatibility.
Returns:
list[str]: List of matching filenames and directories (directories end with a slash).
Usage Example:
fc = FilesCompleter(allowednames=("py",)) completions = fc("test_") print(completions) # ['test_argcomplete.py', 'test_utils.py', ...]Implementation Details:
Uses
_wrapcallto invokebash -c "compgen -A file"orcompgen -A directory.Filters files by extensions using Bash's
-Xoption to exclude non-matching files.Appends a trailing slash (
/) to directory names ifdirectoriesisTrue.Handles cases with or without allowed extensions differently.
Removes duplicates by converting to sets.
TestArgComplete
A test class using `pytest` to validate the behavior of file completers against Bash's `compgen`.
Test Methods:
test_compare_with_compgen(self, tmp_path: Path, monkeypatch: MonkeyPatch) -> NoneCompares the
FastFilesCompleter(imported from_pytest._argcomplete) with theFilesCompleteragainst Bash completion results.Skips test on Windows and macOS.
Uses a temporary path (
tmp_path) isolated for testing.Changes the current working directory to
tmp_path.Creates a test file named
"data".Tests multiple prefix values (
"d","data","doesnotexist","").Asserts that completions match using
equal_with_bash.
test_remove_dir_prefix(self)Tests the behavior of completion with directory prefixes (e.g.,
/usr/), noting that it is incompatible withcompgenbut compatible with Bash itself.Skips test on Windows and macOS.
Checks that completions differ from Bash's
compgen.
Usage:
These tests run automatically in a pytest environment when the file is included in the test suite.
Important Implementation Details and Algorithms
Bash
compgenIntegration: The file completers rely on thebashbuiltin commandcompgento generate lists of file and directory completions based on a prefix. This approach leverages the native shell's autocompletion logic, ensuring close fidelity to user expectations.Extension Filtering: The
FilesCompleterclass filters file completions by allowed extensions using Bash's-Xpattern to exclude undesired files.Directory Handling: Directories are appended with a trailing slash (
/) to distinguish them from files.Subprocess Safety: The
_wrapcallfunction safely wraps subprocess calls, returning empty results instead of crashing when the command fails.Testing Strategy: The tests compare two Python completers (
FastFilesCompleterandFilesCompleter) against Bash's output to validate correctness and consistency.
Interaction with Other Parts of the System
The file imports and tests
FastFilesCompleterfrom the internal_pytest._argcompletemodule, indicating it is part of the broader pytest testing framework or ecosystem.It uses
pytestandpytestmonkeypatching (MonkeyPatch) utilities for testing in isolated and controlled environments.Interacts with the system shell (
bash) through subprocess calls to verify autocompletion results.Functions as a validation tool ensuring that autocompletion features in pytest or related tooling behave as expected when compared to native Bash completions.
Visual Diagram
classDiagram
class FilesCompleter {
-allowednames: list
-directories: bool
+__init__(allowednames=(), directories=True)
+__call__(prefix, **kwargs) list~str~
}
class TestArgComplete {
+test_compare_with_compgen(tmp_path: Path, monkeypatch: MonkeyPatch)
+test_remove_dir_prefix()
}
FilesCompleter <.. TestArgComplete : uses
class _wrapcall {
<<function>>
+_wrapcall(*args, **kargs) list~str~
}
class equal_with_bash {
<<function>>
+equal_with_bash(prefix, ffc, fc, out=None) bool
}
TestArgComplete ..> equal_with_bash : calls
FilesCompleter ..> _wrapcall : calls
Summary
The `test_argcomplete.py` file is a focused testing utility for verifying file completion behavior in Python against Bash's native completions. It implements a `FilesCompleter` class leveraging Bash's `compgen`, compares it with an internal `FastFilesCompleter`, and provides automated tests to ensure consistent and reliable autocompletion features. This module is crucial for maintaining the quality and accuracy of shell-like completion features in related Python tooling.