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

v1.0.0 BREAKING CHANGES release thread #273

Merged
merged 20 commits into from
Dec 3, 2022
Merged

Conversation

tombh
Copy link
Collaborator

@tombh tombh commented Oct 17, 2022

With huge thanks and kudos to Esbonio's @alcarney and Microsoft's @karthiknadig we now have a pre release version of Pygls that migrates away from Pydantic and to lsprotocol.

⚠️ This involves breaking changes. Existing projects depending on Pygls will need to update their code. Testers are welcome.

You can try it by explicitly setting your dependency to pygls=1.0.0a2. The migration guide is at: docs/pages/migrating-to-v1.rst

lsprotocol is mostly just a module that officially and comprehensively defines the data structures and types that make up the LSP specification. Therefore, what it offers are upstream (from Microsoft, the creators of LSP) guarantees on adherence to the formal behaviour and expectations of the specification.

TODO:

This may also be a good opportunity to introduce other breaking changes, such as in #274

Notes:

Edit: added line about taking advantage of a breaking change release

@dimbleby
Copy link
Contributor

My main observation from pappasam/jedi-language-server#230 is that it's a real shame that lsprotocol doesn't expose types, that will make authoring language servers that little bit more error prone than it need be.

Otherwise it all seems to have gone pretty smoothly, nice job.

@karthiknadig
Copy link
Contributor

@dimbleby if you see anything missing, please file bug on lsprotocol. I can try and improve code generation to produce any missing or supporting types.

@dimbleby
Copy link
Contributor

dimbleby commented Oct 18, 2022

@karthiknadig you probably want to get involved in the bug at pappasam/jedi-language-server#230 (comment)

@tombh
Copy link
Collaborator Author

tombh commented Oct 18, 2022

@dimbleby Wow that's awesome that you've already managed to integrate this. Can you explain more about lsprotocol not exposing types? I mean I see that it does use Python types, eg: types.py. So do you mean that it lacks a py.typed stub to help tools like Mypy orient themselves? Or do you mean that it doesn't give type-based feedback during serialisation/deserialisation? Or something else?

@dimbleby
Copy link
Contributor

dimbleby commented Oct 18, 2022

I mean type annotations, I would love for lsprotocol to (i) be clean under mypy --strict and (ii) include a py.typed so that users could take advantage of that

you'll likely have seen that it's not quite so awesome as all that, pappasam/jedi-language-server#230 (comment) looks like an lsprotocol bug

@tombh
Copy link
Collaborator Author

tombh commented Oct 18, 2022

Ok, so it's more a matter of having better typing support, rather than introducing types in the first place? It seems like lsprotocol very much leans in the direction of wanting to fully support Mypy right? So it should be a legitimate next step to explore, or even that @karthiknadig intends for full support and we've just surfaced some minor bugs?

@dimbleby
Copy link
Contributor

some way still to go, if mypy support is intended:

$ mypy lsprotocol
...
Found 25 errors in 2 files (checked 5 source files)

$ mypy --strict lsprotocol
...
Found 68 errors in 4 files (checked 5 source files)

Actually that's a relatively small number for a project that perhaps hasn't yet even tried - possibly it wouldn't be tremendously hard to get to zero errors.

@tombh tombh mentioned this pull request Oct 18, 2022
@karthiknadig
Copy link
Contributor

Created microsoft/lsprotocol#96 to track mypy --strict issues.

@alcarney
Copy link
Collaborator

Not sure how we want to handle issues with this branch? Do we want to create dedicated issues but tag them with something like v1, or just track everything in this PR?

I've noticed that the server process just completely crashes if it encounters a message it cannot parse/does not like.
Happy to open a dedicated issue for this if we want to go that route :)

@tombh
Copy link
Collaborator Author

tombh commented Oct 23, 2022

Good question @alcarney, it probably depends on the issue. I think that one may need its own issue, because it's more likely to be a bug in Pygls itself right?

@tombh
Copy link
Collaborator Author

tombh commented Oct 23, 2022

Just a little update to summarise from the other threads involved.

@alcarney
Copy link
Collaborator

@tombh yes, the error handling in pygls needs some refinement as one bad message probably shouldn't take out the server completely

@tombh
Copy link
Collaborator Author

tombh commented Oct 23, 2022

I've made a new issue for the more general problem of unhandled errors: #277

@tombh
Copy link
Collaborator Author

tombh commented Oct 31, 2022

I've just rebased the recent changes we've merged into master in the last few days, most notably improved error handling #282. That addresses an underlying issue that @alcarney noticed with this new code, namely that the server wasn't catching unhandled deserialisation errors, which I think understandably could come up more now that we've changed all the underlying types.

