Skip to content

Cannot make ruff and rope code actions work #625

Open
@vspinu

Description

@vspinu

I am not able to make ruff's local fixes to work no matter what I try. Same for rope auto-import code actions.

This is the config which is actually sent to the server:

[Trace - 12:34:00 AM] Sending request 'initialize - (1443)'.
Params: {
  "processId": 35160,
  "rootPath": "/Users/vitalie/dev/adyen_pyspark",
  "clientInfo": {
    "name": "emacs",
    "version": "GNU Emacs 29.4 (build 1, aarch64-apple-darwin21.6.0, NS appkit-2113.60 Version 12.6.6 (Build 21G646))\n of 2024-07-25"
  },
  "rootUri": "file:///Users/vitalie/dev/adyen_pyspark",
  "capabilities": {
    "general": {
      "positionEncodings": [
        "utf-32",
        "utf-16"
      ]
    },
    "workspace": {
      "workspaceEdit": {
        "documentChanges": true,
        "resourceOperations": [
          "create",
          "rename",
          "delete"
        ]
      },
      "applyEdit": true,
      "symbol": {
        "symbolKind": {
          "valueSet": [
            1,
            2,
            3,
            4,
            5,
            6,
            7,
            8,
            9,
            10,
            11,
            12,
            13,
            14,
            15,
            16,
            17,
            18,
            19,
            20,
            21,
            22,
            23,
            24,
            25,
            26
          ]
        }
      },
      "executeCommand": {
        "dynamicRegistration": false
      },
      "didChangeWatchedFiles": {
        "dynamicRegistration": true
      },
      "workspaceFolders": true,
      "configuration": true,
      "codeLens": {
        "refreshSupport": true
      },
      "diagnostics": {
        "refreshSupport": false
      },
      "fileOperations": {
        "didCreate": false,
        "willCreate": false,
        "didRename": true,
        "willRename": true,
        "didDelete": false,
        "willDelete": false
      }
    },
    "textDocument": {
      "declaration": {
        "dynamicRegistration": true,
        "linkSupport": true
      },
      "definition": {
        "dynamicRegistration": true,
        "linkSupport": true
      },
      "references": {
        "dynamicRegistration": true
      },
      "implementation": {
        "dynamicRegistration": true,
        "linkSupport": true
      },
      "typeDefinition": {
        "dynamicRegistration": true,
        "linkSupport": true
      },
      "synchronization": {
        "willSave": true,
        "didSave": true,
        "willSaveWaitUntil": true
      },
      "documentSymbol": {
        "symbolKind": {
          "valueSet": [
            1,
            2,
            3,
            4,
            5,
            6,
            7,
            8,
            9,
            10,
            11,
            12,
            13,
            14,
            15,
            16,
            17,
            18,
            19,
            20,
            21,
            22,
            23,
            24,
            25,
            26
          ]
        },
        "hierarchicalDocumentSymbolSupport": true
      },
      "formatting": {
        "dynamicRegistration": true
      },
      "rangeFormatting": {
        "dynamicRegistration": true
      },
      "onTypeFormatting": {
        "dynamicRegistration": true
      },
      "rename": {
        "dynamicRegistration": true,
        "prepareSupport": true
      },
      "codeAction": {
        "dynamicRegistration": true,
        "isPreferredSupport": true,
        "codeActionLiteralSupport": {
          "codeActionKind": {
            "valueSet": [
              "",
              "quickfix",
              "refactor",
              "refactor.extract",
              "refactor.inline",
              "refactor.rewrite",
              "source",
              "source.organizeImports"
            ]
          }
        },
        "resolveSupport": {
          "properties": [
            "edit",
            "command"
          ]
        },
        "dataSupport": true
      },
      "completion": {
        "completionItem": {
          "snippetSupport": false,
          "documentationFormat": [
            "markdown",
            "plaintext"
          ],
          "resolveAdditionalTextEditsSupport": true,
          "insertReplaceSupport": true,
          "deprecatedSupport": true,
          "resolveSupport": {
            "properties": [
              "documentation",
              "detail",
              "additionalTextEdits",
              "command",
              "insertTextFormat",
              "insertTextMode"
            ]
          },
          "insertTextModeSupport": {
            "valueSet": [
              1,
              2
            ]
          }
        },
        "contextSupport": true,
        "dynamicRegistration": true
      },
      "signatureHelp": {
        "signatureInformation": {
          "parameterInformation": {
            "labelOffsetSupport": true
          }
        },
        "dynamicRegistration": true
      },
      "documentLink": {
        "dynamicRegistration": true,
        "tooltipSupport": true
      },
      "hover": {
        "contentFormat": [
          "markdown",
          "plaintext"
        ],
        "dynamicRegistration": true
      },
      "foldingRange": {
        "dynamicRegistration": true
      },
      "selectionRange": {
        "dynamicRegistration": true
      },
      "callHierarchy": {
        "dynamicRegistration": false
      },
      "typeHierarchy": {
        "dynamicRegistration": true
      },
      "publishDiagnostics": {
        "relatedInformation": true,
        "tagSupport": {
          "valueSet": [
            1,
            2
          ]
        },
        "versionSupport": true
      },
      "diagnostic": {
        "dynamicRegistration": false,
        "relatedDocumentSupport": false
      },
      "linkedEditingRange": {
        "dynamicRegistration": true
      }
    },
    "window": {
      "workDoneProgress": true,
      "showDocument": {
        "support": true
      }
    }
  },
  "initializationOptions": null,
  "workDoneToken": "1"
}


