Skip to content

Commit 60a5d0a

Browse files
authored
Merge branch 'develop' into uri_match_parent
2 parents edce2fc + 19fc07a commit 60a5d0a

11 files changed

Lines changed: 78 additions & 22 deletions

File tree

.github/workflows/static.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,13 @@ jobs:
2222
OS: 'linux'
2323
timeout-minutes: 2
2424
steps:
25-
- uses: actions/cache@v4
25+
- uses: actions/cache@v6
2626
with:
2727
path: ~/.cache/pip
2828
key: static-pip-${{ hashFiles('pyproject.toml') }}
2929
restore-keys: static-pip-
30-
- uses: actions/checkout@v4
31-
- uses: actions/setup-python@v5
30+
- uses: actions/checkout@v7
31+
- uses: actions/setup-python@v6
3232
with:
3333
python-version: '3.9'
3434
architecture: 'x64'

.github/workflows/test-linux.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,13 @@ jobs:
2727
PYTHON_VERSION: ['3.14', '3.13', '3.12', '3.11', '3.10', '3.9']
2828
timeout-minutes: 10
2929
steps:
30-
- uses: actions/cache@v4
30+
- uses: actions/cache@v6
3131
with:
3232
path: ~/.cache/pip
3333
key: ${{ runner.os }}-${{ matrix.PYTHON_VERSION }}-pip-${{ hashFiles('pyproject.toml') }}
3434
restore-keys: ${{ runner.os }}-${{ matrix.PYTHON_VERSION }}-pip-
35-
- uses: actions/checkout@v4
36-
- uses: actions/setup-python@v5
35+
- uses: actions/checkout@v7
36+
- uses: actions/setup-python@v6
3737
with:
3838
python-version: ${{ matrix.PYTHON_VERSION }}
3939
architecture: 'x64'

.github/workflows/test-mac.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,24 +16,24 @@ concurrency:
1616
jobs:
1717
build:
1818
name: Mac Py${{ matrix.PYTHON_VERSION }}
19-
runs-on: macos-13
19+
runs-on: macos-14
2020
env:
2121
CI: 'true'
2222
OS: 'macos'
2323
PYTHON_VERSION: ${{ matrix.PYTHON_VERSION }}
2424
strategy:
2525
fail-fast: false
2626
matrix:
27-
PYTHON_VERSION: ['3.14', '3.12', '3.9']
27+
PYTHON_VERSION: ['3.14', '3.12', '3.11']
2828
timeout-minutes: 10
2929
steps:
30-
- uses: actions/cache@v4
30+
- uses: actions/cache@v6
3131
with:
3232
path: ~/Library/Caches/pip
3333
key: ${{ runner.os }}-${{ matrix.PYTHON_VERSION }}-pip-${{ hashFiles('pyproject.toml') }}
3434
restore-keys: ${{ runner.os }}-${{ matrix.PYTHON_VERSION }}-pip-
35-
- uses: actions/checkout@v4
36-
- uses: actions/setup-python@v5
35+
- uses: actions/checkout@v7
36+
- uses: actions/setup-python@v6
3737
with:
3838
python-version: ${{ matrix.PYTHON_VERSION }}
3939
architecture: 'x64'

.github/workflows/test-win.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,13 @@ jobs:
2727
PYTHON_VERSION: ['3.14', '3.12', '3.9']
2828
timeout-minutes: 10
2929
steps:
30-
- uses: actions/cache@v4
30+
- uses: actions/cache@v6
3131
with:
3232
path: ~\AppData\Local\pip\Cache
3333
key: ${{ runner.os }}-${{ matrix.PYTHON_VERSION }}-pip-${{ hashFiles('pyproject.toml') }}
3434
restore-keys: ${{ runner.os }}-${{ matrix.PYTHON_VERSION }}-pip-
35-
- uses: actions/checkout@v4
36-
- uses: actions/setup-python@v5
35+
- uses: actions/checkout@v7
36+
- uses: actions/setup-python@v6
3737
with:
3838
python-version: ${{ matrix.PYTHON_VERSION }}
3939
architecture: 'x64'

CONFIGURATION.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,6 @@ This server can be configured using the `workspace/didChangeConfiguration` metho
7878
| `pylsp.rope.ropeFolder` | `array` of unique `string` items | The name of the folder in which rope stores project configurations and data. Pass `null` for not using such a folder at all. | `null` |
7979
| `pylsp.signature.formatter` | `string` (one of: `'black'`, `'ruff'`, `None`) | Formatter to use for reformatting signatures in docstrings. | `"black"` |
8080
| `pylsp.signature.include_docstring` | `boolean` | Include signature docstring. | `true` |
81-
| `pylsp.signature.line_length` | `number` | Maximum line length in signatures. | `88` |
81+
| `pylsp.signature.line_length` | `integer` | Maximum line length in signatures. | `88` |
8282

8383
This documentation was generated from `pylsp/config/schema.json`. Please do not edit this file directly.

pylsp/_utils.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,13 @@ def find_parents(root, path, names):
9898
# Split the relative by directory, generate all the parent directories, then check each of them.
9999
# This avoids running a loop that has different base-cases for unix/windows
100100
# e.g. /a/b and /a/b/c/d/e.py -> ['/a/b', 'c', 'd']
101-
dirs = [root] + os.path.relpath(os.path.dirname(path), root).split(os.path.sep)
101+
try:
102+
dirs = [root] + os.path.relpath(os.path.dirname(path), root).split(os.path.sep)
103+
except ValueError:
104+
# On Windows, relpath raises ValueError when path and root are on different mounts
105+
# (e.g. a UNC share root vs a drive-letter path). Nothing to find in this case.
106+
log.warning("Path %r not in %r", path, root)
107+
return []
102108

103109
# Search each of /a/b/c, /a/b, /a
104110
while dirs:

pylsp/config/schema.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,10 @@
9191
"description": "List of errors and warnings to ignore (or skip)."
9292
},
9393
"pylsp.plugins.flake8.maxComplexity": {
94-
"type": "integer",
94+
"type": [
95+
"integer",
96+
"null"
97+
],
9598
"default": null,
9699
"description": "Maximum allowed complexity threshold."
97100
},
@@ -536,7 +539,7 @@
536539
"description": "Include signature docstring."
537540
},
538541
"pylsp.signature.line_length": {
539-
"type": "number",
542+
"type": "integer",
540543
"default": 88,
541544
"description": "Maximum line length in signatures."
542545
}

pylsp/plugins/definition.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,10 @@ def pylsp_definitions(
7171
},
7272
}
7373
for d in definitions
74-
if d.is_definition() and (follow_builtin_defns or _not_internal_definition(d))
74+
if d.is_definition()
75+
and d.line is not None
76+
and d.column is not None
77+
and (follow_builtin_defns or _not_internal_definition(d))
7578
]
7679

7780

test/plugins/test_completion.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,7 @@ def test_matplotlib_completions(config, workspace) -> None:
322322

323323

324324
def test_snippets_completion(config, workspace) -> None:
325-
doc_snippets = "from collections import defaultdict \na=defaultdict"
325+
doc_snippets = "from collections import defaultdict \ndef foo(a): pass\nfoo"
326326
com_position = {"line": 0, "character": 35}
327327
doc = Document(DOC_URI, workspace, doc_snippets)
328328
config.capabilities["textDocument"] = {
@@ -332,9 +332,9 @@ def test_snippets_completion(config, workspace) -> None:
332332
completions = pylsp_jedi_completions(config, doc, com_position)
333333
assert completions[0]["insertText"] == "defaultdict"
334334

335-
com_position = {"line": 1, "character": len(doc_snippets)}
335+
com_position = {"line": 2, "character": 3}
336336
completions = pylsp_jedi_completions(config, doc, com_position)
337-
assert completions[0]["insertText"] == "defaultdict($0)"
337+
assert completions[0]["insertText"] == "foo($0)"
338338
assert completions[0]["insertTextFormat"] == lsp.InsertTextFormat.Snippet
339339

340340

test/plugins/test_definitions.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
import os
55

6+
import jedi
7+
68
from pylsp import uris
79
from pylsp.plugins.definition import pylsp_definitions
810
from pylsp.workspace import Document
@@ -173,3 +175,27 @@ def foo():
173175
assert [{"uri": module_uri, "range": def_range}] == pylsp_definitions(
174176
config, doc, cursor_pos
175177
)
178+
179+
180+
def test_definition_without_source_position(config, workspace, monkeypatch) -> None:
181+
# A definition jedi resolves without a source position (e.g. a compiled
182+
# builtin, where line/column are None) must be dropped, not crash with
183+
# `TypeError: unsupported operand type(s) for -: 'NoneType' and 'int'`.
184+
# Regression test for #623 and #624.
185+
class _NoPositionName:
186+
line = None
187+
column = None
188+
module_path = None
189+
name = "compiled"
190+
191+
def is_definition(self) -> bool:
192+
return True
193+
194+
monkeypatch.setattr(
195+
jedi.api.Script, "goto", lambda *args, **kwargs: [_NoPositionName()]
196+
)
197+
198+
doc = Document(DOC_URI, workspace, DOC)
199+
# follow_builtin_definitions defaults to True, so the None-guard in the
200+
# return comprehension is the only thing preventing the crash.
201+
assert pylsp_definitions(config, doc, {"line": 3, "character": 6}) == []

0 commit comments

Comments
 (0)