This is an automated email from the ASF dual-hosted git repository.

abeizn pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-devlake.git


The following commit(s) were added to refs/heads/main by this push:
     new a22b1ddb4 fix: Downgrade python to 3.9 (#4947)
a22b1ddb4 is described below

commit a22b1ddb485e731e3e2bc0ed4c2dc641c3fe6e22
Author: Camille Teruel <[email protected]>
AuthorDate: Tue Apr 18 12:45:31 2023 +0200

    fix: Downgrade python to 3.9 (#4947)
    
    * fix: Downgrade python to 3.9
    
    * Fix python dependency spec of poetry project to exclude 3.10
    * Make code compatible with python 3.9:
        * Replace match statements with if/elif
        * Replace a type hint
    
    * fix: Use python 3.9 in github workflows
    
    ---------
    
    Co-authored-by: Camille Teruel <[email protected]>
---
 .github/workflows/test-e2e.yml                     |  4 +
 .github/workflows/test.yml                         |  2 +
 .../python/plugins/azuredevops/azuredevops/api.py  |  4 +-
 .../azuredevops/azuredevops/streams/builds.py      | 42 +++++------
 .../azuredevops/azuredevops/streams/jobs.py        | 38 +++++-----
 backend/python/plugins/azuredevops/poetry.lock     | 86 +++++++++-------------
 backend/python/plugins/azuredevops/pyproject.toml  |  2 +-
 backend/python/pydevlake/poetry.lock               | 84 ++++++++-------------
 backend/python/pydevlake/pyproject.toml            |  2 +-
 backend/python/test/fakeplugin/poetry.lock         | 86 +++++++++-------------
 backend/python/test/fakeplugin/pyproject.toml      |  2 +-
 devops/docker/lake-builder/Dockerfile              |  2 +-
 12 files changed, 147 insertions(+), 207 deletions(-)

diff --git a/.github/workflows/test-e2e.yml b/.github/workflows/test-e2e.yml
index ac54cd45b..9e8ed95f7 100644
--- a/.github/workflows/test-e2e.yml
+++ b/.github/workflows/test-e2e.yml
@@ -49,6 +49,8 @@ jobs:
         uses: actions/checkout@v3
       - run: git config --global --add safe.directory $(pwd)
       - name: Build Python
+        with:
+          python-version: 3.9.9
         run: |
           cd backend
           echo "Building Python"
@@ -88,6 +90,8 @@ jobs:
         uses: actions/checkout@v3
       - run: git config --global --add safe.directory $(pwd)
       - name: Build Python
+        with:
+          python-version: 3.9.9
         run: |
           cd backend
           echo "Building Python"
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 4a689bce7..57d9aceb3 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -45,6 +45,8 @@ jobs:
       uses: actions/checkout@v3
     - run: git config --global --add safe.directory $(pwd)
     - name: Build Python
+      with:
+        python-version: 3.9.9
       run: |
         cd backend
         make build-python
diff --git a/backend/python/plugins/azuredevops/azuredevops/api.py 
b/backend/python/plugins/azuredevops/azuredevops/api.py
index b4db91640..3730b8877 100644
--- a/backend/python/plugins/azuredevops/azuredevops/api.py
+++ b/backend/python/plugins/azuredevops/azuredevops/api.py
@@ -18,14 +18,12 @@ import base64
 
 from pydevlake.api import API, request_hook, Paginator, Request
 
-from azuredevops.models import AzureDevOpsConnection
-
 
 class AzurePaginator(Paginator):
     def get_items(self, response) -> Optional[list[object]]:
         return response.json['value']
 
-    def get_next_page_id(self, response) -> Optional[int | str]:
+    def get_next_page_id(self, response) -> Optional[str]:
         return response.headers.get('x-ms-continuation')
 
     def set_next_page_param(self, request, next_page_id):
diff --git a/backend/python/plugins/azuredevops/azuredevops/streams/builds.py 
b/backend/python/plugins/azuredevops/azuredevops/streams/builds.py
index a8ef02005..bc105cc62 100644
--- a/backend/python/plugins/azuredevops/azuredevops/streams/builds.py
+++ b/backend/python/plugins/azuredevops/azuredevops/streams/builds.py
@@ -51,30 +51,28 @@ class Builds(Stream):
 
     def convert(self, b: Build, ctx: Context):
         result = None
-        match b.build_result:
-            case Build.Result.Canceled:
-                result = devops.CICDResult.ABORT
-            case Build.Result.Failed:
-                result = devops.CICDResult.FAILURE
-            case Build.Result.PartiallySucceeded:
-                result = devops.CICDResult.SUCCESS
-            case Build.Result.Succeeded:
-                result = devops.CICDResult.SUCCESS
+        if b.build_result == Build.Result.Canceled:
+            result = devops.CICDResult.ABORT
+        elif b.build_result == Build.Result.Failed:
+            result = devops.CICDResult.FAILURE
+        elif b.build_result == Build.Result.PartiallySucceeded:
+            result = devops.CICDResult.SUCCESS
+        elif b.build_result ==  Build.Result.Succeeded:
+            result = devops.CICDResult.SUCCESS
 
         status = None
-        match b.status:
-            case Build.Status.All:
-                status = devops.CICDStatus.IN_PROGRESS
-            case Build.Status.Cancelling:
-                status = devops.CICDStatus.DONE
-            case Build.Status.Completed:
-                status = devops.CICDStatus.DONE
-            case Build.Status.InProgress:
-                status = devops.CICDStatus.IN_PROGRESS
-            case Build.Status.NotStarted:
-                status = devops.CICDStatus.IN_PROGRESS
-            case Build.Status.Postponed:
-                status = devops.CICDStatus.IN_PROGRESS
+        if b.status == Build.Status.All:
+            status = devops.CICDStatus.IN_PROGRESS
+        elif b.status == Build.Status.Cancelling:
+            status = devops.CICDStatus.DONE
+        elif b.status == Build.Status.Completed:
+            status = devops.CICDStatus.DONE
+        elif b.status ==  Build.Status.InProgress:
+            status = devops.CICDStatus.IN_PROGRESS
+        elif b.status == Build.Status.NotStarted:
+            status = devops.CICDStatus.IN_PROGRESS
+        elif b.status ==  Build.Status.Postponed:
+            status = devops.CICDStatus.IN_PROGRESS
 
         type = devops.CICDType.BUILD
         if ctx.transformation_rule and 
ctx.transformation_rule.deployment_pattern.search(b.name):
diff --git a/backend/python/plugins/azuredevops/azuredevops/streams/jobs.py 
b/backend/python/plugins/azuredevops/azuredevops/streams/jobs.py
index c6d34a7fd..89e6e4a25 100644
--- a/backend/python/plugins/azuredevops/azuredevops/streams/jobs.py
+++ b/backend/python/plugins/azuredevops/azuredevops/streams/jobs.py
@@ -41,28 +41,26 @@ class Jobs(Substream):
 
     def convert(self, j: Job, ctx: Context) -> Iterable[devops.CICDPipeline]:
         result = None
-        match j.result:
-            case Job.Result.Abandoned:
-                result = devops.CICDResult.ABORT
-            case Job.Result.Canceled:
-                result = devops.CICDResult.ABORT
-            case Job.Result.Failed:
-                result = devops.CICDResult.FAILURE
-            case Job.Result.Skipped:
-                result = devops.CICDResult.ABORT
-            case Job.Result.Succeeded:
-                result = devops.CICDResult.SUCCESS
-            case Job.Result.SucceededWithIssues:
-                result = devops.CICDResult.FAILURE
+        if j.result == Job.Result.Abandoned:
+            result = devops.CICDResult.ABORT
+        elif j.result == Job.Result.Canceled:
+            result = devops.CICDResult.ABORT
+        elif j.result == Job.Result.Failed:
+            result = devops.CICDResult.FAILURE
+        elif j.result == Job.Result.Skipped:
+            result = devops.CICDResult.ABORT
+        elif j.result == Job.Result.Succeeded:
+            result = devops.CICDResult.SUCCESS
+        elif j.result == Job.Result.SucceededWithIssues:
+            result = devops.CICDResult.FAILURE
 
         status = None
-        match j.state:
-            case Job.State.Completed:
-                status = devops.CICDStatus.DONE
-            case Job.State.InProgress:
-                status = devops.CICDStatus.IN_PROGRESS
-            case Job.State.Pending:
-                status = devops.CICDStatus.IN_PROGRESS
+        if j.state == Job.State.Completed:
+            status = devops.CICDStatus.DONE
+        elif j.state == Job.State.InProgress:
+            status = devops.CICDStatus.IN_PROGRESS
+        if j.state == Job.State.Pending:
+            status = devops.CICDStatus.IN_PROGRESS
 
         type = devops.CICDType.BUILD
         if ctx.transformation_rule and 
ctx.transformation_rule.deployment_pattern.search(j.name):
diff --git a/backend/python/plugins/azuredevops/poetry.lock 
b/backend/python/plugins/azuredevops/poetry.lock
index 74b8c9635..63c0e1b47 100644
--- a/backend/python/plugins/azuredevops/poetry.lock
+++ b/backend/python/plugins/azuredevops/poetry.lock
@@ -1,24 +1,5 @@
 # This file is automatically @generated by Poetry 1.4.1 and should not be 
changed by hand.
 
-[[package]]
-name = "attrs"
-version = "22.2.0"
-description = "Classes Without Boilerplate"
-category = "main"
-optional = false
-python-versions = ">=3.6"
-files = [
-    {file = "attrs-22.2.0-py3-none-any.whl", hash = 
"sha256:29e95c7f6778868dbd49170f98f8818f78f3dc5e0e37c0b1f474e3561b240836"},
-    {file = "attrs-22.2.0.tar.gz", hash = 
"sha256:c9227bfc2f01993c03f68db37d1d15c9690188323c067c641f1a35ca58185f99"},
-]
-
-[package.extras]
-cov = ["attrs[tests]", "coverage-enable-subprocess", "coverage[toml] (>=5.3)"]
-dev = ["attrs[docs,tests]"]
-docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", 
"sphinxcontrib-towncrier", "towncrier", "zope.interface"]
-tests = ["attrs[tests-no-zope]", "zope.interface"]
-tests-no-zope = ["cloudpickle", "cloudpickle", "hypothesis", "hypothesis", 
"mypy (>=0.971,<0.990)", "mypy (>=0.971,<0.990)", "pympler", "pympler", "pytest 
(>=4.3.0)", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-mypy-plugins", 
"pytest-xdist[psutil]", "pytest-xdist[psutil]"]
-
 [[package]]
 name = "certifi"
 version = "2022.12.7"
@@ -246,21 +227,21 @@ files = [
 
 [[package]]
 name = "inflect"
-version = "6.0.2"
+version = "6.0.4"
 description = "Correctly generate plurals, singular nouns, ordinals, 
indefinite articles; convert numbers to words"
 category = "main"
 optional = false
 python-versions = ">=3.7"
 files = [
-    {file = "inflect-6.0.2-py3-none-any.whl", hash = 
"sha256:182741ec7e9e4c8f7f55b01fa6d80bcd3c4a183d349dfa6d9abbff0a1279e98f"},
-    {file = "inflect-6.0.2.tar.gz", hash = 
"sha256:f1a6bcb0105046f89619fde1a7d044c612c614c2d85ef182582d9dc9b86d309a"},
+    {file = "inflect-6.0.4-py3-none-any.whl", hash = 
"sha256:2d592e7e4eafb6e51f9c626c5dd4288f5ce55981eaac9b342e868ead95ead5c3"},
+    {file = "inflect-6.0.4.tar.gz", hash = 
"sha256:1842649a17b6cad66812a5c9bdfacb6310e1e7b6dd8a31f026766df1b62612eb"},
 ]
 
 [package.dependencies]
 pydantic = ">=1.9.1"
 
 [package.extras]
-docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", 
"rst.linker (>=1.9)", "sphinx (>=3.5)"]
+docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", 
"rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"]
 testing = ["flake8 (<5)", "pygments", "pytest (>=6)", "pytest-black 
(>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", 
"pytest-flake8", "pytest-mypy (>=0.9.1)"]
 
 [[package]]
@@ -318,14 +299,14 @@ files = [
 
 [[package]]
 name = "packaging"
-version = "23.0"
+version = "23.1"
 description = "Core utilities for Python packages"
 category = "main"
 optional = false
 python-versions = ">=3.7"
 files = [
-    {file = "packaging-23.0-py3-none-any.whl", hash = 
"sha256:714ac14496c3e68c99c29b00845f7a2b85f3bb6f1078fd9f72fd20f0570002b2"},
-    {file = "packaging-23.0.tar.gz", hash = 
"sha256:b6ad297f8907de0fa2fe1ccbd26fdaf387f5f47c7275fedf8cce89f99446cf97"},
+    {file = "packaging-23.1-py3-none-any.whl", hash = 
"sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61"},
+    {file = "packaging-23.1.tar.gz", hash = 
"sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f"},
 ]
 
 [[package]]
@@ -346,25 +327,25 @@ testing = ["pytest", "pytest-benchmark"]
 
 [[package]]
 name = "psycopg2"
-version = "2.9.5"
+version = "2.9.6"
 description = "psycopg2 - Python-PostgreSQL Database Adapter"
 category = "main"
 optional = false
 python-versions = ">=3.6"
 files = [
-    {file = "psycopg2-2.9.5-cp310-cp310-win32.whl", hash = 
"sha256:d3ef67e630b0de0779c42912fe2cbae3805ebaba30cda27fea2a3de650a9414f"},
-    {file = "psycopg2-2.9.5-cp310-cp310-win_amd64.whl", hash = 
"sha256:4cb9936316d88bfab614666eb9e32995e794ed0f8f6b3b718666c22819c1d7ee"},
-    {file = "psycopg2-2.9.5-cp311-cp311-win32.whl", hash = 
"sha256:093e3894d2d3c592ab0945d9eba9d139c139664dcf83a1c440b8a7aa9bb21955"},
-    {file = "psycopg2-2.9.5-cp311-cp311-win_amd64.whl", hash = 
"sha256:920bf418000dd17669d2904472efeab2b20546efd0548139618f8fa305d1d7ad"},
-    {file = "psycopg2-2.9.5-cp36-cp36m-win32.whl", hash = 
"sha256:b9ac1b0d8ecc49e05e4e182694f418d27f3aedcfca854ebd6c05bb1cffa10d6d"},
-    {file = "psycopg2-2.9.5-cp36-cp36m-win_amd64.whl", hash = 
"sha256:fc04dd5189b90d825509caa510f20d1d504761e78b8dfb95a0ede180f71d50e5"},
-    {file = "psycopg2-2.9.5-cp37-cp37m-win32.whl", hash = 
"sha256:922cc5f0b98a5f2b1ff481f5551b95cd04580fd6f0c72d9b22e6c0145a4840e0"},
-    {file = "psycopg2-2.9.5-cp37-cp37m-win_amd64.whl", hash = 
"sha256:1e5a38aa85bd660c53947bd28aeaafb6a97d70423606f1ccb044a03a1203fe4a"},
-    {file = "psycopg2-2.9.5-cp38-cp38-win32.whl", hash = 
"sha256:f5b6320dbc3cf6cfb9f25308286f9f7ab464e65cfb105b64cc9c52831748ced2"},
-    {file = "psycopg2-2.9.5-cp38-cp38-win_amd64.whl", hash = 
"sha256:1a5c7d7d577e0eabfcf15eb87d1e19314c8c4f0e722a301f98e0e3a65e238b4e"},
-    {file = "psycopg2-2.9.5-cp39-cp39-win32.whl", hash = 
"sha256:322fd5fca0b1113677089d4ebd5222c964b1760e361f151cbb2706c4912112c5"},
-    {file = "psycopg2-2.9.5-cp39-cp39-win_amd64.whl", hash = 
"sha256:190d51e8c1b25a47484e52a79638a8182451d6f6dff99f26ad9bd81e5359a0fa"},
-    {file = "psycopg2-2.9.5.tar.gz", hash = 
"sha256:a5246d2e683a972e2187a8714b5c2cf8156c064629f9a9b1a873c1730d9e245a"},
+    {file = "psycopg2-2.9.6-cp310-cp310-win32.whl", hash = 
"sha256:f7a7a5ee78ba7dc74265ba69e010ae89dae635eea0e97b055fb641a01a31d2b1"},
+    {file = "psycopg2-2.9.6-cp310-cp310-win_amd64.whl", hash = 
"sha256:f75001a1cbbe523e00b0ef896a5a1ada2da93ccd752b7636db5a99bc57c44494"},
+    {file = "psycopg2-2.9.6-cp311-cp311-win32.whl", hash = 
"sha256:53f4ad0a3988f983e9b49a5d9765d663bbe84f508ed655affdb810af9d0972ad"},
+    {file = "psycopg2-2.9.6-cp311-cp311-win_amd64.whl", hash = 
"sha256:b81fcb9ecfc584f661b71c889edeae70bae30d3ef74fa0ca388ecda50b1222b7"},
+    {file = "psycopg2-2.9.6-cp36-cp36m-win32.whl", hash = 
"sha256:11aca705ec888e4f4cea97289a0bf0f22a067a32614f6ef64fcf7b8bfbc53744"},
+    {file = "psycopg2-2.9.6-cp36-cp36m-win_amd64.whl", hash = 
"sha256:36c941a767341d11549c0fbdbb2bf5be2eda4caf87f65dfcd7d146828bd27f39"},
+    {file = "psycopg2-2.9.6-cp37-cp37m-win32.whl", hash = 
"sha256:869776630c04f335d4124f120b7fb377fe44b0a7645ab3c34b4ba42516951889"},
+    {file = "psycopg2-2.9.6-cp37-cp37m-win_amd64.whl", hash = 
"sha256:a8ad4a47f42aa6aec8d061fdae21eaed8d864d4bb0f0cade5ad32ca16fcd6258"},
+    {file = "psycopg2-2.9.6-cp38-cp38-win32.whl", hash = 
"sha256:2362ee4d07ac85ff0ad93e22c693d0f37ff63e28f0615a16b6635a645f4b9214"},
+    {file = "psycopg2-2.9.6-cp38-cp38-win_amd64.whl", hash = 
"sha256:d24ead3716a7d093b90b27b3d73459fe8cd90fd7065cf43b3c40966221d8c394"},
+    {file = "psycopg2-2.9.6-cp39-cp39-win32.whl", hash = 
"sha256:1861a53a6a0fd248e42ea37c957d36950da00266378746588eab4f4b5649e95f"},
+    {file = "psycopg2-2.9.6-cp39-cp39-win_amd64.whl", hash = 
"sha256:ded2faa2e6dfb430af7713d87ab4abbfc764d8d7fb73eafe96a24155f906ebf5"},
+    {file = "psycopg2-2.9.6.tar.gz", hash = 
"sha256:f15158418fd826831b28585e2ab48ed8df2d0d98f502a2b4fe619e7d5ca29011"},
 ]
 
 [[package]]
@@ -422,13 +403,13 @@ email = ["email-validator (>=1.0.3)"]
 
 [[package]]
 name = "pydevd-pycharm"
-version = "231.8109.140"
+version = "231.8770.15"
 description = "PyCharm Debugger (used in PyCharm and PyDev)"
 category = "main"
 optional = false
 python-versions = "*"
 files = [
-    {file = "pydevd-pycharm-231.8109.140.tar.gz", hash = 
"sha256:3240cfc0ff3ef895fbd2462afbb9a409bf333e9ab50e964e3c7ede2ca026ed77"},
+    {file = "pydevd-pycharm-231.8770.15.tar.gz", hash = 
"sha256:607eb16a0d0e28dd05f68b7b332fd1dcc2cce1faae28db2e0b2df6765edebd7f"},
 ]
 
 [[package]]
@@ -437,7 +418,7 @@ version = "0.1.0"
 description = "Devlake plugin framework"
 category = "main"
 optional = false
-python-versions = "^3.10"
+python-versions = "~3.9"
 files = []
 develop = true
 
@@ -459,18 +440,17 @@ url = "../../pydevlake"
 
 [[package]]
 name = "pytest"
-version = "7.2.2"
+version = "7.3.1"
 description = "pytest: simple powerful testing with Python"
 category = "main"
 optional = false
 python-versions = ">=3.7"
 files = [
-    {file = "pytest-7.2.2-py3-none-any.whl", hash = 
"sha256:130328f552dcfac0b1cec75c12e3f005619dc5f874f0a06e8ff7263f0ee6225e"},
-    {file = "pytest-7.2.2.tar.gz", hash = 
"sha256:c99ab0c73aceb050f68929bc93af19ab6db0558791c6a0715723abe9d0ade9d4"},
+    {file = "pytest-7.3.1-py3-none-any.whl", hash = 
"sha256:3799fa815351fea3a5e96ac7e503a96fa51cc9942c3753cda7651b93c1cfa362"},
+    {file = "pytest-7.3.1.tar.gz", hash = 
"sha256:434afafd78b1d78ed0addf160ad2b77a30d35d4bdf8af234fe621919d9ed15e3"},
 ]
 
 [package.dependencies]
-attrs = ">=19.2.0"
 colorama = {version = "*", markers = "sys_platform == \"win32\""}
 exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < 
\"3.11\""}
 iniconfig = "*"
@@ -479,7 +459,7 @@ pluggy = ">=0.12,<2.0"
 tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""}
 
 [package.extras]
-testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "pygments 
(>=2.7.2)", "requests", "xmlschema"]
+testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", 
"nose", "pygments (>=2.7.2)", "requests", "xmlschema"]
 
 [[package]]
 name = "requests"
@@ -592,14 +572,14 @@ sqlcipher = ["sqlcipher3-binary"]
 
 [[package]]
 name = "sqlalchemy2-stubs"
-version = "0.0.2a32"
+version = "0.0.2a34"
 description = "Typing Stubs for SQLAlchemy 1.4"
 category = "main"
 optional = false
 python-versions = ">=3.6"
 files = [
-    {file = "sqlalchemy2-stubs-0.0.2a32.tar.gz", hash = 
"sha256:2a2cfab71d35ac63bf21ad841d8610cd93a3bd4c6562848c538fa975585c2739"},
-    {file = "sqlalchemy2_stubs-0.0.2a32-py3-none-any.whl", hash = 
"sha256:7f5fb30b0cf7c6b74c50c1d94df77ff32007afee8d80499752eb3fedffdbdfb8"},
+    {file = "sqlalchemy2-stubs-0.0.2a34.tar.gz", hash = 
"sha256:2432137ab2fde1a608df4544f6712427b0b7ff25990cfbbc5a9d1db6c8c6f489"},
+    {file = "sqlalchemy2_stubs-0.0.2a34-py3-none-any.whl", hash = 
"sha256:a313220ac793404349899faf1272e821a62dbe1d3a029bd444faa8d3e966cd07"},
 ]
 
 [package.dependencies]
@@ -680,5 +660,5 @@ socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"]
 
 [metadata]
 lock-version = "2.0"
-python-versions = "^3.10"
-content-hash = 
"517d44ea03bb02a3b6f1d1dbb00b29022a7852fc619e565192f0a5e8197dbc4f"
+python-versions = "~3.9"
+content-hash = 
"f028a55435b72ab4a5d4a4055db1ca6815a750c8c8e4f00404cff16d0d724454"
diff --git a/backend/python/plugins/azuredevops/pyproject.toml 
b/backend/python/plugins/azuredevops/pyproject.toml
index aad5b9602..b168c86f2 100644
--- a/backend/python/plugins/azuredevops/pyproject.toml
+++ b/backend/python/plugins/azuredevops/pyproject.toml
@@ -21,7 +21,7 @@ authors = ["Hezheng Yin <[email protected]>"]
 readme = "README.md"
 
 [tool.poetry.dependencies]
-python = "^3.9"
+python = "~3.9"
 pydevlake = { path = "../../pydevlake", develop = true }
 iso8601 = "^1.1.0"
 
diff --git a/backend/python/pydevlake/poetry.lock 
b/backend/python/pydevlake/poetry.lock
index 14c9c6ca3..3c693468c 100644
--- a/backend/python/pydevlake/poetry.lock
+++ b/backend/python/pydevlake/poetry.lock
@@ -1,24 +1,5 @@
 # This file is automatically @generated by Poetry 1.4.1 and should not be 