[Trace - 12:34:02 AM] Received response 'initialize - (1443)' in 1724ms.
Result: {
  "capabilities": {
    "codeActionProvider": true,
    "codeLensProvider": {
      "resolveProvider": null
    },
    "completionProvider": {
      "resolveProvider": true,
      "triggerCharacters": [
        "."
      ]
    },
    "documentFormattingProvider": true,
    "documentHighlightProvider": true,
    "documentRangeFormattingProvider": true,
    "documentSymbolProvider": true,
    "definitionProvider": true,
    "executeCommandProvider": {
      "commands": [
        "pylsp_rope.quickfix.generate",
        "pylsp_rope.refactor.introduce_parameter",
        "pylsp_rope.refactor.extract.method",
        "pylsp_rope.refactor.extract.variable",
        "pylsp_rope.refactor.inline",
        "pylsp_rope.refactor.local_to_field",
        "pylsp_rope.refactor.method_to_method_object",
        "pylsp_rope.refactor.use_function",
        "pylsp_rope.source.organize_import"
      ]
    },
    "hoverProvider": true,
    "referencesProvider": true,
    "renameProvider": true,
    "foldingRangeProvider": true,
    "signatureHelpProvider": {
      "triggerCharacters": [
        "(",
        ",",
        "="
      ]
    },
    "textDocumentSync": {
      "change": 2,
      "save": {
        "includeText": true
      },
      "openClose": true
    },
    "notebookDocumentSync": {
      "notebookSelector": [
        {
          "cells": [
            {
              "language": "python"
            }
          ]
        }
      ]
    },
    "workspace": {
      "workspaceFolders": {
        "supported": true,
        "changeNotifications": true
      }
    },
    "experimental": {}
  },
  "serverInfo": {
    "name": "pylsp",
    "version": "1.12.2"
  }
}


[Trace - 12:34:02 AM] Sending notification 'initialized'.
Params: {}


[Trace - 12:34:02 AM] Sending notification 'workspace/didChangeConfiguration'.
Params: {
  "settings": {
    "pylsp": {
      "plugins": {
        "autopep8": {
          "enabled": false
        },
        "yapf": {
          "enabled": false
        },
        "black": {
          "enabled": true
        },
        "pyls_isort": {
          "enabled": false
        },
        "rope_autoimport": {
          "enabled": true,
          "memory": false,
          "completions": {
            "enabled": false
          },
          "code_actions": {
            "enabled": true
          }
        },
        "rope_completion": {
          "enabled": false,
          "eager": false
        },
        "pyflakes": {
          "enabled": true
        },
        "pydocstyle": {
          "matchDir": "[^\\.].*",
          "match": "(?!test_).*\\.py",
          "enabled": true
        },
        "pycodestyle": {
          "hangClosing": false,
          "enabled": false
        },
        "pylint": {
          "enabled": false,
          "args": []
        },
        "flake8": {
          "enabled": true,
          "ignore": [
            "W293",
            "E303"
          ]
        },
        "preload": {
          "enabled": false
        },
        "mccabe": {
          "threshold": 15,
          "enabled": false
        },
        "ruff": {
          "enabled": true,
          "extendIgnore": [
            "W293",
            "E303"
          ],
          "unsafeFixes": true,
          "lineLength": 88,
          "ignore": [
            "W293",
            "E303"
          ],
          "preview": false
        },
        "pylsp_mypy": {
          "enabled": false,
          "live_mode": true,
          "dmypy": false,
          "strict": false,
          "overrides": [
            true
          ],
          "dmypy_status_file": ".dmypy.json",
          "report_progress": false
        },
        "jedi_symbols": {
          "all_scopes": true,
          "enabled": true
        },
        "jedi_signature_help": {
          "enabled": true
        },
        "jedi_references": {
          "enabled": true
        },
        "jedi_hover": {
          "enabled": true
        },
        "jedi_definition": {
          "follow_builtin_imports": true,
          "follow_imports": true,
          "enabled": true
        },
        "jedi_completion": {
          "include_params": true,
          "enabled": true,
          "include_class_objects": true,
          "fuzzy": true
        },
        "jedi": {
          "environment": true
        },
        "jedi_rename": {
          "enabled": false
        },
        "isort": {
          "enabled": false
        }
      },
      "configurationSources": [
        "flake8"
      ]
    }
  }
}

