nvim-neotest / nvim-nio

A library for asynchronous IO in Neovim
MIT License
288 stars 8 forks source link

[BUG] `Future already set` error #16

Closed mennohofste closed 4 months ago

mennohofste commented 5 months ago

NeoVim Version NVIM v0.10.0-dev-2246+gf4b3636f2-Homebrew

Describe the bug This is a separate bug report for the issues mentioned in https://github.com/nvim-neotest/nvim-nio/issues/15. I wanted to create a separate report to avoid high-jacking that issue.

In some scenario's the test suite hangs when running tests. One scenario in particular that I encounter a lot seems to be the parametrize function from Python pytest.

The bug appears to be introduced with one of the latest commits 79e8968769d4422c08d514a413815bea6c1f67f9.

To Reproduce minimal.lua

local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
if not (vim.uv or vim.loop).fs_stat(lazypath) then
    vim.fn.system({
        "git",
        "clone",
        "--filter=blob:none",
        "https://github.com/folke/lazy.nvim.git",
        "--branch=stable", -- latest stable release
        lazypath,
    })
end
vim.opt.rtp:prepend(lazypath)
vim.g.mapleader = " "
vim.g.maplocalleader = "\\"

require("lazy").setup({
    {
        "nvim-neotest/neotest",
        dependencies = {
            "nvim-lua/plenary.nvim",
            "nvim-neotest/nvim-nio",
            "nvim-neotest/neotest-python",
            "nvim-treesitter/nvim-treesitter",
        },
        config = function()
            require("neotest").setup({
                adapters = {
                    require("neotest-python")({ runner = "pytest" }),
                },
            })
        end,
        keys = {
            {
                "<leader>tt",
                function()
                    require("neotest").run.run(vim.fn.expand("%"))
                end,
                desc = "Run File",
            },
        },
    },
})

test_bug.py

import pytest

@pytest.mark.parametrize("i", range(10))
def test_p(i: int): ...

Steps to reproduce the behavior:

  1. Create folder with minimal.lua and test_bug.py
  2. Install pytest in your Python env (python -m pip install pytest)
  3. Open bugged file with minimal config (nvim --clean -u minimal.lua test_bug.py)
  4. Run tests (<leader>tt)
  5. See error and hanging tests

Expected behavior I expect to see 10 different passing tests.

Logs neotest.log

