nvim-neotest / nvim-neotest/neotest-python
multiple `python_functions` patterns in `pyproject.toml` causes only first pattern to be recognized
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 192
- Forks
- 60
- PR merge metrics
- No merged PRs in 30d
Description
Bug: multiple python_functions patterns in pyproject.toml causes only first pattern to be recognized
Description
When python_functions is configured with multiple space-separated patterns in pyproject.toml, neotest-python only recognizes test functions matching the first pattern. Functions matching subsequent patterns are silently ignored in the neotest UI, even though pytest itself collects them correctly.
Environment
- neotest-python version: e6df4f1 (origin/master, origin/HEAD)
- Neovim version: v0.12.1
- pytest version: 9.0.3
Configuration
pyproject.toml:
[tool.pytest.ini_options]
python_functions = "should_* scenario_* test_*"
neotest setup:
require("neotest-python")({
runner = "pytest",
pytest_discover_instances = true,
})
Steps to reproduce
- Configure
python_functionswith multiple patterns inpyproject.tomlas above - Enable
pytest_discover_instances = truein neotest-python config - Open a test file containing functions with different prefixes, e.g.
should_foo,scenario_bar,test_baz - Observe that only
should_*functions appear in neotest —scenario_*andtest_*are not discovered
Expected behaviour
All functions matching any of the configured patterns should be discovered and displayed by neotest.
Actual behaviour
Only functions matching the first pattern (should_*) is discovered.
Running the extraction script manually confirms the problem:
cd /your/project && python ~/.local/share/nvim/lazy/neotest-python/neotest.py --pytest-extract-test-name-template
# returns: {"python_functions": "should_*"}
# expected: {"python_functions": "should_* scenario_* test_*"}
Root cause (two layers)
Layer 1 — Python script (neotest_python/pytest.py line 243):
config.getini("python_functions") returns a list of all configured patterns, but only the first element is taken:
# bug
config = {"python_functions": config.getini("python_functions")[0]}
This means the JSON output sent to the Lua layer already loses all patterns after the first.
Layer 2 — Lua (lua/neotest-python/base.lua line ~120):
Even if the Python script were fixed to return all patterns as a space-separated string, the Lua layer assigns the raw string directly into a treesitter #match? predicate:
-- bug
test_function_pattern = pytest_option.python_functions
-- result: "should_* scenario_* test_*" passed as a single regex
The treesitter #match? predicate expects a single regex pattern. A space-separated glob string is not valid regex alternation.
Fix (both files required)
neotest_python/pytest.py line 243:
# before
config = {"python_functions": config.getini("python_functions")[0]}
# after
config = {"python_functions": " ".join(config.getini("python_functions"))}
lua/neotest-python/base.lua line ~120:
-- before
test_function_pattern = pytest_option.python_functions
-- after
local patterns = vim.split(pytest_option.python_functions, " ", { trimempty = true })
local regex_parts = vim.tbl_map(function(p)
return "^" .. p:gsub("%*", "")
end, patterns)
test_function_pattern = table.concat(regex_parts, "|")
-- result: "^should_|^scenario_|^test_"
This produces a valid treesitter regex alternation that correctly matches all configured prefixes.
Verification
After applying both fixes, all should_*, scenario_* and test_* functions are correctly discovered by neotest. Running pytest --collect-only was always collecting them correctly, confirming the issue was entirely within neotest-python's pattern handling.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with neotest_python/pytest.py around line 243 and lua/neotest-python/base.lua around line 120, then run the extraction command from the issue to inspect the JSON output. Trace how multiple pytest patterns reach the treesitter predicate and verify discovery with functions using should_, scenario_, and test_ prefixes; done means all configured patterns appear in the neotest UI.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- lua, neovim, python
- Domain
- testing-qa
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 68/100