Description
The pyutils-unusedcode tool crashes with a subprocess.CalledProcessError when it encounters pytest fixtures that are used as parameters rather than called directly.
Environment
- Tool:
pyutils-unusedcode from python-utility-scripts
- Python: 3.12
- OS: Linux
Steps to Reproduce
-
Create a pytest fixture in a test file:
@pytest.fixture
def sample_clusters() -> list[ClusterInfo]:
return [...]
-
Use the fixture as a parameter in test functions:
def test_something(sample_clusters: list[ClusterInfo]) -> None:
# Use the fixture
assert len(sample_clusters) == 2
-
Run pyutils-unusedcode on the codebase
Expected Behavior
The tool should recognize that pytest fixtures are used as parameters and either:
- Skip them automatically
- Handle the
git grep exit code gracefully
- Continue processing other functions
Actual Behavior
The tool crashes with:
subprocess.CalledProcessError: Command '['git', 'grep', '-wE', 'sample_clusters(.*)']' returned non-zero exit status 1.
Full Stack Trace:
Traceback (most recent call last):
File "/path/to/pyutils-unusedcode", line 10, in <module>
sys.exit(get_unused_functions())
File "/path/to/click/core.py", line 1442, in __call__
return self.main(*args, **kwargs)
[... stack trace continues ...]
File "/path/to/unused_code.py", line 78, in process_file
_func_grep_found = subprocess.check_output(["git", "grep", "-wE", f"{func.name}(.*)"], shell=False)
File "/path/to/subprocess.py", line 466, in check_output
return run(*popenargs, stdout=PIPE, timeout=timeout, check=True,
File "/path/to/subprocess.py", line 571, in run
raise CalledProcessError(retcode, process.args,
subprocess.CalledProcessError: Command '['git', 'grep', '-wE', 'sample_clusters(.*)']' returned non-zero exit status 1.
Root Cause
- The tool uses
git grep -wE 'function_name(.*)' to find function usage
- Pytest fixtures are used as parameters (e.g.,
def test_foo(sample_clusters):), not called with parentheses
- When
git grep finds no matches, it returns exit code 1
- The tool uses
subprocess.check_output() which raises an exception on non-zero exit codes
Suggested Fix
In unused_code.py line 78, handle the case where git grep returns no matches:
try:
_func_grep_found = subprocess.check_output(
["git", "grep", "-wE", f"{func.name}(.*)"],
shell=False,
stderr=subprocess.DEVNULL
)
except subprocess.CalledProcessError as e:
if e.returncode == 1: # No matches found
_func_grep_found = b"" # Treat as empty result
else:
raise # Re-raise for other errors
Workaround
Add pytest fixture names to the exclusion list:
pyutils-unusedcode --exclude-function-prefixes "fixture_name1,fixture_name2"
Additional Context
This issue commonly occurs with pytest fixtures, which are a standard testing pattern. The tool should handle this case gracefully rather than requiring manual exclusions for every fixture.
The tool should ideally:
- Detect pytest fixtures automatically (functions decorated with
@pytest.fixture)
- Use different search patterns for fixtures (look for parameter usage instead of function calls)
- Handle
git grep exit codes gracefully for any function that might not have matches
Description
The
pyutils-unusedcodetool crashes with asubprocess.CalledProcessErrorwhen it encounters pytest fixtures that are used as parameters rather than called directly.Environment
pyutils-unusedcodefrompython-utility-scriptsSteps to Reproduce
Create a pytest fixture in a test file:
Use the fixture as a parameter in test functions:
Run
pyutils-unusedcodeon the codebaseExpected Behavior
The tool should recognize that pytest fixtures are used as parameters and either:
git grepexit code gracefullyActual Behavior
The tool crashes with:
Full Stack Trace:
Root Cause
git grep -wE 'function_name(.*)'to find function usagedef test_foo(sample_clusters):), not called with parenthesesgit grepfinds no matches, it returns exit code 1subprocess.check_output()which raises an exception on non-zero exit codesSuggested Fix
In
unused_code.pyline 78, handle the case wheregit grepreturns no matches:Workaround
Add pytest fixture names to the exclusion list:
pyutils-unusedcode --exclude-function-prefixes "fixture_name1,fixture_name2"Additional Context
This issue commonly occurs with pytest fixtures, which are a standard testing pattern. The tool should handle this case gracefully rather than requiring manual exclusions for every fixture.
The tool should ideally:
@pytest.fixture)git grepexit codes gracefully for any function that might not have matches