changed by hand.
 
-[[package]]
-name = "attrs"
-version = "22.2.0"
-description = "Classes Without Boilerplate"
-category = "main"
-optional = false
-python-versions = ">=3.6"
-files = [
-    {file = "attrs-22.2.0-py3-none-any.whl", hash = 
"sha256:29e95c7f6778868dbd49170f98f8818f78f3dc5e0e37c0b1f474e3561b240836"},
-    {file = "attrs-22.2.0.tar.gz", hash = 
"sha256:c9227bfc2f01993c03f68db37d1d15c9690188323c067c641f1a35ca58185f99"},
-]
-
-[package.extras]
-cov = ["attrs[tests]", "coverage-enable-subprocess", "coverage[toml] (>=5.3)"]
-dev = ["attrs[docs,tests]"]
-docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", 
"sphinxcontrib-towncrier", "towncrier", "zope.interface"]
-tests = ["attrs[tests-no-zope]", "zope.interface"]
-tests-no-zope = ["cloudpickle", "cloudpickle", "hypothesis", "hypothesis", 
"mypy (>=0.971,<0.990)", "mypy (>=0.971,<0.990)", "pympler", "pympler", "pytest 
(>=4.3.0)", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-mypy-plugins", 
"pytest-xdist[psutil]", "pytest-xdist[psutil]"]
-
 [[package]]
 name = "certifi"
 version = "2022.12.7"