But I think @alcarney, you we still need to fix that error? All we've done with #282 is catch unhandled errors, rather than fix the unhandled error right?

Also, where are we at with the Mypy types? I don't think that's necessarily a blocking issue? The main thing is that https://pypi.org/project/lsprotocol/2022.0.0a6 fixed the errors in pappasam/jedi-language-server#230 (comment) right?

@alcarney
Copy link
Collaborator

But I think @alcarney, we still need to fix that error?

The error in question was being tracked in microsoft/lsprotocol#102, and should be fixed in the next version of lsprotocol

@tombh
Copy link
Collaborator Author

tombh commented Oct 31, 2022

Ah great! I'll look out for that then

@tombh tombh force-pushed the v1-lsprotocol-breaking-alpha branch from 5816916 to c329c8f Compare November 2, 2022 13:42
@tombh
Copy link
Collaborator Author

tombh commented Nov 2, 2022

📰 New versions news 📰

So it looks like we're getting there with this branch, or indeed are there already. I think the only main thing left to do is write a brief v0.12.x to v1 migration guide.

@alcarney
Copy link
Collaborator

alcarney commented Nov 2, 2022

Hmm... I wonder why all the builds have hung...

I think the only main thing left to do is write a brief v0.12.x to v1 migration guide.

I can put something together as I have a go at porting esbonio - unless anyone else has started working on one?

So it looks like we're getting there with this branch

Exciting! Though do we know how many servers have attempted a migration?

@tombh tombh force-pushed the v1-lsprotocol-breaking-alpha branch from c329c8f to 7c06b31 Compare November 2, 2022 23:20
@tombh
Copy link
Collaborator Author

tombh commented Nov 3, 2022

No, nobody else (well it would only be me anyway) has started on a migration guide. I think you'd be best placed to write it, so if you're up for that then great, but I'm totally happy to do it too.

The only report from the wild about implementing this migration so far that we've had is pappasam/jedi-language-server#230 Yeah, would be nice to get some more feedback for sure.

So, the CI errors. There are 3 interesting things happening.

  1. The LSP client that we use in tests, which is repurposed from the LSP server, doesn't (really?? still!?) have a central place to timeout asyncio futures 🫤 Hence the hung CI. Point 3 here in particular is the culprit for the hang. Let me think about a way to refactor the LSP test client so that at the very least CI doesn't hang again like this.

    PS. I assume that the fact that it's the unique circumstances of the repurposed LSP test client, that this hanging behaviour doesn't reflect a potential issue with the actual server itself. I'm not 100% sure though. I just assume that the server doesn't call anything like a timeout-less, blocking Future.result() in non-async functions 👀

  2. CodeActionKind.Refactor isn't parsing:

E       AssertionError: assert 'refactor' == <CodeActionKind.Refactor: 'refactor'>
E        +  where 'refactor' = CodeAction(title='action2', kind='refactor', diagnostics=None, is_preferred=None, disabled=None, edit=None, command=None, data=None).kind
E        +  and   <CodeActionKind.Refactor: 'refactor'> = CodeActionKind.Refactor
  1. FoldingRange isn't parsing:
    Can be isolated with: .tox/py/bin/python3.10 -m pytest -vvv tests/lsp/test_folding_range.py::test_folding_range_return_list --log-cli-level=DEBUG
| Traceback (most recent call last):
|   File "<cattrs generated structure lsprotocol.types.FoldingRange>", line 28, in structure_FoldingRange
|     res['kind'] = __c_structure_kind(o['kind'], __c_type_kind)
|   File "/home/streamer/Workspace/pygls/.tox/py/lib/python3.10/site-packages/cattrs/converters.py", line 377, in _structure_error
|     raise StructureHandlerNotFoundError(msg, type_=cl)
| cattrs.errors.StructureHandlerNotFoundError: Unsupported type: typing.Union[lsprotocol.types.FoldingRangeKind, str, NoneType]. Register a structure hook for it.
| Structuring class FoldingRange @ attribute kind

As far as I can tell, there are no tests that depend on any of the
values contained within `ClientCapabilities`. This commit adds some
tests around the construction of the `TextDocumentSyncOptions` field for
the server's capabilities.

It also fixes a bug that was introduced in the previous commit
@tombh tombh force-pushed the v1-lsprotocol-breaking-alpha branch from 44b861b to 6fbda1c Compare December 1, 2022 21:13
@tombh
Copy link
Collaborator Author

tombh commented Dec 1, 2022

@charliermarsh Yes, that is indeed helpful to see! Thank you ❤️

