diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index deca16b8..930be985 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -8,6 +8,16 @@ on: branches: - main +# If another push to the same PR or branch happens while this workflow is still running, +# cancel the earlier run in favor of the next run. +# +# There's no point in testing an outdated version of the code. GitHub only allows +# a limited number of job runners to be active at the same time, so it's better to cancel +# pointless jobs early so that more useful jobs can run sooner. +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: build: strategy: diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index ece0517b..c1a6936e 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -8,6 +8,16 @@ on: branches: - main +# If another push to the same PR or branch happens while this workflow is still running, +# cancel the earlier run in favor of the next run. +# +# There's no point in testing an outdated version of the code. GitHub only allows +# a limited number of job runners to be active at the same time, so it's better to cancel +# pointless jobs early so that more useful jobs can run sooner. +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: test: strategy: @@ -41,10 +51,6 @@ 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 --no-interaction --no-root - - - name: Install project run: poetry install --no-interaction --all-extras - name: Run integration tests diff --git a/.github/workflows/integration_test_minimal.yml b/.github/workflows/integration_test_minimal.yml index 9b5df90f..e27ab10a 100644 --- a/.github/workflows/integration_test_minimal.yml +++ b/.github/workflows/integration_test_minimal.yml @@ -8,6 +8,16 @@ on: branches: - main +# If another push to the same PR or branch happens while this workflow is still running, +# cancel the earlier run in favor of the next run. +# +# There's no point in testing an outdated version of the code. GitHub only allows +# a limited number of job runners to be active at the same time, so it's better to cancel +# pointless jobs early so that more useful jobs can run sooner. +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: test: strategy: @@ -41,10 +51,6 @@ 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 --no-interaction --no-root - - - name: Install project run: poetry install --no-interaction - name: Run integration tests diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index f66c1590..6cec7208 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -38,10 +38,6 @@ 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 --no-interaction --no-root - - - name: Install project run: poetry install --no-interaction - name: Run tests diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 3ec1e312..86d2ed88 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -8,6 +8,16 @@ on: branches: - main +# If another push to the same PR or branch happens while this workflow is still running, +# cancel the earlier run in favor of the next run. +# +# There's no point in testing an outdated version of the code. GitHub only allows +# a limited number of job runners to be active at the same time, so it's better to cancel +# pointless jobs early so that more useful jobs can run sooner. +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: test: strategy: @@ -41,11 +51,7 @@ 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 --no-interaction --no-root - - - name: Install project - run: poetry install --no-interaction --extras "crewai llama-index" + run: poetry install --no-interaction --all-extras --with dev - name: Run tests run: poetry run pytest diff --git a/examples/aider_code_generation.py b/examples/aider_code_generation.py index e86f6fa9..90c6e773 100644 --- a/examples/aider_code_generation.py +++ b/examples/aider_code_generation.py @@ -8,10 +8,10 @@ from langchain_community.tools import ShellTool from motleycrew.agents.crewai import CrewAIMotleyAgent -from motleycrew.common import configure_logging, AsyncBackend +from motleycrew.common import configure_logging from motleycrew.tasks import SimpleTask from motleycache import logger -from motleycrew.tools.aider_tool import AiderTool +from motleycrew.tools.code.aider_tool import AiderTool logger.setLevel(logging.INFO) diff --git a/motleycrew/common/defaults.py b/motleycrew/common/defaults.py index 978bfbb5..e6795f16 100644 --- a/motleycrew/common/defaults.py +++ b/motleycrew/common/defaults.py @@ -28,7 +28,10 @@ class Defaults: "crewai": "pip install crewai", "llama_index": "pip install llama-index", "autogen": "pip install pyautogen", - "lunary": "pip install lunary" + "lunary": "pip install lunary", + "aider": "pip install aider-chat", + "pglast": "pip install pglast", } + DEFAULT_NUM_THREADS = 4 DEFAULT_EVENT_LOOP_SLEEP = 1 diff --git a/motleycrew/tools/__init__.py b/motleycrew/tools/__init__.py index f36c1473..8500ae6c 100644 --- a/motleycrew/tools/__init__.py +++ b/motleycrew/tools/__init__.py @@ -1,7 +1,9 @@ from .tool import MotleyTool from .autogen_chat_tool import AutoGenChatTool -from motleycrew.tools.image.dall_e import DallEImageGeneratorTool +from .image.dall_e import DallEImageGeneratorTool from .llm_tool import LLMTool from .mermaid_evaluator_tool import MermaidEvaluatorTool from .python_repl import PythonREPLTool +from .code.postgresql_linter import PostgreSQLLinterTool +from .code.python_linter import PythonLinterTool diff --git a/motleycrew/tools/code/__init__.py b/motleycrew/tools/code/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/motleycrew/tools/aider_tool.py b/motleycrew/tools/code/aider_tool.py similarity index 91% rename from motleycrew/tools/aider_tool.py rename to motleycrew/tools/code/aider_tool.py index 3c6cfbad..590ddc7d 100644 --- a/motleycrew/tools/aider_tool.py +++ b/motleycrew/tools/code/aider_tool.py @@ -23,7 +23,7 @@ def __init__(self, model: str = None, **kwargs): model (str): model name **kwargs: """ - ensure_module_is_installed("aider", "pip install aider-chat") + ensure_module_is_installed("aider") model = model or Defaults.DEFAULT_LLM_NAME llm_model = Model(model=model) @@ -44,7 +44,7 @@ class AiderToolInput(BaseModel): def create_aider_tool(coder: Coder): - """Create langchain tool from Aider coder.run() method + """Create langchain tool from Aider Coder.run() method Returns: Tool: diff --git a/motleycrew/tools/code/postgresql_linter.py b/motleycrew/tools/code/postgresql_linter.py new file mode 100644 index 00000000..7d534f23 --- /dev/null +++ b/motleycrew/tools/code/postgresql_linter.py @@ -0,0 +1,55 @@ +from langchain_core.tools import Tool +from langchain_core.pydantic_v1 import BaseModel, Field + +try: + from pglast import parse_sql, prettify + from pglast.parser import ParseError +except ImportError: + parse_sql = None + prettify = None + ParseError = None + +from motleycrew.tools import MotleyTool +from motleycrew.common.utils import ensure_module_is_installed + + +class PostgreSQLLinterTool(MotleyTool): + + def __init__(self): + """PostgreSQL code verification tool + """ + ensure_module_is_installed("pglast") + + langchain_tool = create_pgsql_linter_tool() + super().__init__(langchain_tool) + + +class PostgreSQLLinterInput(BaseModel): + """Input for the PostgreSQLLinterTool. + + Attributes: + query (str): + """ + + query: str = Field(description="SQL code for validation") + + +def create_pgsql_linter_tool() -> Tool: + """Create the underlying langchain tool for PostgreSQLLinterTool + + Returns: + Tool: + """ + def parse_func(query: str) -> str: + try: + parse_sql(query) + return prettify(query) + except ParseError as e: + return str(e) + + return Tool.from_function( + func=parse_func, + name="PostgreSQL linter tool", + description="Tool for validating PostgreSQL code", + args_schema=PostgreSQLLinterInput, + ) diff --git a/motleycrew/tools/code/python_linter.py b/motleycrew/tools/code/python_linter.py new file mode 100644 index 00000000..2c764db4 --- /dev/null +++ b/motleycrew/tools/code/python_linter.py @@ -0,0 +1,67 @@ +import os +from typing import Union + +from langchain_core.tools import StructuredTool +from langchain_core.pydantic_v1 import BaseModel, Field + +from motleycrew.common.utils import ensure_module_is_installed +from motleycrew.tools import MotleyTool + +Linter = None + + +class PythonLinterTool(MotleyTool): + + def __init__(self): + """Python code verification tool + """ + ensure_module_is_installed("aider") + + langchain_tool = create_python_linter_tool() + super().__init__(langchain_tool) + + +class PythonLinterInput(BaseModel): + """Input for the PythonLinterTool. + + Attributes: + code (str): + file_name (str): + """ + + code: str = Field(description="Python code for linting") + file_name: str = Field(description="file name for the code", default="code.py") + + +def create_python_linter_tool() -> StructuredTool: + """Create the underlying langchain tool for PythonLinterTool + + Returns: + Tool: + """ + + def lint(code: str, file_name: str = None) -> Union[str, None]: + # create temp python file + temp_file_name = file_name or "code.py" + _, file_ext = os.path.splitext(temp_file_name) + if file_ext != ".py": + raise ValueError("The file extension must be .py") + + with open(temp_file_name, 'w') as f: + f.write(code) + + # lint code + try: + linter = Linter() + return linter.lint(temp_file_name) + except Exception as e: + return str(e) + finally: + os.remove(temp_file_name) + + return StructuredTool.from_function( + func=lint, + name="python linter tool", + description="Tool for validating Python code", + args_schema=PythonLinterInput, + ) diff --git a/motleycrew/tools/tool.py b/motleycrew/tools/tool.py index fc9f3c39..afe47f9a 100644 --- a/motleycrew/tools/tool.py +++ b/motleycrew/tools/tool.py @@ -1,6 +1,6 @@ """ Module description """ -from typing import Union, Annotated, Optional, Dict, Any +from typing import Union, Optional, Dict, Any from typing import Callable from langchain.tools import BaseTool diff --git a/poetry.lock b/poetry.lock index 0489d9d8..215e08d2 100644 --- a/poetry.lock +++ b/poetry.lock @@ -981,13 +981,13 @@ tests = ["asttokens (>=2.1.0)", "coverage", "coverage-enable-subprocess", "ipyth [[package]] name = "fastjsonschema" -version = "2.19.1" +version = "2.20.0" description = "Fastest Python implementation of JSON schema" optional = false python-versions = "*" files = [ - {file = "fastjsonschema-2.19.1-py3-none-any.whl", hash = "sha256:3672b47bc94178c9f23dbb654bf47440155d4db9df5f7bc47643315f9c405cd0"}, - {file = "fastjsonschema-2.19.1.tar.gz", hash = "sha256:e3126a94bdc4623d3de4485f8d468a12f02a67921315ddc87836d6e456dc789d"}, + {file = "fastjsonschema-2.20.0-py3-none-any.whl", hash = "sha256:5875f0b0fa7a0043a91e93a9b8f793bcbbba9691e7fd83dca95c28ba26d21f0a"}, + {file = "fastjsonschema-2.20.0.tar.gz", hash = "sha256:3d48fc5300ee96f5d116f10fe6f28d938e6008f59a6a025c2649475b87f76a23"}, ] [package.extras] @@ -995,18 +995,18 @@ devel = ["colorama", "json-spec", "jsonschema", "pylint", "pytest", "pytest-benc [[package]] name = "flake8" -version = "7.0.0" +version = "7.1.0" description = "the modular source code checker: pep8 pyflakes and co" optional = false python-versions = ">=3.8.1" files = [ - {file = "flake8-7.0.0-py2.py3-none-any.whl", hash = "sha256:a6dfbb75e03252917f2473ea9653f7cd799c3064e54d4c8140044c5c065f53c3"}, - {file = "flake8-7.0.0.tar.gz", hash = "sha256:33f96621059e65eec474169085dc92bf26e7b2d47366b70be2f67ab80dc25132"}, + {file = "flake8-7.1.0-py2.py3-none-any.whl", hash = "sha256:2e416edcc62471a64cea09353f4e7bdba32aeb079b6e360554c659a122b1bc6a"}, + {file = "flake8-7.1.0.tar.gz", hash = "sha256:48a07b626b55236e0fb4784ee69a465fbf59d79eec1f5b4785c3d3bc57d17aa5"}, ] [package.dependencies] mccabe = ">=0.7.0,<0.8.0" -pycodestyle = ">=2.11.0,<2.12.0" +pycodestyle = ">=2.12.0,<2.13.0" pyflakes = ">=3.2.0,<3.3.0" [[package]] @@ -1849,13 +1849,13 @@ types-requests = ">=2.31.0.2,<3.0.0.0" [[package]] name = "langsmith" -version = "0.1.77" +version = "0.1.80" description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langsmith-0.1.77-py3-none-any.whl", hash = "sha256:2202cc21b1ed7e7b9e5d2af2694be28898afa048c09fdf09f620cbd9301755ae"}, - {file = "langsmith-0.1.77.tar.gz", hash = "sha256:4ace09077a9a4e412afeb4b517ca68e7de7b07f36e4792dc8236ac5207c0c0c7"}, + {file = "langsmith-0.1.80-py3-none-any.whl", hash = "sha256:951fc29576b52afd8378d41f6db343090fea863e3620f0ca97e83b221f93c94d"}, + {file = "langsmith-0.1.80.tar.gz", hash = "sha256:a29b1dde27612308beee424f1388ad844c8e7e375bf2ac8bdf4da174013f279d"}, ] [package.dependencies] @@ -1865,19 +1865,19 @@ requests = ">=2,<3" [[package]] name = "llama-index" -version = "0.10.44" +version = "0.10.46" description = "Interface between LLMs and your data" optional = true python-versions = "<4.0,>=3.8.1" files = [ - {file = "llama_index-0.10.44-py3-none-any.whl", hash = "sha256:ca87b2258cc0fba43204c0fd511b2ca3b36ae246315652e18b4acda1e48b5499"}, - {file = "llama_index-0.10.44.tar.gz", hash = "sha256:c22eaa2ab5531d8cd0ee4ce4849e2bd85caef680d271adcd67997a85f343e72e"}, + {file = "llama_index-0.10.46-py3-none-any.whl", hash = "sha256:2adb116a8c67b1d8688277dff1559390a3e070ad684d5d0912bd475ab0df6bb6"}, + {file = "llama_index-0.10.46.tar.gz", hash = "sha256:a02957143158d09e6f8bb128a5362578c925161fcf3dffcb226d485f2f529209"}, ] [package.dependencies] llama-index-agent-openai = ">=0.1.4,<0.3.0" llama-index-cli = ">=0.1.2,<0.2.0" -llama-index-core = "0.10.44" +llama-index-core = "0.10.46" llama-index-embeddings-openai = ">=0.1.5,<0.2.0" llama-index-indices-managed-llama-cloud = ">=0.1.2,<0.2.0" llama-index-legacy = ">=0.9.48,<0.10.0" @@ -1922,13 +1922,13 @@ llama-index-llms-openai = ">=0.1.1,<0.2.0" [[package]] name = "llama-index-core" -version = "0.10.44" +version = "0.10.46" description = "Interface between LLMs and your data" optional = true python-versions = "<4.0,>=3.8.1" files = [ - {file = "llama_index_core-0.10.44-py3-none-any.whl", hash = "sha256:eea293fb9bafab303bbf6de8f0fca45188971fda80d77fbd4fed5773967ef49c"}, - {file = "llama_index_core-0.10.44.tar.gz", hash = "sha256:df1543e6935bb909b22a50d3f702096c8431bab94642cbb3ba6b07ea9f8edf38"}, + {file = "llama_index_core-0.10.46-py3-none-any.whl", hash = "sha256:403acc4a6139a8228b686a3a5051bdc09699243c1689668a5755e2be7affda5c"}, + {file = "llama_index_core-0.10.46.tar.gz", hash = "sha256:6c38467fc6974d316a22afa4214e610636cbec16fcb7b065e3f011fef35bb75f"}, ] [package.dependencies] @@ -1942,14 +1942,14 @@ llamaindex-py-client = ">=0.1.18,<0.2.0" nest-asyncio = ">=1.5.8,<2.0.0" networkx = ">=3.0" nltk = ">=3.8.1,<4.0.0" -numpy = "*" +numpy = "<2.0.0" openai = ">=1.1.0" pandas = "*" pillow = ">=9.0.0" PyYAML = ">=6.0.1" requests = ">=2.31.0" SQLAlchemy = {version = ">=1.4.49", extras = ["asyncio"]} -tenacity = ">=8.2.0,<9.0.0" +tenacity = ">=8.2.0,<8.4.0" tiktoken = ">=0.3.3" tqdm = ">=4.66.1,<5.0.0" typing-extensions = ">=4.5.0" @@ -3028,6 +3028,62 @@ files = [ [package.dependencies] ptyprocess = ">=0.5" +[[package]] +name = "pglast" +version = "6.2" +description = "PostgreSQL Languages AST and statements prettifier" +optional = true +python-versions = "*" +files = [ + {file = "pglast-6.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:04feec50aade19f44c52d1d0af2ca5af14a4b70677abd3ece060c22fdf3560b7"}, + {file = "pglast-6.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f9d64b0f62c9c468f22a34cae943b4abb39d1097f66320960dd49176515667e1"}, + {file = "pglast-6.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50fe3381ae61faabed30a57f565f3df359c15c1c1ab0af781f035bcea6d9f061"}, + {file = "pglast-6.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4da9a34ebea61f332dc1981380b2860fa289b7e4a3221b0dc3c243a8c6c4861f"}, + {file = "pglast-6.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1123edf2260924628a9184e06026c19c25bde2654508582c3053a0ea58432d2d"}, + {file = "pglast-6.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:3c93d9925a799a17523405860631205a226f273a0f0d94e08e4ec157f72665b1"}, + {file = "pglast-6.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e52a6557f5ca50fbfa22edf0e232879050764aada2fb1303a4dd2d430104f7cd"}, + {file = "pglast-6.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ce411a9cc3e34e2659bd5ff4087b53ee35d1aab9548f49df9c4b8c401ccc95a9"}, + {file = "pglast-6.2-cp310-cp310-win32.whl", hash = "sha256:65fe4070d15fe64d76e6aa5a02e0658550fc4864cff8da2e751335d258accba3"}, + {file = "pglast-6.2-cp310-cp310-win_amd64.whl", hash = "sha256:635e89c96d420a33cbebdc2a8eb896a3ef6124db282d189a3796c3786c7aad44"}, + {file = "pglast-6.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7cdda7b7265869343de76a49bcf6660adb4c94390f0d9464dc2cfac3889cfa07"}, + {file = "pglast-6.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dad8a9edbe87ff447fd42e0fdcd956de8ef756071161d2b13f6edb04a5caf0fc"}, + {file = "pglast-6.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2424f9c0975a703237f5a0f88eaaaaa6d86ed3d9afec3a576d7f720ad05b4a2f"}, + {file = "pglast-6.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a998d3f6cc83ffd968999d317d2dc1f56972fff5c192554cbaec9779b8abfd56"}, + {file = "pglast-6.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e32f002cf1a9a166f68efa401fb80768249f3774ef38b5ac648637862b33c1d6"}, + {file = "pglast-6.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:560c5bcfba1750d2d96af38aef4d67317c58a94d75d3ac84ebb2bdb53cff6de3"}, + {file = "pglast-6.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:e59c5e911f74e781ffcc6ac633260a42db8dc7ba01e48d6409749b4447af97cd"}, + {file = "pglast-6.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:145113ce961e25d6b0ed1248cd88168a06b7c464563baba87cafdffbb5c23e4c"}, + {file = "pglast-6.2-cp311-cp311-win32.whl", hash = "sha256:ceceff7a4545b4f6ade8f95b018f19f7c25fa8c461fdc63e304d5c21f02b4720"}, + {file = "pglast-6.2-cp311-cp311-win_amd64.whl", hash = "sha256:73923944f2ff5ed9c4b5a363e8aee6fcff8e8a725b503a8a2596b854b9782065"}, + {file = "pglast-6.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d615e5824341ba0113b9acdde2c4855cffff1ad28f1613c0e165372dc6b355d1"}, + {file = "pglast-6.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:afc9d1c9b2151e37b2e0a757be72823b08383c6d5742de7999968b14ec99184f"}, + {file = "pglast-6.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:97776ac917dbd20c5450d54775d91863dec39fc620fb8b76107c60dcb68002df"}, + {file = "pglast-6.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3c53f3c94cb1235c81a57c9e0a6163b4952154f115ee3a7f74ab6d59917a5624"}, + {file = "pglast-6.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6d8e7f89e581289c04217669d89db44107a6cf12d96e395cd3e6819d607f700a"}, + {file = "pglast-6.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:6535a96a64da4c7d35888926fbe8f8395b0c15c29c8b2164c3cae0d62491eb6a"}, + {file = "pglast-6.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:f125ce136844e0b7e71aef0cef9d1693207d268eaaa23c3609230ae444977ed0"}, + {file = "pglast-6.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:34391a6a20745acdd035885337b7a0f674bdf2bc9b7144d899bbf5a10cf27805"}, + {file = "pglast-6.2-cp312-cp312-win32.whl", hash = "sha256:e44096aac305d0725680636f823249cbc43cc7e67da5dfe7eb70e962dd582f5d"}, + {file = "pglast-6.2-cp312-cp312-win_amd64.whl", hash = "sha256:cd4bdc38df19916cdc6d115634d5c0b6a631937bf9881c487b8a27fba226331e"}, + {file = "pglast-6.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:aef460dcc8c33ed87804d88afe720511be4ca13ecde46d6586e9b62cfaa3b6ab"}, + {file = "pglast-6.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f7c6fd6640fe019dcc79fc2606374b8e533259e5eac26b4cb57ab687706bfe6a"}, + {file = "pglast-6.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3d032b58d2dc7dcc0c8f18730ce0e73a004565c6df90d91be5da5dadca9452e7"}, + {file = "pglast-6.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9ebd1ae4185765ba91392f173fb69e034da0e0952cf3b06b4d471c5d38d4c36"}, + {file = "pglast-6.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:03edc0e5c0ac63ee20867207f4fca73b19eeabe5daaa524c7e887fed2894f31f"}, + {file = "pglast-6.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f732f3bde3626058fdd6a58d1286c0d45b9dc24e4f5ee3f702b2f1259748290"}, + {file = "pglast-6.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:e16b0b767cc093bb305c51471728a16d8aff8c2b207feabcbfad8f6e012f4009"}, + {file = "pglast-6.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:88db769cdab81d58e76d7cd3e03fe48728c1819d470cc7ec1edc19d32646ddc3"}, + {file = "pglast-6.2-cp39-cp39-win32.whl", hash = "sha256:178d22fdcfb79edc9c52173743da5b2ff49d9dcd22f837a6e2fc587b17221847"}, + {file = "pglast-6.2-cp39-cp39-win_amd64.whl", hash = "sha256:dbc829c45b217aa5f6802dde995cff6577a3bdcd0984003c09a55438435c696e"}, + {file = "pglast-6.2.tar.gz", hash = "sha256:9863fba39d96ba7e80744da330024198b475d0498de74ab36cccc1d3a0455cc8"}, +] + +[package.dependencies] +setuptools = "*" + +[package.extras] +dev = ["cython", "metapensiero.tool.bump-version", "pycparser", "readme-renderer"] + [[package]] name = "pillow" version = "10.3.0" @@ -3181,27 +3237,28 @@ files = [ [[package]] name = "psutil" -version = "5.9.8" +version = "6.0.0" description = "Cross-platform lib for process and system monitoring in Python." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" -files = [ - {file = "psutil-5.9.8-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:26bd09967ae00920df88e0352a91cff1a78f8d69b3ecabbfe733610c0af486c8"}, - {file = "psutil-5.9.8-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:05806de88103b25903dff19bb6692bd2e714ccf9e668d050d144012055cbca73"}, - {file = "psutil-5.9.8-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:611052c4bc70432ec770d5d54f64206aa7203a101ec273a0cd82418c86503bb7"}, - {file = "psutil-5.9.8-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:50187900d73c1381ba1454cf40308c2bf6f34268518b3f36a9b663ca87e65e36"}, - {file = "psutil-5.9.8-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:02615ed8c5ea222323408ceba16c60e99c3f91639b07da6373fb7e6539abc56d"}, - {file = "psutil-5.9.8-cp27-none-win32.whl", hash = "sha256:36f435891adb138ed3c9e58c6af3e2e6ca9ac2f365efe1f9cfef2794e6c93b4e"}, - {file = "psutil-5.9.8-cp27-none-win_amd64.whl", hash = "sha256:bd1184ceb3f87651a67b2708d4c3338e9b10c5df903f2e3776b62303b26cb631"}, - {file = "psutil-5.9.8-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:aee678c8720623dc456fa20659af736241f575d79429a0e5e9cf88ae0605cc81"}, - {file = "psutil-5.9.8-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8cb6403ce6d8e047495a701dc7c5bd788add903f8986d523e3e20b98b733e421"}, - {file = "psutil-5.9.8-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d06016f7f8625a1825ba3732081d77c94589dca78b7a3fc072194851e88461a4"}, - {file = "psutil-5.9.8-cp36-cp36m-win32.whl", hash = "sha256:7d79560ad97af658a0f6adfef8b834b53f64746d45b403f225b85c5c2c140eee"}, - {file = "psutil-5.9.8-cp36-cp36m-win_amd64.whl", hash = "sha256:27cc40c3493bb10de1be4b3f07cae4c010ce715290a5be22b98493509c6299e2"}, - {file = "psutil-5.9.8-cp37-abi3-win32.whl", hash = "sha256:bc56c2a1b0d15aa3eaa5a60c9f3f8e3e565303b465dbf57a1b730e7a2b9844e0"}, - {file = "psutil-5.9.8-cp37-abi3-win_amd64.whl", hash = "sha256:8db4c1b57507eef143a15a6884ca10f7c73876cdf5d51e713151c1236a0e68cf"}, - {file = "psutil-5.9.8-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:d16bbddf0693323b8c6123dd804100241da461e41d6e332fb0ba6058f630f8c8"}, - {file = "psutil-5.9.8.tar.gz", hash = "sha256:6be126e3225486dff286a8fb9a06246a5253f4c7c53b475ea5f5ac934e64194c"}, +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" +files = [ + {file = "psutil-6.0.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:a021da3e881cd935e64a3d0a20983bda0bb4cf80e4f74fa9bfcb1bc5785360c6"}, + {file = "psutil-6.0.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:1287c2b95f1c0a364d23bc6f2ea2365a8d4d9b726a3be7294296ff7ba97c17f0"}, + {file = "psutil-6.0.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:a9a3dbfb4de4f18174528d87cc352d1f788b7496991cca33c6996f40c9e3c92c"}, + {file = "psutil-6.0.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:6ec7588fb3ddaec7344a825afe298db83fe01bfaaab39155fa84cf1c0d6b13c3"}, + {file = "psutil-6.0.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:1e7c870afcb7d91fdea2b37c24aeb08f98b6d67257a5cb0a8bc3ac68d0f1a68c"}, + {file = "psutil-6.0.0-cp27-none-win32.whl", hash = "sha256:02b69001f44cc73c1c5279d02b30a817e339ceb258ad75997325e0e6169d8b35"}, + {file = "psutil-6.0.0-cp27-none-win_amd64.whl", hash = "sha256:21f1fb635deccd510f69f485b87433460a603919b45e2a324ad65b0cc74f8fb1"}, + {file = "psutil-6.0.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:c588a7e9b1173b6e866756dde596fd4cad94f9399daf99ad8c3258b3cb2b47a0"}, + {file = "psutil-6.0.0-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ed2440ada7ef7d0d608f20ad89a04ec47d2d3ab7190896cd62ca5fc4fe08bf0"}, + {file = "psutil-6.0.0-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5fd9a97c8e94059b0ef54a7d4baf13b405011176c3b6ff257c247cae0d560ecd"}, + {file = "psutil-6.0.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e2e8d0054fc88153ca0544f5c4d554d42e33df2e009c4ff42284ac9ebdef4132"}, + {file = "psutil-6.0.0-cp36-cp36m-win32.whl", hash = "sha256:fc8c9510cde0146432bbdb433322861ee8c3efbf8589865c8bf8d21cb30c4d14"}, + {file = "psutil-6.0.0-cp36-cp36m-win_amd64.whl", hash = "sha256:34859b8d8f423b86e4385ff3665d3f4d94be3cdf48221fbe476e883514fdb71c"}, + {file = "psutil-6.0.0-cp37-abi3-win32.whl", hash = "sha256:a495580d6bae27291324fe60cea0b5a7c23fa36a7cd35035a16d93bdcf076b9d"}, + {file = "psutil-6.0.0-cp37-abi3-win_amd64.whl", hash = "sha256:33ea5e1c975250a720b3a6609c490db40dae5d83a4eb315170c4fe0d8b1f34b3"}, + {file = "psutil-6.0.0-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:ffe7fc9b6b36beadc8c322f84e1caff51e8703b88eee1da46d1e3a6ae11b4fd0"}, + {file = "psutil-6.0.0.tar.gz", hash = "sha256:8faae4f310b6d969fa26ca0545338b21f73c6b15db7c4a8d934a5482faa818f2"}, ] [package.extras] @@ -3234,13 +3291,13 @@ tests = ["pytest"] [[package]] name = "pycodestyle" -version = "2.11.1" +version = "2.12.0" description = "Python style guide checker" optional = false python-versions = ">=3.8" files = [ - {file = "pycodestyle-2.11.1-py2.py3-none-any.whl", hash = "sha256:44fe31000b2d866f2e41841b18528a505fbd7fef9017b04eff4e2648a0fadc67"}, - {file = "pycodestyle-2.11.1.tar.gz", hash = "sha256:41ba0e7afc9752dfb53ced5489e89f8186be00e599e712660695b7a75ff2663f"}, + {file = "pycodestyle-2.12.0-py2.py3-none-any.whl", hash = "sha256:949a39f6b86c3e1515ba1787c2022131d165a8ad271b11370a8819aa070269e4"}, + {file = "pycodestyle-2.12.0.tar.gz", hash = "sha256:442f950141b4f43df752dd303511ffded3a04c2b6fb7f65980574f0c31e6e79c"}, ] [[package]] @@ -4198,64 +4255,64 @@ test = ["pytest"] [[package]] name = "sqlalchemy" -version = "2.0.30" +version = "2.0.31" description = "Database Abstraction Library" optional = false python-versions = ">=3.7" files = [ - {file = "SQLAlchemy-2.0.30-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:3b48154678e76445c7ded1896715ce05319f74b1e73cf82d4f8b59b46e9c0ddc"}, - {file = "SQLAlchemy-2.0.30-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2753743c2afd061bb95a61a51bbb6a1a11ac1c44292fad898f10c9839a7f75b2"}, - {file = "SQLAlchemy-2.0.30-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a7bfc726d167f425d4c16269a9a10fe8630ff6d14b683d588044dcef2d0f6be7"}, - {file = "SQLAlchemy-2.0.30-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c4f61ada6979223013d9ab83a3ed003ded6959eae37d0d685db2c147e9143797"}, - {file = "SQLAlchemy-2.0.30-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:3a365eda439b7a00732638f11072907c1bc8e351c7665e7e5da91b169af794af"}, - {file = "SQLAlchemy-2.0.30-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bba002a9447b291548e8d66fd8c96a6a7ed4f2def0bb155f4f0a1309fd2735d5"}, - {file = "SQLAlchemy-2.0.30-cp310-cp310-win32.whl", hash = "sha256:0138c5c16be3600923fa2169532205d18891b28afa817cb49b50e08f62198bb8"}, - {file = "SQLAlchemy-2.0.30-cp310-cp310-win_amd64.whl", hash = "sha256:99650e9f4cf3ad0d409fed3eec4f071fadd032e9a5edc7270cd646a26446feeb"}, - {file = "SQLAlchemy-2.0.30-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:955991a09f0992c68a499791a753523f50f71a6885531568404fa0f231832aa0"}, - {file = "SQLAlchemy-2.0.30-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f69e4c756ee2686767eb80f94c0125c8b0a0b87ede03eacc5c8ae3b54b99dc46"}, - {file = "SQLAlchemy-2.0.30-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69c9db1ce00e59e8dd09d7bae852a9add716efdc070a3e2068377e6ff0d6fdaa"}, - {file = "SQLAlchemy-2.0.30-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a1429a4b0f709f19ff3b0cf13675b2b9bfa8a7e79990003207a011c0db880a13"}, - {file = "SQLAlchemy-2.0.30-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:efedba7e13aa9a6c8407c48facfdfa108a5a4128e35f4c68f20c3407e4376aa9"}, - {file = "SQLAlchemy-2.0.30-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:16863e2b132b761891d6c49f0a0f70030e0bcac4fd208117f6b7e053e68668d0"}, - {file = "SQLAlchemy-2.0.30-cp311-cp311-win32.whl", hash = "sha256:2ecabd9ccaa6e914e3dbb2aa46b76dede7eadc8cbf1b8083c94d936bcd5ffb49"}, - {file = "SQLAlchemy-2.0.30-cp311-cp311-win_amd64.whl", hash = "sha256:0b3f4c438e37d22b83e640f825ef0f37b95db9aa2d68203f2c9549375d0b2260"}, - {file = "SQLAlchemy-2.0.30-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5a79d65395ac5e6b0c2890935bad892eabb911c4aa8e8015067ddb37eea3d56c"}, - {file = "SQLAlchemy-2.0.30-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9a5baf9267b752390252889f0c802ea13b52dfee5e369527da229189b8bd592e"}, - {file = "SQLAlchemy-2.0.30-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3cb5a646930c5123f8461f6468901573f334c2c63c795b9af350063a736d0134"}, - {file = "SQLAlchemy-2.0.30-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:296230899df0b77dec4eb799bcea6fbe39a43707ce7bb166519c97b583cfcab3"}, - {file = "SQLAlchemy-2.0.30-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:c62d401223f468eb4da32627bffc0c78ed516b03bb8a34a58be54d618b74d472"}, - {file = "SQLAlchemy-2.0.30-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:3b69e934f0f2b677ec111b4d83f92dc1a3210a779f69bf905273192cf4ed433e"}, - {file = "SQLAlchemy-2.0.30-cp312-cp312-win32.whl", hash = "sha256:77d2edb1f54aff37e3318f611637171e8ec71472f1fdc7348b41dcb226f93d90"}, - {file = "SQLAlchemy-2.0.30-cp312-cp312-win_amd64.whl", hash = "sha256:b6c7ec2b1f4969fc19b65b7059ed00497e25f54069407a8701091beb69e591a5"}, - {file = "SQLAlchemy-2.0.30-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:5a8e3b0a7e09e94be7510d1661339d6b52daf202ed2f5b1f9f48ea34ee6f2d57"}, - {file = "SQLAlchemy-2.0.30-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b60203c63e8f984df92035610c5fb76d941254cf5d19751faab7d33b21e5ddc0"}, - {file = "SQLAlchemy-2.0.30-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f1dc3eabd8c0232ee8387fbe03e0a62220a6f089e278b1f0aaf5e2d6210741ad"}, - {file = "SQLAlchemy-2.0.30-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:40ad017c672c00b9b663fcfcd5f0864a0a97828e2ee7ab0c140dc84058d194cf"}, - {file = "SQLAlchemy-2.0.30-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:e42203d8d20dc704604862977b1470a122e4892791fe3ed165f041e4bf447a1b"}, - {file = "SQLAlchemy-2.0.30-cp37-cp37m-win32.whl", hash = "sha256:2a4f4da89c74435f2bc61878cd08f3646b699e7d2eba97144030d1be44e27584"}, - {file = "SQLAlchemy-2.0.30-cp37-cp37m-win_amd64.whl", hash = "sha256:b6bf767d14b77f6a18b6982cbbf29d71bede087edae495d11ab358280f304d8e"}, - {file = "SQLAlchemy-2.0.30-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:bc0c53579650a891f9b83fa3cecd4e00218e071d0ba00c4890f5be0c34887ed3"}, - {file = "SQLAlchemy-2.0.30-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:311710f9a2ee235f1403537b10c7687214bb1f2b9ebb52702c5aa4a77f0b3af7"}, - {file = "SQLAlchemy-2.0.30-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:408f8b0e2c04677e9c93f40eef3ab22f550fecb3011b187f66a096395ff3d9fd"}, - {file = "SQLAlchemy-2.0.30-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:37a4b4fb0dd4d2669070fb05b8b8824afd0af57587393015baee1cf9890242d9"}, - {file = "SQLAlchemy-2.0.30-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:a943d297126c9230719c27fcbbeab57ecd5d15b0bd6bfd26e91bfcfe64220621"}, - {file = "SQLAlchemy-2.0.30-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:0a089e218654e740a41388893e090d2e2c22c29028c9d1353feb38638820bbeb"}, - {file = "SQLAlchemy-2.0.30-cp38-cp38-win32.whl", hash = "sha256:fa561138a64f949f3e889eb9ab8c58e1504ab351d6cf55259dc4c248eaa19da6"}, - {file = "SQLAlchemy-2.0.30-cp38-cp38-win_amd64.whl", hash = "sha256:7d74336c65705b986d12a7e337ba27ab2b9d819993851b140efdf029248e818e"}, - {file = "SQLAlchemy-2.0.30-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ae8c62fe2480dd61c532ccafdbce9b29dacc126fe8be0d9a927ca3e699b9491a"}, - {file = "SQLAlchemy-2.0.30-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2383146973a15435e4717f94c7509982770e3e54974c71f76500a0136f22810b"}, - {file = "SQLAlchemy-2.0.30-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8409de825f2c3b62ab15788635ccaec0c881c3f12a8af2b12ae4910a0a9aeef6"}, - {file = "SQLAlchemy-2.0.30-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0094c5dc698a5f78d3d1539853e8ecec02516b62b8223c970c86d44e7a80f6c7"}, - {file = "SQLAlchemy-2.0.30-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:edc16a50f5e1b7a06a2dcc1f2205b0b961074c123ed17ebda726f376a5ab0953"}, - {file = "SQLAlchemy-2.0.30-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:f7703c2010355dd28f53deb644a05fc30f796bd8598b43f0ba678878780b6e4c"}, - {file = "SQLAlchemy-2.0.30-cp39-cp39-win32.whl", hash = "sha256:1f9a727312ff6ad5248a4367358e2cf7e625e98b1028b1d7ab7b806b7d757513"}, - {file = "SQLAlchemy-2.0.30-cp39-cp39-win_amd64.whl", hash = "sha256:a0ef36b28534f2a5771191be6edb44cc2673c7b2edf6deac6562400288664221"}, - {file = "SQLAlchemy-2.0.30-py3-none-any.whl", hash = "sha256:7108d569d3990c71e26a42f60474b4c02c8586c4681af5fd67e51a044fdea86a"}, - {file = "SQLAlchemy-2.0.30.tar.gz", hash = "sha256:2b1708916730f4830bc69d6f49d37f7698b5bd7530aca7f04f785f8849e95255"}, + {file = "SQLAlchemy-2.0.31-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f2a213c1b699d3f5768a7272de720387ae0122f1becf0901ed6eaa1abd1baf6c"}, + {file = "SQLAlchemy-2.0.31-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9fea3d0884e82d1e33226935dac990b967bef21315cbcc894605db3441347443"}, + {file = "SQLAlchemy-2.0.31-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f3ad7f221d8a69d32d197e5968d798217a4feebe30144986af71ada8c548e9fa"}, + {file = "SQLAlchemy-2.0.31-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f2bee229715b6366f86a95d497c347c22ddffa2c7c96143b59a2aa5cc9eebbc"}, + {file = "SQLAlchemy-2.0.31-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:cd5b94d4819c0c89280b7c6109c7b788a576084bf0a480ae17c227b0bc41e109"}, + {file = "SQLAlchemy-2.0.31-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:750900a471d39a7eeba57580b11983030517a1f512c2cb287d5ad0fcf3aebd58"}, + {file = "SQLAlchemy-2.0.31-cp310-cp310-win32.whl", hash = "sha256:7bd112be780928c7f493c1a192cd8c5fc2a2a7b52b790bc5a84203fb4381c6be"}, + {file = "SQLAlchemy-2.0.31-cp310-cp310-win_amd64.whl", hash = "sha256:5a48ac4d359f058474fadc2115f78a5cdac9988d4f99eae44917f36aa1476327"}, + {file = "SQLAlchemy-2.0.31-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f68470edd70c3ac3b6cd5c2a22a8daf18415203ca1b036aaeb9b0fb6f54e8298"}, + {file = "SQLAlchemy-2.0.31-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2e2c38c2a4c5c634fe6c3c58a789712719fa1bf9b9d6ff5ebfce9a9e5b89c1ca"}, + {file = "SQLAlchemy-2.0.31-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd15026f77420eb2b324dcb93551ad9c5f22fab2c150c286ef1dc1160f110203"}, + {file = "SQLAlchemy-2.0.31-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2196208432deebdfe3b22185d46b08f00ac9d7b01284e168c212919891289396"}, + {file = "SQLAlchemy-2.0.31-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:352b2770097f41bff6029b280c0e03b217c2dcaddc40726f8f53ed58d8a85da4"}, + {file = "SQLAlchemy-2.0.31-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:56d51ae825d20d604583f82c9527d285e9e6d14f9a5516463d9705dab20c3740"}, + {file = "SQLAlchemy-2.0.31-cp311-cp311-win32.whl", hash = "sha256:6e2622844551945db81c26a02f27d94145b561f9d4b0c39ce7bfd2fda5776dac"}, + {file = "SQLAlchemy-2.0.31-cp311-cp311-win_amd64.whl", hash = "sha256:ccaf1b0c90435b6e430f5dd30a5aede4764942a695552eb3a4ab74ed63c5b8d3"}, + {file = "SQLAlchemy-2.0.31-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3b74570d99126992d4b0f91fb87c586a574a5872651185de8297c6f90055ae42"}, + {file = "SQLAlchemy-2.0.31-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6f77c4f042ad493cb8595e2f503c7a4fe44cd7bd59c7582fd6d78d7e7b8ec52c"}, + {file = "SQLAlchemy-2.0.31-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cd1591329333daf94467e699e11015d9c944f44c94d2091f4ac493ced0119449"}, + {file = "SQLAlchemy-2.0.31-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:74afabeeff415e35525bf7a4ecdab015f00e06456166a2eba7590e49f8db940e"}, + {file = "SQLAlchemy-2.0.31-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:b9c01990d9015df2c6f818aa8f4297d42ee71c9502026bb074e713d496e26b67"}, + {file = "SQLAlchemy-2.0.31-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:66f63278db425838b3c2b1c596654b31939427016ba030e951b292e32b99553e"}, + {file = "SQLAlchemy-2.0.31-cp312-cp312-win32.whl", hash = "sha256:0b0f658414ee4e4b8cbcd4a9bb0fd743c5eeb81fc858ca517217a8013d282c96"}, + {file = "SQLAlchemy-2.0.31-cp312-cp312-win_amd64.whl", hash = "sha256:fa4b1af3e619b5b0b435e333f3967612db06351217c58bfb50cee5f003db2a5a"}, + {file = "SQLAlchemy-2.0.31-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:f43e93057cf52a227eda401251c72b6fbe4756f35fa6bfebb5d73b86881e59b0"}, + {file = "SQLAlchemy-2.0.31-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d337bf94052856d1b330d5fcad44582a30c532a2463776e1651bd3294ee7e58b"}, + {file = "SQLAlchemy-2.0.31-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c06fb43a51ccdff3b4006aafee9fcf15f63f23c580675f7734245ceb6b6a9e05"}, + {file = "SQLAlchemy-2.0.31-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:b6e22630e89f0e8c12332b2b4c282cb01cf4da0d26795b7eae16702a608e7ca1"}, + {file = "SQLAlchemy-2.0.31-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:79a40771363c5e9f3a77f0e28b3302801db08040928146e6808b5b7a40749c88"}, + {file = "SQLAlchemy-2.0.31-cp37-cp37m-win32.whl", hash = "sha256:501ff052229cb79dd4c49c402f6cb03b5a40ae4771efc8bb2bfac9f6c3d3508f"}, + {file = "SQLAlchemy-2.0.31-cp37-cp37m-win_amd64.whl", hash = "sha256:597fec37c382a5442ffd471f66ce12d07d91b281fd474289356b1a0041bdf31d"}, + {file = "SQLAlchemy-2.0.31-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:dc6d69f8829712a4fd799d2ac8d79bdeff651c2301b081fd5d3fe697bd5b4ab9"}, + {file = "SQLAlchemy-2.0.31-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:23b9fbb2f5dd9e630db70fbe47d963c7779e9c81830869bd7d137c2dc1ad05fb"}, + {file = "SQLAlchemy-2.0.31-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2a21c97efcbb9f255d5c12a96ae14da873233597dfd00a3a0c4ce5b3e5e79704"}, + {file = "SQLAlchemy-2.0.31-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26a6a9837589c42b16693cf7bf836f5d42218f44d198f9343dd71d3164ceeeac"}, + {file = "SQLAlchemy-2.0.31-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc251477eae03c20fae8db9c1c23ea2ebc47331bcd73927cdcaecd02af98d3c3"}, + {file = "SQLAlchemy-2.0.31-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:2fd17e3bb8058359fa61248c52c7b09a97cf3c820e54207a50af529876451808"}, + {file = "SQLAlchemy-2.0.31-cp38-cp38-win32.whl", hash = "sha256:c76c81c52e1e08f12f4b6a07af2b96b9b15ea67ccdd40ae17019f1c373faa227"}, + {file = "SQLAlchemy-2.0.31-cp38-cp38-win_amd64.whl", hash = "sha256:4b600e9a212ed59355813becbcf282cfda5c93678e15c25a0ef896b354423238"}, + {file = "SQLAlchemy-2.0.31-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b6cf796d9fcc9b37011d3f9936189b3c8074a02a4ed0c0fbbc126772c31a6d4"}, + {file = "SQLAlchemy-2.0.31-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:78fe11dbe37d92667c2c6e74379f75746dc947ee505555a0197cfba9a6d4f1a4"}, + {file = "SQLAlchemy-2.0.31-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2fc47dc6185a83c8100b37acda27658fe4dbd33b7d5e7324111f6521008ab4fe"}, + {file = "SQLAlchemy-2.0.31-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8a41514c1a779e2aa9a19f67aaadeb5cbddf0b2b508843fcd7bafdf4c6864005"}, + {file = "SQLAlchemy-2.0.31-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:afb6dde6c11ea4525318e279cd93c8734b795ac8bb5dda0eedd9ebaca7fa23f1"}, + {file = "SQLAlchemy-2.0.31-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:3f9faef422cfbb8fd53716cd14ba95e2ef655400235c3dfad1b5f467ba179c8c"}, + {file = "SQLAlchemy-2.0.31-cp39-cp39-win32.whl", hash = "sha256:fc6b14e8602f59c6ba893980bea96571dd0ed83d8ebb9c4479d9ed5425d562e9"}, + {file = "SQLAlchemy-2.0.31-cp39-cp39-win_amd64.whl", hash = "sha256:3cb8a66b167b033ec72c3812ffc8441d4e9f5f78f5e31e54dcd4c90a4ca5bebc"}, + {file = "SQLAlchemy-2.0.31-py3-none-any.whl", hash = "sha256:69f3e3c08867a8e4856e92d7afb618b95cdee18e0bc1647b77599722c9a28911"}, + {file = "SQLAlchemy-2.0.31.tar.gz", hash = "sha256:b607489dd4a54de56984a0c7656247504bd5523d9d0ba799aef59d4add009484"}, ] [package.dependencies] -greenlet = {version = "!=0.4.17", optional = true, markers = "platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\" or extra == \"asyncio\""} +greenlet = {version = "!=0.4.17", optional = true, markers = "python_version < \"3.13\" and (platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\") or extra == \"asyncio\""} typing-extensions = ">=4.6.0" [package.extras] @@ -4538,13 +4595,13 @@ files = [ [[package]] name = "urllib3" -version = "2.2.1" +version = "2.2.2" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false python-versions = ">=3.8" files = [ - {file = "urllib3-2.2.1-py3-none-any.whl", hash = "sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d"}, - {file = "urllib3-2.2.1.tar.gz", hash = "sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19"}, + {file = "urllib3-2.2.2-py3-none-any.whl", hash = "sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472"}, + {file = "urllib3-2.2.2.tar.gz", hash = "sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168"}, ] [package.extras] @@ -4776,8 +4833,9 @@ test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", crewai = ["crewai"] llama-index = ["llama-index"] lunary = ["lunary"] +pglast = ["pglast"] [metadata] lock-version = "2.0" python-versions = ">=3.10,<=3.13" -content-hash = "d6c8bb2eca4af216bada710556b05538b009ce31c1dbe7b6ddc3d11bb0d38b8a" +content-hash = "0b0c18292d40e41a9319e6d2b0209905daaa89fab0bdcf8fcc55aa75fa995286" diff --git a/pyproject.toml b/pyproject.toml index e59983ea..b94ad873 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -25,6 +25,7 @@ requests = "^2.31.0" curl-cffi = "^0.6.4" httpx = "^0.27.0" motleycache = "^0.0.4" +pglast = {version = "^6.2", optional = true} [tool.poetry.group.dev.dependencies] black = "^24.2.0" @@ -45,6 +46,7 @@ nbformat = "^5.10.4" crewai = ["crewai"] llama-index = ["llama-index"] lunary = ["lunary"] +pglast = ["pglast"] [build-system] requires = ["poetry-core"] diff --git a/tests/test_tools/test_linter_tools.py b/tests/test_tools/test_linter_tools.py new file mode 100644 index 00000000..0bbb8ce1 --- /dev/null +++ b/tests/test_tools/test_linter_tools.py @@ -0,0 +1,60 @@ +import pytest + +from motleycrew.tools import PostgreSQLLinterTool, PythonLinterTool +from motleycrew.common.exceptions import ModuleNotInstalled + + +@pytest.fixture +def pgsql_linter_tool(): + tool = PostgreSQLLinterTool() + return tool + + +@pytest.fixture +def python_linter_tool(): + try: + tool = PythonLinterTool() + except ModuleNotInstalled: + tool = None + return tool + + +@pytest.mark.parametrize( + "query, expected", + [ + ("select a from table_name", "SELECT a\nFROM table_name"), + ("select a from table_name where a = 1", "SELECT a\nFROM table_name\nWHERE a = 1"), + ("selec a from table_name where a = 1", 'syntax error at or near "selec", at index 0') + + ]) +def test_pgsql_tool(pgsql_linter_tool, query, expected): + parse_result = pgsql_linter_tool.invoke({"query": query}) + assert expected == parse_result + + +@pytest.mark.parametrize( + "code, file_name, valid_code, raises", + [ + ("def plus(a, b):\n\treturn a + b", None, True, False), + ("def plus(a):\n\treturn a + b", "test_code.py", False, False), + ("def plus(a, b):\nreturn a + b", "test_code.py", False, False), + ("def plus(a, b):\n\treturn a + b", "code.js", True, True), + ] +) +def test_python_tool(python_linter_tool, code, file_name, valid_code, raises): + if python_linter_tool is None: + return + + params = {"code": code} + if file_name: + params["file_name"] = file_name + + if raises: + with pytest.raises(ValueError): + python_linter_tool.invoke(params) + else: + linter_result = python_linter_tool.invoke(params) + if valid_code: + assert linter_result is None + else: + assert isinstance(linter_result, str)