@@ -246,21 +227,21 @@ files = [
 
 [[package]]
 name = "inflect"
-version = "6.0.2"
+version = "6.0.4"
 description = "Correctly generate plurals, singular nouns, ordinals, 
indefinite articles; convert numbers to words"
 category = "main"
 optional = false
 python-versions = ">=3.7"
 files = [
-    {file = "inflect-6.0.2-py3-none-any.whl", hash = 
"sha256:182741ec7e9e4c8f7f55b01fa6d80bcd3c4a183d349dfa6d9abbff0a1279e98f"},
-    {file = "inflect-6.0.2.tar.gz", hash = 
"sha256:f1a6bcb0105046f89619fde1a7d044c612c614c2d85ef182582d9dc9b86d309a"},
+    {file = "inflect-6.0.4-py3-none-any.whl", hash = 
"sha256:2d592e7e4eafb6e51f9c626c5dd4288f5ce55981eaac9b342e868ead95ead5c3"},
+    {file = "inflect-6.0.4.tar.gz", hash = 
"sha256:1842649a17b6cad66812a5c9bdfacb6310e1e7b6dd8a31f026766df1b62612eb"},
 ]
 
 [package.dependencies]
 pydantic = ">=1.9.1"
 
 [package.extras]
-docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", 
"rst.linker (>=1.9)", "sphinx (>=3.5)"]
+docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", 
"rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"]
 testing = ["flake8 (<5)", "pygments", "pytest (>=6)", "pytest-black 
(>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", 
"pytest-flake8", "pytest-mypy (>=0.9.1)"]
 
 [[package]]
@@ -306,14 +287,14 @@ files = [
 
 [[package]]
 name = "packaging"
-version = "23.0"
+version = "23.1"
 description = "Core utilities for Python packages"
 category = "main"
 optional = false
 python-versions = ">=3.7"
 files = [
-    {file = "packaging-23.0-py3-none-any.whl", hash = 
"sha256:714ac14496c3e68c99c29b00845f7a2b85f3bb6f1078fd9f72fd20f0570002b2"},
-    {file = "packaging-23.0.tar.gz", hash = 
"sha256:b6ad297f8907de0fa2fe1ccbd26fdaf387f5f47c7275fedf8cce89f99446cf97"},
+    {file = "packaging-23.1-py3-none-any.whl", hash = 
"sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61"},
+    {file = "packaging-23.1.tar.gz", hash = 
"sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f"},
 ]
 
 [[package]]
@@ -334,25 +315,25 @@ testing = ["pytest", "pytest-benchmark"]
 
 [[package]]
 name = "psycopg2"
-version = "2.9.5"
+version = "2.9.6"
 description = "psycopg2 - Python-PostgreSQL Database Adapter"
 category = "main"
 optional = false
 python-versions = ">=3.6"
 files = [
-    {file = "psycopg2-2.9.5-cp310-cp310-win32.whl", hash = 
"sha256:d3ef67e630b0de0779c42912fe2cbae3805ebaba30cda27fea2a3de650a9414f"},
-    {file = "psycopg2-2.9.5-cp310-cp310-win_amd64.whl", hash = 
"sha256:4cb9936316d88bfab614666eb9e32995e794ed0f8f6b3b718666c22819c1d7ee"},
-    {file = "psycopg2-2.9.5-cp311-cp311-win32.whl", hash = 
"sha256:093e3894d2d3c592ab0945d9eba9d139c139664dcf83a1c440b8a7aa9bb21955"},
-    {file = "psycopg2-2.9.5-cp311-cp311-win_amd64.whl", hash = 
"sha256:920bf418000dd17669d2904472efeab2b20546efd0548139618f8fa305d1d7ad"},
-    {file = "psycopg2-2.9.5-cp36-cp36m-win32.whl", hash = 
"sha256:b9ac1b0d8ecc49e05e4e182694f418d27f3aedcfca854ebd6c05bb1cffa10d6d"},
-    {file = "psycopg2-2.9.5-cp36-cp36m-win_amd64.whl", hash = 
"sha256:fc04dd5189b90d825509caa510f20d1d504761e78b8dfb95a0ede180f71d50e5"},
-    {file = "psycopg2-2.9.5-cp37-cp37m-win32.whl", hash = 
"sha256:922cc5f0b98a5f2b1ff481f5551b95cd04580fd6f0c72d9b22e6c0145a4840e0"},
-    {file = "psycopg2-2.9.5-cp37-cp37m-win_amd64.whl", hash = 
"sha256:1e5a38aa85bd660c53947bd28aeaafb6a97d70423606f1ccb044a03a1203fe4a"},
-    {file = "psycopg2-2.9.5-cp38-cp38-win32.whl", hash = 
"sha256:f5b6320dbc3cf6cfb9f25308286f9f7ab464e65cfb105b64cc9c52831748ced2"},
-    {file = "psycopg2-2.9.5-cp38-cp38-win_amd64.whl", hash = 
"sha256:1a5c7d7d577e0eabfcf15eb87d1e19314c8c4f0e722a301f98e0e3a65e238b4e"},
-    {file = "psycopg2-2.9.5-cp39-cp39-win32.whl", hash = 
"sha256:322fd5fca0b1113677089d4ebd5222c964b1760e361f151cbb2706c4912112c5"},
-    {file = "psycopg2-2.9.5-cp39-cp39-win_amd64.whl", hash = 
"sha256:190d51e8c1b25a47484e52a79638a8182451d6f6dff99f26ad9bd81e5359a0fa"},
-    {file = "psycopg2-2.9.5.tar.gz", hash = 
"sha256:a5246d2e683a972e2187a8714b5c2cf8156c064629f9a9b1a873c1730d9e245a"},
+    {file = "psycopg2-2.9.6-cp310-cp310-win32.whl", hash = 
"sha256:f7a7a5ee78ba7dc74265ba69e010ae89dae635eea0e97b055fb641a01a31d2b1"},
+    {file = "psycopg2-2.9.6-cp310-cp310-win_amd64.whl", hash = 
"sha256:f75001a1cbbe523e00b0ef896a5a1ada2da93ccd752b7636db5a99bc57c44494"},
+    {file = "psycopg2-2.9.6-cp311-cp311-win32.whl", hash = 
"sha256:53f4ad0a3988f983e9b49a5d9765d663bbe84f508ed655affdb810af9d0972ad"},
+    {file = "psycopg2-2.9.6-cp311-cp311-win_amd64.whl", hash = 
"sha256:b81fcb9ecfc584f661b71c889edeae70bae30d3ef74fa0ca388ecda50b1222b7"},
+    {file = "psycopg2-2.9.6-cp36-cp36m-win32.whl", hash = 
"sha256:11aca705ec888e4f4cea97289a0bf0f22a067a32614f6ef64fcf7b8bfbc53744"},
+    {file = "psycopg2-2.9.6-cp36-cp36m-win_amd64.whl", hash = 
"sha256:36c941a767341d11549c0fbdbb2bf5be2eda4caf87f65dfcd7d146828bd27f39"},
+    {file = "psycopg2-2.9.6-cp37-cp37m-win32.whl", hash = 
"sha256:869776630c04f335d4124f120b7fb377fe44b0a7645ab3c34b4ba42516951889"},
+    {file = "psycopg2-2.9.6-cp37-cp37m-win_amd64.whl", hash = 
"sha256:a8ad4a47f42aa6aec8d061fdae21eaed8d864d4bb0f0cade5ad32ca16fcd6258"},
+    {file = "psycopg2-2.9.6-cp38-cp38-win32.whl", hash = 
"sha256:2362ee4d07ac85ff0ad93e22c693d0f37ff63e28f0615a16b6635a645f4b9214"},
+    {file = "psycopg2-2.9.6-cp38-cp38-win_amd64.whl", hash = 
"sha256:d24ead3716a7d093b90b27b3d73459fe8cd90fd7065cf43b3c40966221d8c394"},
+    {file = "psycopg2-2.9.6-cp39-cp39-win32.whl", hash = 
"sha256:1861a53a6a0fd248e42ea37c957d36950da00266378746588eab4f4b5649e95f"},
+    {file = "psycopg2-2.9.6-cp39-cp39-win_amd64.whl", hash = 
"sha256:ded2faa2e6dfb430af7713d87ab4abbfc764d8d7fb73eafe96a24155f906ebf5"},
+    {file = "psycopg2-2.9.6.tar.gz", hash = 
"sha256:f15158418fd826831b28585e2ab48ed8df2d0d98f502a2b4fe619e7d5ca29011"},
 ]
 
 [[package]]
@@ -410,29 +391,28 @@ email = ["email-validator (>=1.0.3)"]
 
 [[package]]
 name = "pydevd-pycharm"
-version = "231.8109.140"
+version = "231.8770.15"
 description = "PyCharm Debugger (used in PyCharm and PyDev)"
 category = "main"
 optional = false
 python-versions = "*"
 files = [
-    {file = "pydevd-pycharm-231.8109.140.tar.gz", hash = 
"sha256:3240cfc0ff3ef895fbd2462afbb9a409bf333e9ab50e964e3c7ede2ca026ed77"},
+    {file = "pydevd-pycharm-231.8770.15.tar.gz", hash = 
"sha256:607eb16a0d0e28dd05f68b7b332fd1dcc2cce1faae28db2e0b2df6765edebd7f"},
 ]
 
 [[package]]
 name = "pytest"
-version = "7.2.2"
+version = "7.3.1"
 description = "pytest: simple powerful testing with Python"
 category = "main"
 optional = false
 python-versions = ">=3.7"
 files = [
-    {file = "pytest-7.2.2-py3-none-any.whl", hash = 
"sha256:130328f552dcfac0b1cec75c12e3f005619dc5f874f0a06e8ff7263f0ee6225e"},
-    {file = "pytest-7.2.2.tar.gz", hash = 
"sha256:c99ab0c73aceb050f68929bc93af19ab6db0558791c6a0715723abe9d0ade9d4"},
+    {file = "pytest-7.3.1-py3-none-any.whl", hash = 
"sha256:3799fa815351fea3a5e96ac7e503a96fa51cc9942c3753cda7651b93c1cfa362"},
+    {file = "pytest-7.3.1.tar.gz", hash = 
"sha256:434afafd78b1d78ed0addf160ad2b77a30d35d4bdf8af234fe621919d9ed15e3"},
 ]
 
 [package.dependencies]
-attrs = ">=19.2.0"
 colorama = {version = "*", markers = "sys_platform == \"win32\""}
 exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < 
\"3.11\""}
 iniconfig = "*"
@@ -441,7 +421,7 @@ pluggy = ">=0.12,<2.0"
 tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""}
 
 [package.extras]
-testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "pygments 
(>=2.7.2)", "requests", "xmlschema"]
+testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", 
"nose", "pygments (>=2.7.2)", "requests", "xmlschema"]
 
 [[package]]
 name = "requests"
@@ -554,14 +534,14 @@ sqlcipher = ["sqlcipher3-binary"]
 
 [[package]]
 name = "sqlalchemy2-stubs"
-version = "0.0.2a32"
+version = "0.0.2a34"
 description = "Typing Stubs for SQLAlchemy 1.4"
 category = "main"
 optional = false
 python-versions = ">=3.6"
 files = [
-    {file = "sqlalchemy2-stubs-0.0.2a32.tar.gz", hash = 
"sha256:2a2cfab71d35ac63bf21ad841d8610cd93a3bd4c6562848c538fa975585c2739"},
-    {file = "sqlalchemy2_stubs-0.0.2a32-py3-none-any.whl", hash = 
"sha256:7f5fb30b0cf7c6b74c50c1d94df77ff32007afee8d80499752eb3fedffdbdfb8"},
+    {file = "sqlalchemy2-stubs-0.0.2a34.tar.gz", hash = 
"sha256:2432137ab2fde1a608df4544f6712427b0b7ff25990cfbbc5a9d1db6c8c6f489"},
+    {file = "sqlalchemy2_stubs-0.0.2a34-py3-none-any.whl", hash = 
"sha256:a313220ac793404349899faf1272e821a62dbe1d3a029bd444faa8d3e966cd07"},
 ]
 
 [package.dependencies]
@@ -642,5 +622,5 @@ socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"]
 
 [metadata]
 lock-version = "2.0"
-python-versions = "^3.10"
-content-hash = 
"7f9231d791832106dc95d2052cb5a6f11ae1ddb9c4ecfa072e1e74e0e914ea9b"
+python-versions = "~3.9"
+content-hash = 
"75a142aa83def49843dbd04fbaea54779d3cc12398fc484bda5be0e7ebc28e48"
diff --git a/backend/python/pydevlake/pyproject.toml 
b/backend/python/pydevlake/pyproject.toml
index a882f9220..0bfcadbb4 100644
--- a/backend/python/pydevlake/pyproject.toml
+++ b/backend/python/pydevlake/pyproject.toml
@@ -22,7 +22,7 @@ license = "Apache-2.0"
 readme = "README.md"
 
 [tool.poetry.dependencies]
-python = "^3.9"
+python = "~3.9"
 sqlmodel = "^0.0.8"
 mysqlclient = "^2.1.1"
 requests = "^2.28.1"
diff --git a/backend/python/test/fakeplugin/poetry.lock 
b/backend/python/test/fakeplugin/poetry.lock
index 6aa757eed..a9067012c 100644
--- a/backend/python/test/fakeplugin/poetry.lock
+++ b/backend/python/test/fakeplugin/poetry.lock
@@ -1,24 +1,5 @@
 # This file is automatically @generated by Poetry 1.4.1 and should not be 
changed by hand.
 
-[[package]]
-name = "attrs"
-version = "22.2.0"
-description = "Classes Without Boilerplate"
-category = "main"
-optional = false
-python-versions = ">=3.6"
-files = [
-    {file = "attrs-22.2.0-py3-none-any.whl", hash = 
"sha256:29e95c7f6778868dbd49170f98f8818f78f3dc5e0e37c0b1f474e3561b240836"},
-    {file = "attrs-22.2.0.tar.gz", hash = 
"sha256:c9227bfc2f01993c03f68db37d1d15c9690188323c067c641f1a35ca58185f99"},
-]
-
-[package.extras]
-cov = ["attrs[tests]", "coverage-enable-subprocess", "coverage[toml] (>=5.3)"]
-dev = ["attrs[docs,tests]"]
-docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", 
"sphinxcontrib-towncrier", "towncrier", "zope.interface"]
-tests = ["attrs[tests-no-zope]", "zope.interface"]
-tests-no-zope = ["cloudpickle", "cloudpickle", "hypothesis", "hypothesis", 
"mypy (>=0.971,<0.990)", "mypy (>=0.971,<0.990)", "pympler", "pympler", "pytest 
(>=4.3.0)", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-mypy-plugins", 
"pytest-xdist[psutil]", "pytest-xdist[psutil]"]
-
 [[package]]
 name = "certifi"
 version = "2022.12.7"
