Skip to content

Bug: get_linter_options mutates shared plugin state by modifying the linter table in place (python.lua) #69

@ooloth

Description

@ooloth

Why

Mutating the table returned by require('lint.linters.*') modifies a module-level singleton; any subsequent call that reads the same linter table — including other buffers or a re-lint — will see the mutated value, which can cause subtle, hard-to-reproduce bugs when switching between virtualenvs or project roots.

Current state

Lines 85–89 of python.lua implement get_linter_options by directly assigning into the table returned by require('lint.linters.' .. linter): linter_options.cmd = prefer_venv_executable(linter). Because require caches its return value, this mutates the shared singleton for the lifetime of the Neovim session.

Ideal state

  • get_linter_options builds and returns a new table containing only the fields it needs to override (e.g. using vim.tbl_extend('force', original, { cmd = prefer_venv_executable(linter) }))
  • The table returned by require('lint.linters.' .. linter) is never modified
  • Re-linting in a different virtualenv picks up the correct executable each time

Starting points

  • lua/config/plugins/specs/python.lua (lines 85–89)
  • lua/config/util.lua (definition of prefer_venv_executable, for context)

QA plan

  1. Open two Python buffers from projects with different virtualenvs — Expect each buffer uses the correct linter executable for its project.
  2. After linting buffer A, require the linter module in the Neovim REPL and inspect its cmd field — Expect it matches the plugin's original default, not the project-specific path.

Done when

get_linter_options returns a new table and the original lint.linters.* table is unmodified after linting runs.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions