Repository: PurpleMyst/sansio-lsp-client (language: python)

Issue:
cattrs and Python 3.9
Currently, sansio-lsp-client doesn't work on Python 3.9 because cattr before v1.1.0 does not support Python 3.9. On the other hand, v1.1.0 drops the support for Python 3.6, and the rest of porcupine still supports Python 3.6 (but I guess I can stop supporting it in Porcupine too). https://cattrs.readthedocs.io/en/latest/history.html

Ideally, sansio-lsp-client would depend on an older version of cattrs on Python 3.6 and the latest version on all other Pythons. If that's not possible, we should figure out whether 3.9 is more popular than 3.6, and based on that, decide which version of cattrs to depend on.


Discussion / hints:
Another possible solution is switching to [pydantic](https://pypi.org/project/pydantic/). It solves, for all intents and purposes, the same problem but I've preferred it over cattr for personal project I've developed after this one. 

What is it in cattr <1.1.0 that does not support Python3.9? 

We should weigh the cost/benefit of both solutions, and I'd be curious to see a full-on cattr vs pydantic comparison. One thing that's good about pydantic is that converting to-and-from JSON is a first-class use case.

Oh, here's a [pydantic vs attrs vs dataclasses comparison](https://stefan.sofa-rockers.org/2020/05/29/attrs-dataclasses-pydantic/) I found on the internet. I'm reading through it right now.

What do you think?
Honestly, I don't like cattrs. As far as I know, it relies heavily on version-dependent implementation details. [Here](https://github.com/Akuli/porcupine/runs/1681060170) is an error from Porcupine tests, showing how `cattrs` casually imports a symbol named `_Union`.
Now that I think about it, Porcupine already depends on dacite for serializing classes to JSON and back. It uses it for attaching somewhat arbitrary data to Tk events that only support strings of data.
> 
> 
> Honestly, I don't like cattrs. As far as I know, it relies heavily on version-dependent implementation details. [Here](https://github.com/Akuli/porcupine/runs/1681060170) is an error from Porcupine tests, showing how `cattrs` casually imports a symbol named `_Union`.

Yeah, I chose `cattrs` for this project simply because it looked to be the only solution at the time. I'm fully in favor of switching it out.



> 
> 
> Now that I think about it, Porcupine already depends on dacite for serializing classes to JSON and back. It uses it for attaching somewhat arbitrary data to Tk events that only support strings of data.

dacite looks interesting. I think I'm a bigger fan of pydantic simply because of its validation and its interconversion capabilities. Also, we *might* be able to utilize JSON schemas of the LSP to automatically "catch up" with new versions of the spec. Might be fun, idk, what do you think?
I haven't used pydantic. Use it if you like it. Dacite also validates something, but maybe you meant that pydantic validates even more.

I don't know what the JSON schemas are, and automatically catching up with new versions of the spec sounds too good to be true. If sansio-lsp-client just outputs the data from the langserver as is, then doesn't it mean that I need to handle LSP spec changes in the editor plugin instead? Changes in LSP spec is one of the things that I want sansio-lsp-client to abstract away.

Fix patch:
diff --git a/.github/workflows/black.yml b/.github/workflows/black.yml
index 2e7f786..bc4a3df 100644
--- a/.github/workflows/black.yml
+++ b/.github/workflows/black.yml
@@ -7,8 +7,7 @@ jobs:
     name: Black
     steps:
     - uses: actions/checkout@v1
-    - name: Set up Python 3.8
-      uses: actions/setup-python@v1
+    - uses: actions/setup-python@v1
       with:
         python-version: 3.8
     - name: Install Dependencies
diff --git a/.github/workflows/mypy.yml b/.github/workflows/mypy.yml
index 56a1f09..b3a6b63 100644
--- a/.github/workflows/mypy.yml
+++ b/.github/workflows/mypy.yml
@@ -7,10 +7,9 @@ jobs:
     name: Mypy
     steps:
     - uses: actions/checkout@v1
-    - name: Set up Python 3.8
-      uses: actions/setup-python@v1
+    - uses: actions/setup-python@v1
       with:
-        python-version: 3.8
+        python-version: 3.9
     - name: Install Dependencies
       run: |
         pip install poetry && poetry install


Test patch:
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 275b0ca..9bb3f3e 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -4,7 +4,7 @@ jobs:
     runs-on: ubuntu-latest
     strategy:
       matrix:
-        python-version: ["3.6", "3.7", "3.8"]  # TODO: Python 3.9 support
+        python-version: ["3.6", "3.7", "3.8", "3.9"]
     steps:
     - uses: actions/checkout@v1
     - uses: actions/setup-python@v1