Everybody: I've updated Pygls' README and docs to state that v1 alpha is now the recommended version to start new Pygls-based LSP servers.

Having released a fix on our main branch for a LSP type issue that is already fixed in this branch, I'm feeling like we're ready to release this branch.

Today, the fact that this branch is not released caused a tiny bit more real extra work rather than the theoretical extra work that might come from releasing this branch. Which is to say, there's a reasonable assumption that this branch will not cause any extra work when released, and an actual fact that not releasing it has already created a tiny bit more work.

Fixing the LSP type issue today felt very much like supporting an old version of Pygls. Which is something we can still totally do even once this v1 branch is released.

What do you think @alcarney?

@alcarney
Copy link
Collaborator

alcarney commented Dec 1, 2022

I agree, I can't think of a technical reason to hold this branch back anymore.

The only other thing that's probably worth doing before a release, is to make sure the docs, README etc are consistent with all the changes here.

alcarney and others added 11 commits December 2, 2022 09:44
This removes the `attrs.field` definitions from the
`JsonRPCResponseMessage`, `JsonRPCRequestMessage` and
`JsonRPCNotification` types. This prevents any dictionaries passed to
the `result` or `params` fields from being corrupted during
serialization.

To preserve the "converting dictionaries to objects" behavior, this
commit extends the converter we get from `lsprotocol` to include
structure hooks that calls `dict_to_object` on the required fields
during parsing.

Finally, the module level converter has been removed in favour of a
converter attached to the `JsonRPCProtocol` object in preparation for
allowing servers to provide their own custom converters.
@tombh tombh force-pushed the v1-lsprotocol-breaking-alpha branch from 6fbda1c to 288f33b Compare December 2, 2022 12:44
@tombh
Copy link
Collaborator Author

tombh commented Dec 2, 2022

Great. I've just pushed those doc changes and bumped the version to v1.0.0. I'm ready to merge! Sanity-check depending of course.

@alcarney
Copy link
Collaborator

alcarney commented Dec 2, 2022

Looks good.

One final thought, should we wait for a non-alpha release of lsprotocol? Technically, I don't think it matters, but I'm (possibly overthinking!) how it would look to someone unfamiliar with the details when they see a 1.0 pulling in an alpha library?

@brettcannon
Copy link
Contributor

One final thought, should we wait for a non-alpha release of lsprotocol?

FYI Karthik won't be available to make a final release until the latter half of this month, but we would be happy to if the library is working as you all need it to be.

@tombh
Copy link
Collaborator Author

tombh commented Dec 3, 2022

@alcarney Good point. Ideally yes, it'd be good to release with a non-alpha lsprotocol. I wonder if we're in a bit of a chicken and the egg situation? That's the main reason I'm voting for a release now, just to fall on one side of the line. It's only a vote, so totally happy to wait as well. But I'm feeling like this v1 branch now offers something better than current v0.x. Even if it might not be perfect.

@brettcannon From my perspective I think pygls and lsprotocol are ready and am happy to even release pygls with the alpha lsprotocol. So take that as one vote of confidence, but of course let the general consensus be the guide.

@alcarney
Copy link
Collaborator

alcarney commented Dec 3, 2022

@tombh, just remembered another change I think we wanted to make so I've opened #295.

Happy to release v1.0 with an alpha lsprotocol if you are, just thought I'd check 🙂

@tombh tombh requested a review from alcarney December 3, 2022 18:24
@tombh
Copy link
Collaborator Author

tombh commented Dec 3, 2022

Well, LGTM then 🚀

Copy link
Collaborator

@alcarney alcarney left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't believe it's actually happening! 😅

@tombh tombh merged commit e0f1ba3 into master Dec 3, 2022
@tombh
Copy link
Collaborator Author

tombh commented Dec 3, 2022

Woohoo! 🎉 Merged and published. Thank you everybody ❤️🙇

I actually streamed the moment live on Twitch 😎 https://clips.twitch.tv/DeadExquisiteButterPJSugar-DLXXPnknw87VSdPs

Here's the Pypi package: https://pypi.org/project/pygls/1.0.0

And the migration docs have been published too: https://pygls.readthedocs.io/en/latest/pages/migrating-to-v1.html (I notice I didn't get the list syntax right for the links to other already migrated projects, I'll make a little PR for that).

@tombh tombh deleted the v1-lsprotocol-breaking-alpha branch December 3, 2022 19:01
@charliermarsh
Copy link

Congratulations on the release!

@brettcannon
Copy link
Contributor

Congrats on the release! And thanks to everyone for providing feedback on lsprotocol so we could improve it for everyone's benefit!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants