Skip to content

Drop Python 3.8, add Python 3.11 to CI and run pyupgrade #650

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
May 28, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
strategy:
fail-fast: false
matrix:
PYTHON_VERSION: ['3.8']
PYTHON_VERSION: ['3.9']
timeout-minutes: 10
steps:
- uses: actions/cache@v1
Expand Down
4 changes: 1 addition & 3 deletions .github/workflows/static.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,7 @@ jobs:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
# TODO: check with Python 3, but need to fix the
# errors first
python-version: '3.8'
python-version: '3.9'
architecture: 'x64'
- run: python -m pip install --upgrade pip setuptools jsonschema
# If we don't install pycodestyle, pylint will throw an unused-argument error in pylsp/plugins/pycodestyle_lint.py:72
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test-linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
strategy:
fail-fast: false
matrix:
PYTHON_VERSION: ['3.10', '3.9', '3.8']
PYTHON_VERSION: ['3.11', '3.10', '3.9']
timeout-minutes: 10
steps:
- uses: actions/cache@v4
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test-mac.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
strategy:
fail-fast: false
matrix:
PYTHON_VERSION: ['3.10', '3.9', '3.8']
PYTHON_VERSION: ['3.11', '3.10', '3.9']
timeout-minutes: 10
steps:
- uses: actions/cache@v4
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test-win.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
strategy:
fail-fast: false
matrix:
PYTHON_VERSION: ['3.10', '3.9', '3.8']
PYTHON_VERSION: ['3.11', '3.10', '3.9']
timeout-minutes: 10
steps:
- uses: actions/cache@v4
Expand Down
4 changes: 2 additions & 2 deletions pylsp/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
start_ws_lang_server,
)

LOG_FORMAT = "%(asctime)s {0} - %(levelname)s - %(name)s - %(message)s".format(
LOG_FORMAT = "%(asctime)s {} - %(levelname)s - %(name)s - %(message)s".format(
time.localtime().tm_zone
)

Expand Down Expand Up @@ -98,7 +98,7 @@ def _configure_logger(verbose=0, log_config=None, log_file=None) -> None:
root_logger = logging.root

if log_config:
with open(log_config, "r", encoding="utf-8") as f:
with open(log_config, encoding="utf-8") as f:
logging.config.dictConfig(json.load(f))
else:
formatter = logging.Formatter(LOG_FORMAT)
Expand Down
8 changes: 4 additions & 4 deletions pylsp/_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import re
import threading
import time
from typing import List, Optional
from typing import Optional

import docstring_to_markdown
import jedi
Expand Down Expand Up @@ -78,7 +78,7 @@ def find_parents(root, path, names):

Args:
path (str): The file path to start searching up from.
names (List[str]): The file/directory names to look for.
names (list[str]): The file/directory names to look for.
root (str): The directory at which to stop recursing upwards.

Note:
Expand Down Expand Up @@ -198,7 +198,7 @@ def wrap_signature(signature):
SERVER_SUPPORTED_MARKUP_KINDS = {"markdown", "plaintext"}


def choose_markup_kind(client_supported_markup_kinds: List[str]):
def choose_markup_kind(client_supported_markup_kinds: list[str]):
"""Choose a markup kind supported by both client and the server.

This gives priority to the markup kinds provided earlier on the client preference list.
Expand All @@ -210,7 +210,7 @@ def choose_markup_kind(client_supported_markup_kinds: List[str]):


def format_docstring(
contents: str, markup_kind: str, signatures: Optional[List[str]] = None
contents: str, markup_kind: str, signatures: Optional[list[str]] = None
):
"""Transform the provided docstring into a MarkupContent object.

Expand Down
5 changes: 3 additions & 2 deletions pylsp/config/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@

import logging
import sys
from collections.abc import Mapping, Sequence
from functools import lru_cache
from typing import List, Mapping, Sequence, Union
from typing import Union

import pluggy
from pluggy._hooks import HookImpl
Expand Down Expand Up @@ -32,7 +33,7 @@ def _hookexec(
methods: Sequence[HookImpl],
kwargs: Mapping[str, object],
firstresult: bool,
) -> Union[object, List[object]]:
) -> Union[object, list[object]]:
# called from all hookcaller instances.
# enable_tracing will set its own wrapping function at self._inner_hookexec
try:
Expand Down
4 changes: 2 additions & 2 deletions pylsp/plugins/_resolvers.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ def resolve(self, completion):
def format_label(completion, sig):
if sig and completion.type in ("function", "method"):
params = ", ".join(param.name for param in sig[0].params)
label = "{}({})".format(completion.name, params)
label = f"{completion.name}({params})"
return label
return completion.name

Expand All @@ -115,7 +115,7 @@ def format_snippet(completion, sig):
snippet_completion["insertTextFormat"] = lsp.InsertTextFormat.Snippet
snippet = completion.name + "("
for i, param in enumerate(positional_args):
snippet += "${%s:%s}" % (i + 1, param.name)
snippet += "${{{}:{}}}".format(i + 1, param.name)
if i < len(positional_args) - 1:
snippet += ", "
snippet += ")$0"
Expand Down
17 changes: 9 additions & 8 deletions pylsp/plugins/_rope_task_handle.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
from __future__ import annotations

import logging
from typing import Callable, ContextManager, List, Optional, Sequence
from collections.abc import Sequence
from typing import Callable, ContextManager

from rope.base.taskhandle import BaseJobSet, BaseTaskHandle

Expand All @@ -19,13 +20,13 @@ class PylspJobSet(BaseJobSet):
_report_iter: ContextManager
job_name: str = ""

def __init__(self, count: Optional[int], report_iter: ContextManager) -> None:
def __init__(self, count: int | None, report_iter: ContextManager) -> None:
if count is not None:
self.count = count
self._reporter = report_iter.__enter__()
self._report_iter = report_iter

def started_job(self, name: Optional[str]) -> None:
def started_job(self, name: str | None) -> None:
if name:
self.job_name = name

Expand All @@ -42,7 +43,7 @@ def finished_job(self) -> None:
def check_status(self) -> None:
pass

def get_percent_done(self) -> Optional[float]:
def get_percent_done(self) -> float | None:
if self.count == 0:
return 0
return (self.done / self.count) * 100
Expand All @@ -66,8 +67,8 @@ def _report(self) -> None:

class PylspTaskHandle(BaseTaskHandle):
name: str
observers: List
job_sets: List[PylspJobSet]
observers: list
job_sets: list[PylspJobSet]
stopped: bool
workspace: Workspace
_report: Callable[[str, str], None]
Expand All @@ -77,7 +78,7 @@ def __init__(self, workspace: Workspace) -> None:
self.job_sets = []
self.observers = []

def create_jobset(self, name="JobSet", count: Optional[int] = None):
def create_jobset(self, name="JobSet", count: int | None = None):
report_iter = self.workspace.report_progress(
name, None, None, skip_token_initialization=True
)
Expand All @@ -89,7 +90,7 @@ def create_jobset(self, name="JobSet", count: Optional[int] = None):
def stop(self) -> None:
pass

def current_jobset(self) -> Optional[BaseJobSet]:
def current_jobset(self) -> BaseJobSet | None:
pass

def add_observer(self) -> None:
Expand Down
8 changes: 4 additions & 4 deletions pylsp/plugins/definition.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from __future__ import annotations

import logging
from typing import TYPE_CHECKING, Any, Dict, List
from typing import TYPE_CHECKING, Any

import jedi

Expand All @@ -23,7 +23,7 @@


def _resolve_definition(
maybe_defn: Name, script: Script, settings: Dict[str, Any]
maybe_defn: Name, script: Script, settings: dict[str, Any]
) -> Name:
for _ in range(MAX_JEDI_GOTO_HOPS):
if maybe_defn.is_definition() or maybe_defn.module_path != script.path:
Expand All @@ -43,8 +43,8 @@ def _resolve_definition(

@hookimpl
def pylsp_definitions(
config: Config, document: Document, position: Dict[str, int]
) -> List[Dict[str, Any]]:
config: Config, document: Document, position: dict[str, int]
) -> list[dict[str, Any]]:
settings = config.plugin_settings("jedi_definition")
code_position = _utils.position_to_jedi_linecolumn(document, position)
script = document.jedi_script(use_document_path=True)
Expand Down
6 changes: 3 additions & 3 deletions pylsp/plugins/flake8_lint.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ def run_flake8(flake8_executable, args, document, source):
cmd = [flake8_executable]
cmd.extend(args)
p = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE, **popen_kwargs)
except IOError:
except OSError:
log.debug(
"Can't execute %s. Trying with '%s -m flake8'",
flake8_executable,
Expand Down Expand Up @@ -165,9 +165,9 @@ def build_args(options):
arg = "--{}={}".format(arg_name, ",".join(arg_val))
elif isinstance(arg_val, bool):
if arg_val:
arg = "--{}".format(arg_name)
arg = f"--{arg_name}"
else:
arg = "--{}={}".format(arg_name, arg_val)
arg = f"--{arg_name}={arg_val}"
args.append(arg)
return args

Expand Down
2 changes: 1 addition & 1 deletion pylsp/plugins/pylint_lint.py
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ def _run_pylint_stdio(pylint_executable, document, flags):
cmd.extend(flags)
cmd.extend(["--from-stdin", document.path])
p = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE)
except IOError:
except OSError:
log.debug("Can't execute %s. Trying with 'python -m pylint'", pylint_executable)
cmd = [sys.executable, "-m", "pylint"]
cmd.extend(flags)
Expand Down
31 changes: 16 additions & 15 deletions pylsp/plugins/rope_autoimport.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

import logging
import threading
from typing import Any, Dict, Generator, List, Optional, Set, Union
from collections.abc import Generator
from typing import Any, Optional, Union

import parso
from jedi import Script
Expand Down Expand Up @@ -36,7 +37,7 @@ def reload_cache(
self,
config: Config,
workspace: Workspace,
files: Optional[List[Document]] = None,
files: Optional[list[Document]] = None,
single_thread: Optional[bool] = True,
):
if self.is_blocked():
Expand All @@ -45,7 +46,7 @@ def reload_cache(
memory: bool = config.plugin_settings("rope_autoimport").get("memory", False)
rope_config = config.settings().get("rope", {})
autoimport = workspace._rope_autoimport(rope_config, memory)
resources: Optional[List[Resource]] = (
resources: Optional[list[Resource]] = (
None
if files is None
else [document._rope_resource(rope_config) for document in files]
Expand All @@ -65,7 +66,7 @@ def _reload_cache(
self,
workspace: Workspace,
autoimport: AutoImport,
resources: Optional[List[Resource]] = None,
resources: Optional[list[Resource]] = None,
) -> None:
task_handle = PylspTaskHandle(workspace)
autoimport.generate_cache(task_handle=task_handle, resources=resources)
Expand All @@ -76,7 +77,7 @@ def is_blocked(self):


@hookimpl
def pylsp_settings() -> Dict[str, Dict[str, Dict[str, Any]]]:
def pylsp_settings() -> dict[str, dict[str, dict[str, Any]]]:
# Default rope_completion to disabled
return {
"plugins": {
Expand Down Expand Up @@ -180,13 +181,13 @@ def _handle_argument(node: NodeOrLeaf, word_node: tree.Leaf):


def _process_statements(
suggestions: List[SearchResult],
suggestions: list[SearchResult],
doc_uri: str,
word: str,
autoimport: AutoImport,
document: Document,
feature: str = "completions",
) -> Generator[Dict[str, Any], None, None]:
) -> Generator[dict[str, Any], None, None]:
for suggestion in suggestions:
insert_line = autoimport.find_insertion_line(document.source) - 1
start = {"line": insert_line, "character": 0}
Expand Down Expand Up @@ -220,7 +221,7 @@ def _process_statements(
raise ValueError(f"Unknown feature: {feature}")


def get_names(script: Script) -> Set[str]:
def get_names(script: Script) -> set[str]:
"""Get all names to ignore from the current file."""
raw_names = script.get_names(definitions=True)
log.debug(raw_names)
Expand All @@ -233,7 +234,7 @@ def pylsp_completions(
workspace: Workspace,
document: Document,
position,
ignored_names: Union[Set[str], None],
ignored_names: Union[set[str], None],
):
"""Get autoimport suggestions."""
if (
Expand All @@ -251,7 +252,7 @@ def pylsp_completions(
word = word_node.value
log.debug(f"autoimport: searching for word: {word}")
rope_config = config.settings(document_path=document.path).get("rope", {})
ignored_names: Set[str] = ignored_names or get_names(
ignored_names: set[str] = ignored_names or get_names(
document.jedi_script(use_document_path=True)
)
autoimport = workspace._rope_autoimport(rope_config)
Expand Down Expand Up @@ -303,9 +304,9 @@ def pylsp_code_actions(
config: Config,
workspace: Workspace,
document: Document,
range: Dict,
context: Dict,
) -> List[Dict]:
range: dict,
context: dict,
) -> list[dict]:
"""
Provide code actions through rope.

Expand All @@ -317,9 +318,9 @@ def pylsp_code_actions(
Current workspace.
document : pylsp.workspace.Document
Document to apply code actions on.
range : Dict
range : dict
Range argument given by pylsp. Not used here.
context : Dict
context : dict
CodeActionContext given as dict.

Returns
Expand Down
2 changes: 1 addition & 1 deletion pylsp/plugins/rope_completion.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def _resolve_completion(completion, data, markup_kind):
except Exception as e:
log.debug("Failed to resolve Rope completion: %s", e)
doc = ""
completion["detail"] = "{0} {1}".format(data.scope or "", data.name)
completion["detail"] = "{} {}".format(data.scope or "", data.name)
completion["documentation"] = doc
return completion

Expand Down
Loading