Skip to content

Commit

Permalink
API: drop None rather than unset in JSON response
Browse files Browse the repository at this point in the history
Fixes #217, #231.

I am still new to the project, so I may not have the full story. But it
started with a somewhat far-reaching merge to remove defaults from all
serialisable fields in the API: #198. This had the knock-on effect of
regressing progress notifications, as reported by @MatejKastak in #217.
One of their suggestions is to not use `exclude_unset=True`. Some months
later @dimbleby suggested that `exclude_none=True` would also fix the
issue[1]. Considering those 2 suggestions, let's replace
`exclude_unset=True` with `exclude_none=True`.

1. #198 (comment)
  • Loading branch information
tombh committed Jun 1, 2022
1 parent 4ce8988 commit e3ee7ee
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 1 deletion.
1 change: 1 addition & 0 deletions CONTRIBUTORS.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
- [Matej Kašťák](https://github.com/MatejKastak)
- [Max O'Cull](https://github.com/Maxattax97)
- [Samuel Roeca](https://github.com/pappasam)
- [Tom BH](https://github.com/tombh)
- [Tomoya Tanjo](https://github.com/tom-tan)
- [yorodm](https://github.com/yorodm)
- [bollwyvl](https://github.com/bollwyvl)
Expand Down
2 changes: 1 addition & 1 deletion pygls/protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,7 @@ def _send_data(self, data):
return

try:
body = data.json(by_alias=True, exclude_unset=True, encoder=default_serializer)
body = data.json(by_alias=True, exclude_none=True, encoder=default_serializer)
logger.info('Sending data: %s', body)

body = body.encode(self.CHARSET)
Expand Down
117 changes: 117 additions & 0 deletions tests/lsp/test_progress.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
############################################################################
# Copyright(c) Open Law Library. All rights reserved. #
# See ThirdPartyNotices.txt in the project root for additional notices. #
# #
# Licensed under the Apache License, Version 2.0 (the "License") #
# you may not use this file except in compliance with the License. #
# You may obtain a copy of the License at #
# #
# http: // www.apache.org/licenses/LICENSE-2.0 #
# #
# Unless required by applicable law or agreed to in writing, software #
# distributed under the License is distributed on an "AS IS" BASIS, #
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
# See the License for the specific language governing permissions and #
# limitations under the License. #
############################################################################
import platform
import sys
import unittest
from typing import List, Optional

import time
from pygls.lsp.methods import (
CODE_LENS,
PROGRESS_NOTIFICATION

)
from pygls.lsp.types import (
CodeLens,
CodeLensParams,
CodeLensOptions,
TextDocumentIdentifier,
WorkDoneProgressBegin,
WorkDoneProgressEnd,
WorkDoneProgressReport
)
from pygls.lsp.types.basic_structures import ProgressParams
from ..conftest import CALL_TIMEOUT, ClientServer


PROGRESS_TOKEN = 'token'


class TestCodeLens(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.client_server = ClientServer()
cls.client, cls.server = cls.client_server
cls.notifications: List[ProgressParams] = []

@cls.server.feature(
CODE_LENS,
CodeLensOptions(
resolve_provider=False,
work_done_progress=PROGRESS_TOKEN
),
)
def f1(params: CodeLensParams) -> Optional[List[CodeLens]]:
cls.server.lsp.progress.begin(
PROGRESS_TOKEN,
WorkDoneProgressBegin(title='starting', percentage=0)
)
cls.server.lsp.progress.report(
PROGRESS_TOKEN,
WorkDoneProgressReport(message='doing', percentage=50),
)
cls.server.lsp.progress.end(
PROGRESS_TOKEN,
WorkDoneProgressEnd(message='done')
)
return None

@cls.client.feature(
PROGRESS_NOTIFICATION
)
def f2(params):
cls.notifications.append(params)

cls.client_server.start()

@classmethod
def tearDownClass(cls):
cls.client_server.stop()

def test_capabilities(self):
capabilities = self.server.server_capabilities

assert capabilities.code_lens_provider
assert capabilities.code_lens_provider.work_done_progress == PROGRESS_TOKEN

def test_progress_notifications(self):
self.client.lsp.send_request(
CODE_LENS,
CodeLensParams(
text_document=TextDocumentIdentifier(uri='file://return.none'),
work_done_token=PROGRESS_TOKEN
),
).result(timeout=CALL_TIMEOUT)

time.sleep(0.1)

assert len(self.notifications) == 3
assert self.notifications[0].token == PROGRESS_TOKEN
assert self.notifications[0].value == {
'kind': 'begin', 'title': 'starting', 'percentage': 0
}
assert self.notifications[1].value == {
'kind': 'report', 'message': 'doing', 'percentage': 50
}
assert self.notifications[2].value == {
'kind': 'end', 'message': 'done'
}


IS_WIN_PY_36 = platform.system() == "Windows" and sys.version == 3.6
if __name__ == '__main__' and not IS_WIN_PY_36:
unittest.main()

0 comments on commit e3ee7ee

Please sign in to comment.