@@ -246,21 +227,21 @@ files = [
 
 [[package]]
 name = "inflect"
-version = "6.0.2"
+version = "6.0.4"
 description = "Correctly generate plurals, singular nouns, ordinals, 
indefinite articles; convert numbers to words"
 category = "main"
 optional = false
 python-versions = ">=3.7"
 files = [
-    {file = "inflect-6.0.2-py3-none-any.whl", hash = 
"sha256:182741ec7e9e4c8f7f55b01fa6d80bcd3c4a183d349dfa6d9abbff0a1279e98f"},
-    {file = "inflect-6.0.2.tar.gz", hash = 
"sha256:f1a6bcb0105046f89619fde1a7d044c612c614c2d85ef182582d9dc9b86d309a"},
+    {file = "inflect-6.0.4-py3-none-any.whl", hash = 
"sha256:2d592e7e4eafb6e51f9c626c5dd4288f5ce55981eaac9b342e868ead95ead5c3"},
+    {file = "inflect-6.0.4.tar.gz", hash = 
"sha256:1842649a17b6cad66812a5c9bdfacb6310e1e7b6dd8a31f026766df1b62612eb"},
 ]
 
 [package.dependencies]
 pydantic = ">=1.9.1"
 
 [package.extras]
-docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", 
"rst.linker (>=1.9)", "sphinx (>=3.5)"]
+docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", 
"rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"]
 testing = ["flake8 (<5)", "pygments", "pytest (>=6)", "pytest-black 
(>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", 
"pytest-flake8", "pytest-mypy (>=0.9.1)"]
 
 [[package]]
@@ -306,14 +287,14 @@ files = [
 
 [[package]]
 name = "packaging"
-version = "23.0"
+version = "23.1"
 description = "Core utilities for Python packages"
 category = "main"
 optional = false
 python-versions = ">=3.7"
 files = [
-    {file = "packaging-23.0-py3-none-any.whl", hash = 
"sha256:714ac14496c3e68c99c29b00845f7a2b85f3bb6f1078fd9f72fd20f0570002b2"},
-    {file = "packaging-23.0.tar.gz", hash = 
"sha256:b6ad297f8907de0fa2fe1ccbd26fdaf387f5f47c7275fedf8cce89f99446cf97"},
+    {file = "packaging-23.1-py3-none-any.whl", hash = 
"sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61"},
+    {file = "packaging-23.1.tar.gz", hash = 
"sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f"},
 ]
 
 [[package]]
@@ -334,25 +315,25 @@ testing = ["pytest", "pytest-benchmark"]
 
 [[package]]
 name = "psycopg2"
-version = "2.9.5"
+version = "2.9.6"
 description = "psycopg2 - Python-PostgreSQL Database Adapter"
 category = "main"
 optional = false
 python-versions = ">=3.6"
 files = [
-    {file = "psycopg2-2.9.5-cp310-cp310-win32.whl", hash = 
"sha256:d3ef67e630b0de0779c42912fe2cbae3805ebaba30cda27fea2a3de650a9414f"},
-    {file = "psycopg2-2.9.5-cp310-cp310-win_amd64.whl", hash = 
"sha256:4cb9936316d88bfab614666eb9e32995e794ed0f8f6b3b718666c22819c1d7ee"},
-    {file = "psycopg2-2.9.5-cp311-cp311-win32.whl", hash = 
"sha256:093e3894d2d3c592ab0945d9eba9d139c139664dcf83a1c440b8a7aa9bb21955"},
-    {file = "psycopg2-2.9.5-cp311-cp311-win_amd64.whl", hash = 
"sha256:920bf418000dd17669d2904472efeab2b20546efd0548139618f8fa305d1d7ad"},
-    {file = "psycopg2-2.9.5-cp36-cp36m-win32.whl", hash = 
"sha256:b9ac1b0d8ecc49e05e4e182694f418d27f3aedcfca854ebd6c05bb1cffa10d6d"},
-    {file = "psycopg2-2.9.5-cp36-cp36m-win_amd64.whl", hash = 
"sha256:fc04dd5189b90d825509caa510f20d1d504761e78b8dfb95a0ede180f71d50e5"},
-    {file = "psycopg2-2.9.5-cp37-cp37m-win32.whl", hash = 
"sha256:922cc5f0b98a5f2b1ff481f5551b95cd04580fd6f0c72d9b22e6c0145a4840e0"},
-    {file = "psycopg2-2.9.5-cp37-cp37m-win_amd64.whl", hash = 
"sha256:1e5a38aa85bd660c53947bd28aeaafb6a97d70423606f1ccb044a03a1203fe4a"},
-    {file = "psycopg2-2.9.5-cp38-cp38-win32.whl", hash = 
"sha256:f5b6320dbc3cf6cfb9f25308286f9f7ab464e65cfb105b64cc9c52831748ced2"},
-    {file = "psycopg2-2.9.5-cp38-cp38-win_amd64.whl", hash = 
"sha256:1a5c7d7d577e0eabfcf15eb87d1e19314c8c4f0e722a301f98e0e3a65e238b4e"},
-    {file = "psycopg2-2.9.5-cp39-cp39-win32.whl", hash = 
"sha256:322fd5fca0b1113677089d4ebd5222c964b1760e361f151cbb2706c4912112c5"},
-    {file = "psycopg2-2.9.5-cp39-cp39-win_amd64.whl", hash = 
"sha256:190d51e8c1b25a47484e52a79638a8182451d6f6dff99f26ad9bd81e5359a0fa"},
-    {file = "psycopg2-2.9.5.tar.gz", hash = 
"sha256:a5246d2e683a972e2187a8714b5c2cf8156c064629f9a9b1a873c1730d9e245a"},
+    {file = "psycopg2-2.9.6-cp310-cp310-win32.whl", hash = 
"sha256:f7a7a5ee78ba7dc74265ba69e010ae89dae635eea0e97b055fb641a01a31d2b1"},
+    {file = "psycopg2-2.9.6-cp310-cp310-win_amd64.whl", hash = 
"sha256:f75001a1cbbe523e00b0ef896a5a1ada2da93ccd752b7636db5a99bc57c44494"},
+    {file = "psycopg2-2.9.6-cp311-cp311-win32.whl", hash = 
"sha256:53f4ad0a3988f983e9b49a5d9765d663bbe84f508ed655affdb810af9d0972ad"},
+    {file = "psycopg2-2.9.6-cp311-cp311-win_amd64.whl", hash = 
"sha256:b81fcb9ecfc584f661b71c889edeae70bae30d3ef74fa0ca388ecda50b1222b7"},
+    {file = "psycopg2-2.9.6-cp36-cp36m-win32.whl", hash = 
"sha256:11aca705ec888e4f4cea97289a0bf0f22a067a32614f6ef64fcf7b8bfbc53744"},
+    {file = "psycopg2-2.9.6-cp36-cp36m-win_amd64.whl", hash = 
"sha256:36c941a767341d11549c0fbdbb2bf5be2eda4caf87f65dfcd7d146828bd27f39"},
+    {file = "psycopg2-2.9.6-cp37-cp37m-win32.whl", hash = 
"sha256:869776630c04f335d4124f120b7fb377fe44b0a7645ab3c34b4ba42516951889"},
+    {file = "psycopg2-2.9.6-cp37-cp37m-win_amd64.whl", hash = 
"sha256:a8ad4a47f42aa6aec8d061fdae21eaed8d864d4bb0f0cade5ad32ca16fcd6258"},
+    {file = "psycopg2-2.9.6-cp38-cp38-win32.whl", hash = 
"sha256:2362ee4d07ac85ff0ad93e22c693d0f37ff63e28f0615a16b6635a645f4b9214"},
+    {file = "psycopg2-2.9.6-cp38-cp38-win_amd64.whl", hash = 
"sha256:d24ead3716a7d093b90b27b3d73459fe8cd90fd7065cf43b3c40966221d8c394"},
+    {file = "psycopg2-2.9.6-cp39-cp39-win32.whl", hash = 
"sha256:1861a53a6a0fd248e42ea37c957d36950da00266378746588eab4f4b5649e95f"},
+    {file = "psycopg2-2.9.6-cp39-cp39-win_amd64.whl", hash = 
"sha256:ded2faa2e6dfb430af7713d87ab4abbfc764d8d7fb73eafe96a24155f906ebf5"},
+    {file = "psycopg2-2.9.6.tar.gz", hash = 
"sha256:f15158418fd826831b28585e2ab48ed8df2d0d98f502a2b4fe619e7d5ca29011"},
 ]
 
 [[package]]
@@ -410,13 +391,13 @@ email = ["email-validator (>=1.0.3)"]
 
 [[package]]
 name = "pydevd-pycharm"
-version = "231.8109.140"
+version = "231.8770.15"
 description = "PyCharm Debugger (used in PyCharm and PyDev)"
 category = "main"
 optional = false
 python-versions = "*"
 files = [
-    {file = "pydevd-pycharm-231.8109.140.tar.gz", hash = 
"sha256:3240cfc0ff3ef895fbd2462afbb9a409bf333e9ab50e964e3c7ede2ca026ed77"},
+    {file = "pydevd-pycharm-231.8770.15.tar.gz", hash = 
"sha256:607eb16a0d0e28dd05f68b7b332fd1dcc2cce1faae28db2e0b2df6765edebd7f"},
 ]
 
 [[package]]
@@ -425,7 +406,7 @@ version = "0.1.0"
 description = "Devlake plugin framework"
 category = "main"
 optional = false
-python-versions = "^3.10"
+python-versions = "~3.9"
 files = []
 develop = true
 
@@ -447,18 +428,17 @@ url = "../../pydevlake"
 
 [[package]]
 name = "pytest"
-version = "7.2.2"
+version = "7.3.1"
 description = "pytest: simple powerful testing with Python"
 category = "main"
 optional = false
 python-versions = ">=3.7"
 files = [
-    {file = "pytest-7.2.2-py3-none-any.whl", hash = 
"sha256:130328f552dcfac0b1cec75c12e3f005619dc5f874f0a06e8ff7263f0ee6225e"},
-    {file = "pytest-7.2.2.tar.gz", hash = 
"sha256:c99ab0c73aceb050f68929bc93af19ab6db0558791c6a0715723abe9d0ade9d4"},
+    {file = "pytest-7.3.1-py3-none-any.whl", hash = 
"sha256:3799fa815351fea3a5e96ac7e503a96fa51cc9942c3753cda7651b93c1cfa362"},
+    {file = "pytest-7.3.1.tar.gz", hash = 
"sha256:434afafd78b1d78ed0addf160ad2b77a30d35d4bdf8af234fe621919d9ed15e3"},
 ]
 
 [package.dependencies]
-attrs = ">=19.2.0"
 colorama = {version = "*", markers = "sys_platform == \"win32\""}
 exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < 
\"3.11\""}
 iniconfig = "*"
@@ -467,7 +447,7 @@ pluggy = ">=0.12,<2.0"
 tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""}
 
 [package.extras]
-testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "pygments 
(>=2.7.2)", "requests", "xmlschema"]
+testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", 
"nose", "pygments (>=2.7.2)", "requests", "xmlschema"]
 
 [[package]]
 name = "requests"
@@ -580,14 +560,14 @@ sqlcipher = ["sqlcipher3-binary"]
 
 [[package]]
 name = "sqlalchemy2-stubs"
-version = "0.0.2a32"
+version = "0.0.2a34"
 description = "Typing Stubs for SQLAlchemy 1.4"
 category = "main"
 optional = false
 python-versions = ">=3.6"
 files = [
-    {file = "sqlalchemy2-stubs-0.0.2a32.tar.gz", hash = 
"sha256:2a2cfab71d35ac63bf21ad841d8610cd93a3bd4c6562848c538fa975585c2739"},
-    {file = "sqlalchemy2_stubs-0.0.2a32-py3-none-any.whl", hash = 
"sha256:7f5fb30b0cf7c6b74c50c1d94df77ff32007afee8d80499752eb3fedffdbdfb8"},
+    {file = "sqlalchemy2-stubs-0.0.2a34.tar.gz", hash = 
"sha256:2432137ab2fde1a608df4544f6712427b0b7ff25990cfbbc5a9d1db6c8c6f489"},
+    {file = "sqlalchemy2_stubs-0.0.2a34-py3-none-any.whl", hash = 
"sha256:a313220ac793404349899faf1272e821a62dbe1d3a029bd444faa8d3e966cd07"},
 ]
 
 [package.dependencies]
@@ -668,5 +648,5 @@ socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"]
 
 [metadata]
 lock-version = "2.0"
-python-versions = "^3.10"
-content-hash = 
"9057035f9ea219d89eb3e7ad8697bcf424257a1242f8dddc713d48907aba7948"
+python-versions = "~3.9"
+content-hash = 
"8be160f388cef16858a77c530903d4bf65500a77ea4ef45dbad1b070715ec738"
diff --git a/backend/python/test/fakeplugin/pyproject.toml 
b/backend/python/test/fakeplugin/pyproject.toml
index ca7c8ee70..9f17ea3b3 100644
--- a/backend/python/test/fakeplugin/pyproject.toml
+++ b/backend/python/test/fakeplugin/pyproject.toml
@@ -20,7 +20,7 @@ description = "Fake python plugin used only in tests"
 authors = []
 
 [tool.poetry.dependencies]
-python = "^3.10"
+python = "~3.9"
 pydevlake = { path = "../../pydevlake", develop = true }
 
 
diff --git a/devops/docker/lake-builder/Dockerfile 
b/devops/docker/lake-builder/Dockerfile
index 3e6344ffe..904d739a4 100644
--- a/devops/docker/lake-builder/Dockerfile
+++ b/devops/docker/lake-builder/Dockerfile
@@ -41,7 +41,7 @@ RUN \
     cp *libgit2* /tmp/deps/ &&\
     cp -r ../include /tmp/deps/include
 
-FROM python:3.11.2-slim-bullseye
+FROM python:3.9.9-slim-bullseye
 
 RUN apt -y update && apt -y upgrade && apt -y install tzdata make tar curl gcc 
g++ pkg-config git \
     libssh2-1 zlib1g libffi-dev  \


Reply via email to