INFO | 2024-05-02T14:11:33Z+0300 | ...ocal/share/nvim/lazy/neotest/lua/neotest/config/init.lua:447 | Configuration complete
DEBUG | 2024-05-02T14:11:33Z+0300 | ...ocal/share/nvim/lazy/neotest/lua/neotest/config/init.lua:448 | User config {
  adapters = { {
      build_spec = <function 1>,
      discover_positions = <function 2>,
      filter_dir = <function 3>,
      is_test_file = <function 4>,
      name = "neotest-python",
      results = <function 5>,
      root = <function 6>,
      <metatable> = {
        __call = <function 7>
      }
    } },
  benchmark = {
    enabled = true
  },
  consumers = {},
  default_strategy = "integrated",
  diagnostic = {
    enabled = true,
    severity = 1
  },
  discovery = {
    concurrent = 14,
    enabled = true
  },
  floating = {
    border = "rounded",
    max_height = 0.6,
    max_width = 0.6,
    options = {}
  },
  highlights = {
    adapter_name = "NeotestAdapterName",
    border = "NeotestBorder",
    dir = "NeotestDir",
    expand_marker = "NeotestExpandMarker",
    failed = "NeotestFailed",
    file = "NeotestFile",
    focused = "NeotestFocused",
    indent = "NeotestIndent",
    marked = "NeotestMarked",
    namespace = "NeotestNamespace",
    passed = "NeotestPassed",
    running = "NeotestRunning",
    select_win = "NeotestWinSelect",
    skipped = "NeotestSkipped",
    target = "NeotestTarget",
    test = "NeotestTest",
    unknown = "NeotestUnknown",
    watching = "NeotestWatching"
  },
  icons = {
    child_indent = "│",
    child_prefix = "├",
    collapsed = "─",
    expanded = "╮",
    failed = "",
    final_child_indent = " ",
    final_child_prefix = "╰",
    non_collapsible = "─",
    notify = "",
    passed = "",
    running = "",
    running_animated = { "/", "|", "\\", "-", "/", "|", "\\", "-" },
    skipped = "",
    unknown = "",
    watching = ""
  },
  jump = {
    enabled = true
  },
  log_level = 1,
  output = {
    enabled = true,
    open_on_run = "short"
  },
  output_panel = {
    enabled = true,
    open = "botright split | resize 15"
  },
  projects = {
    <metatable> = {
      __index = <function 8>
    }
  },
  quickfix = {
    enabled = true,
    open = false
  },
  run = {
    enabled = true
  },
  running = {
    concurrent = true
  },
  state = {
    enabled = true
  },
  status = {
    enabled = true,
    signs = true,
    virtual_text = false
  },
  strategies = {
    integrated = {
      height = 40,
      width = 120
    }
  },
  summary = {
    animated = true,
    enabled = true,
    expand_errors = true,
    follow = true,
    mappings = {
      attach = "a",
      clear_marked = "M",
      clear_target = "T",
      debug = "d",
      debug_marked = "D",
      expand = { "<CR>", "<2-LeftMouse>" },
      expand_all = "e",
      help = "?",
      jumpto = "i",
      mark = "m",
      next_failed = "J",
      output = "o",
      prev_failed = "K",
      run = "r",
      run_marked = "R",
      short = "O",
      stop = "u",
      target = "t",
      watch = "w"
    },
    open = "botright vsplit | vertical resize 50"
  },
  watch = {
    enabled = true,
    symbol_queries = {
      elixir = <function 9>,
      go = "        ;query\n        ;Captures imported types\n        (qualified_type name: (type_identifier) @symbol)\n        ;Captures package-local and built-in types\n        (type_identifier)@symbol\n        ;Captures imported function calls and variables/constants\n        (selector_expression field: (field_identifier) @symbol)\n        ;Captures package-local functions calls\n        (call_expression function: (identifier) @symbol)\n      ",
      haskell = "        ;query\n        ;explicit import\n        ((import_item [(variable)]) @symbol)\n        ;symbols that may be imported implicitly\n        ((type) @symbol)\n        (qualified_variable (variable) @symbol)\n        (exp_apply (exp_name (variable) @symbol))\n        ((constructor) @symbol)\n        ((operator) @symbol)\n      ",
      javascript = '  ;query\n  ;Captures named imports\n  (import_specifier name: (identifier) @symbol)\n  ;Captures default import\n  (import_clause (identifier) @symbol)\n  ;Capture require statements\n  (variable_declarator \n  name: (identifier) @symbol\n  value: (call_expression (identifier) @function  (#eq? @function "require")))\n  ;Capture namespace imports\n  (namespace_import (identifier) @symbol)\n',
      lua = '        ;query\n        ;Captures module names in require calls\n        (function_call\n          name: ((identifier) @function (#eq? @function "require"))\n          arguments: (arguments (string) @symbol))\n      ',
      python = "        ;query\n        ;Captures imports and modules they're imported from\n        (import_from_statement (_ (identifier) @symbol))\n        (import_statement (_ (identifier) @symbol))\n      ",
      ruby = '        ;query\n        ;rspec - class name\n        (call\n          method: (identifier) @_ (#match? @_ "^(describe|context)")\n          arguments: (argument_list (constant) @symbol )\n        )\n\n        ;rspec - namespaced class name\n        (call\n          method: (identifier)\n          arguments: (argument_list\n            (scope_resolution\n              name: (constant) @symbol))\n        )\n      ',
      rust = "        ;query\n        ;submodule import\n        (mod_item\n          name: (identifier) @symbol)\n        ;single import\n        (use_declaration\n          argument: (scoped_identifier\n            name: (identifier) @symbol))\n        ;import list\n        (use_declaration\n          argument: (scoped_use_list\n            list: (use_list\n                [(scoped_identifier\n                   path: (identifier)\n                   name: (identifier) @symbol)\n                 ((identifier) @symbol)])))\n        ;wildcard import\n        (use_declaration\n          argument: (scoped_use_list\n            path: (identifier)\n            [(use_list\n              [(scoped_identifier\n                path: (identifier)\n                name: (identifier) @symbol)\n                ((identifier) @symbol)\n              ])]))\n      ",
      tsx = '  ;query\n  ;Captures named imports\n  (import_specifier name: (identifier) @symbol)\n  ;Captures default import\n  (import_clause (identifier) @symbol)\n  ;Capture require statements\n  (variable_declarator \n  name: (identifier) @symbol\n  value: (call_expression (identifier) @function  (#eq? @function "require")))\n  ;Capture namespace imports\n  (namespace_import (identifier) @symbol)\n',
      typescript = '  ;query\n  ;Captures named imports\n  (import_specifier name: (identifier) @symbol)\n  ;Captures default import\n  (import_clause (identifier) @symbol)\n  ;Capture require statements\n  (variable_declarator \n  name: (identifier) @symbol\n  value: (call_expression (identifier) @function  (#eq? @function "require")))\n  ;Capture namespace imports\n  (namespace_import (identifier) @symbol)\n'
    }
  }
}
INFO | 2024-05-02T14:11:33Z+0300 | ...l/share/nvim/lazy/neotest/lua/neotest/lib/subprocess.lua:33 | Starting child process
INFO | 2024-05-02T14:11:33Z+0300 | ...l/share/nvim/lazy/neotest/lua/neotest/lib/subprocess.lua:36 | Parent address: localhost:61403
INFO | 2024-05-02T14:11:33Z+0300 | ...l/share/nvim/lazy/neotest/lua/neotest/lib/subprocess.lua:42 | Starting child process with command: /opt/homebrew/Cellar/neovim/HEAD-f4b3636/bin/nvim --embed --headless -n
INFO | 2024-05-02T14:11:33Z+0300 | ...ocal/share/nvim/lazy/neotest/lua/neotest/client/init.lua:378 | Initialising client
INFO | 2024-05-02T14:11:33Z+0300 | ...are/nvim/lazy/neotest/lua/neotest/client/events/init.lua:48 | Emitting starting event
DEBUG | 2024-05-02T14:11:33Z+0300 | ...are/nvim/lazy/neotest/lua/neotest/client/events/init.lua:50 | Calling listener summary for event starting
INFO | 2024-05-02T14:11:33Z+0300 | ...al/share/nvim/lazy/neotest/lua/neotest/adapters/init.lua:18 | Found 0 adapters for directory /Users/mennohofste/projects/nio_bug
DEBUG | 2024-05-02T14:11:33Z+0300 | ...al/share/nvim/lazy/neotest/lua/neotest/adapters/init.lua:19 | Adapters: {}
INFO | 2024-05-02T14:11:33Z+0300 | ...al/share/nvim/lazy/neotest/lua/neotest/adapters/init.lua:50 | Adapter neotest-python matched buffer /Users/mennohofste/projects/nio_bug/test_bug.py
INFO | 2024-05-02T14:11:33Z+0300 | ...ocal/share/nvim/lazy/neotest/lua/neotest/client/init.lua:279 | Searching /Users/mennohofste/projects/nio_bug for test files
DEBUG | 2024-05-02T14:11:33Z+0300 | ...al/share/nvim/lazy/neotest/lua/neotest/lib/file/find.lua:26 | Scanning directory: __pycache__
DEBUG | 2024-05-02T14:11:33Z+0300 | ...ocal/share/nvim/lazy/neotest/lua/neotest/client/init.lua:295 | Found { {
    id = "/Users/mennohofste/projects/nio_bug",
    name = "nio_bug",
    path = "/Users/mennohofste/projects/nio_bug",
    type = "dir"
  }, { {
      id = "/Users/mennohofste/projects/nio_bug/test_bug.py",
      name = "test_bug.py",
      path = "/Users/mennohofste/projects/nio_bug/test_bug.py",
      type = "file"
    } } }
