Skip to content
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

Sketching out a potential new architecture for pygls #418

Closed
wants to merge 17 commits into from
Closed
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
182 changes: 136 additions & 46 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -25,10 +25,52 @@ jobs:
cancel_others: 'true'
skip_after_successful_duplicate: 'false'

build:
needs: pre_job
if: needs.pre_job.outputs.should_skip != 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Use Python
uses: actions/setup-python@v5
with:
python-version: "3.x"

- name: Install Poetry
uses: snok/install-poetry@v1
with:
virtualenvs-in-project: true

- name: Load cached venv
id: cached-poetry-dependencies
uses: actions/cache@v3
with:
path: .venv
key: venv-${{ hashFiles('**/poetry.lock') }}

- name: Install dependencies
if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true'
run: poetry install

- name: Build packages (sdist and wheel)
run: |
git describe --tags --abbrev=0
poetry build

- uses: actions/upload-artifact@v4
with:
name: dist
path: "dist/*"


test:
needs: pre_job
if: needs.pre_job.outputs.should_skip != 'true'
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest]
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
@@ -44,7 +86,6 @@ jobs:
- name: Install Poetry
uses: snok/install-poetry@v1
with:
version: '1.5.1'
virtualenvs-in-project: true
- name: Load cached venv
id: cached-poetry-dependencies
@@ -54,72 +95,126 @@ jobs:
key: venv-${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('**/poetry.lock') }}
- name: Install dependencies
if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true'
run: poetry install --all-extras
run: poetry install --with test
- name: Run tests
run: |
source $VENV # Only needed because of Github Action caching
poe test

test-pyodide:
needs: pre_job
needs: [pre_job, build]
if: needs.pre_job.outputs.should_skip != 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Use Python "3.10"
uses: actions/setup-python@v4
- uses: actions/checkout@v4

- uses: 'actions/setup-node@v4'
with:
node-version: 18.x
cache: 'npm'
cache-dependency-path: 'tests/pyodide/package-lock.json'

- name: Use Python "3.12"
id: setup-python
uses: actions/setup-python@v5
with:
python-version: "3.10"
python-version: "3.12"

- name: Install Poetry
uses: snok/install-poetry@v1
with:
virtualenvs-in-project: true

- uses: actions/download-artifact@v4
with:
name: dist
path: 'dist'

- name: Install Dependencies
if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true'
run: |
poetry install --with pyodide
- name: Run Testsuite
uses: nick-fields/retry@v2
with:
timeout_minutes: 10
max_attempts: 6
command: |
source $VENV
poe test-pyodide || true
poetry install --with test

lint:
needs: pre_job
cd tests/pyodide
npm ci

- name: Run tests
run: |
source $VENV
poe test-pyodide

test-wasi:
needs: [pre_job, build]
if: needs.pre_job.outputs.should_skip != 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Use Python
uses: actions/setup-python@v4
- uses: actions/checkout@v4

- name: Use Python "3.12"
uses: actions/setup-python@v5
with:
python-version: "3.x"
python-version: "3.12"

- name: Install Poetry
uses: snok/install-poetry@v1
with:
virtualenvs-in-project: true
- name: Load cached venv
id: cached-poetry-dependencies
uses: actions/cache@v3

- uses: actions/download-artifact@v4
with:
path: .venv
key: venv-${{ hashFiles('**/poetry.lock') }}
- name: Install dependencies
if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true'
run: poetry install --all-extras --with dev
- name: Run lints
name: dist
path: 'dist'

- name: Install Dependencies
run: |
set -eux

poetry install --with test

# Wasmtime WASI Host
gh release download v16.0.0 \
--repo bytecodealliance/wasmtime \
--pattern 'wasmtime-v16.0.0-x86_64-linux.tar.xz' \
--dir /tmp

tar -xvf /tmp/wasmtime-v16.0.0-x86_64-linux.tar.xz \
--wildcards 'wasmtime*/wasmtime'

mv wasmtime-v16.0.0-x86_64-linux/wasmtime $HOME/.local/bin
rm -r wasmtime-v16.0.0-x86_64-linux
wasmtime --version

# WASI Python build
gh release download v3.12.1 \
--repo brettcannon/cpython-wasi-build \
--pattern 'python*sdk-20.zip' \
--dir tests/wasi

unzip -q tests/wasi/python-3.12.1-wasi_sdk-20.zip -d tests/wasi
rm tests/wasi/python-3.12.1-wasi_sdk-20.zip

# Install Python dependencies
pip install \
--target tests/wasi/lib/python3.12/site-packages \
--only-binary :all: \
--implementation py \
--abi none \
--platform any \
--python-version "3.12" \
dist/pygls-*.whl