When I ask for code actions on a ruff diagnostic message (or on an unimpored symbol) I don't see "local" code actions. Only global ones. Both ruff and rope are enabled in the config as could be seen in the messages from above.

This is the list of code actions I actually receive:

[Trace - 12:53:26 AM] Sending request 'textDocument/codeAction - (1477)'.
Params: {
  "textDocument": {
    "uri": "file...py"
  },
  "range": {
    "start": {
      "line": 50,
      "character": 17
    },
    "end": {
      "line": 50,
      "character": 17
    }
  },
  "context": {
    "diagnostics": [
      {
        "range": {
          "start": {
            "line": 50,
            "character": 12
          },
          "end": {
            "line": 50,
            "character": 31
          }
        },
        "message": "Consider `[*EXPL_COLS, \"day\"]` instead of concatenation",
        "severity": 2,
        "code": "RUF005",
        "source": "ruff",
        "tags": [],
        "data": {
          "edits": [
            {
              "content": "[*EXPL_COLS, \"day\"]",
              "location": {
                "row": 51,
                "column": 13
              },
              "end_location": {
                "row": 51,
                "column": 32
              }
            }
          ],
          "message": "Replace with `[*EXPL_COLS, \"day\"]`",
          "applicability": "unsafe"
        }
      }
    ]
  }
}