DEBUG | 2024-05-02T14:11:33Z+0300 | ...hare/nvim/lazy/neotest/lua/neotest/client/state/init.lua:54 | New positions at ID /Users/mennohofste/projects/nio_bug
INFO | 2024-05-02T14:11:33Z+0300 | ...are/nvim/lazy/neotest/lua/neotest/client/events/init.lua:48 | Emitting discover_positions event
DEBUG | 2024-05-02T14:11:33Z+0300 | ...are/nvim/lazy/neotest/lua/neotest/client/events/init.lua:50 | Calling listener diagnostic for event discover_positions
INFO | 2024-05-02T14:11:33Z+0300 | ...ocal/share/nvim/lazy/neotest/lua/neotest/client/init.lua:325 | Discovering files with 14 workers
DEBUG | 2024-05-02T14:11:33Z+0300 | ...are/nvim/lazy/neotest/lua/neotest/client/events/init.lua:50 | Calling listener status for event discover_positions
DEBUG | 2024-05-02T14:11:33Z+0300 | ...are/nvim/lazy/neotest/lua/neotest/client/events/init.lua:50 | Calling listener state for event discover_positions
DEBUG | 2024-05-02T14:11:33Z+0300 | ...are/nvim/lazy/neotest/lua/neotest/client/events/init.lua:50 | Calling listener summary for event discover_positions
INFO | 2024-05-02T14:11:33Z+0300 | ...ocal/share/nvim/lazy/neotest/lua/neotest/client/init.lua:299 | Parsing /Users/mennohofste/projects/nio_bug/test_bug.py
DEBUG | 2024-05-02T14:11:33Z+0300 | ...l/share/nvim/lazy/neotest/lua/neotest/lib/subprocess.lua:140 | Waiting for result 1
DEBUG | 2024-05-02T14:11:33Z+0300 | ...l/share/nvim/lazy/neotest/lua/neotest/lib/subprocess.lua:91 | Result registed for callback 1
DEBUG | 2024-05-02T14:11:33Z+0300 | ...ocal/share/nvim/lazy/neotest/lua/neotest/client/init.lua:305 | Found { {
    id = "/Users/mennohofste/projects/nio_bug/test_bug.py",
    name = "test_bug.py",
    path = "/Users/mennohofste/projects/nio_bug/test_bug.py",
    range = { 0, 0, 5, 0 },
    type = "file"
  }, { {
      id = "/Users/mennohofste/projects/nio_bug/test_bug.py::test_p",
      name = "test_p",
      path = "/Users/mennohofste/projects/nio_bug/test_bug.py",
      range = { 3, 0, 4, 23 },
      type = "test"
    } } }
DEBUG | 2024-05-02T14:11:33Z+0300 | ...hare/nvim/lazy/neotest/lua/neotest/client/state/init.lua:54 | New positions at ID /Users/mennohofste/projects/nio_bug/test_bug.py
INFO | 2024-05-02T14:11:33Z+0300 | ...are/nvim/lazy/neotest/lua/neotest/client/events/init.lua:48 | Emitting discover_positions event
DEBUG | 2024-05-02T14:11:33Z+0300 | ...are/nvim/lazy/neotest/lua/neotest/client/events/init.lua:50 | Calling listener diagnostic for event discover_positions
DEBUG | 2024-05-02T14:11:33Z+0300 | ...are/nvim/lazy/neotest/lua/neotest/client/events/init.lua:50 | Calling listener status for event discover_positions
DEBUG | 2024-05-02T14:11:33Z+0300 | ...are/nvim/lazy/neotest/lua/neotest/client/events/init.lua:50 | Calling listener state for event discover_positions
DEBUG | 2024-05-02T14:11:33Z+0300 | ...are/nvim/lazy/neotest/lua/neotest/client/events/init.lua:50 | Calling listener summary for event discover_positions
INFO | 2024-05-02T14:11:33Z+0300 | ...ocal/share/nvim/lazy/neotest/lua/neotest/client/init.lua:494 | Initialisation finished in 0.006 seconds
INFO | 2024-05-02T14:11:33Z+0300 | ...are/nvim/lazy/neotest/lua/neotest/client/events/init.lua:48 | Emitting test_file_focused event
DEBUG | 2024-05-02T14:11:33Z+0300 | ...are/nvim/lazy/neotest/lua/neotest/client/events/init.lua:50 | Calling listener status for event test_file_focused
DEBUG | 2024-05-02T14:11:33Z+0300 | ...are/nvim/lazy/neotest/lua/neotest/client/events/init.lua:50 | Calling listener diagnostic for event test_file_focused
DEBUG | 2024-05-02T14:11:33Z+0300 | ...are/nvim/lazy/neotest/lua/neotest/client/events/init.lua:50 | Calling listener summary for event test_file_focused
INFO | 2024-05-02T14:11:33Z+0300 | ...are/nvim/lazy/neotest/lua/neotest/client/events/init.lua:48 | Emitting started event
DEBUG | 2024-05-02T14:11:33Z+0300 | ...are/nvim/lazy/neotest/lua/neotest/client/events/init.lua:50 | Calling listener summary for event started
DEBUG | 2024-05-02T14:11:33Z+0300 | ...hare/nvim/lazy/neotest/lua/neotest/client/state/init.lua:85 | Setting positions to running /Users/mennohofste/projects/nio_bug/test_bug.py
INFO | 2024-05-02T14:11:33Z+0300 | ...are/nvim/lazy/neotest/lua/neotest/client/events/init.lua:48 | Emitting run event
DEBUG | 2024-05-02T14:11:33Z+0300 | ...are/nvim/lazy/neotest/lua/neotest/client/events/init.lua:50 | Calling listener diagnostic for event run
DEBUG | 2024-05-02T14:11:33Z+0300 | ...are/nvim/lazy/neotest/lua/neotest/client/events/init.lua:50 | Calling listener status for event run
DEBUG | 2024-05-02T14:11:33Z+0300 | ...are/nvim/lazy/neotest/lua/neotest/client/events/init.lua:50 | Calling listener state for event run
DEBUG | 2024-05-02T14:11:33Z+0300 | ...are/nvim/lazy/neotest/lua/neotest/client/events/init.lua:50 | Calling listener summary for event run
DEBUG | 2024-05-02T14:11:33Z+0300 | ...al/share/nvim/lazy/neotest/lua/neotest/lib/file/init.lua:38 | Writing file: /var/folders/fg/t83hr_r539g7db8k_9_lmr_r0000gn/T/nvim.mennohofste/JLSVoe/1
INFO | 2024-05-02T14:11:33Z+0300 | ...nvim/lazy/neotest/lua/neotest/client/strategies/init.lua:34 | Starting process neotest-python:/Users/mennohofste/projects/nio_bug-/Users/mennohofste/projects/nio_bug/test_bug.py with strategy integrated
DEBUG | 2024-05-02T14:11:33Z+0300 | ...nvim/lazy/neotest/lua/neotest/client/strategies/init.lua:35 | Strategy spec {
  command = { "/usr/bin/python3", "/Users/mennohofste/.local/share/nvim/lazy/neotest-python/neotest.py", "--results-file", "/var/folders/fg/t83hr_r539g7db8k_9_lmr_r0000gn/T/nvim.mennohofste/JLSVoe/0", "--stream-file", "/var/folders/fg/t83hr_r539g7db8k_9_lmr_r0000gn/T/nvim.mennohofste/JLSVoe/1", "--runner", "pytest", "--", "/Users/mennohofste/projects/nio_bug/test_bug.py" },
  context = {
    results_path = "/var/folders/fg/t83hr_r539g7db8k_9_lmr_r0000gn/T/nvim.mennohofste/JLSVoe/0",
    stop_stream = <function 1>
  },
  strategy = {
    height = 40,
    width = 120
  },
  stream = <function 2>
}
INFO | 2024-05-02T14:11:37Z+0300 | ...are/nvim/lazy/neotest/lua/neotest/client/events/init.lua:48 | Emitting test_focused event
DEBUG | 2024-05-02T14:11:37Z+0300 | ...are/nvim/lazy/neotest/lua/neotest/client/events/init.lua:50 | Calling listener summary for event test_focused

Additional context This message appears in :messages. It is slightly different from the issue I was referring to.

.../.local/share/nvim/lazy/nvim-nio/lua/nio/control.lua:133: Future already set
stack traceback:
^I[C]: in function 'error'
^I.../.local/share/nvim/lazy/nvim-nio/lua/nio/control.lua:133: in function 'set_error'
^I.../.local/share/nvim/lazy/nvim-nio/lua/nio/tasks.lua:93: in function 'close_task'
^I.../.local/share/nvim/lazy/nvim-nio/lua/nio/tasks.lua:111: in function 'cb'
^I.../.local/share/nvim/lazy/nvim-nio/lua/nio/tasks.lua:185: in function 'waiter'
^I.../.local/share/nvim/lazy/nvim-nio/lua/nio/control.lua:116: in function 'wake'
^I.../.local/share/nvim/lazy/nvim-nio/lua/nio/control.lua:129: in function 'set'
^I...eotest/lua/neotest/client/strategies/integrated/init.lua:47: in function <...eotest/lua/neotest/client/strategies/integrated/init.lua:45>