ls -l tests/wasi/lib/python3.12/site-packages/

env:
GH_TOKEN: ${{ github.token }}

- name: Run tests
run: |
source $VENV
poe lint
poe test-wasi

build:
lint:
needs: pre_job
if: needs.pre_job.outputs.should_skip != 'true'
if: false # needs.pre_job.outputs.should_skip != 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
@@ -141,13 +236,8 @@ jobs:
key: venv-${{ hashFiles('**/poetry.lock') }}
- name: Install dependencies
if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true'
run: poetry install --all-extras
- name: Build packages (sdist and wheel)
run: poetry install --all-extras --with dev
- name: Run lints
run: |
git describe --tags --abbrev=0
poetry build
- name: Upload builds
uses: actions/upload-artifact@v3
with:
name: build-artifacts
path: "dist/*"
source $VENV
poe lint
52 changes: 27 additions & 25 deletions examples/servers/code_actions.py
Original file line number Diff line number Diff line change
@@ -14,33 +14,26 @@
# See the License for the specific language governing permissions and #
# limitations under the License. #
############################################################################
import logging
import re
from pygls.server import LanguageServer
from lsprotocol.types import (
TEXT_DOCUMENT_CODE_ACTION,
CodeAction,
CodeActionKind,
CodeActionOptions,
CodeActionParams,
Position,
Range,
TextEdit,
WorkspaceEdit,
)

from lsprotocol import types

from pygls import IS_WASM
from pygls.lsp.server import LanguageServer

ADDITION = re.compile(r"^\s*(\d+)\s*\+\s*(\d+)\s*=(?=\s*$)")
server = LanguageServer("code-action-server", "v0.1")
server = LanguageServer("code-action-server", "v1")


@server.feature(
TEXT_DOCUMENT_CODE_ACTION,
CodeActionOptions(code_action_kinds=[CodeActionKind.QuickFix]),
types.TEXT_DOCUMENT_CODE_ACTION,
types.CodeActionOptions(code_action_kinds=[types.CodeActionKind.QuickFix]),
)
def code_actions(params: CodeActionParams):
def code_actions(params: types.CodeActionParams):
items = []
document_uri = params.text_document.uri
document = server.workspace.get_document(document_uri)
document = server.workspace.get_text_document(document_uri)

start_line = params.range.start.line
end_line = params.range.end.line
@@ -49,26 +42,35 @@ def code_actions(params: CodeActionParams):
for idx, line in enumerate(lines):
match = ADDITION.match(line)
if match is not None:
range_ = Range(
start=Position(line=start_line + idx, character=0),
end=Position(line=start_line + idx, character=len(line) - 1),
range_ = types.Range(
start=types.Position(line=start_line + idx, character=0),
end=types.Position(line=start_line + idx, character=len(line) - 1),
)

left = int(match.group(1))
right = int(match.group(2))
answer = left + right

text_edit = TextEdit(range=range_, new_text=f"{line.strip()} {answer}!")
text_edit = types.TextEdit(
range=range_, new_text=f"{line.strip()} {answer}!"
)

action = CodeAction(
action = types.CodeAction(
title=f"Evaluate '{match.group(0)}'",
kind=CodeActionKind.QuickFix,
edit=WorkspaceEdit(changes={document_uri: [text_edit]}),
kind=types.CodeActionKind.QuickFix,
edit=types.WorkspaceEdit(changes={document_uri: [text_edit]}),
)
items.append(action)

return items


if __name__ == "__main__":
server.start_io()
logging.basicConfig(level=logging.INFO, format="[%(levelname)s]: %(message)s")

if IS_WASM:
server.start_io()
else:
import asyncio

asyncio.run(server.start_io())
Loading

Unchanged files with check annotations Beta

function getClientOptions(): LanguageClientOptions {
const config = vscode.workspace.getConfiguration('pygls.client')
const options = {
documentSelector: config.get<any>('documentSelector'),

Check warning on line 211 in examples/vscode-playground/src/extension.ts

GitHub Actions / build

Unexpected any. Specify a different type
outputChannel: logger,
connectionOptions: {
maxRestartCount: 0 // don't restart on server failure.
return options
}
function startLangServerTCP(addr: number): LanguageClient {

Check warning on line 221 in examples/vscode-playground/src/extension.ts

GitHub Actions / build

'startLangServerTCP' is defined but never used
const serverOptions: ServerOptions = () => {
return new Promise((resolve /*, reject */) => {
const clientSocket = new net.Socket();