[Trace - 12:53:28 AM] Received response 'textDocument/codeAction - (1477)' in 1375ms.
Result: [
  {
    "title": "Extract method including similar statements",
    "kind": "refactor.extract",
    "command": {
      "title": "Extract method including similar statements",
      "command": "pylsp_rope.refactor.extract.method",
      "arguments": [
        {
          "document_uri": "file:....e.py",
          "range": {
            "start": {
              "line": 50,
              "character": 17
            },
            "end": {
              "line": 50,
              "character": 17
            }
          },
          "global_": null,
          "similar": true
        }
      ]
    }
  },
  {
    "title": "Extract method",
    "kind": "refactor.extract",
    "command": {
      "title": "Extract method",
      "command": "pylsp_rope.refactor.extract.method",
      "arguments": [
        {
          "document_uri": "file....e.py",
          "range": {
            "start": {
              "line": 50,
              "character": 17
            },
            "end": {
              "line": 50,
              "character": 17
            }
          },
          "global_": null,
          "similar": null
        }
      ]
    }
  },
  {
    "title": "Extract global method including similar statements",
    "kind": "refactor.extract",
    "command": {
      "title": "Extract global method including similar statements",
      "command": "pylsp_rope.refactor.extract.method",
      "arguments": [
        {
          "document_uri": "file:....e.py",
          "range": {
            "start": {
              "line": 50,
              "character": 17
            },
            "end": {
              "line": 50,
              "character": 17
            }
          },
          "global_": true,
          "similar": true
        }
      ]
    }
  },
  {
    "title": "Extract global method",
    "kind": "refactor.extract",
    "command": {
      "title": "Extract global method",
      "command": "pylsp_rope.refactor.extract.method",
      "arguments": [
        {
          "document_uri": "fi.....py",
          "range": {
            "start": {
              "line": 50,
              "character": 17
            },
            "end": {
              "line": 50,
              "character": 17
            }
          },
          "global_": true,
          "similar": null
        }
      ]
    }
  },
  {
    "title": "Convert local variable to field",
    "kind": "refactor.rewrite",
    "command": {
      "title": "Convert local variable to field",
      "command": "pylsp_rope.refactor.local_to_field",
      "arguments": [
        {
          "document_uri": "fil....py",
          "position": {
            "line": 50,
            "character": 17
          }
        }
      ]
    }
  },
  {
    "title": "Organize import",
    "kind": "source.organizeImports",
    "command": {
      "title": "Organize import",
      "command": "pylsp_rope.source.organize_import",
      "arguments": [
        {
          "document_uri": "f....py"
        }
      ]
    }
  },
  {
    "title": "Ruff (RUF005): Disable for this line",
    "kind": "quickfix",
    "diagnostics": [
      {
        "range": {
          "start": {
            "line": 50,
            "character": 12
          },
          "end": {
            "line": 50,
            "character": 31
          }
        },
        "message": "Consider `[*EXPL_COLS, \"day\"]` instead of concatenation",
        "severity": 2,
        "code": "RUF005",
        "source": "ruff",
        "tags": [],
        "data": {
          "edits": [
            {
              "content": "[*EXPL_COLS, \"day\"]",
              "location": {
                "row": 51,
                "column": 13
              },
              "end_location": {
                "row": 51,
                "column": 32
              }
            }
          ],
          "message": "Replace with `[*EXPL_COLS, \"day\"]`",
          "applicability": "unsafe"
        }
      }
    ],
    "edit": {
      "changes": {
        "file:///....epy": [
          {
            "range": {
              "start": {
                "line": 50,
                "character": 0
              },
              "end": {
                "line": 50,
                "character": 32
              }
            },
            "newText": "    .select(EXPL_COLS + [\"day\"])  # noqa: RUF005"
          }
        ]
      }
    }
  },
  {
    "title": "Ruff: Organize imports",
    "kind": "source.organizeImports",
    "diagnostics": [
      {
        "range": {
          "start": {
            "line": 0,
            "character": 0
          },
          "end": {
            "line": 11,
            "character": 34
          }
        },
        "message": "Import block is un-sorted or un-formatted",
        "severity": 2,
        "code": "I001",
        "source": "ruff",
        "tags": [],
        "data": {
          "edits": [
            {
              "content": "impo.... gg\n\n",
              "location": {
                "row": 1,
                "column": 1
              },
              "end_location": {
                "row": 15,
                "column": 1
              }
            }
          ],
          "message": "Organize imports",
          "applicability": "safe"
        }
      }
    ],
    "edit": {
      "changes": {
        "file:/.....py": [
          {
            "range": {
              "start": {
                "line": 0,
                "character": 0
              },
              "end": {
                "line": 14,
                "character": 0
              }
            },
            "newText": "....."
          }
        ]
      }
    }
  },
  {
    "title": "Ruff (I001): Disable for this line",
    "kind": "quickfix",
    "diagnostics": [
      {
        "range": {
          "start": {
            "line": 0,
            "character": 0
          },
          "end": {
            "line": 11,
            "character": 34
          }
        },
        "message": "Import block is un-sorted or un-formatted",
        "severity": 2,
        "code": "I001",
        "source": "ruff",
        "tags": [],
        "data": {
          "edits": [
            {
              "content": "....",
              "location": {
                "row": 1,
                "column": 1
              },
              "end_location": {
                "row": 15,
                "column": 1
              }
            }
          ],
          "message": "Organize imports",
          "applicability": "safe"
        }
      }
    ],
    "edit": {
      "changes": {
        "....py": [
          {
            "range": {
              "start": {
                "line": 0,
                "character": 0
              },
              "end": {
                "line": 0,
                "character": 14
              }
            },
            "newText": "import logging  # noqa: I001"
          }
        ]
      }
    }
  },
  {
    "title": "Ruff: Fix All (safe fixes)",
    "kind": "source.fixAll",
    "edit": {
      "changes": {
        "file:///....py": [
          {
            "range": {
              "start": {
                "line": 0,
                "character": 0
              },
              "end": {
                "line": 69,
                "character": 0
              }
            },
            "newText": "...."
          }
        ]
      }
    }
  }
]

When I activate ruff-lsp server I do get the local suggestions. So it has to do with the python-ruff-lsp plugin somehow.

The stderr log does not show any errors. So I suspect this might have to do with mis-configuration on my side.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions