nvim-treesitter / nvim-treesitter/nvim-treesitter-textobjects

python class decorators are mistaken as startpoint for undecorated classes defined after it

Open
#783 4 comments 4 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
Tree-sitter Query
Stars
2.8k
Forks
271
Avg merge
8d 8h
Merged PRs (30d)
1

Description

Describe the bug
When multiple classes are defined in a single python file, and one or more classes are decorated with dataclasses.dataclass, this plugin mistakes that line as the start point for non-dataclasses defined after it and before any other dataclass.

To Reproduce
Steps to reproduce the behavior:

  1. Copy the following example code into a new python file:
import dataclasses


@dataclasses.dataclass
class SomeDataClass:
    name: str


class SomeClass:
    def __init__(self):
        pass


class SomeOtherClass:
    def __init__(self):
        pass

2a. Place cursor somewhere inside SomeClass
2b. Callrequire("nvim-treesitter-textobjects.select").select_textobject("@class.inner", "textobjects") directly or via keybind
2c. Observe that the contents of SomeDataClass are selected instead of SomeClass

3a. Place cursor somewhere inside SomeClass
3b. Callrequire("nvim-treesitter-textobjects.select").select_textobject("@class.outer", "textobjects") directly or via keybind
3c. Observe that both SomeClass and SomeDataClass are selected instead of just SomeClass

4a. Place cursor somewhere inside SomeOtherClass
4b. Callrequire("nvim-treesitter-textobjects.select").select_textobject("@class.inner", "textobjects") directly or via keybind
4c. Observe that the contents of SomeDataClass are selected instead of SomeOtherClass

5a. Place cursor somewhere inside SomeOtherClass
5b. Callrequire("nvim-treesitter-textobjects.select").select_textobject("@class.outer", "textobjects") directly or via keybind
5c. Observe that all three classes are selected instead of just SomeOtherClass

Expected behavior
When selecting @class.inner or @class.outer, the class the cursor is inside of should be selected, not the previous dataclass and not multiple classes.

Output of :checkhealth nvim-treesitter

Requirements ~

  • ✅ OK Neovim was compiled with tree-sitter runtime ABI version 15 (required >=13).
  • ✅ OK tree-sitter 0.25.7 (/usr/bin/tree-sitter)
  • ✅ OK node 24.4.0 (/usr/bin/node)
  • ✅ OK tar 1.35.0 (/usr/bin/tar)
  • ✅ OK curl 8.14.1 (/usr/bin/curl)
    curl 8.14.1 (x86_64-pc-linux-gnu) libcurl/8.14.1 OpenSSL/3.5.1 zlib/1.3.1 brotli/1.1.0 zstd/1.5.7 libidn2/2.3.7 libpsl/0.21.5 libssh2/1.11.1 nghttp2/1.66.0 nghttp3/1.10.1
    Release-Date: 2025-06-04
    Protocols: dict file ftp ftps gopher gophers http https imap imaps ipfs ipns mqtt pop3 pop3s rtsp scp sftp smb smbs smtp smtps telnet tftp ws wss
    Features: alt-svc AsynchDNS brotli GSS-API HSTS HTTP2 HTTP3 HTTPS-proxy IDN IPv6 Kerberos Largefile libz NTLM PSL SPNEGO SSL threadsafe TLS-SRP UnixSockets zstd

OS Info ~

  • version: #1 ZEN SMP PREEMPT_DYNAMIC Thu, 10 Jul 2025 17:10:03 +0000
  • sysname: Linux
  • release: 6.15.6-zen1-1-zen
  • machine: x86_64

Install directory for parsers and queries ~

  • ~/.local/share/nvim/site/
  • ✅ OK is writable.
  • ✅ OK is in runtimepath.

Installed languages H L F I J ~

  • bash ✓ ✓ ✓ . ✓

  • c_sharp ✓ ✓ ✓ . ✓

  • css ✓ . ✓ ✓ ✓

  • ecma

  • gdscript ✓ ✓ ✓ ✓ ✓

  • gdshader ✓ . . . ✓

  • git_config ✓ . ✓ . ✓

  • git_rebase ✓ . . . ✓

  • gitattributes ✓ ✓ . . ✓

  • gitcommit ✓ . . . ✓

  • gitignore ✓ . . . ✓

  • godot_resource ✓ ✓ ✓ . ✓

  • html ✓ ✓ ✓ ✓ ✓

  • html_tags

  • ini ✓ . ✓ . ✓

  • javascript ✓ ✓ ✓ ✓ ✓

  • json ✓ ✓ ✓ ✓ .

  • jsonc ✓ ✓ ✓ ✓ ✓

  • jsx

  • python ✓ ✓ ✓ ✓ ✓

  • todotxt ✓ . . . .

  • toml ✓ ✓ ✓ ✓ ✓

  • yaml ✓ ✓ ✓ ✓ ✓

    Legend: H[ighlight], L[ocals], F[olds], I[ndents], In[J]ections ~

Output of nvim --version

NVIM v0.11.3
Build type: RelWithDebInfo
LuaJIT 2.1.1748459687
Run "nvim -V1 -v" for more info

Additional context
Add any other context about the problem here.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at require("nvim-treesitter-textobjects.select").select_textobject("@class.inner", "textobjects") and the corresponding @class.outer path, then reproduce the example with the Python parser. Trace how the class selections are determined and verify that each class selects only its own inner or outer range, rather than including the preceding dataclass.

Written by the indexing model from the issue text.

Assessment

Tech stack
lua, python
Domain
tooling
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.