diff --git a/.dockerignore b/.dockerignore index 3f78c748..cb26562a 100644 --- a/.dockerignore +++ b/.dockerignore @@ -5,3 +5,9 @@ .github .idea node_modules +venv +.venv +build +**/*.egg-info +**/model_pb2* +linters diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a3763b5d..3bd27396 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,79 +1,97 @@ name: Python build -on: [ push, pull_request ] +on: + push: + branches: + - main + - develop + pull_request: -jobs: - - build: - runs-on: ubuntu-latest - # Consistent with base image in Dockerfile - # container: stepik/hyperstyle-base:py3.8.11-java11.0.11-node14.17.3-go1.18.5 - container: nastyabirillo/hyperstyle:1.4.4 +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true +jobs: + build_image: + name: Build Image + runs-on: [ self-hosted, small ] steps: - - name: Install git - run: | - apt-get update - apt-get -y install git + - uses: actions/checkout@v4 - - name: Check env variables - run: | - echo $DETEKT_DIRECTORY && echo $DETEKT_VERSION - echo $CHECKSTYLE_DIRECTORY && echo CHECKSTYLE_VERSION - echo $PMD_DIRECTORY && echo PMD_VERSION + - uses: docker/login-action@v3 + with: + registry: hyperskill.azurecr.io + username: ${{ secrets.REGISTRY_USER }} + password: ${{ secrets.REGISTRY_PASSWORD }} - - name: Checkout - uses: actions/checkout@v3 + - uses: docker/setup-buildx-action@v3 - - name: Install requirements + - name: Build and push server image + uses: docker/build-push-action@v6 + with: + context: . + pull: true + push: true + tags: hyperskill.azurecr.io/hyperstyle:${{ github.sha }} + cache-from: | + type=gha + type=gha,scope=main + cache-to: type=gha,mode=max + + tests: + name: Tests + needs: + - build_image + runs-on: [ self-hosted, small ] + container: + image: hyperskill.azurecr.io/hyperstyle:${{ github.sha }} + credentials: + username: ${{ secrets.REGISTRY_USER }} + password: ${{ secrets.REGISTRY_PASSWORD }} + steps: + - name: Run tests run: | - pip install --no-cache-dir -r requirements-test.txt -r requirements.txt + cd /review + /hyperstyle/bin/pytest - - name: Set up git rights + build: + runs-on: [ self-hosted, small ] + needs: + - build_image + container: + image: hyperskill.azurecr.io/hyperstyle:${{ github.sha }} + credentials: + username: ${{ secrets.REGISTRY_USER }} + password: ${{ secrets.REGISTRY_PASSWORD }} + steps: + - name: Check env variables run: | - git config --global --add safe.directory '*' + echo $DETEKT_DIRECTORY && echo $DETEKT_VERSION + echo $CHECKSTYLE_DIRECTORY && echo $CHECKSTYLE_VERSION + echo $PMD_DIRECTORY && echo $PMD_VERSION + echo $GOLANG_LINT_DIRECTORY && echo $GOLANG_LINT_VERSION - name: Lint with flake8 run: | + cd /review # stop the build if there are Python syntax errors or undefined names - flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics --exclude=.git,__pycache__,docs/source/conf.py,old,build,dist,venv,test/resources,.eggs,review.egg-info,.pytest_cache,node_modules + /hyperstyle/bin/flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics --exclude=.git,__pycache__,docs/source/conf.py,old,build,dist,venv,test/resources,.eggs,review.egg-info,.pytest_cache,node_modules,hyperstyle/src/python/review/inspectors/common/inspector/proto + # TODO: change max-complexity into 10 after refactoring # TODO: remove R504, A003, E800, E402, WPS1, WPS2, WPS3, WPS4, WPS5, WPS6, H601 - flake8 . --count --max-complexity=11 --max-line-length=120 --max-doc-length=120 --ignore=R504,A003,E800,E402,W503,WPS,H601,N400 --statistics --exclude=.git,__pycache__,docs/source/conf.py,old,build,dist,venv,test/resources,.eggs,review.egg-info,.pytest_cache,node_modules - - - name: Sort whitelists - run: | - for file in "whitelist.txt" "hyperstyle/src/python/review/inspectors/flake8/whitelist.txt" - do - LC_ALL=C sort $file -o $file - done - - name: Commit sorted whitelists - uses: EndBug/add-and-commit@v7.2.1 - with: - add: "['whitelist.txt', 'hyperstyle/src/python/review/inspectors/flake8/whitelist.txt']" - message: 'Sort whitelists (Github Actions)' - - - name: Set up Eslint - run: | - # Consistent with eslint version in Dockerfile - npm install eslint@7.5.0 -g && eslint --init - - - name: Test with pytest - run: | - pytest -vv - - - name: Install review module - run: | - pip install . + /hyperstyle/bin/flake8 . --count --max-complexity=11 --max-line-length=120 --max-doc-length=120 --ignore=R504,A003,E800,E402,W503,WPS,H601,N400,I100,I201,I202, --statistics --exclude=.git,__pycache__,docs/source/conf.py,old,build,dist,venv,test/resources,.eggs,review.egg-info,.pytest_cache,node_modules,hyperstyle/src/python/review/inspectors/common/inspector/proto - name: Check installed module can run python linters run: | - review setup.py + cd /review + /hyperstyle/bin/python -m hyperstyle.src.python.review.run_tool test/resources/inspectors/python/case39_no_issues.py - name: Check installed module can run java linters run: | - review test/resources/inspectors/java/test_algorithm_with_scanner.java + cd /review + /hyperstyle/bin/python -m hyperstyle.src.python.review.run_tool test/resources/inspectors/java/test_algorithm_with_scanner.java - name: Check installed module can run js linters run: | - review test/resources/inspectors/js/case0_no_issues.js + cd /review + /hyperstyle/bin/python -m hyperstyle.src.python.review.run_tool test/resources/inspectors/js/case0_no_issues.js diff --git a/.github/workflows/build_base_image.yml b/.github/workflows/build_base_image.yml index 51ae5774..7f66dab4 100644 --- a/.github/workflows/build_base_image.yml +++ b/.github/workflows/build_base_image.yml @@ -7,7 +7,7 @@ on: type: string description: 'Image tag' required: true - default: 'py3.12.5-java11.0.11-node14.17.3-go1.18.5' + default: 'py3.10.14-java11.0.11-node14.17.3-go1.18.5' concurrency: group: ${{ github.workflow }}-${{ github.ref }} diff --git a/.github/workflows/build_image.yml b/.github/workflows/build_image.yml new file mode 100644 index 00000000..80f61805 --- /dev/null +++ b/.github/workflows/build_image.yml @@ -0,0 +1,43 @@ +name: Build Image after Release + +on: + workflow_dispatch: + inputs: + image_tag: + description: 'Image tag' + required: true + default: 'latest' + release: + types: + - released + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: false + +jobs: + build_image: + name: Build Image + runs-on: [ self-hosted, small ] + steps: + - uses: actions/checkout@v4 + + - uses: docker/login-action@v3 + with: + registry: hyperskill.azurecr.io + username: ${{ secrets.REGISTRY_USER }} + password: ${{ secrets.REGISTRY_PASSWORD }} + + - uses: docker/setup-buildx-action@v3 + + - name: Build and push server image + uses: docker/build-push-action@v6 + with: + context: . + pull: true + push: true + tags: hyperskill.azurecr.io/hyperstyle:${{ inputs.image_tag || github.event.release.tag_name }} + cache-from: | + type=gha + type=gha,scope=main + cache-to: type=gha,mode=max diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 47819798..c1cbfafb 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -1,19 +1,23 @@ -# Publish to PyPI in case of releasing +name: Publish to PyPI in case of releasing on: push: +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: false + jobs: build-n-publish: name: Build and publish Python 🐍 distributions 📦 to PyPI - runs-on: ubuntu-latest + runs-on: [ self-hosted, small ] steps: - uses: actions/checkout@v2 - - name: Set up Python 3.8 - uses: actions/setup-python@v2 + - name: Set up Python + uses: actions/setup-python@v4 with: - python-version: 3.8 + python-version-file: .python-version - name: Install pypa/build run: | python -m pip install build --user @@ -24,4 +28,4 @@ jobs: if: startsWith(github.ref, 'refs/tags') uses: pypa/gh-action-pypi-publish@master with: - password: ${{ secrets.SECRETS_TEST_PYPI_API_TOKEN }} \ No newline at end of file + password: ${{ secrets.SECRETS_TEST_PYPI_API_TOKEN }} diff --git a/.github/workflows/sort_whitespaces.yml b/.github/workflows/sort_whitespaces.yml new file mode 100644 index 00000000..ecbc7a64 --- /dev/null +++ b/.github/workflows/sort_whitespaces.yml @@ -0,0 +1,39 @@ +name: Sort whitespaces + +on: + push: + branches: + - main + - develop + paths: + - 'whitelist.txt' + - 'hyperstyle/src/python/review/inspectors/flake8/whitelist.txt' + pull_request: + paths: + - 'whitelist.txt' + - 'hyperstyle/src/python/review/inspectors/flake8/whitelist.txt' + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + sort_whitespaces: + name: Sort whitespaces + runs-on: [ self-hosted, small ] + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Sort whitelists + run: | + for file in "whitelist.txt" "hyperstyle/src/python/review/inspectors/flake8/whitelist.txt" + do + LC_ALL=C sort $file -o $file + done + + - name: Commit sorted whitelists + uses: EndBug/add-and-commit@v7.2.1 + with: + add: "['whitelist.txt', 'hyperstyle/src/python/review/inspectors/flake8/whitelist.txt']" + message: 'Sort whitelists (Github Actions)' diff --git a/.gitignore b/.gitignore index 63d25e2b..981f14ba 100644 --- a/.gitignore +++ b/.gitignore @@ -77,3 +77,11 @@ __pycache__/ /.intellij_inspector/out/ lightweight.Dockerfile +linters + +node_modules +.eslintrc.js +package-lock.json + +hyperstyle/src/python/review/inspectors/common/inspector/proto/model_pb2* +.env diff --git a/.python-version b/.python-version new file mode 100644 index 00000000..1445aee8 --- /dev/null +++ b/.python-version @@ -0,0 +1 @@ +3.10.14 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ce90bf0e..341e2ddb 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -10,9 +10,9 @@ In this document you will find a detailed description of how to add new function ## Adding a new inspector for an existing language If you want to add a new inspector for an existing language, you need to: -1. Inherit from the [`BaseInspector`](hyperstyle/src/python/review/inspectors/base_inspector.py#L9) class. -2. Define the [`inspector_type`](hyperstyle/src/python/review/inspectors/base_inspector.py#L29) property. To do this, you need to update the [`InspectorType`](hyperstyle/src/python/review/inspectors/inspector_type.py#L6) class by adding there a name of the inspector. -3. Implement the [`inspect`](hyperstyle/src/python/review/inspectors/base_inspector.py#L33) function, which should run an analysis of the language and return a list of found issues; +1. Inherit from the [`BaseInspector`](hyperstyle/src/python/review/inspectors/common/inspector/base_inspector.py#L9) class. +2. Define the [`inspector_type`](hyperstyle/src/python/review/inspectors/common/inspector/base_inspector.py#L29) property. To do this, you need to update the [`InspectorType`](hyperstyle/src/python/review/inspectors/common/inspector/inspector_type.py#L6) class by adding there a name of the inspector. +3. Implement the [`inspect`](hyperstyle/src/python/review/inspectors/common/inspector/base_inspector.py#L33) function, which should run an analysis of the language and return a list of found issues; Usually the inspector runs a third-party linter through a command line and parses its result. In this case it will be useful to implement several auxiliary functions: 1. `create_command` – creates a command to run the linter via subprocess. @@ -31,9 +31,9 @@ If you are implementing the inspector that uses the third-party linter, you must ### Implementation of the `parse` function -Usually, the `parse` function parses the result of the third-party linter line-by-line, then creates a base issue using the [`BaseIssue`](hyperstyle/src/python/review/inspectors/issue.py#L199) dataclass, which is later converted to either [`CodeIssue`](hyperstyle/src/python/review/inspectors/issue.py#L217) or one of the measurable issues using the [`convert_base_issue`](hyperstyle/src/python/review/inspectors/common/base_issue_converter.py#L17) function and an instance of the [`IssueConigsHandler`](hyperstyle/src/python/review/inspectors/issue_configs.py#L117) class. The resulting issue is added to the general list of found issues and this list is returned from the function after the parsing is finished. +Usually, the `parse` function parses the result of the third-party linter line-by-line, then creates a base issue using the [`BaseIssue`](hyperstyle/src/python/review/inspectors/common/issue/issue.py#L199) dataclass, which is later converted to either [`CodeIssue`](hyperstyle/src/python/review/inspectors/common/issue/issue.py#L217) or one of the measurable issues using the [`convert_base_issue`](hyperstyle/src/python/review/inspectors/common/issue/base_issue_converter.py#L17) function and an instance of the [`IssueConigsHandler`](hyperstyle/src/python/review/inspectors/common/issue/issue_configs.py#L117) class. The resulting issue is added to the general list of found issues and this list is returned from the function after the parsing is finished. -The `IssueConfigHandler` class handles custom issue descriptions and also parses metrics from their descriptions (examples of metrics are: line or function length, cyclomatic complexity, maintainability index). It receives instances of [`IssueConfig`](hyperstyle/src/python/review/inspectors/issue_configs.py#L46) or [`MeasurableIssueConfig`](hyperstyle/src/python/review/inspectors/issue_configs.py#L85) classes as input, which should be stored in the `ISSUE_CONFIGS` list next to the inspector. +The `IssueConfigHandler` class handles custom issue descriptions and also parses metrics from their descriptions (examples of metrics are: line or function length, cyclomatic complexity, maintainability index). It receives instances of [`IssueConfig`](hyperstyle/src/python/review/inspectors/common/issue/issue_configs.py#L46) or [`MeasurableIssueConfig`](hyperstyle/src/python/review/inspectors/common/issue/issue_configs.py#L85) classes as input, which should be stored in the `ISSUE_CONFIGS` list next to the inspector. Also, if the third-party linter supports output in "Checkstyle" format, you can use the [`parse_xml_file_result`](hyperstyle/src/python/review/inspectors/common/xml_parser.py#L47) function to parse the output file. @@ -42,7 +42,7 @@ Also, if the third-party linter supports output in "Checkstyle" format, you can A sample checklist for adding a new inspector looks like this: - [ ] I've inherited from the `BaseInspector` class. - [ ] I've implemented the `inspect` function and _if needed_ I've added a check for the existence of third-party linter environment variables using the [`check_set_up_env_variable`](hyperstyle/src/python/review/common/file_system.py#L124) function. -- [ ] I've added a new inspector type to the `InspectorType` class, updated the [`available_values`](hyperstyle/src/python/review/inspectors/inspector_type.py#L27) function and defined the inspector type. +- [ ] I've added a new inspector type to the `InspectorType` class, updated the [`available_values`](hyperstyle/src/python/review/inspectors/common/inspector/inspector_type.py#L27) function and defined the inspector type. - [ ] _If needed_. I've added a config to run the third-party linter. - [ ] _If needed_. I've implemented the `create_command` function. - [ ] _if needed_. I've implemented the `parse` function and defined the `ISSUES_CONFIGS` list in a separate file. diff --git a/Dockerfile b/Dockerfile index 4ba0e5e6..9cedaea3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,64 +1,79 @@ -FROM hyperskill.azurecr.io/hyperstyle-base:py3.8.11-java11.0.11-node14.17.3-go1.18.5 +FROM hyperskill.azurecr.io/hyperstyle-base:py3.10.14-java11.0.11-node14.17.3-go1.18.5 -RUN npm install eslint@7.5.0 -g \ - && eslint --init +ENV LINTERS_DIRECTORY=/opt/linters -COPY . review -RUN pip install --no-cache-dir \ - -r review/requirements-test.txt \ - -r review/requirements.txt \ - ./review +ENV ESLINT_VERSION=7.5.0 -ENV LINTERS_DIRECTORY /opt/linters +ENV CHECKSTYLE_VERSION=8.44 +ENV CHECKSTYLE_DIRECTORY=${LINTERS_DIRECTORY}/checkstyle -ENV CHECKSTYLE_VERSION 8.44 -ENV CHECKSTYLE_DIRECTORY ${LINTERS_DIRECTORY}/checkstyle +ENV DETEKT_VERSION=1.14.2 +ENV DETEKT_DIRECTORY=${LINTERS_DIRECTORY}/detekt -ENV DETEKT_VERSION 1.14.2 -ENV DETEKT_DIRECTORY ${LINTERS_DIRECTORY}/detekt +ENV PMD_VERSION=6.37.0 +ENV PMD_DIRECTORY=${LINTERS_DIRECTORY}/pmd -ENV PMD_VERSION 6.37.0 -ENV PMD_DIRECTORY ${LINTERS_DIRECTORY}/pmd +ENV GOLANG_LINT_VERSION=1.49.0 +ENV GOLANG_LINT_DIRECTORY=${LINTERS_DIRECTORY}/golangci-lint -ENV GOLANG_LINT_VERSION 1.49.0 -ENV GOLANG_LINT_DIRECTORY ${LINTERS_DIRECTORY}/golangci-lint - -RUN mkdir -p ${CHECKSTYLE_DIRECTORY} && \ - mkdir -p ${DETEKT_DIRECTORY} && \ - mkdir -p ${PMD_DIRECTORY} && \ - mkdir -p ${GOLANG_LINT_DIRECTORY} +RUN mkdir -p ${CHECKSTYLE_DIRECTORY} \ + && mkdir -p ${DETEKT_DIRECTORY} \ + && mkdir -p ${PMD_DIRECTORY} \ + && mkdir -p ${GOLANG_LINT_DIRECTORY} # Install Curl and Unzip -RUN apt -y update && \ - apt -y upgrade && \ - apt -y install curl unzip +RUN apt-get update \ + && apt-get install -y --no-install-recommends curl unzip ca-certificates \ + && rm -rf /var/lib/apt/lists/* + +# Install eslint +RUN npm install eslint@${ESLINT_VERSION} -g \ + && eslint --init # Install Detekt and Detekt-formatting RUN curl -sSLO https://github.com/detekt/detekt/releases/download/v${DETEKT_VERSION}/detekt-cli-${DETEKT_VERSION}.zip \ - && unzip detekt-cli-${DETEKT_VERSION}.zip -d ${DETEKT_DIRECTORY} \ - && curl -H "Accept: application/zip" https://repo.maven.apache.org/maven2/io/gitlab/arturbosch/detekt/detekt-formatting/${DETEKT_VERSION}/detekt-formatting-${DETEKT_VERSION}.jar -o ${DETEKT_DIRECTORY}/detekt-formatting-${DETEKT_VERSION}.jar + && unzip detekt-cli-${DETEKT_VERSION}.zip -d ${DETEKT_DIRECTORY} \ + && rm detekt-cli-${DETEKT_VERSION}.zip \ + && curl -H "Accept: application/zip" https://repo.maven.apache.org/maven2/io/gitlab/arturbosch/detekt/detekt-formatting/${DETEKT_VERSION}/detekt-formatting-${DETEKT_VERSION}.jar -o ${DETEKT_DIRECTORY}/detekt-formatting-${DETEKT_VERSION}.jar # Install Checkstyle RUN curl -L https://github.com/checkstyle/checkstyle/releases/download/checkstyle-${CHECKSTYLE_VERSION}/checkstyle-${CHECKSTYLE_VERSION}-all.jar > ${CHECKSTYLE_DIRECTORY}/checkstyle-${CHECKSTYLE_VERSION}-all.jar # Install PMD RUN curl -sSLO https://github.com/pmd/pmd/releases/download/pmd_releases/${PMD_VERSION}/pmd-bin-${PMD_VERSION}.zip \ - && unzip pmd-bin-${PMD_VERSION}.zip -d ${PMD_DIRECTORY} + && unzip pmd-bin-${PMD_VERSION}.zip -d ${PMD_DIRECTORY} \ + && rm pmd-bin-${PMD_VERSION}.zip # Install golangci-lint -RUN curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh \ - | sh -s -- -b ${GOLANG_LINT_DIRECTORY} v${GOLANG_LINT_VERSION} +RUN curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh \ + | sh -s -- -b ${GOLANG_LINT_DIRECTORY} v${GOLANG_LINT_VERSION} # Install third party golang libraries and pre-cache them by compiling main.go # Taken from: https://github.com/StepicOrg/epicbox-images/blob/a5eadb5211909fc7ef99724ee0b8bf3a758ae1b7/epicbox-go/Dockerfile -RUN curl -sSfLO https://raw.githubusercontent.com/StepicOrg/epicbox-images/a5eadb5211909fc7ef99724ee0b8bf3a758ae1b7/epicbox-go/go.mod && \ - curl -sSfLO https://raw.githubusercontent.com/StepicOrg/epicbox-images/a5eadb5211909fc7ef99724ee0b8bf3a758ae1b7/epicbox-go/go.sum && \ - curl -sSfLO https://raw.githubusercontent.com/StepicOrg/epicbox-images/a5eadb5211909fc7ef99724ee0b8bf3a758ae1b7/epicbox-go/main.go && \ - go mod download && \ - go mod verify && \ - go mod tidy && \ - go run main.go && \ - rm main.go && \ - chmod ugo-w go.mod go.sum - -CMD ["/bin/bash"] +RUN curl -sSfLO https://raw.githubusercontent.com/StepicOrg/epicbox-images/a5eadb5211909fc7ef99724ee0b8bf3a758ae1b7/epicbox-go/go.mod \ + && curl -sSfLO https://raw.githubusercontent.com/StepicOrg/epicbox-images/a5eadb5211909fc7ef99724ee0b8bf3a758ae1b7/epicbox-go/go.sum \ + && curl -sSfLO https://raw.githubusercontent.com/StepicOrg/epicbox-images/a5eadb5211909fc7ef99724ee0b8bf3a758ae1b7/epicbox-go/main.go \ + && go mod download \ + && go mod verify \ + && go mod tidy \ + && go run main.go \ + && rm main.go \ + && chmod ugo-w go.mod go.sum + +ARG POETRY_VERSION=1.8.3 +RUN pip install poetry==${POETRY_VERSION} \ + && poetry config virtualenvs.create false \ + && python -m venv /hyperstyle + +WORKDIR /review + +COPY pyproject.toml poetry.lock ./ +RUN . /hyperstyle/bin/activate \ + && poetry install --no-interaction --no-ansi --no-cache --no-root + +COPY . . + +RUN PROTO_PATH="hyperstyle/src/python/review/inspectors/common/inspector/proto" \ + && /hyperstyle/bin/python -m grpc_tools.protoc --proto_path=. --python_out=. --pyi_out=. --grpc_python_out=. ${PROTO_PATH}/model.proto + +CMD ["/hyperstyle/bin/pytest"] diff --git a/MANIFEST.in b/MANIFEST.in deleted file mode 100644 index bdf4942c..00000000 --- a/MANIFEST.in +++ /dev/null @@ -1,3 +0,0 @@ -include VERSION.md -include requirements.txt -recursive-exclude __pycache__ *.pyc *.pyo *.orig \ No newline at end of file diff --git a/README.md b/README.md index 22797696..b6f29a35 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ A tool for running a set of pre-configured linters and evaluating code quality. It is used on the [Hyperskill](https://hyperskill.org/) platform to check the quality of learners' code. -[Read more detail about the project at Hyperskill Help Center](https://support.hyperskill.org/hc/en-us/articles/360049582712-Code-style-Code-quality) +[Read more details about the project at Hyperskill Help Center](https://support.hyperskill.org/hc/en-us/articles/360049582712-Code-style-Code-quality) [The dockerized version](https://hub.docker.com/r/stepik/hyperstyle/tags) @@ -24,13 +24,14 @@ The source code of **hyperstyle** is distributed under the Apache 2.0 License. The 3rd party software we use in this project has its own licenses. + Python language (all versions can be found in the [requirements.txt](requirements.txt) file): -- [x] flake8 [MIT] +- [x] flake8 [MIT] * [Site and docs](https://flake8.pycqa.org/en/latest/) * [Repository](https://github.com/PyCQA/flake8) -- [x] Pylint [GNU LGPL v2] +- [x] Pylint [GNU LGPL v2] * [Site and docs](https://www.pylint.org/) * [Repository](https://github.com/PyCQA/pylint) @@ -38,13 +39,19 @@ Python language (all versions can be found in the [requirements.txt](requirement * [Site and docs](https://radon.readthedocs.io/en/latest/) * [Repository](https://github.com/rubik/radon) +- [x] Python IJ Inspections [MIT] + * [Site and docs](https://www.jetbrains.com/help/pycharm/disabling-and-enabling-inspections.html) + * [Repository](https://github.com/JetBrains-Research/code-quality-ij-server/tree/master) + + + Java language: -- [x] PMD [BSD] (Version: 6.37.0) +- [x] PMD [BSD] (Version: 6.37.0) * [Site and docs](https://pmd.github.io/) * [Repository](https://github.com/pmd/pmd) -- [x] Checkstyle [GNU LGPL v2.1] (Version: 8.44) +- [x] Checkstyle [GNU LGPL v2.1] (Version: 8.44) * [Site and docs](https://checkstyle.sourceforge.io/) * [Repository](https://github.com/checkstyle/checkstyle) @@ -52,15 +59,18 @@ Java language: Kotlin language: -- [x] Detekt [Apache 2.0] (Version: 1.14.2) +- [x] Detekt [Apache 2.0] (Version: 1.14.2) * [Site and docs](https://detekt.github.io/detekt/) * [Repository](https://github.com/detekt/detekt) +- [x] Kotlin IJ inspections [MIT] + * [Site and docs](https://www.jetbrains.com/help/idea/code-inspection.html) + * [Repository](https://github.com/JetBrains-Research/code-quality-ij-server/tree/master) JavaScript language: -- [x] ESlint [MIT] (Version: 7.5.0) +- [x] ESlint [MIT] (Version: 7.5.0) * [Site and docs](https://eslint.org/) * [Repository](https://github.com/eslint/eslint) @@ -75,7 +85,9 @@ Go language: ## Installation -You have to create set of environment variables: +### Pre-requirements + +You have to create a set of environment variables in order to be able to use several linters: - `CHECKSTYLE_VERSION` (the value of the variable must be the same with its value in [Dockerfile](Dockerfile)) - `CHECKSTYLE_DIRECTORY` (the directory with `CHECKSTYLE` linter sources) - `DETEKT_VERSION` (the value of the variable must be the same with its value in [Dockerfile](Dockerfile)) @@ -85,52 +97,97 @@ You have to create set of environment variables: - `GOLANG_LINT_VERSION` (the value of the variable must be the same with its value in [Dockerfile](Dockerfile)) - `GOLANG_LINT_DIRECTORY` (the directory with `GOLANG_LINT` linter sources) -### Using script +### Using pip -Just run the following command: -```bash -./setup_environment.sh -``` -and install everything the script suggests. +Just run the following commands to install everything you need to run the tool: + +1. Install the latest version of hyperstyle from [PyPI](https://pypi.org/project/hyperstyle/): + ```bash + pip install hyperstyle + ``` + + You could also install a specific version: + ```bash + pip install hyperstyle== + ``` + where `` is your versions. + The list of all available versions you could find [here](https://pypi.org/project/hyperstyle/#history). + +2. Install (or update) linters specified in the environment variables above: + ```bash + curl -sSL https://github.com/hyperskill/hyperstyle/blob/main/setup_environment.sh | bash - + ``` + This is necessary because the package does not distribute several third-party linters. + + For now the script proposes to install development requirements, you should skip this step. + + You can also install linters manually. To do this, please refer to [this](#linter-manual-installation) section. + +### Using docker + +Alternatively, you can build a docker image by [Dockerfile](Dockerfile) and run the tool inside this image. +Or use the public docker image, that we use in the [build.yml](.github/workflows/build.yml) file. -**Note**: You can also use this script to update linters. To do this, just update the corresponding -linter version variables, run the script, and reinstall only the necessary linters. +### Manually (for development purposes) -### Manually +To set up a development environment, you need to run the following commands: -If you don't want to use the script, you can install the environment manually. +1. Download the repository: + ```bash + git clone https://github.com/hyperskill/hyperstyle.git && cd hyperstyle + ``` -Simply clone the repository and run the following commands: +2. Install a virtual environment: + ```bash + python3 -m venv venv && source venv/bin/activate + ``` -1. `pip install -r requirements.txt` -2. `pip install -r requirements-test.txt` for tests -3. `npm install eslint@7.5.0 -g && eslint --init` +3. Install development requirements and install (or update) linters specified in the environment variables above: + ```bash + ./setup_environment.sh + ``` + + It will install all dependencies from the [requirements-dev.txt](requirements-dev.txt), + which contains runtime, test and build dependencies. + + You can also install linters manually. To do this, please refer to [this](#linter-manual-installation) section. + +### Linter manual installation + +You can download all linters' sources by the following commands: + +- `ESLINT`: + ```bash + npm install eslint@7.5.0 -g && eslint --init + ``` -You can download all linters sources manually or by the following commands: - `CHECKSTYLE`: -```bash -curl -L https://github.com/checkstyle/checkstyle/releases/download/checkstyle-${CHECKSTYLE_VERSION}/checkstyle-${CHECKSTYLE_VERSION}-all.jar > ${CHECKSTYLE_DIRECTORY}/checkstyle-${CHECKSTYLE_VERSION}-all.jar -``` + ```bash + curl -L https://github.com/checkstyle/checkstyle/releases/download/checkstyle-${CHECKSTYLE_VERSION}/checkstyle-${CHECKSTYLE_VERSION}-all.jar > ${CHECKSTYLE_DIRECTORY}/checkstyle-${CHECKSTYLE_VERSION}-all.jar + ``` + - `DETEKT`: -```bash -curl -sSLO https://github.com/detekt/detekt/releases/download/v${DETEKT_VERSION}/detekt-cli-${DETEKT_VERSION}.zip \ -&& unzip detekt-cli-${DETEKT_VERSION}.zip -d ${DETEKT_DIRECTORY} \ -&& curl -H "Accept: application/zip" https://repo.maven.apache.org/maven2/io/gitlab/arturbosch/detekt/detekt-formatting/${DETEKT_VERSION}/detekt-formatting-${DETEKT_VERSION}.jar -o ${DETEKT_DIRECTORY}/detekt-formatting-${DETEKT_VERSION}.jar -``` + ```bash + curl -sSLO https://github.com/detekt/detekt/releases/download/v${DETEKT_VERSION}/detekt-cli-${DETEKT_VERSION}.zip \ + && unzip detekt-cli-${DETEKT_VERSION}.zip -d ${DETEKT_DIRECTORY} \ + && curl -H "Accept: application/zip" https://repo.maven.apache.org/maven2/io/gitlab/arturbosch/detekt/detekt-formatting/${DETEKT_VERSION}/detekt-formatting-${DETEKT_VERSION}.jar -o ${DETEKT_DIRECTORY}/detekt-formatting-${DETEKT_VERSION}.jar + ``` + - `PMD`: -```bash -curl -sSLO https://github.com/pmd/pmd/releases/download/pmd_releases/${PMD_VERSION}/pmd-bin-${PMD_VERSION}.zip \ -&& unzip pmd-bin-${PMD_VERSION}.zip -d ${PMD_DIRECTORY} -``` -- `GOLANG_LINT`: -```bash -curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b ${GOLANG_LINT_DIRECTORY} v${GOLANG_LINT_VERSION} -``` + ```bash + curl -sSLO https://github.com/pmd/pmd/releases/download/pmd_releases/${PMD_VERSION}/pmd-bin-${PMD_VERSION}.zip \ + && unzip pmd-bin-${PMD_VERSION}.zip -d ${PMD_DIRECTORY} + ``` -### Using docker +- `GOLANG_LINT`: + ```bash + curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b ${GOLANG_LINT_DIRECTORY} v${GOLANG_LINT_VERSION} + ``` -Alternatively, you can build a docker image by [Dockerfile](Dockerfile) and run the tool inside this image. -Or use the public docker image, that we use in the [build.yml](.github/workflows/build.yml) file. +- IJ-based linters: + ```bash + python3 -m grpc_tools.protoc --proto_path=. --python_out=. --pyi_out=. --grpc_python_out=. hyperstyle/src/python/review/inspectors/common/inspector/proto/model.proto + ``` ## Usage @@ -143,22 +200,23 @@ A simple configuration: `python run_tool.py `. Optional arguments: -Argument | Description ---- | --- -**‑h**, **‑‑help** | show the help message and exit. -**‑v**, **‑‑verbosity** | choose logging level according [this](https://docs.python.org/3/library/logging.html#levels) list: `1` - **ERROR**; `2` - **INFO**; `3` - **DEBUG**; `0` - disable logging (**CRITICAL** value); default value is `0` (**CRITICAL**). -**‑d**, **‑‑disable** | disable inspectors. Available values: for **Python** language: `pylint` for [Pylint](https://github.com/PyCQA/pylint), `flake8` for [flake8](https://flake8.pycqa.org/en/latest/), `radon` for [Radon](https://radon.readthedocs.io/en/latest/), `python_ast` to check different measures providing by AST; for **Java** language: `checkstyle` for the [Checkstyle](https://checkstyle.sourceforge.io/), `pmd` for [PMD](https://pmd.github.io/); for `Kotlin` language: detekt for [Detekt](https://detekt.github.io/detekt/); for **JavaScript** language: `eslint` for [ESlint](https://eslint.org/); for **Go** language: `golang_lint` for [golangci-lint](https://golangci-lint.run/). Example: `-d pylint,flake8`. -**‑‑allow-duplicates** | allow duplicate issues found by different linters. By default, duplicates are skipped. -**‑‑language-version**, **‑‑language_version** | specify the language version for JAVA inspectors. Available values: `java7`, `java8`, `java9`, `java11`, `java15`, `java17`. **Note**: **‑‑language_version** is deprecated and will be deleted in the future. -**‑‑n-cpu**, **‑‑n_cpu** | specify number of _cpu_ that can be used to run inspectors. **Note**: **‑‑n_cpu** is deprecated. Will be deleted in the future. -**‑f**, **‑‑format** | the output format. Available values: `json`, `text`. Default value is `json`. -**‑s**, **‑‑start-line**| the first line to be analyzed. By default it starts from `1`. -**‑e**, **‑‑end-line** | the end line to be analyzed. The default value is `None`, which meant to handle file by the end. -**‑‑new-format** | the argument determines whether the tool should use the _new format_. _New format_ means separating the result by the files to allow getting quality and observed issues for each file separately. The default value is `False`. -**‑‑history** | JSON string with a list of issues for each language. For each issue its class and quantity are specified. Example: `--history "{\"python\": [{\"origin_class\": \"SC200\", \"number\": 20}, {\"origin_class\": \"WPS314\", \"number\": 3}]}"` -**‑‑with‑all‑categories** | Without this flag, all issues will be categorized into 5 main categories: `CODE_STYLE`, `BEST_PRACTICES`, `ERROR_PRONE`, `COMPLEXITY`, `INFO`. -**‑‑group‑by‑difficulty** | With this flag, the final grade and influence on penalty will be grouped by the issue difficulty. -**‑‑language** | Specify the language to inspect. The tool will check all languages by default. The default value is `None`. +| Argument | Description | +|------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| **‑h**, **‑‑help** | show the help message and exit. | +| **‑v**, **‑‑verbosity** | choose logging level according [this](https://docs.python.org/3/library/logging.html#levels) list: `1` - **ERROR**; `2` - **INFO**; `3` - **DEBUG**; `0` - disable logging (**CRITICAL** value); default value is `0` (**CRITICAL**). | +| **‑d**, **‑‑disable** | disable inspectors. Available values: for **Python** language: `pylint` for [Pylint](https://github.com/PyCQA/pylint), `flake8` for [flake8](https://flake8.pycqa.org/en/latest/), `radon` for [Radon](https://radon.readthedocs.io/en/latest/), `python_ast` to check different measures providing by AST, `ij-python` for IJ inspections; for **Java** language: `checkstyle` for the [Checkstyle](https://checkstyle.sourceforge.io/), `pmd` for [PMD](https://pmd.github.io/); for **Kotlin** language: `detekt` for [Detekt](https://detekt.github.io/detekt/), `ij-kotlin` for IJ inspections; for **JavaScript** language: `eslint` for [ESlint](https://eslint.org/); for **Go** language: `golang_lint` for [golangci-lint](https://golangci-lint.run/). Example: `-d pylint,flake8`. | +| **‑‑allow-duplicates** | allow duplicate issues found by different linters. By default, duplicates are skipped. | +| **‑‑language-version**, **‑‑language_version** | specify the language version for JAVA inspectors. Available values: `java7`, `java8`, `java9`, `java11`, `java15`, `java17`. **Note**: **‑‑language_version** is deprecated and will be deleted in the future. | +| **‑‑n-cpu**, **‑‑n_cpu** | specify number of _cpu_ that can be used to run inspectors. **Note**: **‑‑n_cpu** is deprecated. Will be deleted in the future. | +| **‑f**, **‑‑format** | the output format. Available values: `json`, `text`. Default value is `json`. | +| **‑s**, **‑‑start-line** | the first line to be analyzed. By default it starts from `1`. | +| **‑e**, **‑‑end-line** | the end line to be analyzed. The default value is `None`, which meant to handle file by the end. | +| **‑‑new-format** | the argument determines whether the tool should use the _new format_. _New format_ means separating the result by the files to allow getting quality and observed issues for each file separately. The default value is `False`. | +| **‑‑history** | JSON string with a list of issues for each language. For each issue its class and quantity are specified. Example: `--history "{\"python\": [{\"origin_class\": \"SC200\", \"number\": 20}, {\"origin_class\": \"WPS314\", \"number\": 3}]}"` | +| **‑‑with‑all‑categories** | Without this flag, all issues will be categorized into 5 main categories: `CODE_STYLE`, `BEST_PRACTICES`, `ERROR_PRONE`, `COMPLEXITY`, `INFO`. | +| **‑‑group‑by‑difficulty** | With this flag, the final grade and influence on penalty will be grouped by the issue difficulty. | +| **‑‑language** | Specify the language to inspect. The tool will check all languages by default. The default value is `None`. | +| **‑‑ij‑config** | JSON string containing information for setting up a connection to the IJ server for each language to be analyzed with the IJ inspector. Example: `--ij-config "{\"python\": {\"host\": \"localhost\", \"port\": 8080}, \"kotlin\": {\"host\": \"localhost\", \"port\": 8081}}"` | The output examples: diff --git a/VERSION.md b/VERSION.md deleted file mode 100644 index 1c99cf0e..00000000 --- a/VERSION.md +++ /dev/null @@ -1 +0,0 @@ -1.4.4 diff --git a/base.Dockerfile b/base.Dockerfile index a7d6c6bb..a9d7c75b 100644 --- a/base.Dockerfile +++ b/base.Dockerfile @@ -1,4 +1,4 @@ -FROM python:3.12.5-slim +FROM python:3.10.14-slim ######### # Taken from https://github.com/docker-library/openjdk/blob/608f26c5ea63ca34070b439c904cb94a30f6b0c1/11/jdk/slim-buster/Dockerfile diff --git a/hyperstyle/src/python/common/tool_arguments.py b/hyperstyle/src/python/common/tool_arguments.py index f258bb11..e4455bb3 100644 --- a/hyperstyle/src/python/common/tool_arguments.py +++ b/hyperstyle/src/python/common/tool_arguments.py @@ -4,7 +4,7 @@ from hyperstyle.src.python.review.common.language import Language from hyperstyle.src.python.review.common.language_version import LanguageVersion -from hyperstyle.src.python.review.inspectors.inspector_type import InspectorType +from hyperstyle.src.python.review.inspectors.common.inspector.inspector_type import InspectorType @unique @@ -80,7 +80,7 @@ class RunToolArgument(Enum): 'should use the new format') HISTORY = ArgumentsInfo(None, '--history', - 'Json string, which contains lists of issues in the previous submissions ' + 'JSON string, which contains lists of issues in the previous submissions ' 'for other tasks for one user.') WITH_ALL_CATEGORIES = ArgumentsInfo(None, '--with-all-categories', @@ -89,3 +89,11 @@ class RunToolArgument(Enum): GROUP_BY_DIFFICULTY = ArgumentsInfo(None, '--group-by-difficulty', 'With this flag, the final grade will be grouped by the issue difficulty.') + + IJ_CONFIG = ArgumentsInfo( + None, + '--ij-config', + 'JSON string containing information for setting up a connection to the IJ server ' + 'for each language to be analyzed with the IJ inspector. ' + 'It should be a dictionary of dictionaries where for each language host and port are specified.', + ) diff --git a/hyperstyle/src/python/review/application_config.py b/hyperstyle/src/python/review/application_config.py index 79514c3f..f8315a10 100644 --- a/hyperstyle/src/python/review/application_config.py +++ b/hyperstyle/src/python/review/application_config.py @@ -2,7 +2,7 @@ from typing import Optional, Set from hyperstyle.src.python.review.common.language import Language -from hyperstyle.src.python.review.inspectors.inspector_type import InspectorType +from hyperstyle.src.python.review.inspectors.common.inspector.inspector_type import InspectorType @dataclass @@ -18,6 +18,7 @@ class ApplicationConfig: new_format: bool = False history: Optional[str] = None group_by_difficulty: bool = False + ij_config: Optional[str] = None @staticmethod def get_default_config() -> 'ApplicationConfig': diff --git a/hyperstyle/src/python/review/common/parallel_runner.py b/hyperstyle/src/python/review/common/parallel_runner.py index 7b6a7e45..e0033eb3 100644 --- a/hyperstyle/src/python/review/common/parallel_runner.py +++ b/hyperstyle/src/python/review/common/parallel_runner.py @@ -6,8 +6,8 @@ from typing import Any, Callable, Dict, List from hyperstyle.src.python.review.application_config import ApplicationConfig -from hyperstyle.src.python.review.inspectors.base_inspector import BaseInspector -from hyperstyle.src.python.review.inspectors.issue import BaseIssue +from hyperstyle.src.python.review.inspectors.common.inspector.base_inspector import BaseInspector +from hyperstyle.src.python.review.inspectors.common.issue.issue import BaseIssue logger = logging.getLogger(__name__) @@ -39,11 +39,11 @@ def inspect_in_parallel(inspector_runner: Callable[[Any, ApplicationConfig, Base data: Any, config: ApplicationConfig, inspectors: List[BaseInspector]) -> List[BaseIssue]: - inspectors = filter(lambda i: i.inspector_type not in config.disabled_inspectors, inspectors) + inspectors_to_run = filter(lambda i: i.inspector_type not in config.disabled_inspectors, inspectors) if config.n_cpu == 1: issues = [] - for inspector in inspectors: + for inspector in inspectors_to_run: inspector_issues = inspector_runner(data, config, inspector) issues.extend(inspector_issues) return issues @@ -51,7 +51,7 @@ def inspect_in_parallel(inspector_runner: Callable[[Any, ApplicationConfig, Base with multiprocessing.Pool(config.n_cpu) as pool: issues = pool.map( functools.partial(inspector_runner, data, config), - inspectors, + inspectors_to_run, ) return list(itertools.chain(*issues)) diff --git a/hyperstyle/src/python/review/inspectors/base_inspector.py b/hyperstyle/src/python/review/inspectors/base_inspector.py deleted file mode 100644 index 401ef6a4..00000000 --- a/hyperstyle/src/python/review/inspectors/base_inspector.py +++ /dev/null @@ -1,41 +0,0 @@ -import abc -from pathlib import Path -from typing import Any, Dict, List - -from hyperstyle.src.python.review.inspectors.inspector_type import InspectorType -from hyperstyle.src.python.review.inspectors.issue import BaseIssue - - -class BaseInspector(abc.ABC): - """ - Each external inspector contains a dictionary in which the IssueType corresponds to the original linter classes. - The dictionary helps to categorize errors during parsing the linters' output. - - To add a new inspector, you need: - - to create a class that inherits from the BaseInspector class, - - define the type of inspector (the type filed) by adding a new option in the InspectorType, - - implement the function. - - Typically, the function launches a linter and parses its output (XML or JSON) to get a list of BaseIssue. - - Also, if you need to launch inspectors in memory (without using/creating a file with code, you need to implement - function. - - Some inspectors (internal) do not require creating a dictionary with IssueType. - This is connected to the fact that they do not launch an additional analysis tool and work with the code directly, - for example, the python AST inspector. - """ - - # Type of inspection for analyzing, e.g. pylint, detekt and etc - @property - @abc.abstractmethod - def inspector_type(self) -> InspectorType: - raise NotImplementedError('inspector_type property not implemented yet') - - @abc.abstractmethod - def inspect(self, path: Path, config: Dict[str, Any]) -> List[BaseIssue]: - raise NotImplementedError('inspect method not implemented yet') - - @abc.abstractmethod - def inspect_in_memory(self, code: str, config: Dict[str, Any]) -> List[BaseIssue]: - raise NotImplementedError('inspect in memory method not implemented yet') diff --git a/hyperstyle/src/python/review/inspectors/checkstyle/checkstyle.py b/hyperstyle/src/python/review/inspectors/checkstyle/checkstyle.py index e2d726c8..1c83ab45 100644 --- a/hyperstyle/src/python/review/inspectors/checkstyle/checkstyle.py +++ b/hyperstyle/src/python/review/inspectors/checkstyle/checkstyle.py @@ -5,13 +5,13 @@ from hyperstyle.src.python.review.common.file_system import check_set_up_env_variable, new_temp_dir from hyperstyle.src.python.review.common.subprocess_runner import run_in_subprocess -from hyperstyle.src.python.review.inspectors.base_inspector import BaseInspector +from hyperstyle.src.python.review.inspectors.common.inspector.base_inspector import BaseInspector from hyperstyle.src.python.review.inspectors.checkstyle.issue_configs import ISSUE_CONFIGS from hyperstyle.src.python.review.inspectors.checkstyle.issue_types import CHECK_CLASS_NAME_TO_ISSUE_TYPE from hyperstyle.src.python.review.inspectors.common.xml_parser import parse_xml_file_result -from hyperstyle.src.python.review.inspectors.inspector_type import InspectorType -from hyperstyle.src.python.review.inspectors.issue import BaseIssue, IssueDifficulty, IssueType -from hyperstyle.src.python.review.inspectors.issue_configs import IssueConfigsHandler +from hyperstyle.src.python.review.inspectors.common.inspector.inspector_type import InspectorType +from hyperstyle.src.python.review.inspectors.common.issue.issue import BaseIssue, IssueDifficulty, IssueType +from hyperstyle.src.python.review.inspectors.common.issue.issue_configs import IssueConfigsHandler logger = logging.getLogger(__name__) diff --git a/hyperstyle/src/python/review/inspectors/checkstyle/files/config.xml b/hyperstyle/src/python/review/inspectors/checkstyle/files/config.xml index f49b5267..2018949b 100644 --- a/hyperstyle/src/python/review/inspectors/checkstyle/files/config.xml +++ b/hyperstyle/src/python/review/inspectors/checkstyle/files/config.xml @@ -6,8 +6,9 @@ - - + + + diff --git a/hyperstyle/src/python/review/inspectors/checkstyle/issue_configs.py b/hyperstyle/src/python/review/inspectors/checkstyle/issue_configs.py index ddbc1262..d76f4590 100644 --- a/hyperstyle/src/python/review/inspectors/checkstyle/issue_configs.py +++ b/hyperstyle/src/python/review/inspectors/checkstyle/issue_configs.py @@ -1,13 +1,13 @@ import re -from hyperstyle.src.python.review.inspectors.common.tips import ( +from hyperstyle.src.python.review.inspectors.common.issue.tips import ( get_bool_expr_len_tip, get_cyclomatic_complexity_tip, get_func_len_tip, get_line_len_tip, get_magic_number_tip, ) -from hyperstyle.src.python.review.inspectors.issue_configs import ( +from hyperstyle.src.python.review.inspectors.common.issue.issue_configs import ( IssueConfig, IssueDescriptionParser, MeasurableIssueConfig, diff --git a/hyperstyle/src/python/review/inspectors/checkstyle/issue_types.py b/hyperstyle/src/python/review/inspectors/checkstyle/issue_types.py index 604d8a2d..61941556 100644 --- a/hyperstyle/src/python/review/inspectors/checkstyle/issue_types.py +++ b/hyperstyle/src/python/review/inspectors/checkstyle/issue_types.py @@ -1,6 +1,6 @@ from typing import Dict -from hyperstyle.src.python.review.inspectors.issue import IssueType +from hyperstyle.src.python.review.inspectors.common.issue.issue import IssueType CHECK_CLASS_NAME_TO_ISSUE_TYPE: Dict[str, IssueType] = { # ---- Annotations ---- diff --git a/hyperstyle/src/python/review/inspectors/common/inspector/__init__.py b/hyperstyle/src/python/review/inspectors/common/inspector/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/hyperstyle/src/python/review/inspectors/common/inspector/base_inspector.py b/hyperstyle/src/python/review/inspectors/common/inspector/base_inspector.py new file mode 100644 index 00000000..fd669327 --- /dev/null +++ b/hyperstyle/src/python/review/inspectors/common/inspector/base_inspector.py @@ -0,0 +1,154 @@ +import logging +from abc import ABC, abstractmethod +from pathlib import Path +from typing import Any, Dict, List + +from hyperstyle.src.python.review.common.file_system import get_content_from_file +from hyperstyle.src.python.review.inspectors.common.inspector.ij_client import IJClient +from hyperstyle.src.python.review.inspectors.common.inspector.inspector_type import InspectorType +from hyperstyle.src.python.review.inspectors.common.inspector.proto import model_pb2 +from hyperstyle.src.python.review.inspectors.common.issue.base_issue_converter import convert_base_issue +from hyperstyle.src.python.review.inspectors.common.issue.issue import BaseIssue, IssueDifficulty, IssueType +from hyperstyle.src.python.review.inspectors.common.issue.issue_configs import IssueConfig, IssueConfigsHandler + + +logger = logging.getLogger(__name__) + + +class BaseInspector(ABC): + """ + Each external inspector contains a dictionary in which the IssueType corresponds to the original linter classes. + The dictionary helps to categorize errors during parsing the linters' output. + + To add a new inspector, you need: + - to create a class that inherits from the BaseInspector class, + - define the type of inspector (the type filed) by adding a new option in the InspectorType, + - implement the function. + + Typically, the function launches a linter and parses its output (XML or JSON) to get a list of BaseIssue. + + Also, if you need to launch inspectors in memory (without using/creating a file with code, you need to implement + function. + + Some inspectors (internal) do not require creating a dictionary with IssueType. + This is connected to the fact that they do not launch an additional analysis tool and work with the code directly, + for example, the python AST inspector. + """ + + # Type of inspection for analyzing, e.g. pylint, detekt and etc + @property + @abstractmethod + def inspector_type(self) -> InspectorType: + raise NotImplementedError('inspector_type property not implemented yet') + + @abstractmethod + def inspect(self, path: Path, config: Dict[str, Any]) -> List[BaseIssue]: + raise NotImplementedError('inspect method not implemented yet') + + @abstractmethod + def inspect_in_memory(self, code: str, config: Dict[str, Any]) -> List[BaseIssue]: + raise NotImplementedError('inspect in memory method not implemented yet') + + +class BaseIJInspector(BaseInspector): + """ + Base class for every IJ-based inspector. + + It inherits from the `BaseInspector` class, so see its documentation for more information. + + To implement this kind of inspector, you should additionally specify `language_id` from the `model.proto` file, + specify issue configs and implement the `choose_issue_type` function. + + Before running the inspector, you should set up connection parameters + using the `setup_connection_parameters` function. + """ + host: str + port: int + + @property + @abstractmethod + def language_id(self) -> model_pb2.LanguageId: + raise NotImplementedError('language_id property is not implemented yet') + + @property + @abstractmethod + def issue_configs(self) -> List[IssueConfig]: + raise NotImplementedError('issue_configs property is not implemented yet') + + @property + @abstractmethod + def ij_inspection_to_issue_type(self) -> Dict[str, IssueType]: + raise NotImplementedError('ij_inspection_to_issue_type property is not implemented yet') + + @property + @abstractmethod + def ij_message_to_issue_type(self) -> Dict[str, Dict[str, IssueType]]: + raise NotImplementedError('ij_message_to_issue_type property is not implemented yet') + + def setup_connection_parameters(self, host: str, port: int): + self.host = host + self.port = port + + def inspect(self, path: Path, config: Dict[str, Any]) -> List[BaseIssue]: + code = get_content_from_file(path) + return self._get_inspection_result(code, path) + + def inspect_in_memory(self, code: str, config: Dict[str, Any]) -> List[BaseIssue]: + return self._get_inspection_result(code, Path("")) + + def convert_to_base_issues(self, inspection_result: model_pb2.InspectionResult, file_path: Path) -> List[BaseIssue]: + base_issues = [] + issue_configs_handler = IssueConfigsHandler(*self.issue_configs) + for problem in inspection_result.problems: + issue_type = self.choose_issue_type(problem) + base_issue = BaseIssue( + origin_class=problem.inspector, + type=issue_type, + description=problem.name, + file_path=file_path, + line_no=problem.lineNumber, + column_no=problem.offset, + inspector_type=self.inspector_type, + difficulty=IssueDifficulty.get_by_issue_type(issue_type), + ) + + issue = convert_base_issue(base_issue, issue_configs_handler) + if issue is None: + logger.error(f'{self.inspector_type.value}: an error occurred during converting a base issue.') + continue + + base_issues.append(base_issue) + + return base_issues + + def _get_inspection_result(self, code_text: str, file_path: Path) -> List[BaseIssue]: + if self.host is None or self.port is None: + raise Exception('Connection parameters is not set up.') + + try: + client = IJClient(self.host, self.port) + + code = model_pb2.Code() + code.languageId = self.language_id + code.text = code_text + + inspection_result = client.inspect(code) + + return self.convert_to_base_issues(inspection_result, file_path) + + except Exception as e: + # TODO: replace with error when add mock server into tests + logger.info('Inspector failed to connect to code server.', e) + return [] + + def choose_issue_type(self, problem: model_pb2.Problem) -> IssueType: + if problem.inspector in self.ij_message_to_issue_type: + for key, value in self.ij_message_to_issue_type[problem.inspector].items(): + if problem.name in key: + return value + + if problem.inspector in self.ij_inspection_to_issue_type: + return self.ij_inspection_to_issue_type[problem.inspector] + + # PEP-8 inspection + return IssueType.CODE_STYLE diff --git a/hyperstyle/src/python/review/inspectors/common/inspector/ij_client.py b/hyperstyle/src/python/review/inspectors/common/inspector/ij_client.py new file mode 100644 index 00000000..ff7a0d20 --- /dev/null +++ b/hyperstyle/src/python/review/inspectors/common/inspector/ij_client.py @@ -0,0 +1,28 @@ +import grpc + +from hyperstyle.src.python.review.inspectors.common.inspector.proto import model_pb2, model_pb2_grpc + +TIMEOUT = 1 + + +class IJClient(object): + def __init__(self, host: str = 'localhost', port: int = 8080): + self.host = host + self.port = port + + # instantiate a channel + self.channel = grpc.insecure_channel(f'{self.host}:{self.port}') + + # bind the client and the server + try: + grpc.channel_ready_future(self.channel).result(timeout=TIMEOUT) + except grpc.FutureTimeoutError: + raise Exception("Failed to connect to ij code server") + else: + self.stub = model_pb2_grpc.CodeInspectionServiceStub(self.channel) + + def inspect(self, code: model_pb2.Code) -> model_pb2.InspectionResult: + return self.stub.inspect(code, timeout=TIMEOUT) + + def init(self, service: model_pb2.Service) -> model_pb2.InitResult: + return self.stub.init(service, timeout=TIMEOUT) diff --git a/hyperstyle/src/python/review/inspectors/inspector_type.py b/hyperstyle/src/python/review/inspectors/common/inspector/inspector_type.py similarity index 78% rename from hyperstyle/src/python/review/inspectors/inspector_type.py rename to hyperstyle/src/python/review/inspectors/common/inspector/inspector_type.py index 5ce892d6..04c1ceee 100644 --- a/hyperstyle/src/python/review/inspectors/inspector_type.py +++ b/hyperstyle/src/python/review/inspectors/common/inspector/inspector_type.py @@ -9,6 +9,7 @@ class InspectorType(Enum): PYTHON_AST = 'PYTHON_AST' FLAKE8 = 'FLAKE8' RADON = 'RADON' + IJ_PYTHON = 'IJ_PYTHON' # Java language PMD = 'PMD' @@ -16,6 +17,7 @@ class InspectorType(Enum): # Kotlin language DETEKT = 'DETEKT' + IJ_KOTLIN = 'IJ_KOTLIN' # JavaScript language ESLINT = 'ESLINT' @@ -25,6 +27,8 @@ class InspectorType(Enum): UNDEFINED = 'UNDEFINED' QODANA = 'QODANA' + # TODO: it is used on production for java inspections, remove in the future releases + IJ_OLD = 'INTELLIJ' @classmethod def available_values(cls) -> List[str]: @@ -34,6 +38,7 @@ def available_values(cls) -> List[str]: cls.FLAKE8.value, cls.PYTHON_AST.value, cls.RADON.value, + cls.IJ_PYTHON.value, # Java language cls.PMD.value, @@ -41,10 +46,13 @@ def available_values(cls) -> List[str]: # Kotlin language cls.DETEKT.value, + cls.IJ_KOTLIN.value, # JavaScript language cls.ESLINT.value, # Go language cls.GOLANG_LINT.value, + + cls.IJ_OLD.value, ] diff --git a/hyperstyle/src/python/review/inspectors/common/inspector/proto/__init__.py b/hyperstyle/src/python/review/inspectors/common/inspector/proto/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/hyperstyle/src/python/review/inspectors/common/inspector/proto/model.proto b/hyperstyle/src/python/review/inspectors/common/inspector/proto/model.proto new file mode 100644 index 00000000..4dfb60da --- /dev/null +++ b/hyperstyle/src/python/review/inspectors/common/inspector/proto/model.proto @@ -0,0 +1,41 @@ +syntax = "proto3"; + +option java_multiple_files = true; +option java_package = "org.jetbrains.research.ij.headless.server"; +option java_outer_classname = "CodeServerProto"; + +service CodeInspectionService { + rpc inspect (Code) returns (InspectionResult) {}; +} + +enum LanguageId { + Python = 0; + kotlin = 1; + Java = 2; +} + +message Code { + string text = 1; + LanguageId languageId = 2; +} + +message Problem { + string name = 1; + string inspector = 2; + uint64 lineNumber = 3; + uint64 offset = 4; + uint64 length = 5; +} + +message InspectionResult { + repeated Problem problems = 1; +} + +message Service { + string name = 1; + LanguageId languageId = 2; +} + +message InitResult { + uint64 status = 1; +} diff --git a/hyperstyle/src/python/review/inspectors/common/issue/__init__.py b/hyperstyle/src/python/review/inspectors/common/issue/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/hyperstyle/src/python/review/inspectors/common/base_issue_converter.py b/hyperstyle/src/python/review/inspectors/common/issue/base_issue_converter.py similarity index 90% rename from hyperstyle/src/python/review/inspectors/common/base_issue_converter.py rename to hyperstyle/src/python/review/inspectors/common/issue/base_issue_converter.py index d2a3b9cf..d8ceaa62 100644 --- a/hyperstyle/src/python/review/inspectors/common/base_issue_converter.py +++ b/hyperstyle/src/python/review/inspectors/common/issue/base_issue_converter.py @@ -1,14 +1,14 @@ import logging from typing import Optional -from hyperstyle.src.python.review.inspectors.issue import ( +from hyperstyle.src.python.review.inspectors.common.issue.issue import ( BaseIssue, get_issue_class_by_issue_type, get_measure_name_by_measurable_issue_type, IssueData, Measurable, ) -from hyperstyle.src.python.review.inspectors.issue_configs import IssueConfigsHandler +from hyperstyle.src.python.review.inspectors.common.issue.issue_configs import IssueConfigsHandler logger = logging.getLogger(__name__) diff --git a/hyperstyle/src/python/review/inspectors/issue.py b/hyperstyle/src/python/review/inspectors/common/issue/issue.py similarity index 99% rename from hyperstyle/src/python/review/inspectors/issue.py rename to hyperstyle/src/python/review/inspectors/common/issue/issue.py index a8f03bb1..06c509d9 100644 --- a/hyperstyle/src/python/review/inspectors/issue.py +++ b/hyperstyle/src/python/review/inspectors/common/issue/issue.py @@ -6,7 +6,7 @@ from pathlib import Path from typing import Any, Dict, List, Type, Union -from hyperstyle.src.python.review.inspectors.inspector_type import InspectorType +from hyperstyle.src.python.review.inspectors.common.inspector.inspector_type import InspectorType logger = logging.getLogger(__name__) diff --git a/hyperstyle/src/python/review/inspectors/issue_configs.py b/hyperstyle/src/python/review/inspectors/common/issue/issue_configs.py similarity index 100% rename from hyperstyle/src/python/review/inspectors/issue_configs.py rename to hyperstyle/src/python/review/inspectors/common/issue/issue_configs.py diff --git a/hyperstyle/src/python/review/inspectors/common/tips.py b/hyperstyle/src/python/review/inspectors/common/issue/tips.py similarity index 100% rename from hyperstyle/src/python/review/inspectors/common/tips.py rename to hyperstyle/src/python/review/inspectors/common/issue/tips.py diff --git a/hyperstyle/src/python/review/inspectors/common/utils.py b/hyperstyle/src/python/review/inspectors/common/utils.py index de633472..981d8e1f 100644 --- a/hyperstyle/src/python/review/inspectors/common/utils.py +++ b/hyperstyle/src/python/review/inspectors/common/utils.py @@ -5,7 +5,7 @@ from typing import List from hyperstyle.src.python.review.common.file_system import get_content_from_file -from hyperstyle.src.python.review.inspectors.inspector_type import InspectorType +from hyperstyle.src.python.review.inspectors.common.inspector.inspector_type import InspectorType logger = logging.getLogger(__name__) @@ -37,17 +37,6 @@ def convert_percentage_of_value_to_lack_of_value(percentage_of_value: float) -> return floor(100 - percentage_of_value) -# TODO: When upgrading to python 3.9+, replace it with removeprefix. -# See: https://docs.python.org/3.9/library/stdtypes.html#str.removeprefix -def remove_prefix(text: str, prefix: str) -> str: - """ - Removes the prefix if it is present, otherwise returns the original string. - """ - if text.startswith(prefix): - return text[len(prefix):] - return text - - def _get_format_fields(input_string: str) -> List[str]: """ Get all format fields from the input string. diff --git a/hyperstyle/src/python/review/inspectors/common/xml_parser.py b/hyperstyle/src/python/review/inspectors/common/xml_parser.py index 7e4dde18..ff4b3fa3 100644 --- a/hyperstyle/src/python/review/inspectors/common/xml_parser.py +++ b/hyperstyle/src/python/review/inspectors/common/xml_parser.py @@ -3,11 +3,11 @@ from typing import Callable, List from xml.etree import ElementTree -from hyperstyle.src.python.review.inspectors.common.base_issue_converter import convert_base_issue +from hyperstyle.src.python.review.inspectors.common.issue.base_issue_converter import convert_base_issue from hyperstyle.src.python.review.inspectors.common.utils import is_result_file_correct -from hyperstyle.src.python.review.inspectors.inspector_type import InspectorType -from hyperstyle.src.python.review.inspectors.issue import BaseIssue, IssueDifficulty, IssueType -from hyperstyle.src.python.review.inspectors.issue_configs import IssueConfigsHandler +from hyperstyle.src.python.review.inspectors.common.inspector.inspector_type import InspectorType +from hyperstyle.src.python.review.inspectors.common.issue.issue import BaseIssue, IssueDifficulty, IssueType +from hyperstyle.src.python.review.inspectors.common.issue.issue_configs import IssueConfigsHandler logger = logging.getLogger(__name__) diff --git a/hyperstyle/src/python/review/inspectors/detekt/detekt.py b/hyperstyle/src/python/review/inspectors/detekt/detekt.py index c0bcf1a9..3bba971c 100644 --- a/hyperstyle/src/python/review/inspectors/detekt/detekt.py +++ b/hyperstyle/src/python/review/inspectors/detekt/detekt.py @@ -5,13 +5,13 @@ from hyperstyle.src.python.review.common.file_system import check_set_up_env_variable, new_temp_dir from hyperstyle.src.python.review.common.subprocess_runner import run_in_subprocess -from hyperstyle.src.python.review.inspectors.base_inspector import BaseInspector +from hyperstyle.src.python.review.inspectors.common.inspector.base_inspector import BaseInspector from hyperstyle.src.python.review.inspectors.common.xml_parser import parse_xml_file_result from hyperstyle.src.python.review.inspectors.detekt.issue_configs import ISSUE_CONFIGS from hyperstyle.src.python.review.inspectors.detekt.issue_types import DETEKT_CLASS_NAME_TO_ISSUE_TYPE -from hyperstyle.src.python.review.inspectors.inspector_type import InspectorType -from hyperstyle.src.python.review.inspectors.issue import BaseIssue, IssueDifficulty, IssueType -from hyperstyle.src.python.review.inspectors.issue_configs import IssueConfigsHandler +from hyperstyle.src.python.review.inspectors.common.inspector.inspector_type import InspectorType +from hyperstyle.src.python.review.inspectors.common.issue.issue import BaseIssue, IssueDifficulty, IssueType +from hyperstyle.src.python.review.inspectors.common.issue.issue_configs import IssueConfigsHandler logger = logging.getLogger(__name__) diff --git a/hyperstyle/src/python/review/inspectors/detekt/files/detekt-config.yml b/hyperstyle/src/python/review/inspectors/detekt/files/detekt-config.yml index 950bc7b4..fe49c429 100644 --- a/hyperstyle/src/python/review/inspectors/detekt/files/detekt-config.yml +++ b/hyperstyle/src/python/review/inspectors/detekt/files/detekt-config.yml @@ -1,5 +1,5 @@ -# This config was created based on the default config for Detekt 1.18.0 -# using the following table: https://bit.ly/2V2kCyi +# This config was created based on the default config for Detekt 1.18.0 using the following table: +# https://docs.google.com/spreadsheets/d/1N6CMqXKW-FnrlevwwD8iO75M1gTjmLO_ # Some inspections have been commented out due to problems with upgrading to version 1.18.0. # The current config contains only those inspections that work on version 1.14.2. diff --git a/hyperstyle/src/python/review/inspectors/detekt/issue_configs.py b/hyperstyle/src/python/review/inspectors/detekt/issue_configs.py index 426944ba..813c3a27 100644 --- a/hyperstyle/src/python/review/inspectors/detekt/issue_configs.py +++ b/hyperstyle/src/python/review/inspectors/detekt/issue_configs.py @@ -1,12 +1,12 @@ import re -from hyperstyle.src.python.review.inspectors.common.tips import ( +from hyperstyle.src.python.review.inspectors.common.issue.tips import ( get_bool_expr_len_tip, get_cyclomatic_complexity_tip, get_func_len_tip, get_magic_number_tip, ) -from hyperstyle.src.python.review.inspectors.issue_configs import ( +from hyperstyle.src.python.review.inspectors.common.issue.issue_configs import ( IssueConfig, IssueDescriptionParser, MeasurableIssueConfig, diff --git a/hyperstyle/src/python/review/inspectors/detekt/issue_types.py b/hyperstyle/src/python/review/inspectors/detekt/issue_types.py index 19b4da80..35b9d07d 100644 --- a/hyperstyle/src/python/review/inspectors/detekt/issue_types.py +++ b/hyperstyle/src/python/review/inspectors/detekt/issue_types.py @@ -1,6 +1,6 @@ from typing import Dict -from hyperstyle.src.python.review.inspectors.issue import IssueType +from hyperstyle.src.python.review.inspectors.common.issue.issue import IssueType DETEKT_CLASS_NAME_TO_ISSUE_TYPE: Dict[str, IssueType] = { # Comments diff --git a/hyperstyle/src/python/review/inspectors/eslint/eslint.py b/hyperstyle/src/python/review/inspectors/eslint/eslint.py index 20e35092..d0557fb3 100644 --- a/hyperstyle/src/python/review/inspectors/eslint/eslint.py +++ b/hyperstyle/src/python/review/inspectors/eslint/eslint.py @@ -3,13 +3,13 @@ from hyperstyle.src.python.review.common.file_system import new_temp_dir from hyperstyle.src.python.review.common.subprocess_runner import run_in_subprocess -from hyperstyle.src.python.review.inspectors.base_inspector import BaseInspector +from hyperstyle.src.python.review.inspectors.common.inspector.base_inspector import BaseInspector from hyperstyle.src.python.review.inspectors.common.xml_parser import parse_xml_file_result from hyperstyle.src.python.review.inspectors.eslint.issue_configs import ISSUE_CONFIGS from hyperstyle.src.python.review.inspectors.eslint.issue_types import ESLINT_CLASS_NAME_TO_ISSUE_TYPE -from hyperstyle.src.python.review.inspectors.inspector_type import InspectorType -from hyperstyle.src.python.review.inspectors.issue import BaseIssue, IssueDifficulty, IssueType -from hyperstyle.src.python.review.inspectors.issue_configs import IssueConfigsHandler +from hyperstyle.src.python.review.inspectors.common.inspector.inspector_type import InspectorType +from hyperstyle.src.python.review.inspectors.common.issue.issue import BaseIssue, IssueDifficulty, IssueType +from hyperstyle.src.python.review.inspectors.common.issue.issue_configs import IssueConfigsHandler PATH_ESLINT_CONFIG = Path(__file__).parent / '.eslintrc' diff --git a/hyperstyle/src/python/review/inspectors/eslint/issue_configs.py b/hyperstyle/src/python/review/inspectors/eslint/issue_configs.py index fe15f326..7ae584a6 100644 --- a/hyperstyle/src/python/review/inspectors/eslint/issue_configs.py +++ b/hyperstyle/src/python/review/inspectors/eslint/issue_configs.py @@ -1,7 +1,10 @@ import re -from hyperstyle.src.python.review.inspectors.common.tips import get_cyclomatic_complexity_tip -from hyperstyle.src.python.review.inspectors.issue_configs import IssueDescriptionParser, MeasurableIssueConfig +from hyperstyle.src.python.review.inspectors.common.issue.tips import get_cyclomatic_complexity_tip +from hyperstyle.src.python.review.inspectors.common.issue.issue_configs import ( + IssueDescriptionParser, + MeasurableIssueConfig, +) ISSUE_CONFIGS = [ MeasurableIssueConfig( diff --git a/hyperstyle/src/python/review/inspectors/eslint/issue_types.py b/hyperstyle/src/python/review/inspectors/eslint/issue_types.py index db8b082b..1ab776b1 100644 --- a/hyperstyle/src/python/review/inspectors/eslint/issue_types.py +++ b/hyperstyle/src/python/review/inspectors/eslint/issue_types.py @@ -1,6 +1,6 @@ from typing import Dict -from hyperstyle.src.python.review.inspectors.issue import IssueType +from hyperstyle.src.python.review.inspectors.common.issue.issue import IssueType ESLINT_CLASS_NAME_TO_ISSUE_TYPE: Dict[str, IssueType] = { # Possible errors (according to Eslint doc) diff --git a/hyperstyle/src/python/review/inspectors/flake8/flake8.py b/hyperstyle/src/python/review/inspectors/flake8/flake8.py index f63fbe9a..63d5f21d 100644 --- a/hyperstyle/src/python/review/inspectors/flake8/flake8.py +++ b/hyperstyle/src/python/review/inspectors/flake8/flake8.py @@ -1,16 +1,17 @@ import logging import re +import sys from pathlib import Path from typing import Any, Dict, List from hyperstyle.src.python.review.common.subprocess_runner import run_in_subprocess -from hyperstyle.src.python.review.inspectors.base_inspector import BaseInspector -from hyperstyle.src.python.review.inspectors.common.base_issue_converter import convert_base_issue +from hyperstyle.src.python.review.inspectors.common.inspector.base_inspector import BaseInspector +from hyperstyle.src.python.review.inspectors.common.issue.base_issue_converter import convert_base_issue from hyperstyle.src.python.review.inspectors.flake8.issue_configs import ISSUE_CONFIGS from hyperstyle.src.python.review.inspectors.flake8.issue_types import CODE_PREFIX_TO_ISSUE_TYPE, CODE_TO_ISSUE_TYPE -from hyperstyle.src.python.review.inspectors.inspector_type import InspectorType -from hyperstyle.src.python.review.inspectors.issue import BaseIssue, IssueDifficulty, IssueType -from hyperstyle.src.python.review.inspectors.issue_configs import IssueConfigsHandler +from hyperstyle.src.python.review.inspectors.common.inspector.inspector_type import InspectorType +from hyperstyle.src.python.review.inspectors.common.issue.issue import BaseIssue, IssueDifficulty, IssueType +from hyperstyle.src.python.review.inspectors.common.issue.issue_configs import IssueConfigsHandler logger = logging.getLogger(__name__) @@ -22,6 +23,7 @@ FORMAT = '%(path)s:%(row)d:%(col)d:%(code)s:%(text)s' INSPECTOR_NAME = 'flake8' BASE_COMMAND = [ + sys.executable, '-m', 'flake8', f'--format={FORMAT}', f'--config={PATH_FLAKE8_CONFIG}', diff --git a/hyperstyle/src/python/review/inspectors/flake8/issue_configs.py b/hyperstyle/src/python/review/inspectors/flake8/issue_configs.py index ee721f76..9117e44c 100644 --- a/hyperstyle/src/python/review/inspectors/flake8/issue_configs.py +++ b/hyperstyle/src/python/review/inspectors/flake8/issue_configs.py @@ -1,6 +1,6 @@ import re -from hyperstyle.src.python.review.inspectors.common.tips import ( +from hyperstyle.src.python.review.inspectors.common.issue.tips import ( get_augmented_assign_pattern_tip, get_cohesion_tip, get_cyclomatic_complexity_tip, @@ -8,7 +8,7 @@ get_magic_number_tip, ) from hyperstyle.src.python.review.inspectors.common.utils import convert_percentage_of_value_to_lack_of_value -from hyperstyle.src.python.review.inspectors.issue_configs import ( +from hyperstyle.src.python.review.inspectors.common.issue.issue_configs import ( IssueConfig, IssueDescriptionParser, MeasurableIssueConfig, diff --git a/hyperstyle/src/python/review/inspectors/flake8/issue_types.py b/hyperstyle/src/python/review/inspectors/flake8/issue_types.py index d3e549d3..f3cf4a48 100644 --- a/hyperstyle/src/python/review/inspectors/flake8/issue_types.py +++ b/hyperstyle/src/python/review/inspectors/flake8/issue_types.py @@ -1,6 +1,6 @@ from typing import Dict -from hyperstyle.src.python.review.inspectors.issue import IssueType +from hyperstyle.src.python.review.inspectors.common.issue.issue import IssueType CODE_TO_ISSUE_TYPE: Dict[str, IssueType] = { # Line length @@ -37,7 +37,8 @@ # Cohesion 'H601': IssueType.COHESION, - # The categorization for WPS was created using the following document: https://bit.ly/3yms06n + # The categorization for WPS was created using the following document: + # https://docs.google.com/document/d/1Y_DkYuglPvYlYmAJoyvkXEERbNDS3UhS # WPS: Naming 'WPS117': IssueType.CODE_STYLE, # Forbid naming variables self, cls, or mcs. diff --git a/hyperstyle/src/python/review/inspectors/golang_lint/config.yml b/hyperstyle/src/python/review/inspectors/golang_lint/config.yml index fe00bdf1..02a1e8e1 100644 --- a/hyperstyle/src/python/review/inspectors/golang_lint/config.yml +++ b/hyperstyle/src/python/review/inspectors/golang_lint/config.yml @@ -1,4 +1,5 @@ -# The configuration was made using the following table: https://bit.ly/3Kvz0nK +# The configuration was made using the following table: +# https://docs.google.com/spreadsheets/d/1zJrORtjZ3UyoLJV5qaLw9Y_cnK0sNlDW run: tests: false diff --git a/hyperstyle/src/python/review/inspectors/golang_lint/golang_lint.py b/hyperstyle/src/python/review/inspectors/golang_lint/golang_lint.py index 087228e4..9f6c6674 100644 --- a/hyperstyle/src/python/review/inspectors/golang_lint/golang_lint.py +++ b/hyperstyle/src/python/review/inspectors/golang_lint/golang_lint.py @@ -7,17 +7,17 @@ from hyperstyle.src.python.review.common.file_system import check_set_up_env_variable, new_temp_dir from hyperstyle.src.python.review.common.subprocess_runner import run_in_subprocess -from hyperstyle.src.python.review.inspectors.base_inspector import BaseInspector -from hyperstyle.src.python.review.inspectors.common.base_issue_converter import convert_base_issue +from hyperstyle.src.python.review.inspectors.common.inspector.base_inspector import BaseInspector +from hyperstyle.src.python.review.inspectors.common.issue.base_issue_converter import convert_base_issue from hyperstyle.src.python.review.inspectors.common.utils import is_result_file_correct from hyperstyle.src.python.review.inspectors.golang_lint.issue_configs import ISSUE_CONFIGS from hyperstyle.src.python.review.inspectors.golang_lint.issue_types import ( CODE_PREFIX_TO_ISSUE_TYPE, CODE_TO_ISSUE_TYPE, ) -from hyperstyle.src.python.review.inspectors.inspector_type import InspectorType -from hyperstyle.src.python.review.inspectors.issue import BaseIssue, IssueDifficulty, IssueType -from hyperstyle.src.python.review.inspectors.issue_configs import IssueConfigsHandler +from hyperstyle.src.python.review.inspectors.common.inspector.inspector_type import InspectorType +from hyperstyle.src.python.review.inspectors.common.issue.issue import BaseIssue, IssueDifficulty, IssueType +from hyperstyle.src.python.review.inspectors.common.issue.issue_configs import IssueConfigsHandler GOLANG_LINT_DIRECTORY_ENV = 'GOLANG_LINT_DIRECTORY' GOLANG_LINT_CONFIG_PATH = Path(__file__).parent / 'config.yml' diff --git a/hyperstyle/src/python/review/inspectors/golang_lint/issue_configs.py b/hyperstyle/src/python/review/inspectors/golang_lint/issue_configs.py index 18e7233e..a348abbd 100644 --- a/hyperstyle/src/python/review/inspectors/golang_lint/issue_configs.py +++ b/hyperstyle/src/python/review/inspectors/golang_lint/issue_configs.py @@ -1,6 +1,6 @@ import re -from hyperstyle.src.python.review.inspectors.common.tips import ( +from hyperstyle.src.python.review.inspectors.common.issue.tips import ( get_cyclomatic_complexity_tip, get_func_len_tip, get_line_len_tip, @@ -8,7 +8,7 @@ get_maintainability_index_tip, ) from hyperstyle.src.python.review.inspectors.common.utils import convert_percentage_of_value_to_lack_of_value -from hyperstyle.src.python.review.inspectors.issue_configs import ( +from hyperstyle.src.python.review.inspectors.common.issue.issue_configs import ( IssueConfig, IssueDescriptionParser, MeasurableIssueConfig, diff --git a/hyperstyle/src/python/review/inspectors/golang_lint/issue_types.py b/hyperstyle/src/python/review/inspectors/golang_lint/issue_types.py index 8addba6d..4ee25e90 100644 --- a/hyperstyle/src/python/review/inspectors/golang_lint/issue_types.py +++ b/hyperstyle/src/python/review/inspectors/golang_lint/issue_types.py @@ -2,9 +2,10 @@ from typing import Dict -from hyperstyle.src.python.review.inspectors.issue import IssueType +from hyperstyle.src.python.review.inspectors.common.issue.issue import IssueType -# The configuration was made using the following table: https://bit.ly/3Kvz0nK +# The configuration was made using the following table: +# https://docs.google.com/spreadsheets/d/1zJrORtjZ3UyoLJV5qaLw9Y_cnK0sNlDW CODE_TO_ISSUE_TYPE: Dict[str, IssueType] = { 'errcheck': IssueType.ERROR_PRONE, 'ineffassign': IssueType.ERROR_PRONE, diff --git a/hyperstyle/src/python/review/inspectors/ij_kotlin/__init__.py b/hyperstyle/src/python/review/inspectors/ij_kotlin/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/hyperstyle/src/python/review/inspectors/ij_kotlin/ij_kotlin.py b/hyperstyle/src/python/review/inspectors/ij_kotlin/ij_kotlin.py new file mode 100644 index 00000000..6871a1fa --- /dev/null +++ b/hyperstyle/src/python/review/inspectors/ij_kotlin/ij_kotlin.py @@ -0,0 +1,16 @@ +from hyperstyle.src.python.review.inspectors.common.inspector.base_inspector import BaseIJInspector +from hyperstyle.src.python.review.inspectors.common.inspector.inspector_type import InspectorType +from hyperstyle.src.python.review.inspectors.common.inspector.proto import model_pb2 +from hyperstyle.src.python.review.inspectors.ij_kotlin.issue_configs import ISSUE_CONFIGS +from hyperstyle.src.python.review.inspectors.ij_kotlin.issue_types import ( + IJ_INSPECTION_TO_ISSUE_TYPE, + IJ_MESSAGE_TO_ISSUE_TYPE, +) + + +class KotlinIJInspector(BaseIJInspector): + inspector_type = InspectorType.IJ_KOTLIN + language_id = model_pb2.LanguageId.kotlin + issue_configs = ISSUE_CONFIGS + ij_inspection_to_issue_type = IJ_INSPECTION_TO_ISSUE_TYPE + ij_message_to_issue_type = IJ_MESSAGE_TO_ISSUE_TYPE diff --git a/hyperstyle/src/python/review/inspectors/ij_kotlin/issue_configs.py b/hyperstyle/src/python/review/inspectors/ij_kotlin/issue_configs.py new file mode 100644 index 00000000..5b01ae4b --- /dev/null +++ b/hyperstyle/src/python/review/inspectors/ij_kotlin/issue_configs.py @@ -0,0 +1 @@ +ISSUE_CONFIGS = [] diff --git a/hyperstyle/src/python/review/inspectors/ij_kotlin/issue_types.py b/hyperstyle/src/python/review/inspectors/ij_kotlin/issue_types.py new file mode 100644 index 00000000..5f37738f --- /dev/null +++ b/hyperstyle/src/python/review/inspectors/ij_kotlin/issue_types.py @@ -0,0 +1,3 @@ +IJ_INSPECTION_TO_ISSUE_TYPE = {} + +IJ_MESSAGE_TO_ISSUE_TYPE = {} diff --git a/hyperstyle/src/python/review/inspectors/ij_python/__init__.py b/hyperstyle/src/python/review/inspectors/ij_python/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/hyperstyle/src/python/review/inspectors/ij_python/ij_python.py b/hyperstyle/src/python/review/inspectors/ij_python/ij_python.py new file mode 100644 index 00000000..04f9b40b --- /dev/null +++ b/hyperstyle/src/python/review/inspectors/ij_python/ij_python.py @@ -0,0 +1,16 @@ +from hyperstyle.src.python.review.inspectors.common.inspector.base_inspector import BaseIJInspector +from hyperstyle.src.python.review.inspectors.common.inspector.inspector_type import InspectorType +from hyperstyle.src.python.review.inspectors.common.inspector.proto import model_pb2 +from hyperstyle.src.python.review.inspectors.ij_python.issue_configs import ISSUE_CONFIGS +from hyperstyle.src.python.review.inspectors.ij_python.issue_types import ( + IJ_INSPECTION_TO_ISSUE_TYPE, + IJ_MESSAGE_TO_ISSUE_TYPE, +) + + +class PythonIJInspector(BaseIJInspector): + inspector_type = InspectorType.IJ_PYTHON + language_id = model_pb2.LanguageId.Python + issue_configs = ISSUE_CONFIGS + ij_inspection_to_issue_type = IJ_INSPECTION_TO_ISSUE_TYPE + ij_message_to_issue_type = IJ_MESSAGE_TO_ISSUE_TYPE diff --git a/hyperstyle/src/python/review/inspectors/ij_python/issue_configs.py b/hyperstyle/src/python/review/inspectors/ij_python/issue_configs.py new file mode 100644 index 00000000..827e5f76 --- /dev/null +++ b/hyperstyle/src/python/review/inspectors/ij_python/issue_configs.py @@ -0,0 +1,8 @@ +from hyperstyle.src.python.review.inspectors.common.issue.issue_configs import IssueConfig + +ISSUE_CONFIGS = [ + IssueConfig( + origin_class='E128', + new_description='Incorrect indent', + ), +] diff --git a/hyperstyle/src/python/review/inspectors/ij_python/issue_types.py b/hyperstyle/src/python/review/inspectors/ij_python/issue_types.py new file mode 100644 index 00000000..6bff3d44 --- /dev/null +++ b/hyperstyle/src/python/review/inspectors/ij_python/issue_types.py @@ -0,0 +1,77 @@ +from hyperstyle.src.python.review.inspectors.common.issue.issue import IssueType + +# Synchronized with https://github.com/JetBrains-Research/code-quality-ij-server/tree/master/docs/inspections/python +IJ_INSPECTION_TO_ISSUE_TYPE = { + # BEST_PRACTICES + 'PyUnusedLocalInspection': IssueType.BEST_PRACTICES, + 'PySimplifyBooleanCheckInspection': IssueType.BEST_PRACTICES, + 'PyArgumentEqualDefaultInspection': IssueType.BEST_PRACTICES, + 'PyAttributeOutsideInitInspection': IssueType.BEST_PRACTICES, + 'PyBroadExceptionInspection': IssueType.BEST_PRACTICES, + 'PyDictCreationInspection': IssueType.BEST_PRACTICES, + 'PyFromFutureImportInspection': IssueType.BEST_PRACTICES, + 'PyReturnFromInitInspection': IssueType.BEST_PRACTICES, + 'PyListCreationInspection': IssueType.BEST_PRACTICES, + 'PySetFunctionToLiteralInspection': IssueType.BEST_PRACTICES, + 'PyProtectedMemberInspection': IssueType.BEST_PRACTICES, + 'PyMethodMayBeStaticInspection': IssueType.BEST_PRACTICES, + 'PyChainedComparisonsInspection': IssueType.BEST_PRACTICES, + 'PyGlobalUndefinedInspection': IssueType.BEST_PRACTICES, + 'PyComparisonWithNoneInspection': IssueType.BEST_PRACTICES, + 'PyShadowingNamesInspection': IssueType.BEST_PRACTICES, + + # CODE_STYLE + 'PyRedundantParenthesesInspection': IssueType.CODE_STYLE, + 'PyAugmentAssignmentInspection': IssueType.CODE_STYLE, + 'PyMethodParametersInspection': IssueType.CODE_STYLE, + 'PyUnreachableCodeInspection': IssueType.CODE_STYLE, + 'PyTrailingSemicolonInspection': IssueType.CODE_STYLE, + 'PyStatementEffectInspection': IssueType.CODE_STYLE, + 'PyPep8NamingInspection': IssueType.CODE_STYLE, + 'PyPep8Inspection': IssueType.CODE_STYLE, + + # ERROR_PRONE + 'PyDataclassInspection': IssueType.ERROR_PRONE, + 'PyDefaultArgumentInspection': IssueType.ERROR_PRONE, + 'PyAssignmentToLoopOrWithParameterInspection': IssueType.ERROR_PRONE, + 'PyAsyncCallInspection': IssueType.ERROR_PRONE, + 'PyByteLiteralInspection': IssueType.ERROR_PRONE, + 'PyCallingNonCallableInspection': IssueType.ERROR_PRONE, + 'PyDictDuplicateKeysInspection': IssueType.ERROR_PRONE, + 'PyExceptClausesOrderInspection': IssueType.ERROR_PRONE, + 'PyFinalInspection': IssueType.ERROR_PRONE, + 'PyArgumentListInspection': IssueType.ERROR_PRONE, + 'PyMethodFirstArgAssignmentInspection': IssueType.ERROR_PRONE, + 'PyStringFormatInspection': IssueType.ERROR_PRONE, + 'PyMethodOverridingInspection': IssueType.ERROR_PRONE, + 'PyTupleAssignmentBalanceInspection': IssueType.ERROR_PRONE, + 'PyExceptionInheritInspection': IssueType.ERROR_PRONE, + 'PyUnboundLocalVariableInspection': IssueType.ERROR_PRONE, + 'PySuperArgumentsInspection': IssueType.ERROR_PRONE, + 'PyTupleItemAssignmentInspection': IssueType.ERROR_PRONE, + 'PyPropertyAccessInspection': IssueType.ERROR_PRONE, + 'PyNestedDecoratorsInspection': IssueType.ERROR_PRONE, + 'PyMissingConstructorInspection': IssueType.ERROR_PRONE, + 'PyDecoratorInspection': IssueType.ERROR_PRONE, + 'PyTypeCheckerInspection': IssueType.ERROR_PRONE, + 'PyNoneFunctionAssignmentInspection': IssueType.ERROR_PRONE, + 'PyAbstractClassInspection': IssueType.ERROR_PRONE, + 'PyOverloadsInspection': IssueType.ERROR_PRONE, + 'PyTypeHintsInspection': IssueType.ERROR_PRONE, + 'PyTypedDictInspection': IssueType.ERROR_PRONE, + 'PyShadowingBuiltinsInspection': IssueType.ERROR_PRONE, + 'PyUnresolvedReferencesInspection': IssueType.ERROR_PRONE, +} + +IJ_MESSAGE_TO_ISSUE_TYPE = { + 'PyDataclassInspection': { + 'is useless until ''__post_init__'' is declared': IssueType.BEST_PRACTICES, + 'should take all init-only variables (incl. inherited) in the same order as they are defined': + IssueType.BEST_PRACTICES, + 'would not be called until \'init\' parameter is set to True \'__attrs_post_init__\' ' + 'should not take any parameters except \'self\'': IssueType.BEST_PRACTICES, + }, + 'PyFinalInspection': { + 'No need to mark method in \'Final\' class as \'@final\'': IssueType.BEST_PRACTICES, + }, +} diff --git a/hyperstyle/src/python/review/inspectors/pmd/files/config.xml b/hyperstyle/src/python/review/inspectors/pmd/files/config.xml index abf91677..4961705f 100644 --- a/hyperstyle/src/python/review/inspectors/pmd/files/config.xml +++ b/hyperstyle/src/python/review/inspectors/pmd/files/config.xml @@ -9,7 +9,8 @@ The Basic ruleset contains a collection of good practices which should be followed. - + + diff --git a/hyperstyle/src/python/review/inspectors/pmd/issue_types.py b/hyperstyle/src/python/review/inspectors/pmd/issue_types.py index e505acab..856150ae 100644 --- a/hyperstyle/src/python/review/inspectors/pmd/issue_types.py +++ b/hyperstyle/src/python/review/inspectors/pmd/issue_types.py @@ -1,6 +1,6 @@ from typing import Dict -from hyperstyle.src.python.review.inspectors.issue import IssueType +from hyperstyle.src.python.review.inspectors.common.issue.issue import IssueType PMD_RULE_TO_ISSUE_TYPE: Dict[str, IssueType] = { # ---- Best Practices ---- diff --git a/hyperstyle/src/python/review/inspectors/pmd/pmd.py b/hyperstyle/src/python/review/inspectors/pmd/pmd.py index 3c1b6d72..104d4aeb 100644 --- a/hyperstyle/src/python/review/inspectors/pmd/pmd.py +++ b/hyperstyle/src/python/review/inspectors/pmd/pmd.py @@ -7,12 +7,11 @@ from hyperstyle.src.python.review.common.file_system import check_set_up_env_variable, new_temp_dir from hyperstyle.src.python.review.common.language_version import LanguageVersion from hyperstyle.src.python.review.common.subprocess_runner import run_in_subprocess -from hyperstyle.src.python.review.inspectors.base_inspector import BaseInspector -from hyperstyle.src.python.review.inspectors.common.base_issue_converter import convert_base_issue -from hyperstyle.src.python.review.inspectors.common.utils import remove_prefix -from hyperstyle.src.python.review.inspectors.inspector_type import InspectorType -from hyperstyle.src.python.review.inspectors.issue import BaseIssue, IssueDifficulty, IssueType -from hyperstyle.src.python.review.inspectors.issue_configs import IssueConfigsHandler +from hyperstyle.src.python.review.inspectors.common.inspector.base_inspector import BaseInspector +from hyperstyle.src.python.review.inspectors.common.issue.base_issue_converter import convert_base_issue +from hyperstyle.src.python.review.inspectors.common.inspector.inspector_type import InspectorType +from hyperstyle.src.python.review.inspectors.common.issue.issue import BaseIssue, IssueDifficulty, IssueType +from hyperstyle.src.python.review.inspectors.common.issue.issue_configs import IssueConfigsHandler from hyperstyle.src.python.review.inspectors.pmd.issue_configs import ISSUE_CONFIGS from hyperstyle.src.python.review.inspectors.pmd.issue_types import PMD_RULE_TO_ISSUE_TYPE @@ -138,4 +137,4 @@ def _get_java_version(language_version: LanguageVersion) -> str: ) java_version = DEFAULT_JAVA_VERSION.value - return remove_prefix(java_version, "java") + return java_version.removeprefix('java') diff --git a/hyperstyle/src/python/review/inspectors/pyast/python_ast.py b/hyperstyle/src/python/review/inspectors/pyast/python_ast.py index 5f7d5790..1a473d05 100644 --- a/hyperstyle/src/python/review/inspectors/pyast/python_ast.py +++ b/hyperstyle/src/python/review/inspectors/pyast/python_ast.py @@ -6,10 +6,10 @@ from hyperstyle.src.python.review.common import language from hyperstyle.src.python.review.common.file_system import get_all_file_system_items from hyperstyle.src.python.review.common.language import Language -from hyperstyle.src.python.review.inspectors.base_inspector import BaseInspector -from hyperstyle.src.python.review.inspectors.common.tips import get_bool_expr_len_tip, get_func_len_tip -from hyperstyle.src.python.review.inspectors.inspector_type import InspectorType -from hyperstyle.src.python.review.inspectors.issue import ( +from hyperstyle.src.python.review.inspectors.common.inspector.base_inspector import BaseInspector +from hyperstyle.src.python.review.inspectors.common.issue.tips import get_bool_expr_len_tip, get_func_len_tip +from hyperstyle.src.python.review.inspectors.common.inspector.inspector_type import InspectorType +from hyperstyle.src.python.review.inspectors.common.issue.issue import ( BaseIssue, BoolExprLenIssue, FuncLenIssue, IssueDifficulty, IssueType, ) diff --git a/hyperstyle/src/python/review/inspectors/pylint/issue_configs.py b/hyperstyle/src/python/review/inspectors/pylint/issue_configs.py index 58604ae6..e95a5e8b 100644 --- a/hyperstyle/src/python/review/inspectors/pylint/issue_configs.py +++ b/hyperstyle/src/python/review/inspectors/pylint/issue_configs.py @@ -1,4 +1,4 @@ -from hyperstyle.src.python.review.inspectors.issue_configs import IssueConfig +from hyperstyle.src.python.review.inspectors.common.issue.issue_configs import IssueConfig ISSUE_CONFIGS = [ IssueConfig( diff --git a/hyperstyle/src/python/review/inspectors/pylint/issue_types.py b/hyperstyle/src/python/review/inspectors/pylint/issue_types.py index 5375532d..540359e8 100644 --- a/hyperstyle/src/python/review/inspectors/pylint/issue_types.py +++ b/hyperstyle/src/python/review/inspectors/pylint/issue_types.py @@ -1,6 +1,6 @@ from typing import Dict -from hyperstyle.src.python.review.inspectors.issue import IssueType +from hyperstyle.src.python.review.inspectors.common.issue.issue import IssueType CODE_TO_ISSUE_TYPE: Dict[str, IssueType] = { # Basic checker diff --git a/hyperstyle/src/python/review/inspectors/pylint/pylint.py b/hyperstyle/src/python/review/inspectors/pylint/pylint.py index 3c09cdec..476cef1e 100644 --- a/hyperstyle/src/python/review/inspectors/pylint/pylint.py +++ b/hyperstyle/src/python/review/inspectors/pylint/pylint.py @@ -1,14 +1,15 @@ import logging import re +import sys from pathlib import Path from typing import Any, Dict, List, Optional from hyperstyle.src.python.review.common.subprocess_runner import run_in_subprocess -from hyperstyle.src.python.review.inspectors.base_inspector import BaseInspector -from hyperstyle.src.python.review.inspectors.common.base_issue_converter import convert_base_issue -from hyperstyle.src.python.review.inspectors.inspector_type import InspectorType -from hyperstyle.src.python.review.inspectors.issue import BaseIssue, IssueDifficulty, IssueType -from hyperstyle.src.python.review.inspectors.issue_configs import IssueConfigsHandler +from hyperstyle.src.python.review.inspectors.common.inspector.base_inspector import BaseInspector +from hyperstyle.src.python.review.inspectors.common.issue.base_issue_converter import convert_base_issue +from hyperstyle.src.python.review.inspectors.common.inspector.inspector_type import InspectorType +from hyperstyle.src.python.review.inspectors.common.issue.issue import BaseIssue, IssueDifficulty, IssueType +from hyperstyle.src.python.review.inspectors.common.issue.issue_configs import IssueConfigsHandler from hyperstyle.src.python.review.inspectors.pylint.issue_configs import ISSUE_CONFIGS from hyperstyle.src.python.review.inspectors.pylint.issue_types import CATEGORY_TO_ISSUE_TYPE, CODE_TO_ISSUE_TYPE @@ -21,6 +22,7 @@ INFO_CATEGORY = 'I' BASE_COMMAND = [ + sys.executable, '-m', 'pylint', '--load-plugins', 'pylint_django', # TODO: ask about django settings via an cli argument? diff --git a/hyperstyle/src/python/review/inspectors/radon/radon.py b/hyperstyle/src/python/review/inspectors/radon/radon.py index c7b010c5..aef101ab 100644 --- a/hyperstyle/src/python/review/inspectors/radon/radon.py +++ b/hyperstyle/src/python/review/inspectors/radon/radon.py @@ -1,13 +1,14 @@ import re +import sys from pathlib import Path from typing import Any, Dict, List from hyperstyle.src.python.review.common.subprocess_runner import run_in_subprocess -from hyperstyle.src.python.review.inspectors.base_inspector import BaseInspector -from hyperstyle.src.python.review.inspectors.common.tips import get_maintainability_index_tip +from hyperstyle.src.python.review.inspectors.common.inspector.base_inspector import BaseInspector +from hyperstyle.src.python.review.inspectors.common.issue.tips import get_maintainability_index_tip from hyperstyle.src.python.review.inspectors.common.utils import convert_percentage_of_value_to_lack_of_value -from hyperstyle.src.python.review.inspectors.inspector_type import InspectorType -from hyperstyle.src.python.review.inspectors.issue import ( +from hyperstyle.src.python.review.inspectors.common.inspector.inspector_type import InspectorType +from hyperstyle.src.python.review.inspectors.common.issue.issue import ( BaseIssue, IssueData, IssueDifficulty, @@ -30,6 +31,7 @@ def inspect_in_memory(cls, code: str, config: Dict[str, Any]) -> List[BaseIssue] @classmethod def inspect(cls, path: Path, config: Dict[str, Any]) -> List[BaseIssue]: mi_command = [ + sys.executable, '-m', 'radon', 'mi', # compute the Maintainability Index score '--max', 'F', # set the maximum MI rank to display '--show', # actual MI value is shown in results, alongside the rank diff --git a/hyperstyle/src/python/review/quality/evaluate_quality.py b/hyperstyle/src/python/review/quality/evaluate_quality.py index 100a92dc..1b5e609b 100644 --- a/hyperstyle/src/python/review/quality/evaluate_quality.py +++ b/hyperstyle/src/python/review/quality/evaluate_quality.py @@ -1,7 +1,7 @@ from typing import List from hyperstyle.src.python.review.common.language import Language -from hyperstyle.src.python.review.inspectors.issue import IssueType +from hyperstyle.src.python.review.inspectors.common.issue.issue import IssueType from hyperstyle.src.python.review.quality.model import Quality, Rule from hyperstyle.src.python.review.quality.rules.best_practices_scoring import ( BestPracticesRule, diff --git a/hyperstyle/src/python/review/quality/model.py b/hyperstyle/src/python/review/quality/model.py index ca0f40b1..639cbbb4 100644 --- a/hyperstyle/src/python/review/quality/model.py +++ b/hyperstyle/src/python/review/quality/model.py @@ -4,7 +4,7 @@ from functools import total_ordering from typing import List -from hyperstyle.src.python.review.inspectors.issue import IssueType +from hyperstyle.src.python.review.inspectors.common.issue.issue import IssueType @total_ordering diff --git a/hyperstyle/src/python/review/quality/penalty.py b/hyperstyle/src/python/review/quality/penalty.py index 2add2917..eea08063 100644 --- a/hyperstyle/src/python/review/quality/penalty.py +++ b/hyperstyle/src/python/review/quality/penalty.py @@ -3,7 +3,7 @@ from typing import Dict, List, Optional, Set from hyperstyle.src.python.review.common.language import Language -from hyperstyle.src.python.review.inspectors.issue import BaseIssue, IssueType +from hyperstyle.src.python.review.inspectors.common.issue.issue import BaseIssue, IssueType from hyperstyle.src.python.review.quality.model import QualityType diff --git a/hyperstyle/src/python/review/quality/rules/best_practices_scoring.py b/hyperstyle/src/python/review/quality/rules/best_practices_scoring.py index 1d3ce256..81bed025 100644 --- a/hyperstyle/src/python/review/quality/rules/best_practices_scoring.py +++ b/hyperstyle/src/python/review/quality/rules/best_practices_scoring.py @@ -2,7 +2,7 @@ from typing import Optional from hyperstyle.src.python.review.common.language import Language -from hyperstyle.src.python.review.inspectors.issue import IssueType +from hyperstyle.src.python.review.inspectors.common.issue.issue import IssueType from hyperstyle.src.python.review.quality.model import QualityType, Rule diff --git a/hyperstyle/src/python/review/quality/rules/boolean_length_scoring.py b/hyperstyle/src/python/review/quality/rules/boolean_length_scoring.py index cf685962..c8d49a55 100644 --- a/hyperstyle/src/python/review/quality/rules/boolean_length_scoring.py +++ b/hyperstyle/src/python/review/quality/rules/boolean_length_scoring.py @@ -2,7 +2,7 @@ from typing import Optional from hyperstyle.src.python.review.common.language import Language -from hyperstyle.src.python.review.inspectors.issue import IssueType +from hyperstyle.src.python.review.inspectors.common.issue.issue import IssueType from hyperstyle.src.python.review.quality.model import QualityType, Rule diff --git a/hyperstyle/src/python/review/quality/rules/class_response_scoring.py b/hyperstyle/src/python/review/quality/rules/class_response_scoring.py index a33d60c2..0956886d 100644 --- a/hyperstyle/src/python/review/quality/rules/class_response_scoring.py +++ b/hyperstyle/src/python/review/quality/rules/class_response_scoring.py @@ -2,7 +2,7 @@ from typing import Optional from hyperstyle.src.python.review.common.language import Language -from hyperstyle.src.python.review.inspectors.issue import IssueType +from hyperstyle.src.python.review.inspectors.common.issue.issue import IssueType from hyperstyle.src.python.review.quality.model import QualityType, Rule diff --git a/hyperstyle/src/python/review/quality/rules/code_style_scoring.py b/hyperstyle/src/python/review/quality/rules/code_style_scoring.py index be450212..20d92b88 100644 --- a/hyperstyle/src/python/review/quality/rules/code_style_scoring.py +++ b/hyperstyle/src/python/review/quality/rules/code_style_scoring.py @@ -1,7 +1,7 @@ from dataclasses import dataclass from hyperstyle.src.python.review.common.language import Language -from hyperstyle.src.python.review.inspectors.issue import IssueType +from hyperstyle.src.python.review.inspectors.common.issue.issue import IssueType from hyperstyle.src.python.review.quality.model import QualityType, Rule diff --git a/hyperstyle/src/python/review/quality/rules/cohesion_scoring.py b/hyperstyle/src/python/review/quality/rules/cohesion_scoring.py index 541ac226..2e64fa31 100644 --- a/hyperstyle/src/python/review/quality/rules/cohesion_scoring.py +++ b/hyperstyle/src/python/review/quality/rules/cohesion_scoring.py @@ -2,7 +2,7 @@ from typing import Optional from hyperstyle.src.python.review.common.language import Language -from hyperstyle.src.python.review.inspectors.issue import IssueType +from hyperstyle.src.python.review.inspectors.common.issue.issue import IssueType from hyperstyle.src.python.review.quality.model import QualityType, Rule diff --git a/hyperstyle/src/python/review/quality/rules/complexity_scoring.py b/hyperstyle/src/python/review/quality/rules/complexity_scoring.py index a8a6aa6d..95080a7e 100644 --- a/hyperstyle/src/python/review/quality/rules/complexity_scoring.py +++ b/hyperstyle/src/python/review/quality/rules/complexity_scoring.py @@ -2,7 +2,7 @@ from typing import Optional from hyperstyle.src.python.review.common.language import Language -from hyperstyle.src.python.review.inspectors.issue import IssueType +from hyperstyle.src.python.review.inspectors.common.issue.issue import IssueType from hyperstyle.src.python.review.quality.model import QualityType, Rule diff --git a/hyperstyle/src/python/review/quality/rules/coupling_scoring.py b/hyperstyle/src/python/review/quality/rules/coupling_scoring.py index 552dc1c6..77771a0f 100644 --- a/hyperstyle/src/python/review/quality/rules/coupling_scoring.py +++ b/hyperstyle/src/python/review/quality/rules/coupling_scoring.py @@ -2,7 +2,7 @@ from typing import Optional from hyperstyle.src.python.review.common.language import Language -from hyperstyle.src.python.review.inspectors.issue import IssueType +from hyperstyle.src.python.review.inspectors.common.issue.issue import IssueType from hyperstyle.src.python.review.quality.model import QualityType, Rule diff --git a/hyperstyle/src/python/review/quality/rules/cyclomatic_complexity_scoring.py b/hyperstyle/src/python/review/quality/rules/cyclomatic_complexity_scoring.py index b3dc8d75..be939d85 100644 --- a/hyperstyle/src/python/review/quality/rules/cyclomatic_complexity_scoring.py +++ b/hyperstyle/src/python/review/quality/rules/cyclomatic_complexity_scoring.py @@ -2,7 +2,7 @@ from typing import Optional from hyperstyle.src.python.review.common.language import Language -from hyperstyle.src.python.review.inspectors.issue import IssueType +from hyperstyle.src.python.review.inspectors.common.issue.issue import IssueType from hyperstyle.src.python.review.quality.model import QualityType, Rule diff --git a/hyperstyle/src/python/review/quality/rules/error_prone_scoring.py b/hyperstyle/src/python/review/quality/rules/error_prone_scoring.py index d7549633..b7034cd4 100644 --- a/hyperstyle/src/python/review/quality/rules/error_prone_scoring.py +++ b/hyperstyle/src/python/review/quality/rules/error_prone_scoring.py @@ -2,7 +2,7 @@ from typing import Optional from hyperstyle.src.python.review.common.language import Language -from hyperstyle.src.python.review.inspectors.issue import IssueType +from hyperstyle.src.python.review.inspectors.common.issue.issue import IssueType from hyperstyle.src.python.review.quality.model import QualityType, Rule diff --git a/hyperstyle/src/python/review/quality/rules/function_length_scoring.py b/hyperstyle/src/python/review/quality/rules/function_length_scoring.py index e303f7ba..cff285e7 100644 --- a/hyperstyle/src/python/review/quality/rules/function_length_scoring.py +++ b/hyperstyle/src/python/review/quality/rules/function_length_scoring.py @@ -2,7 +2,7 @@ from typing import Optional from hyperstyle.src.python.review.common.language import Language -from hyperstyle.src.python.review.inspectors.issue import IssueType +from hyperstyle.src.python.review.inspectors.common.issue.issue import IssueType from hyperstyle.src.python.review.quality.model import QualityType, Rule diff --git a/hyperstyle/src/python/review/quality/rules/inheritance_depth_scoring.py b/hyperstyle/src/python/review/quality/rules/inheritance_depth_scoring.py index 4c52daf7..3da80633 100644 --- a/hyperstyle/src/python/review/quality/rules/inheritance_depth_scoring.py +++ b/hyperstyle/src/python/review/quality/rules/inheritance_depth_scoring.py @@ -2,7 +2,7 @@ from typing import Optional from hyperstyle.src.python.review.common.language import Language -from hyperstyle.src.python.review.inspectors.issue import IssueType +from hyperstyle.src.python.review.inspectors.common.issue.issue import IssueType from hyperstyle.src.python.review.quality.model import QualityType, Rule diff --git a/hyperstyle/src/python/review/quality/rules/line_len_scoring.py b/hyperstyle/src/python/review/quality/rules/line_len_scoring.py index fee4e186..8aa30362 100644 --- a/hyperstyle/src/python/review/quality/rules/line_len_scoring.py +++ b/hyperstyle/src/python/review/quality/rules/line_len_scoring.py @@ -1,7 +1,7 @@ from dataclasses import dataclass from hyperstyle.src.python.review.common.language import Language -from hyperstyle.src.python.review.inspectors.issue import IssueType +from hyperstyle.src.python.review.inspectors.common.issue.issue import IssueType from hyperstyle.src.python.review.quality.model import QualityType, Rule diff --git a/hyperstyle/src/python/review/quality/rules/maintainability_scoring.py b/hyperstyle/src/python/review/quality/rules/maintainability_scoring.py index 7ec8e1ef..16fd1cb1 100644 --- a/hyperstyle/src/python/review/quality/rules/maintainability_scoring.py +++ b/hyperstyle/src/python/review/quality/rules/maintainability_scoring.py @@ -2,7 +2,7 @@ from typing import Optional from hyperstyle.src.python.review.common.language import Language -from hyperstyle.src.python.review.inspectors.issue import IssueType +from hyperstyle.src.python.review.inspectors.common.issue.issue import IssueType from hyperstyle.src.python.review.quality.model import QualityType, Rule diff --git a/hyperstyle/src/python/review/quality/rules/method_number_scoring.py b/hyperstyle/src/python/review/quality/rules/method_number_scoring.py index e0da86ec..669f1bb9 100644 --- a/hyperstyle/src/python/review/quality/rules/method_number_scoring.py +++ b/hyperstyle/src/python/review/quality/rules/method_number_scoring.py @@ -2,7 +2,7 @@ from typing import Optional from hyperstyle.src.python.review.common.language import Language -from hyperstyle.src.python.review.inspectors.issue import IssueType +from hyperstyle.src.python.review.inspectors.common.issue.issue import IssueType from hyperstyle.src.python.review.quality.model import QualityType, Rule diff --git a/hyperstyle/src/python/review/quality/rules/weighted_methods_scoring.py b/hyperstyle/src/python/review/quality/rules/weighted_methods_scoring.py index 34ae03d9..1d01d623 100644 --- a/hyperstyle/src/python/review/quality/rules/weighted_methods_scoring.py +++ b/hyperstyle/src/python/review/quality/rules/weighted_methods_scoring.py @@ -2,7 +2,7 @@ from typing import Optional from hyperstyle.src.python.review.common.language import Language -from hyperstyle.src.python.review.inspectors.issue import IssueType +from hyperstyle.src.python.review.inspectors.common.issue.issue import IssueType from hyperstyle.src.python.review.quality.model import QualityType, Rule diff --git a/hyperstyle/src/python/review/reviewers/common.py b/hyperstyle/src/python/review/reviewers/common.py index fbe616fa..a2a28a52 100644 --- a/hyperstyle/src/python/review/reviewers/common.py +++ b/hyperstyle/src/python/review/reviewers/common.py @@ -1,3 +1,5 @@ +import json +import logging from collections import defaultdict from typing import List, Optional @@ -9,11 +11,14 @@ run_inspector_in_memory, ) from hyperstyle.src.python.review.inspectors.checkstyle.checkstyle import CheckstyleInspector +from hyperstyle.src.python.review.inspectors.common.inspector.base_inspector import BaseIJInspector from hyperstyle.src.python.review.inspectors.detekt.detekt import DetektInspector from hyperstyle.src.python.review.inspectors.eslint.eslint import ESLintInspector from hyperstyle.src.python.review.inspectors.flake8.flake8 import Flake8Inspector from hyperstyle.src.python.review.inspectors.golang_lint.golang_lint import GolangLintInspector -from hyperstyle.src.python.review.inspectors.issue import BaseIssue +from hyperstyle.src.python.review.inspectors.ij_kotlin.ij_kotlin import KotlinIJInspector +from hyperstyle.src.python.review.inspectors.ij_python.ij_python import PythonIJInspector +from hyperstyle.src.python.review.inspectors.common.issue.issue import BaseIssue from hyperstyle.src.python.review.inspectors.pmd.pmd import PMDInspector from hyperstyle.src.python.review.inspectors.pyast.python_ast import PythonAstInspector from hyperstyle.src.python.review.inspectors.pylint.pylint import PylintInspector @@ -41,6 +46,7 @@ Flake8Inspector(), PythonAstInspector(), RadonInspector(), + PythonIJInspector(), ], Language.JAVA: [ CheckstyleInspector(), @@ -48,6 +54,7 @@ ], Language.KOTLIN: [ DetektInspector(), + KotlinIJInspector(), ], Language.JS: [ ESLintInspector(), @@ -60,8 +67,31 @@ def _inspect_code(metadata: Metadata, config: ApplicationConfig, language: Language) -> Optional[List[BaseIssue]]: inspectors = LANGUAGE_TO_INSPECTORS[language] + ij_inspectors = list( + filter( + lambda inspector: isinstance(inspector, BaseIJInspector) + and inspector.inspector_type not in config.disabled_inspectors, + inspectors, + ), + ) + + connection_parameters = ( + None if config.ij_config is None else json.loads(config.ij_config).get(language.value.lower()) + ) + if ij_inspectors and connection_parameters is None: + logging.warning( + f'IJ inspectors for the {language.value} will be disabled ' + f'as the IJ config for this language was not specified.', + ) + + config.disabled_inspectors.update(map(lambda inspector: inspector.inspector_type, ij_inspectors)) + else: + for inspector in ij_inspectors: + inspector.setup_connection_parameters(connection_parameters['host'], connection_parameters['port']) + if isinstance(metadata, InMemoryMetadata): return inspect_in_parallel(run_inspector_in_memory, metadata.code, config, inspectors) + return inspect_in_parallel(run_inspector, metadata.path, config, inspectors) @@ -100,9 +130,7 @@ def perform_language_review(metadata: Metadata, config: ApplicationConfig, langu difficulty: Punisher(issues, previous_issues) for difficulty, issues in issues_by_difficulty.items() } - general_quality_by_difficulty = { - difficulty: Quality([]) for difficulty in issues_by_difficulty.keys() - } + general_quality_by_difficulty = {difficulty: Quality([]) for difficulty in issues_by_difficulty.keys()} file_review_results = [] for file in current_files: @@ -115,8 +143,10 @@ def perform_language_review(metadata: Metadata, config: ApplicationConfig, langu } for code_statistics in code_statistics_by_difficulty.values(): - code_statistics.total_lines = min(code_statistics.total_lines, - get_range_lines(config.start_line, config.end_line)) + code_statistics.total_lines = min( + code_statistics.total_lines, + get_range_lines(config.start_line, config.end_line), + ) punisher_by_difficulty = { difficulty: Punisher(file_issues, previous_issues) @@ -143,9 +173,11 @@ def perform_language_review(metadata: Metadata, config: ApplicationConfig, langu ) -def filter_out_of_range_issues(issues: List[BaseIssue], - start_line: int = 1, - end_line: Optional[int] = None) -> List[BaseIssue]: +def filter_out_of_range_issues( + issues: List[BaseIssue], + start_line: int = 1, + end_line: Optional[int] = None, +) -> List[BaseIssue]: if end_line is None: end_line = 100_000_000 diff --git a/hyperstyle/src/python/review/reviewers/perform_review.py b/hyperstyle/src/python/review/reviewers/perform_review.py index 025ca409..cb2ccf91 100644 --- a/hyperstyle/src/python/review/reviewers/perform_review.py +++ b/hyperstyle/src/python/review/reviewers/perform_review.py @@ -6,7 +6,7 @@ from hyperstyle.src.python.review.application_config import ApplicationConfig from hyperstyle.src.python.review.common.language import Language -from hyperstyle.src.python.review.inspectors.issue import IssueType +from hyperstyle.src.python.review.inspectors.common.issue.issue import IssueType from hyperstyle.src.python.review.reviewers.common import perform_language_review from hyperstyle.src.python.review.reviewers.go import perform_go_review from hyperstyle.src.python.review.reviewers.python import perform_python_review diff --git a/hyperstyle/src/python/review/reviewers/review_result.py b/hyperstyle/src/python/review/reviewers/review_result.py index 8c934008..eac03aaa 100644 --- a/hyperstyle/src/python/review/reviewers/review_result.py +++ b/hyperstyle/src/python/review/reviewers/review_result.py @@ -2,7 +2,7 @@ from pathlib import Path from typing import Dict, List -from hyperstyle.src.python.review.inspectors.issue import BaseIssue, IssueDifficulty +from hyperstyle.src.python.review.inspectors.common.issue.issue import BaseIssue, IssueDifficulty from hyperstyle.src.python.review.quality.model import Quality from hyperstyle.src.python.review.quality.penalty import Punisher diff --git a/hyperstyle/src/python/review/reviewers/utils/code_statistics.py b/hyperstyle/src/python/review/reviewers/utils/code_statistics.py index 7e9c5a8c..074027b5 100644 --- a/hyperstyle/src/python/review/reviewers/utils/code_statistics.py +++ b/hyperstyle/src/python/review/reviewers/utils/code_statistics.py @@ -4,7 +4,7 @@ from typing import Dict, List from hyperstyle.src.python.review.common.file_system import get_total_code_lines_from_file -from hyperstyle.src.python.review.inspectors.issue import BaseIssue, IssueType +from hyperstyle.src.python.review.inspectors.common.issue.issue import BaseIssue, IssueType @dataclass diff --git a/hyperstyle/src/python/review/reviewers/utils/issues_filter.py b/hyperstyle/src/python/review/reviewers/utils/issues_filter.py index 5acd4517..1e235ff8 100644 --- a/hyperstyle/src/python/review/reviewers/utils/issues_filter.py +++ b/hyperstyle/src/python/review/reviewers/utils/issues_filter.py @@ -2,7 +2,7 @@ from typing import Dict, List, Tuple from hyperstyle.src.python.review.common.language import Language -from hyperstyle.src.python.review.inspectors.issue import BaseIssue, IssueDifficulty, IssueType, Measurable +from hyperstyle.src.python.review.inspectors.common.issue.issue import BaseIssue, IssueDifficulty, IssueType, Measurable from hyperstyle.src.python.review.quality.rules.boolean_length_scoring import LANGUAGE_TO_BOOLEAN_EXPRESSION_RULE_CONFIG from hyperstyle.src.python.review.quality.rules.class_response_scoring import LANGUAGE_TO_RESPONSE_RULE_CONFIG from hyperstyle.src.python.review.quality.rules.cohesion_scoring import LANGUAGE_TO_COHESION_RULE_CONFIG diff --git a/hyperstyle/src/python/review/reviewers/utils/print_review.py b/hyperstyle/src/python/review/reviewers/utils/print_review.py index b0776163..bfffbf8f 100644 --- a/hyperstyle/src/python/review/reviewers/utils/print_review.py +++ b/hyperstyle/src/python/review/reviewers/utils/print_review.py @@ -6,8 +6,8 @@ from hyperstyle.src.python.review.application_config import ApplicationConfig from hyperstyle.src.python.review.common.file_system import get_file_line -from hyperstyle.src.python.review.inspectors.inspector_type import InspectorType -from hyperstyle.src.python.review.inspectors.issue import BaseIssue, IssueDifficulty, IssueType +from hyperstyle.src.python.review.inspectors.common.inspector.inspector_type import InspectorType +from hyperstyle.src.python.review.inspectors.common.issue.issue import BaseIssue, IssueDifficulty, IssueType from hyperstyle.src.python.review.quality.model import QualityType from hyperstyle.src.python.review.quality.penalty import PenaltyIssue from hyperstyle.src.python.review.reviewers.review_result import FileReviewResult, GeneralReviewResult, ReviewResult diff --git a/hyperstyle/src/python/review/run_tool.py b/hyperstyle/src/python/review/run_tool.py index 613ed1b0..ce7408e0 100644 --- a/hyperstyle/src/python/review/run_tool.py +++ b/hyperstyle/src/python/review/run_tool.py @@ -14,7 +14,7 @@ from hyperstyle.src.python.review.application_config import ApplicationConfig from hyperstyle.src.python.review.common.language import Language from hyperstyle.src.python.review.common.language_version import LanguageVersion -from hyperstyle.src.python.review.inspectors.inspector_type import InspectorType +from hyperstyle.src.python.review.inspectors.common.inspector.inspector_type import InspectorType from hyperstyle.src.python.review.logging_config import logging_config from hyperstyle.src.python.review.reviewers.perform_review import ( OutputFormat, @@ -28,10 +28,6 @@ def parse_disabled_inspectors(value: str) -> Set[InspectorType]: passed_names = value.upper().split(',') - # TODO: delete it after updating the run configuration in production - intellij_key_word = 'intellij'.upper() - if intellij_key_word in passed_names: - passed_names.remove(intellij_key_word) allowed_names = {inspector.value for inspector in InspectorType} if not all(name in allowed_names for name in passed_names): raise argparse.ArgumentError('disable', 'Incorrect inspectors\' names') @@ -55,7 +51,7 @@ def configure_arguments(parser: argparse.ArgumentParser) -> None: choices=VerbosityLevel.values(), type=int) - # Usage example: -d Flake8,Intelli + # Usage example: -d Flake8,IntelliJ parser.add_argument(RunToolArgument.DISABLE.value.short_name, RunToolArgument.DISABLE.value.long_name, help=RunToolArgument.DISABLE.value.description, @@ -126,6 +122,10 @@ def configure_arguments(parser: argparse.ArgumentParser) -> None: help=RunToolArgument.GROUP_BY_DIFFICULTY.value.description, action='store_true') + parser.add_argument(RunToolArgument.IJ_CONFIG.value.long_name, + help=RunToolArgument.IJ_CONFIG.value.description, + type=str) + def configure_logging(verbosity: VerbosityLevel) -> None: if verbosity is VerbosityLevel.ERROR: @@ -173,6 +173,7 @@ def main() -> int: history=args.history, with_all_categories=args.with_all_categories, group_by_difficulty=args.group_by_difficulty, + ij_config=args.ij_config, ) n_issues = perform_and_print_review(args.path, OutputFormat(args.format), config) diff --git a/poetry.lock b/poetry.lock new file mode 100644 index 00000000..4f59c863 --- /dev/null +++ b/poetry.lock @@ -0,0 +1,1393 @@ +# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. + +[[package]] +name = "argparse" +version = "1.4.0" +description = "Python command-line parsing library" +optional = false +python-versions = "*" +files = [ + {file = "argparse-1.4.0-py2.py3-none-any.whl", hash = "sha256:c31647edb69fd3d465a847ea3157d37bed1f95f19760b11a47aa91c04b666314"}, + {file = "argparse-1.4.0.tar.gz", hash = "sha256:62b089a55be1d8949cd2bc7e0df0bddb9e028faefc8c32038cc84862aefdd6e4"}, +] + +[[package]] +name = "asgiref" +version = "3.6.0" +description = "ASGI specs, helper code, and adapters" +optional = false +python-versions = ">=3.7" +files = [ + {file = "asgiref-3.6.0-py3-none-any.whl", hash = "sha256:71e68008da809b957b7ee4b43dbccff33d1b23519fb8344e33f049897077afac"}, + {file = "asgiref-3.6.0.tar.gz", hash = "sha256:9567dfe7bd8d3c8c892227827c41cce860b368104c3431da67a0c5a65a949506"}, +] + +[package.extras] +tests = ["mypy (>=0.800)", "pytest", "pytest-asyncio"] + +[[package]] +name = "astor" +version = "0.8.1" +description = "Read/rewrite/write Python ASTs" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" +files = [ + {file = "astor-0.8.1-py2.py3-none-any.whl", hash = "sha256:070a54e890cefb5b3739d19f30f5a5ec840ffc9c50ffa7d23cc9fc1a38ebbfc5"}, + {file = "astor-0.8.1.tar.gz", hash = "sha256:6a6effda93f4e1ce9f618779b2dd1d9d84f1e32812c23a29b3fff6fd7f63fa5e"}, +] + +[[package]] +name = "astroid" +version = "2.11.7" +description = "An abstract syntax tree for Python with inference support." +optional = false +python-versions = ">=3.6.2" +files = [ + {file = "astroid-2.11.7-py3-none-any.whl", hash = "sha256:86b0a340a512c65abf4368b80252754cda17c02cdbbd3f587dddf98112233e7b"}, + {file = "astroid-2.11.7.tar.gz", hash = "sha256:bb24615c77f4837c707669d16907331374ae8a964650a66999da3f5ca68dc946"}, +] + +[package.dependencies] +lazy-object-proxy = ">=1.4.0" +setuptools = ">=20.0" +wrapt = ">=1.11,<2" + +[[package]] +name = "attrs" +version = "24.2.0" +description = "Classes Without Boilerplate" +optional = false +python-versions = ">=3.7" +files = [ + {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, + {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, +] + +[package.extras] +benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] +tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] + +[[package]] +name = "certifi" +version = "2024.8.30" +description = "Python package for providing Mozilla's CA Bundle." +optional = false +python-versions = ">=3.6" +files = [ + {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, + {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, +] + +[[package]] +name = "charset-normalizer" +version = "3.3.2" +description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." +optional = false +python-versions = ">=3.7.0" +files = [ + {file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-win32.whl", hash = "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-win32.whl", hash = "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-win32.whl", hash = "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d"}, + {file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"}, +] + +[[package]] +name = "cohesion" +version = "1.0.0" +description = "A tool for measuring Python class cohesion." +optional = false +python-versions = "*" +files = [ + {file = "cohesion-1.0.0-py2.py3-none-any.whl", hash = "sha256:a33a526eb8922c7dbfef19257b3532d16e6246c4ece3ab3b492b290d9d3f2d4b"}, +] + +[[package]] +name = "colorama" +version = "0.4.6" +description = "Cross-platform colored terminal text." +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +files = [ + {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, + {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, +] + +[[package]] +name = "dataclasses-json" +version = "0.5.7" +description = "Easily serialize dataclasses to and from JSON" +optional = false +python-versions = ">=3.6" +files = [ + {file = "dataclasses-json-0.5.7.tar.gz", hash = "sha256:c2c11bc8214fbf709ffc369d11446ff6945254a7f09128154a7620613d8fda90"}, + {file = "dataclasses_json-0.5.7-py3-none-any.whl", hash = "sha256:bc285b5f892094c3a53d558858a88553dd6a61a11ab1a8128a0e554385dcc5dd"}, +] + +[package.dependencies] +marshmallow = ">=3.3.0,<4.0.0" +marshmallow-enum = ">=1.5.1,<2.0.0" +typing-inspect = ">=0.4.0" + +[package.extras] +dev = ["flake8", "hypothesis", "ipython", "mypy (>=0.710)", "portray", "pytest (>=6.2.3)", "simplejson", "types-dataclasses"] + +[[package]] +name = "dill" +version = "0.3.8" +description = "serialize all of Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "dill-0.3.8-py3-none-any.whl", hash = "sha256:c36ca9ffb54365bdd2f8eb3eff7d2a21237f8452b57ace88b1ac615b7e815bd7"}, + {file = "dill-0.3.8.tar.gz", hash = "sha256:3ebe3c479ad625c4553aca177444d89b486b1d84982eeacded644afc0cf797ca"}, +] + +[package.extras] +graph = ["objgraph (>=1.7.2)"] +profile = ["gprof2dot (>=2022.7.29)"] + +[[package]] +name = "django" +version = "4.2.5" +description = "A high-level Python web framework that encourages rapid development and clean, pragmatic design." +optional = false +python-versions = ">=3.8" +files = [ + {file = "Django-4.2.5-py3-none-any.whl", hash = "sha256:b6b2b5cae821077f137dc4dade696a1c2aa292f892eca28fa8d7bfdf2608ddd4"}, + {file = "Django-4.2.5.tar.gz", hash = "sha256:5e5c1c9548ffb7796b4a8a4782e9a2e5a3df3615259fc1bfd3ebc73b646146c1"}, +] + +[package.dependencies] +asgiref = ">=3.6.0,<4" +sqlparse = ">=0.3.1" +tzdata = {version = "*", markers = "sys_platform == \"win32\""} + +[package.extras] +argon2 = ["argon2-cffi (>=19.1.0)"] +bcrypt = ["bcrypt"] + +[[package]] +name = "eradicate" +version = "2.3.0" +description = "Removes commented-out code." +optional = false +python-versions = "*" +files = [ + {file = "eradicate-2.3.0-py3-none-any.whl", hash = "sha256:2b29b3dd27171f209e4ddd8204b70c02f0682ae95eecb353f10e8d72b149c63e"}, + {file = "eradicate-2.3.0.tar.gz", hash = "sha256:06df115be3b87d0fc1c483db22a2ebb12bcf40585722810d809cc770f5031c37"}, +] + +[[package]] +name = "exceptiongroup" +version = "1.2.2" +description = "Backport of PEP 654 (exception groups)" +optional = false +python-versions = ">=3.7" +files = [ + {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"}, + {file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"}, +] + +[package.extras] +test = ["pytest (>=6)"] + +[[package]] +name = "flake8" +version = "3.9.0" +description = "the modular source code checker: pep8 pyflakes and co" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" +files = [ + {file = "flake8-3.9.0-py2.py3-none-any.whl", hash = "sha256:12d05ab02614b6aee8df7c36b97d1a3b2372761222b19b58621355e82acddcff"}, + {file = "flake8-3.9.0.tar.gz", hash = "sha256:78873e372b12b093da7b5e5ed302e8ad9e988b38b063b61ad937f26ca58fc5f0"}, +] + +[package.dependencies] +mccabe = ">=0.6.0,<0.7.0" +pycodestyle = ">=2.7.0,<2.8.0" +pyflakes = ">=2.3.0,<2.4.0" + +[[package]] +name = "flake8-broken-line" +version = "0.3.0" +description = "Flake8 plugin to forbid backslashes for line breaks" +optional = false +python-versions = ">=3.6,<4.0" +files = [ + {file = "flake8-broken-line-0.3.0.tar.gz", hash = "sha256:f74e052833324a9e5f0055032f7ccc54b23faabafe5a26241c2f977e70b10b50"}, + {file = "flake8_broken_line-0.3.0-py3-none-any.whl", hash = "sha256:611f79c7f27118e7e5d3dc098ef7681c40aeadf23783700c5dbee840d2baf3af"}, +] + +[package.dependencies] +flake8 = ">=3.5,<4.0" + +[[package]] +name = "flake8-bugbear" +version = "21.4.3" +description = "A plugin for flake8 finding likely bugs and design problems in your program. Contains warnings that don't belong in pyflakes and pycodestyle." +optional = false +python-versions = ">=3.6" +files = [ + {file = "flake8-bugbear-21.4.3.tar.gz", hash = "sha256:2346c81f889955b39e4a368eb7d508de723d9de05716c287dc860a4073dc57e7"}, + {file = "flake8_bugbear-21.4.3-py36.py37.py38-none-any.whl", hash = "sha256:4f305dca96be62bf732a218fe6f1825472a621d3452c5b994d8f89dae21dbafa"}, +] + +[package.dependencies] +attrs = ">=19.2.0" +flake8 = ">=3.0.0" + +[package.extras] +dev = ["black", "coverage", "hypothesis", "hypothesmith"] + +[[package]] +name = "flake8-builtins" +version = "1.5.3" +description = "Check for python builtins being used as variables or parameters." +optional = false +python-versions = "*" +files = [ + {file = "flake8-builtins-1.5.3.tar.gz", hash = "sha256:09998853b2405e98e61d2ff3027c47033adbdc17f9fe44ca58443d876eb00f3b"}, + {file = "flake8_builtins-1.5.3-py2.py3-none-any.whl", hash = "sha256:7706babee43879320376861897e5d1468e396a40b8918ed7bccf70e5f90b8687"}, +] + +[package.dependencies] +flake8 = "*" + +[package.extras] +test = ["coverage", "coveralls", "mock", "pytest", "pytest-cov"] + +[[package]] +name = "flake8-commas" +version = "2.0.0" +description = "Flake8 lint for trailing commas." +optional = false +python-versions = "*" +files = [ + {file = "flake8-commas-2.0.0.tar.gz", hash = "sha256:d3005899466f51380387df7151fb59afec666a0f4f4a2c6a8995b975de0f44b7"}, + {file = "flake8_commas-2.0.0-py2.py3-none-any.whl", hash = "sha256:ee2141a3495ef9789a3894ed8802d03eff1eaaf98ce6d8653a7c573ef101935e"}, +] + +[package.dependencies] +flake8 = ">=2,<4.0.0" + +[[package]] +name = "flake8-comprehensions" +version = "3.4.0" +description = "A flake8 plugin to help you write better list/set/dict comprehensions." +optional = false +python-versions = ">=3.6" +files = [ + {file = "flake8-comprehensions-3.4.0.tar.gz", hash = "sha256:c00039be9f3959a26a98da3024f0fe809859bf1753ccb90e228cc40f3ac31ca7"}, + {file = "flake8_comprehensions-3.4.0-py3-none-any.whl", hash = "sha256:7258a28e229fb9a8d16370b9c47a7d66396ba0201abb06c9d11df41b18ed64c4"}, +] + +[package.dependencies] +flake8 = ">=3.0,<3.2.0 || >3.2.0,<4" + +[[package]] +name = "flake8-eradicate" +version = "1.0.0" +description = "Flake8 plugin to find commented out code" +optional = false +python-versions = ">=3.6,<4.0" +files = [ + {file = "flake8-eradicate-1.0.0.tar.gz", hash = "sha256:fe7167226676823d50cf540532302a6f576c5a398c5260692571a05ef72c5f5b"}, + {file = "flake8_eradicate-1.0.0-py3-none-any.whl", hash = "sha256:0fc4ab858a18c7ed630621b5345254c8f55be6060ea5c44a25e384d613618d1f"}, +] + +[package.dependencies] +attrs = "*" +eradicate = ">=2.0,<3.0" +flake8 = ">=3.5,<4.0" + +[[package]] +name = "flake8-import-order" +version = "0.18.1" +description = "Flake8 and pylama plugin that checks the ordering of import statements." +optional = false +python-versions = "*" +files = [ + {file = "flake8-import-order-0.18.1.tar.gz", hash = "sha256:a28dc39545ea4606c1ac3c24e9d05c849c6e5444a50fb7e9cdd430fc94de6e92"}, + {file = "flake8_import_order-0.18.1-py2.py3-none-any.whl", hash = "sha256:90a80e46886259b9c396b578d75c749801a41ee969a235e163cfe1be7afd2543"}, +] + +[package.dependencies] +pycodestyle = "*" +setuptools = "*" + +[[package]] +name = "flake8-plugin-utils" +version = "1.3.2" +description = "The package provides base classes and utils for flake8 plugin writing" +optional = false +python-versions = ">=3.6,<4.0" +files = [ + {file = "flake8-plugin-utils-1.3.2.tar.gz", hash = "sha256:20fa2a8ca2decac50116edb42e6af0a1253ef639ad79941249b840531889c65a"}, + {file = "flake8_plugin_utils-1.3.2-py3-none-any.whl", hash = "sha256:1fe43e3e9acf3a7c0f6b88f5338cad37044d2f156c43cb6b080b5f9da8a76f06"}, +] + +[[package]] +name = "flake8-polyfill" +version = "1.0.2" +description = "Polyfill package for Flake8 plugins" +optional = false +python-versions = "*" +files = [ + {file = "flake8-polyfill-1.0.2.tar.gz", hash = "sha256:e44b087597f6da52ec6393a709e7108b2905317d0c0b744cdca6208e670d8eda"}, + {file = "flake8_polyfill-1.0.2-py2.py3-none-any.whl", hash = "sha256:12be6a34ee3ab795b19ca73505e7b55826d5f6ad7230d31b18e106400169b9e9"}, +] + +[package.dependencies] +flake8 = "*" + +[[package]] +name = "flake8-return" +version = "1.1.2" +description = "Flake8 plugin that checks return values" +optional = false +python-versions = ">=3.6,<4.0" +files = [ + {file = "flake8-return-1.1.2.tar.gz", hash = "sha256:d646d3b010a9736ddc23c24f98ad3282999f575da45d6eb9cefe4adddb44062d"}, + {file = "flake8_return-1.1.2-py3-none-any.whl", hash = "sha256:183d0ad2f8553cb2c63c0cf288eb799d967577a74639599525adcd3860f6bb12"}, +] + +[package.dependencies] +flake8-plugin-utils = ">=1.0,<2.0" + +[[package]] +name = "flake8-spellcheck" +version = "0.24.0" +description = "Spellcheck variables, comments and docstrings" +optional = false +python-versions = "*" +files = [ + {file = "flake8-spellcheck-0.24.0.tar.gz", hash = "sha256:833c92222158b5dea74f858ccfb9f980b7c865fbd89cabc18447dadb07ec62e6"}, + {file = "flake8_spellcheck-0.24.0-py2.py3-none-any.whl", hash = "sha256:33d1727e4edb2b0cda3a78dee467d7bde53ff5a2a90056bc7d1764e0b060f331"}, +] + +[package.dependencies] +flake8 = ">3.0.0" + +[[package]] +name = "flake8-string-format" +version = "0.3.0" +description = "string format checker, plugin for flake8" +optional = false +python-versions = "*" +files = [ + {file = "flake8-string-format-0.3.0.tar.gz", hash = "sha256:65f3da786a1461ef77fca3780b314edb2853c377f2e35069723348c8917deaa2"}, + {file = "flake8_string_format-0.3.0-py2.py3-none-any.whl", hash = "sha256:812ff431f10576a74c89be4e85b8e075a705be39bc40c4b4278b5b13e2afa9af"}, +] + +[package.dependencies] +flake8 = "*" + +[[package]] +name = "future" +version = "1.0.0" +description = "Clean single-source support for Python 3 and 2" +optional = false +python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" +files = [ + {file = "future-1.0.0-py3-none-any.whl", hash = "sha256:929292d34f5872e70396626ef385ec22355a1fae8ad29e1a734c3e43f9fbc216"}, + {file = "future-1.0.0.tar.gz", hash = "sha256:bd2968309307861edae1458a4f8a4f3598c03be43b97521076aebf5d94c07b05"}, +] + +[[package]] +name = "grpcio" +version = "1.66.1" +description = "HTTP/2-based RPC framework" +optional = false +python-versions = ">=3.8" +files = [ + {file = "grpcio-1.66.1-cp310-cp310-linux_armv7l.whl", hash = "sha256:4877ba180591acdf127afe21ec1c7ff8a5ecf0fe2600f0d3c50e8c4a1cbc6492"}, + {file = "grpcio-1.66.1-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:3750c5a00bd644c75f4507f77a804d0189d97a107eb1481945a0cf3af3e7a5ac"}, + {file = "grpcio-1.66.1-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:a013c5fbb12bfb5f927444b477a26f1080755a931d5d362e6a9a720ca7dbae60"}, + {file = "grpcio-1.66.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b1b24c23d51a1e8790b25514157d43f0a4dce1ac12b3f0b8e9f66a5e2c4c132f"}, + {file = "grpcio-1.66.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b7ffb8ea674d68de4cac6f57d2498fef477cef582f1fa849e9f844863af50083"}, + {file = "grpcio-1.66.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:307b1d538140f19ccbd3aed7a93d8f71103c5d525f3c96f8616111614b14bf2a"}, + {file = "grpcio-1.66.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:1c17ebcec157cfb8dd445890a03e20caf6209a5bd4ac5b040ae9dbc59eef091d"}, + {file = "grpcio-1.66.1-cp310-cp310-win32.whl", hash = "sha256:ef82d361ed5849d34cf09105d00b94b6728d289d6b9235513cb2fcc79f7c432c"}, + {file = "grpcio-1.66.1-cp310-cp310-win_amd64.whl", hash = "sha256:292a846b92cdcd40ecca46e694997dd6b9be6c4c01a94a0dfb3fcb75d20da858"}, + {file = "grpcio-1.66.1-cp311-cp311-linux_armv7l.whl", hash = "sha256:c30aeceeaff11cd5ddbc348f37c58bcb96da8d5aa93fed78ab329de5f37a0d7a"}, + {file = "grpcio-1.66.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8a1e224ce6f740dbb6b24c58f885422deebd7eb724aff0671a847f8951857c26"}, + {file = "grpcio-1.66.1-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:a66fe4dc35d2330c185cfbb42959f57ad36f257e0cc4557d11d9f0a3f14311df"}, + {file = "grpcio-1.66.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e3ba04659e4fce609de2658fe4dbf7d6ed21987a94460f5f92df7579fd5d0e22"}, + {file = "grpcio-1.66.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4573608e23f7e091acfbe3e84ac2045680b69751d8d67685ffa193a4429fedb1"}, + {file = "grpcio-1.66.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:7e06aa1f764ec8265b19d8f00140b8c4b6ca179a6dc67aa9413867c47e1fb04e"}, + {file = "grpcio-1.66.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3885f037eb11f1cacc41f207b705f38a44b69478086f40608959bf5ad85826dd"}, + {file = "grpcio-1.66.1-cp311-cp311-win32.whl", hash = "sha256:97ae7edd3f3f91480e48ede5d3e7d431ad6005bfdbd65c1b56913799ec79e791"}, + {file = "grpcio-1.66.1-cp311-cp311-win_amd64.whl", hash = "sha256:cfd349de4158d797db2bd82d2020554a121674e98fbe6b15328456b3bf2495bb"}, + {file = "grpcio-1.66.1-cp312-cp312-linux_armv7l.whl", hash = "sha256:a92c4f58c01c77205df6ff999faa008540475c39b835277fb8883b11cada127a"}, + {file = "grpcio-1.66.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:fdb14bad0835914f325349ed34a51940bc2ad965142eb3090081593c6e347be9"}, + {file = "grpcio-1.66.1-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:f03a5884c56256e08fd9e262e11b5cfacf1af96e2ce78dc095d2c41ccae2c80d"}, + {file = "grpcio-1.66.1-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2ca2559692d8e7e245d456877a85ee41525f3ed425aa97eb7a70fc9a79df91a0"}, + {file = "grpcio-1.66.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:84ca1be089fb4446490dd1135828bd42a7c7f8421e74fa581611f7afdf7ab761"}, + {file = "grpcio-1.66.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:d639c939ad7c440c7b2819a28d559179a4508783f7e5b991166f8d7a34b52815"}, + {file = "grpcio-1.66.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:b9feb4e5ec8dc2d15709f4d5fc367794d69277f5d680baf1910fc9915c633524"}, + {file = "grpcio-1.66.1-cp312-cp312-win32.whl", hash = "sha256:7101db1bd4cd9b880294dec41a93fcdce465bdbb602cd8dc5bd2d6362b618759"}, + {file = "grpcio-1.66.1-cp312-cp312-win_amd64.whl", hash = "sha256:b0aa03d240b5539648d996cc60438f128c7f46050989e35b25f5c18286c86734"}, + {file = "grpcio-1.66.1-cp38-cp38-linux_armv7l.whl", hash = "sha256:ecfe735e7a59e5a98208447293ff8580e9db1e890e232b8b292dc8bd15afc0d2"}, + {file = "grpcio-1.66.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:4825a3aa5648010842e1c9d35a082187746aa0cdbf1b7a2a930595a94fb10fce"}, + {file = "grpcio-1.66.1-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:f517fd7259fe823ef3bd21e508b653d5492e706e9f0ef82c16ce3347a8a5620c"}, + {file = "grpcio-1.66.1-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f1fe60d0772831d96d263b53d83fb9a3d050a94b0e94b6d004a5ad111faa5b5b"}, + {file = "grpcio-1.66.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:31a049daa428f928f21090403e5d18ea02670e3d5d172581670be006100db9ef"}, + {file = "grpcio-1.66.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:6f914386e52cbdeb5d2a7ce3bf1fdfacbe9d818dd81b6099a05b741aaf3848bb"}, + {file = "grpcio-1.66.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:bff2096bdba686019fb32d2dde45b95981f0d1490e054400f70fc9a8af34b49d"}, + {file = "grpcio-1.66.1-cp38-cp38-win32.whl", hash = "sha256:aa8ba945c96e73de29d25331b26f3e416e0c0f621e984a3ebdb2d0d0b596a3b3"}, + {file = "grpcio-1.66.1-cp38-cp38-win_amd64.whl", hash = "sha256:161d5c535c2bdf61b95080e7f0f017a1dfcb812bf54093e71e5562b16225b4ce"}, + {file = "grpcio-1.66.1-cp39-cp39-linux_armv7l.whl", hash = "sha256:d0cd7050397b3609ea51727b1811e663ffda8bda39c6a5bb69525ef12414b503"}, + {file = "grpcio-1.66.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:0e6c9b42ded5d02b6b1fea3a25f036a2236eeb75d0579bfd43c0018c88bf0a3e"}, + {file = "grpcio-1.66.1-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:c9f80f9fad93a8cf71c7f161778ba47fd730d13a343a46258065c4deb4b550c0"}, + {file = "grpcio-1.66.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5dd67ed9da78e5121efc5c510f0122a972216808d6de70953a740560c572eb44"}, + {file = "grpcio-1.66.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:48b0d92d45ce3be2084b92fb5bae2f64c208fea8ceed7fccf6a7b524d3c4942e"}, + {file = "grpcio-1.66.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:4d813316d1a752be6f5c4360c49f55b06d4fe212d7df03253dfdae90c8a402bb"}, + {file = "grpcio-1.66.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9c9bebc6627873ec27a70fc800f6083a13c70b23a5564788754b9ee52c5aef6c"}, + {file = "grpcio-1.66.1-cp39-cp39-win32.whl", hash = "sha256:30a1c2cf9390c894c90bbc70147f2372130ad189cffef161f0432d0157973f45"}, + {file = "grpcio-1.66.1-cp39-cp39-win_amd64.whl", hash = "sha256:17663598aadbedc3cacd7bbde432f541c8e07d2496564e22b214b22c7523dac8"}, + {file = "grpcio-1.66.1.tar.gz", hash = "sha256:35334f9c9745add3e357e3372756fd32d925bd52c41da97f4dfdafbde0bf0ee2"}, +] + +[package.extras] +protobuf = ["grpcio-tools (>=1.66.1)"] + +[[package]] +name = "grpcio-tools" +version = "1.66.1" +description = "Protobuf code generator for gRPC" +optional = false +python-versions = ">=3.8" +files = [ + {file = "grpcio_tools-1.66.1-cp310-cp310-linux_armv7l.whl", hash = "sha256:e0c71405399ef59782600b1f0bdebc69ba12d7c9527cd268162a86273971d294"}, + {file = "grpcio_tools-1.66.1-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:df1a174a6f9d3b4c380f005f33352d2e95464f33f021fb08084735a2eb6e23b1"}, + {file = "grpcio_tools-1.66.1-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:7d789bfe53fce9e87aa80c3694a366258ce4c41b706258e9228ed4994832b780"}, + {file = "grpcio_tools-1.66.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:95c44a265ff01fd05166edae9350bc2e7d1d9a95e8f53b8cd04d2ae0a588c583"}, + {file = "grpcio_tools-1.66.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b962a8767c3c0f9afe92e0dd6bb0b2305d35195a1053f84d4d31f585b87557ed"}, + {file = "grpcio_tools-1.66.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:d8616773126ec3cdf747b06a12e957b43ac15c34e4728def91fa67249a7c689a"}, + {file = "grpcio_tools-1.66.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0067e79b6001560ac6acc78cca11fd3504fa27f8af46e3cdbac2f4998505e597"}, + {file = "grpcio_tools-1.66.1-cp310-cp310-win32.whl", hash = "sha256:fa4f95a79a34afc3b5464895d091cd1911227fc3ab0441b9a37cd1817cf7db86"}, + {file = "grpcio_tools-1.66.1-cp310-cp310-win_amd64.whl", hash = "sha256:3acce426f5e643de63019311171f4d31131da8149de518716a95c29a2c12dd38"}, + {file = "grpcio_tools-1.66.1-cp311-cp311-linux_armv7l.whl", hash = "sha256:9a07e24feb7472419cf70ebbb38dd4299aea696f91f191b62a99b3ee9ff03f89"}, + {file = "grpcio_tools-1.66.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:097a069e7c640043921ecaf3e88d7af78ccd40c25dbddc91db2a4a2adbd0393d"}, + {file = "grpcio_tools-1.66.1-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:016fa273dc696c9d8045091ac50e000bce766183a6b150801f51c2946e33dbe3"}, + {file = "grpcio_tools-1.66.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1ec9f4f964f8e8ed5e9cc13deb678c83d5597074c256805373220627833bc5ad"}, + {file = "grpcio_tools-1.66.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3198815814cdd12bdb69b7580d7770a4ad4c8b2093e0bd6b987bc817618e3eec"}, + {file = "grpcio_tools-1.66.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:796620fc41d3fbb566d9614ef22bc55df67fac1f1e19c1e0fb6ec48bc9b6a44b"}, + {file = "grpcio_tools-1.66.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:222d8dc218560698e1abf652fb47e4015994ec7a265ef46e012fd9c9e77a4d6b"}, + {file = "grpcio_tools-1.66.1-cp311-cp311-win32.whl", hash = "sha256:56e17a11f34df252b4c6fb8aa8cd7b44d162dba9f3333be87ddf7c8bf496622a"}, + {file = "grpcio_tools-1.66.1-cp311-cp311-win_amd64.whl", hash = "sha256:edd52d667f2aa3c73233be0a821596937f24536647c12d96bfc54aa4cb04747d"}, + {file = "grpcio_tools-1.66.1-cp312-cp312-linux_armv7l.whl", hash = "sha256:869b6960d5daffda0dac1a474b44144f0dace0d4336394e499c4f400c5e2f8d9"}, + {file = "grpcio_tools-1.66.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:68d9390bf9ba863ac147fc722d6548caa587235e887cac1bc2438212e89d1de7"}, + {file = "grpcio_tools-1.66.1-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:b8660401beca7e3af28722439e07b0bcdca80b4a68f5a5a1138ae7b7780a6abf"}, + {file = "grpcio_tools-1.66.1-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb67b9aa9cd69468bceb933e8e0f89fd13695746c018c4d2e6b3b84e73f3ad97"}, + {file = "grpcio_tools-1.66.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5daceb9716e31edc0e1ba0f93303785211438c43502edddad7a919fc4cb3d664"}, + {file = "grpcio_tools-1.66.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:0a86398a4cd0665bc7f09fa90b89bac592c959d2c895bf3cf5d47a98c0f2d24c"}, + {file = "grpcio_tools-1.66.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:1b4acb53338072ab3023e418a5c7059cb15686abd1607516fa1453406dd5f69d"}, + {file = "grpcio_tools-1.66.1-cp312-cp312-win32.whl", hash = "sha256:88e04b7546101bc79c868c941777efd5088063a9e4f03b4d7263dde796fbabf7"}, + {file = "grpcio_tools-1.66.1-cp312-cp312-win_amd64.whl", hash = "sha256:5b4fc56abeafae74140f5da29af1093e88ce64811d77f1a81c3146e9e996fb6a"}, + {file = "grpcio_tools-1.66.1-cp38-cp38-linux_armv7l.whl", hash = "sha256:d4dd2ff982c1aa328ef47ce34f07af82f1f13599912fb1618ebc5fe1e14dddb8"}, + {file = "grpcio_tools-1.66.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:066648543f786cb74b1fef5652359952455dbba37e832642026fd9fd8a219b5f"}, + {file = "grpcio_tools-1.66.1-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:d19d47744c30e6bafa76b3113740e71f382d75ebb2918c1efd62ebe6ba7e20f9"}, + {file = "grpcio_tools-1.66.1-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:739c53571130b359b738ac7d6d0a1f772e15779b66df7e6764bee4071cd38689"}, + {file = "grpcio_tools-1.66.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2226ff8d3ecba83b7622946df19d6e8e15cb52f761b8d9e2f807b228db5f1b1e"}, + {file = "grpcio_tools-1.66.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:2f4b1498cb8b422fbae32a491c9154e8d47650caf5852fbe6b3b34253e824343"}, + {file = "grpcio_tools-1.66.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:93d2d9e14e81affdc63d67c42eb16a8da1b6fecc16442a703ca60eb0e7591691"}, + {file = "grpcio_tools-1.66.1-cp38-cp38-win32.whl", hash = "sha256:d761dfd97a10e4aae73628b5120c64e56f0cded88651d0003d2d80e678c3e7c9"}, + {file = "grpcio_tools-1.66.1-cp38-cp38-win_amd64.whl", hash = "sha256:e1c2ac0955f5fb87b8444316e475242d194c3f3cd0b7b6e54b889a7b6f05156f"}, + {file = "grpcio_tools-1.66.1-cp39-cp39-linux_armv7l.whl", hash = "sha256:5f1f04578b72c281e39274348a61d240c48d5321ba8d7a8838e194099ecbc322"}, + {file = "grpcio_tools-1.66.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:da9b0c08dbbf07535ee1b75a22d0acc5675a808a3a3df9f9b21e0e73ddfbb3a9"}, + {file = "grpcio_tools-1.66.1-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:e302b4e1fa856d74ff65c65888b3a37153287ce6ad5bad80b2fdf95130accec2"}, + {file = "grpcio_tools-1.66.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7fc3f62494f238774755ff90f0e66a93ac7972ea1eb7180c45acf4fd53b25cca"}, + {file = "grpcio_tools-1.66.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:23cad65ff22459aa387f543d293f54834c9aac8f76fb7416a7046556df75b567"}, + {file = "grpcio_tools-1.66.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:3d17a27c567a5e4d18f487368215cb51b43e2499059fd6113b92f7ae1fee48be"}, + {file = "grpcio_tools-1.66.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:4df167e67b083f96bc277032a526f6186e98662aaa49baea1dfb8ecfe26ce117"}, + {file = "grpcio_tools-1.66.1-cp39-cp39-win32.whl", hash = "sha256:f94d5193b2f2a9595795b83e7978b2bee1c0399da66f2f24d179c388f81fb99c"}, + {file = "grpcio_tools-1.66.1-cp39-cp39-win_amd64.whl", hash = "sha256:66f527a1e3f063065e29cf6f3e55892434d13a5a51e3b22402e09da9521e98a3"}, + {file = "grpcio_tools-1.66.1.tar.gz", hash = "sha256:5055ffe840ea8f505c30378be02afb4dbecb33480e554debe10b63d6b2f641c3"}, +] + +[package.dependencies] +grpcio = ">=1.66.1" +protobuf = ">=5.26.1,<6.0dev" +setuptools = "*" + +[[package]] +name = "idna" +version = "3.10" +description = "Internationalized Domain Names in Applications (IDNA)" +optional = false +python-versions = ">=3.6" +files = [ + {file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"}, + {file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"}, +] + +[package.extras] +all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"] + +[[package]] +name = "iniconfig" +version = "2.0.0" +description = "brain-dead simple config-ini parsing" +optional = false +python-versions = ">=3.7" +files = [ + {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, + {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, +] + +[[package]] +name = "isort" +version = "5.13.2" +description = "A Python utility / library to sort Python imports." +optional = false +python-versions = ">=3.8.0" +files = [ + {file = "isort-5.13.2-py3-none-any.whl", hash = "sha256:8ca5e72a8d85860d5a3fa69b8745237f2939afe12dbf656afbcb47fe72d947a6"}, + {file = "isort-5.13.2.tar.gz", hash = "sha256:48fdfcb9face5d58a4f6dde2e72a1fb8dcaf8ab26f95ab49fab84c2ddefb0109"}, +] + +[package.extras] +colors = ["colorama (>=0.4.6)"] + +[[package]] +name = "jsonschema" +version = "4.23.0" +description = "An implementation of JSON Schema validation for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "jsonschema-4.23.0-py3-none-any.whl", hash = "sha256:fbadb6f8b144a8f8cf9f0b89ba94501d143e50411a1278633f56a7acf7fd5566"}, + {file = "jsonschema-4.23.0.tar.gz", hash = "sha256:d71497fef26351a33265337fa77ffeb82423f3ea21283cd9467bb03999266bc4"}, +] + +[package.dependencies] +attrs = ">=22.2.0" +jsonschema-specifications = ">=2023.03.6" +referencing = ">=0.28.4" +rpds-py = ">=0.7.1" + +[package.extras] +format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"] +format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=24.6.0)"] + +[[package]] +name = "jsonschema-specifications" +version = "2023.12.1" +description = "The JSON Schema meta-schemas and vocabularies, exposed as a Registry" +optional = false +python-versions = ">=3.8" +files = [ + {file = "jsonschema_specifications-2023.12.1-py3-none-any.whl", hash = "sha256:87e4fdf3a94858b8a2ba2778d9ba57d8a9cafca7c7489c46ba0d30a8bc6a9c3c"}, + {file = "jsonschema_specifications-2023.12.1.tar.gz", hash = "sha256:48a76787b3e70f5ed53f1160d2b81f586e4ca6d1548c5de7085d1682674764cc"}, +] + +[package.dependencies] +referencing = ">=0.31.0" + +[[package]] +name = "lazy-object-proxy" +version = "1.10.0" +description = "A fast and thorough lazy object proxy." +optional = false +python-versions = ">=3.8" +files = [ + {file = "lazy-object-proxy-1.10.0.tar.gz", hash = "sha256:78247b6d45f43a52ef35c25b5581459e85117225408a4128a3daf8bf9648ac69"}, + {file = "lazy_object_proxy-1.10.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:855e068b0358ab916454464a884779c7ffa312b8925c6f7401e952dcf3b89977"}, + {file = "lazy_object_proxy-1.10.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ab7004cf2e59f7c2e4345604a3e6ea0d92ac44e1c2375527d56492014e690c3"}, + {file = "lazy_object_proxy-1.10.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc0d2fc424e54c70c4bc06787e4072c4f3b1aa2f897dfdc34ce1013cf3ceef05"}, + {file = "lazy_object_proxy-1.10.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e2adb09778797da09d2b5ebdbceebf7dd32e2c96f79da9052b2e87b6ea495895"}, + {file = "lazy_object_proxy-1.10.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b1f711e2c6dcd4edd372cf5dec5c5a30d23bba06ee012093267b3376c079ec83"}, + {file = "lazy_object_proxy-1.10.0-cp310-cp310-win32.whl", hash = "sha256:76a095cfe6045c7d0ca77db9934e8f7b71b14645f0094ffcd842349ada5c5fb9"}, + {file = "lazy_object_proxy-1.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:b4f87d4ed9064b2628da63830986c3d2dca7501e6018347798313fcf028e2fd4"}, + {file = "lazy_object_proxy-1.10.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:fec03caabbc6b59ea4a638bee5fce7117be8e99a4103d9d5ad77f15d6f81020c"}, + {file = "lazy_object_proxy-1.10.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:02c83f957782cbbe8136bee26416686a6ae998c7b6191711a04da776dc9e47d4"}, + {file = "lazy_object_proxy-1.10.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:009e6bb1f1935a62889ddc8541514b6a9e1fcf302667dcb049a0be5c8f613e56"}, + {file = "lazy_object_proxy-1.10.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:75fc59fc450050b1b3c203c35020bc41bd2695ed692a392924c6ce180c6f1dc9"}, + {file = "lazy_object_proxy-1.10.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:782e2c9b2aab1708ffb07d4bf377d12901d7a1d99e5e410d648d892f8967ab1f"}, + {file = "lazy_object_proxy-1.10.0-cp311-cp311-win32.whl", hash = "sha256:edb45bb8278574710e68a6b021599a10ce730d156e5b254941754a9cc0b17d03"}, + {file = "lazy_object_proxy-1.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:e271058822765ad5e3bca7f05f2ace0de58a3f4e62045a8c90a0dfd2f8ad8cc6"}, + {file = "lazy_object_proxy-1.10.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:e98c8af98d5707dcdecc9ab0863c0ea6e88545d42ca7c3feffb6b4d1e370c7ba"}, + {file = "lazy_object_proxy-1.10.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:952c81d415b9b80ea261d2372d2a4a2332a3890c2b83e0535f263ddfe43f0d43"}, + {file = "lazy_object_proxy-1.10.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80b39d3a151309efc8cc48675918891b865bdf742a8616a337cb0090791a0de9"}, + {file = "lazy_object_proxy-1.10.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:e221060b701e2aa2ea991542900dd13907a5c90fa80e199dbf5a03359019e7a3"}, + {file = "lazy_object_proxy-1.10.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:92f09ff65ecff3108e56526f9e2481b8116c0b9e1425325e13245abfd79bdb1b"}, + {file = "lazy_object_proxy-1.10.0-cp312-cp312-win32.whl", hash = "sha256:3ad54b9ddbe20ae9f7c1b29e52f123120772b06dbb18ec6be9101369d63a4074"}, + {file = "lazy_object_proxy-1.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:127a789c75151db6af398b8972178afe6bda7d6f68730c057fbbc2e96b08d282"}, + {file = "lazy_object_proxy-1.10.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9e4ed0518a14dd26092614412936920ad081a424bdcb54cc13349a8e2c6d106a"}, + {file = "lazy_object_proxy-1.10.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5ad9e6ed739285919aa9661a5bbed0aaf410aa60231373c5579c6b4801bd883c"}, + {file = "lazy_object_proxy-1.10.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2fc0a92c02fa1ca1e84fc60fa258458e5bf89d90a1ddaeb8ed9cc3147f417255"}, + {file = "lazy_object_proxy-1.10.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:0aefc7591920bbd360d57ea03c995cebc204b424524a5bd78406f6e1b8b2a5d8"}, + {file = "lazy_object_proxy-1.10.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5faf03a7d8942bb4476e3b62fd0f4cf94eaf4618e304a19865abf89a35c0bbee"}, + {file = "lazy_object_proxy-1.10.0-cp38-cp38-win32.whl", hash = "sha256:e333e2324307a7b5d86adfa835bb500ee70bfcd1447384a822e96495796b0ca4"}, + {file = "lazy_object_proxy-1.10.0-cp38-cp38-win_amd64.whl", hash = "sha256:cb73507defd385b7705c599a94474b1d5222a508e502553ef94114a143ec6696"}, + {file = "lazy_object_proxy-1.10.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:366c32fe5355ef5fc8a232c5436f4cc66e9d3e8967c01fb2e6302fd6627e3d94"}, + {file = "lazy_object_proxy-1.10.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2297f08f08a2bb0d32a4265e98a006643cd7233fb7983032bd61ac7a02956b3b"}, + {file = "lazy_object_proxy-1.10.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18dd842b49456aaa9a7cf535b04ca4571a302ff72ed8740d06b5adcd41fe0757"}, + {file = "lazy_object_proxy-1.10.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:217138197c170a2a74ca0e05bddcd5f1796c735c37d0eee33e43259b192aa424"}, + {file = "lazy_object_proxy-1.10.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9a3a87cf1e133e5b1994144c12ca4aa3d9698517fe1e2ca82977781b16955658"}, + {file = "lazy_object_proxy-1.10.0-cp39-cp39-win32.whl", hash = "sha256:30b339b2a743c5288405aa79a69e706a06e02958eab31859f7f3c04980853b70"}, + {file = "lazy_object_proxy-1.10.0-cp39-cp39-win_amd64.whl", hash = "sha256:a899b10e17743683b293a729d3a11f2f399e8a90c73b089e29f5d0fe3509f0dd"}, + {file = "lazy_object_proxy-1.10.0-pp310.pp311.pp312.pp38.pp39-none-any.whl", hash = "sha256:80fa48bd89c8f2f456fc0765c11c23bf5af827febacd2f523ca5bc1893fcc09d"}, +] + +[[package]] +name = "mando" +version = "0.6.4" +description = "Create Python CLI apps with little to no effort at all!" +optional = false +python-versions = "*" +files = [ + {file = "mando-0.6.4-py2.py3-none-any.whl", hash = "sha256:4ce09faec7e5192ffc3c57830e26acba0fd6cd11e1ee81af0d4df0657463bd1c"}, + {file = "mando-0.6.4.tar.gz", hash = "sha256:79feb19dc0f097daa64a1243db578e7674909b75f88ac2220f1c065c10a0d960"}, +] + +[package.dependencies] +six = "*" + +[package.extras] +restructuredtext = ["rst2ansi"] + +[[package]] +name = "marshmallow" +version = "3.22.0" +description = "A lightweight library for converting complex datatypes to and from native Python datatypes." +optional = false +python-versions = ">=3.8" +files = [ + {file = "marshmallow-3.22.0-py3-none-any.whl", hash = "sha256:71a2dce49ef901c3f97ed296ae5051135fd3febd2bf43afe0ae9a82143a494d9"}, + {file = "marshmallow-3.22.0.tar.gz", hash = "sha256:4972f529104a220bb8637d595aa4c9762afbe7f7a77d82dc58c1615d70c5823e"}, +] + +[package.dependencies] +packaging = ">=17.0" + +[package.extras] +dev = ["marshmallow[tests]", "pre-commit (>=3.5,<4.0)", "tox"] +docs = ["alabaster (==1.0.0)", "autodocsumm (==0.2.13)", "sphinx (==8.0.2)", "sphinx-issues (==4.1.0)", "sphinx-version-warning (==1.1.2)"] +tests = ["pytest", "pytz", "simplejson"] + +[[package]] +name = "marshmallow-enum" +version = "1.5.1" +description = "Enum field for Marshmallow" +optional = false +python-versions = "*" +files = [ + {file = "marshmallow-enum-1.5.1.tar.gz", hash = "sha256:38e697e11f45a8e64b4a1e664000897c659b60aa57bfa18d44e226a9920b6e58"}, + {file = "marshmallow_enum-1.5.1-py2.py3-none-any.whl", hash = "sha256:57161ab3dbfde4f57adeb12090f39592e992b9c86d206d02f6bd03ebec60f072"}, +] + +[package.dependencies] +marshmallow = ">=2.0.0" + +[[package]] +name = "mccabe" +version = "0.6.1" +description = "McCabe checker, plugin for flake8" +optional = false +python-versions = "*" +files = [ + {file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"}, + {file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"}, +] + +[[package]] +name = "mypy-extensions" +version = "1.0.0" +description = "Type system extensions for programs checked with the mypy type checker." +optional = false +python-versions = ">=3.5" +files = [ + {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, + {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, +] + +[[package]] +name = "packaging" +version = "24.1" +description = "Core utilities for Python packages" +optional = false +python-versions = ">=3.8" +files = [ + {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, + {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, +] + +[[package]] +name = "pep8-naming" +version = "0.11.1" +description = "Check PEP-8 naming conventions, plugin for flake8" +optional = false +python-versions = "*" +files = [ + {file = "pep8-naming-0.11.1.tar.gz", hash = "sha256:a1dd47dd243adfe8a83616e27cf03164960b507530f155db94e10b36a6cd6724"}, + {file = "pep8_naming-0.11.1-py2.py3-none-any.whl", hash = "sha256:f43bfe3eea7e0d73e8b5d07d6407ab47f2476ccaeff6937c84275cd30b016738"}, +] + +[package.dependencies] +flake8-polyfill = ">=1.0.2,<2" + +[[package]] +name = "platformdirs" +version = "4.3.6" +description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." +optional = false +python-versions = ">=3.8" +files = [ + {file = "platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb"}, + {file = "platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907"}, +] + +[package.extras] +docs = ["furo (>=2024.8.6)", "proselint (>=0.14)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=8.3.2)", "pytest-cov (>=5)", "pytest-mock (>=3.14)"] +type = ["mypy (>=1.11.2)"] + +[[package]] +name = "pluggy" +version = "1.5.0" +description = "plugin and hook calling mechanisms for python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, + {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, +] + +[package.extras] +dev = ["pre-commit", "tox"] +testing = ["pytest", "pytest-benchmark"] + +[[package]] +name = "protobuf" +version = "5.27.2" +description = "" +optional = false +python-versions = ">=3.8" +files = [ + {file = "protobuf-5.27.2-cp310-abi3-win32.whl", hash = "sha256:354d84fac2b0d76062e9b3221f4abbbacdfd2a4d8af36bab0474f3a0bb30ab38"}, + {file = "protobuf-5.27.2-cp310-abi3-win_amd64.whl", hash = "sha256:0e341109c609749d501986b835f667c6e1e24531096cff9d34ae411595e26505"}, + {file = "protobuf-5.27.2-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:a109916aaac42bff84702fb5187f3edadbc7c97fc2c99c5ff81dd15dcce0d1e5"}, + {file = "protobuf-5.27.2-cp38-abi3-manylinux2014_aarch64.whl", hash = "sha256:176c12b1f1c880bf7a76d9f7c75822b6a2bc3db2d28baa4d300e8ce4cde7409b"}, + {file = "protobuf-5.27.2-cp38-abi3-manylinux2014_x86_64.whl", hash = "sha256:b848dbe1d57ed7c191dfc4ea64b8b004a3f9ece4bf4d0d80a367b76df20bf36e"}, + {file = "protobuf-5.27.2-cp38-cp38-win32.whl", hash = "sha256:4fadd8d83e1992eed0248bc50a4a6361dc31bcccc84388c54c86e530b7f58863"}, + {file = "protobuf-5.27.2-cp38-cp38-win_amd64.whl", hash = "sha256:610e700f02469c4a997e58e328cac6f305f649826853813177e6290416e846c6"}, + {file = "protobuf-5.27.2-cp39-cp39-win32.whl", hash = "sha256:9e8f199bf7f97bd7ecebffcae45ebf9527603549b2b562df0fbc6d4d688f14ca"}, + {file = "protobuf-5.27.2-cp39-cp39-win_amd64.whl", hash = "sha256:7fc3add9e6003e026da5fc9e59b131b8f22b428b991ccd53e2af8071687b4fce"}, + {file = "protobuf-5.27.2-py3-none-any.whl", hash = "sha256:54330f07e4949d09614707c48b06d1a22f8ffb5763c159efd5c0928326a91470"}, + {file = "protobuf-5.27.2.tar.gz", hash = "sha256:f3ecdef226b9af856075f28227ff2c90ce3a594d092c39bee5513573f25e2714"}, +] + +[[package]] +name = "pycodestyle" +version = "2.7.0" +description = "Python style guide checker" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "pycodestyle-2.7.0-py2.py3-none-any.whl", hash = "sha256:514f76d918fcc0b55c6680472f0a37970994e07bbb80725808c17089be302068"}, + {file = "pycodestyle-2.7.0.tar.gz", hash = "sha256:c389c1d06bf7904078ca03399a4816f974a1d590090fecea0c63ec26ebaf1cef"}, +] + +[[package]] +name = "pyflakes" +version = "2.3.1" +description = "passive checker of Python programs" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "pyflakes-2.3.1-py2.py3-none-any.whl", hash = "sha256:7893783d01b8a89811dd72d7dfd4d84ff098e5eed95cfa8905b22bbffe52efc3"}, + {file = "pyflakes-2.3.1.tar.gz", hash = "sha256:f5bc8ecabc05bb9d291eb5203d6810b49040f6ff446a756326104746cc00c1db"}, +] + +[[package]] +name = "pygments" +version = "2.18.0" +description = "Pygments is a syntax highlighting package written in Python." +optional = false +python-versions = ">=3.8" +files = [ + {file = "pygments-2.18.0-py3-none-any.whl", hash = "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a"}, + {file = "pygments-2.18.0.tar.gz", hash = "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199"}, +] + +[package.extras] +windows-terminal = ["colorama (>=0.4.6)"] + +[[package]] +name = "pylint" +version = "2.13.9" +description = "python code static checker" +optional = false +python-versions = ">=3.6.2" +files = [ + {file = "pylint-2.13.9-py3-none-any.whl", hash = "sha256:705c620d388035bdd9ff8b44c5bcdd235bfb49d276d488dd2c8ff1736aa42526"}, + {file = "pylint-2.13.9.tar.gz", hash = "sha256:095567c96e19e6f57b5b907e67d265ff535e588fe26b12b5ebe1fc5645b2c731"}, +] + +[package.dependencies] +astroid = ">=2.11.5,<=2.12.0-dev0" +colorama = {version = "*", markers = "sys_platform == \"win32\""} +dill = ">=0.2" +isort = ">=4.2.5,<6" +mccabe = ">=0.6,<0.8" +platformdirs = ">=2.2.0" +tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} + +[package.extras] +testutil = ["gitpython (>3)"] + +[[package]] +name = "pylint-django" +version = "2.5.3" +description = "A Pylint plugin to help Pylint understand the Django web framework" +optional = false +python-versions = "*" +files = [ + {file = "pylint-django-2.5.3.tar.gz", hash = "sha256:0ac090d106c62fe33782a1d01bda1610b761bb1c9bf5035ced9d5f23a13d8591"}, + {file = "pylint_django-2.5.3-py3-none-any.whl", hash = "sha256:56b12b6adf56d548412445bd35483034394a1a94901c3f8571980a13882299d5"}, +] + +[package.dependencies] +pylint = ">=2.0,<3" +pylint-plugin-utils = ">=0.7" + +[package.extras] +for-tests = ["coverage", "django-tables2", "django-tastypie", "factory-boy", "pylint (>=2.13)", "pytest", "wheel"] +with-django = ["Django"] + +[[package]] +name = "pylint-plugin-utils" +version = "0.8.2" +description = "Utilities and helpers for writing Pylint plugins" +optional = false +python-versions = ">=3.7,<4.0" +files = [ + {file = "pylint_plugin_utils-0.8.2-py3-none-any.whl", hash = "sha256:ae11664737aa2effbf26f973a9e0b6779ab7106ec0adc5fe104b0907ca04e507"}, + {file = "pylint_plugin_utils-0.8.2.tar.gz", hash = "sha256:d3cebf68a38ba3fba23a873809155562571386d4c1b03e5b4c4cc26c3eee93e4"}, +] + +[package.dependencies] +pylint = ">=1.7" + +[[package]] +name = "pytest" +version = "8.3.3" +description = "pytest: simple powerful testing with Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pytest-8.3.3-py3-none-any.whl", hash = "sha256:a6853c7375b2663155079443d2e45de913a911a11d669df02a50814944db57b2"}, + {file = "pytest-8.3.3.tar.gz", hash = "sha256:70b98107bd648308a7952b06e6ca9a50bc660be218d53c257cc1fc94fda10181"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "sys_platform == \"win32\""} +exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} +iniconfig = "*" +packaging = "*" +pluggy = ">=1.5,<2" +tomli = {version = ">=1", markers = "python_version < \"3.11\""} + +[package.extras] +dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] + +[[package]] +name = "pytest-runner" +version = "6.0.1" +description = "Invoke py.test as distutils command with dependency resolution" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pytest-runner-6.0.1.tar.gz", hash = "sha256:70d4739585a7008f37bf4933c013fdb327b8878a5a69fcbb3316c88882f0f49b"}, + {file = "pytest_runner-6.0.1-py3-none-any.whl", hash = "sha256:ea326ed6f6613992746062362efab70212089a4209c08d67177b3df1c52cd9f2"}, +] + +[package.extras] +docs = ["jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx"] +testing = ["pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.0.1)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-virtualenv", "types-setuptools"] + +[[package]] +name = "pytest-subtests" +version = "0.13.1" +description = "unittest subTest() support and subtests fixture" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pytest_subtests-0.13.1-py3-none-any.whl", hash = "sha256:ab616a22f64cd17c1aee65f18af94dbc30c444f8683de2b30895c3778265e3bd"}, + {file = "pytest_subtests-0.13.1.tar.gz", hash = "sha256:989e38f0f1c01bc7c6b2e04db7d9fd859db35d77c2c1a430c831a70cbf3fde2d"}, +] + +[package.dependencies] +attrs = ">=19.2.0" +pytest = ">=7.0" + +[[package]] +name = "radon" +version = "4.5.0" +description = "Code Metrics in Python" +optional = false +python-versions = "*" +files = [ + {file = "radon-4.5.0-py2.py3-none-any.whl", hash = "sha256:ad4c1b7a228cb4d33f7500e89326fd98d287938b96820e748ccdbd1a9bf91f0b"}, + {file = "radon-4.5.0.tar.gz", hash = "sha256:7afa65db14d759616ab68033e0e1caf1f624c97308dd256afa47518ecebddf6e"}, +] + +[package.dependencies] +colorama = {version = ">=0.4.1", markers = "python_version > \"3.4\""} +future = "*" +mando = ">=0.6,<0.7" + +[package.extras] +flake8 = ["flake8-polyfill"] + +[[package]] +name = "referencing" +version = "0.35.1" +description = "JSON Referencing + Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "referencing-0.35.1-py3-none-any.whl", hash = "sha256:eda6d3234d62814d1c64e305c1331c9a3a6132da475ab6382eaa997b21ee75de"}, + {file = "referencing-0.35.1.tar.gz", hash = "sha256:25b42124a6c8b632a425174f24087783efb348a6f1e0008e63cd4466fedf703c"}, +] + +[package.dependencies] +attrs = ">=22.2.0" +rpds-py = ">=0.7.0" + +[[package]] +name = "requests" +version = "2.32.3" +description = "Python HTTP for Humans." +optional = false +python-versions = ">=3.8" +files = [ + {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"}, + {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"}, +] + +[package.dependencies] +certifi = ">=2017.4.17" +charset-normalizer = ">=2,<4" +idna = ">=2.5,<4" +urllib3 = ">=1.21.1,<3" + +[package.extras] +socks = ["PySocks (>=1.5.6,!=1.5.7)"] +use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] + +[[package]] +name = "rpds-py" +version = "0.20.0" +description = "Python bindings to Rust's persistent data structures (rpds)" +optional = false +python-versions = ">=3.8" +files = [ + {file = "rpds_py-0.20.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:3ad0fda1635f8439cde85c700f964b23ed5fc2d28016b32b9ee5fe30da5c84e2"}, + {file = "rpds_py-0.20.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9bb4a0d90fdb03437c109a17eade42dfbf6190408f29b2744114d11586611d6f"}, + {file = "rpds_py-0.20.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c6377e647bbfd0a0b159fe557f2c6c602c159fc752fa316572f012fc0bf67150"}, + {file = "rpds_py-0.20.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:eb851b7df9dda52dc1415ebee12362047ce771fc36914586b2e9fcbd7d293b3e"}, + {file = "rpds_py-0.20.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1e0f80b739e5a8f54837be5d5c924483996b603d5502bfff79bf33da06164ee2"}, + {file = "rpds_py-0.20.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5a8c94dad2e45324fc74dce25e1645d4d14df9a4e54a30fa0ae8bad9a63928e3"}, + {file = "rpds_py-0.20.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8e604fe73ba048c06085beaf51147eaec7df856824bfe7b98657cf436623daf"}, + {file = "rpds_py-0.20.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:df3de6b7726b52966edf29663e57306b23ef775faf0ac01a3e9f4012a24a4140"}, + {file = "rpds_py-0.20.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:cf258ede5bc22a45c8e726b29835b9303c285ab46fc7c3a4cc770736b5304c9f"}, + {file = "rpds_py-0.20.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:55fea87029cded5df854ca7e192ec7bdb7ecd1d9a3f63d5c4eb09148acf4a7ce"}, + {file = "rpds_py-0.20.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ae94bd0b2f02c28e199e9bc51485d0c5601f58780636185660f86bf80c89af94"}, + {file = "rpds_py-0.20.0-cp310-none-win32.whl", hash = "sha256:28527c685f237c05445efec62426d285e47a58fb05ba0090a4340b73ecda6dee"}, + {file = "rpds_py-0.20.0-cp310-none-win_amd64.whl", hash = "sha256:238a2d5b1cad28cdc6ed15faf93a998336eb041c4e440dd7f902528b8891b399"}, + {file = "rpds_py-0.20.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:ac2f4f7a98934c2ed6505aead07b979e6f999389f16b714448fb39bbaa86a489"}, + {file = "rpds_py-0.20.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:220002c1b846db9afd83371d08d239fdc865e8f8c5795bbaec20916a76db3318"}, + {file = "rpds_py-0.20.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8d7919548df3f25374a1f5d01fbcd38dacab338ef5f33e044744b5c36729c8db"}, + {file = "rpds_py-0.20.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:758406267907b3781beee0f0edfe4a179fbd97c0be2e9b1154d7f0a1279cf8e5"}, + {file = "rpds_py-0.20.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3d61339e9f84a3f0767b1995adfb171a0d00a1185192718a17af6e124728e0f5"}, + {file = "rpds_py-0.20.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1259c7b3705ac0a0bd38197565a5d603218591d3f6cee6e614e380b6ba61c6f6"}, + {file = "rpds_py-0.20.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5c1dc0f53856b9cc9a0ccca0a7cc61d3d20a7088201c0937f3f4048c1718a209"}, + {file = "rpds_py-0.20.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7e60cb630f674a31f0368ed32b2a6b4331b8350d67de53c0359992444b116dd3"}, + {file = "rpds_py-0.20.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:dbe982f38565bb50cb7fb061ebf762c2f254ca3d8c20d4006878766e84266272"}, + {file = "rpds_py-0.20.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:514b3293b64187172bc77c8fb0cdae26981618021053b30d8371c3a902d4d5ad"}, + {file = "rpds_py-0.20.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d0a26ffe9d4dd35e4dfdd1e71f46401cff0181c75ac174711ccff0459135fa58"}, + {file = "rpds_py-0.20.0-cp311-none-win32.whl", hash = "sha256:89c19a494bf3ad08c1da49445cc5d13d8fefc265f48ee7e7556839acdacf69d0"}, + {file = "rpds_py-0.20.0-cp311-none-win_amd64.whl", hash = "sha256:c638144ce971df84650d3ed0096e2ae7af8e62ecbbb7b201c8935c370df00a2c"}, + {file = "rpds_py-0.20.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:a84ab91cbe7aab97f7446652d0ed37d35b68a465aeef8fc41932a9d7eee2c1a6"}, + {file = "rpds_py-0.20.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:56e27147a5a4c2c21633ff8475d185734c0e4befd1c989b5b95a5d0db699b21b"}, + {file = "rpds_py-0.20.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2580b0c34583b85efec8c5c5ec9edf2dfe817330cc882ee972ae650e7b5ef739"}, + {file = "rpds_py-0.20.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b80d4a7900cf6b66bb9cee5c352b2d708e29e5a37fe9bf784fa97fc11504bf6c"}, + {file = "rpds_py-0.20.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:50eccbf054e62a7b2209b28dc7a22d6254860209d6753e6b78cfaeb0075d7bee"}, + {file = "rpds_py-0.20.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:49a8063ea4296b3a7e81a5dfb8f7b2d73f0b1c20c2af401fb0cdf22e14711a96"}, + {file = "rpds_py-0.20.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ea438162a9fcbee3ecf36c23e6c68237479f89f962f82dae83dc15feeceb37e4"}, + {file = "rpds_py-0.20.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:18d7585c463087bddcfa74c2ba267339f14f2515158ac4db30b1f9cbdb62c8ef"}, + {file = "rpds_py-0.20.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d4c7d1a051eeb39f5c9547e82ea27cbcc28338482242e3e0b7768033cb083821"}, + {file = "rpds_py-0.20.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:e4df1e3b3bec320790f699890d41c59d250f6beda159ea3c44c3f5bac1976940"}, + {file = "rpds_py-0.20.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2cf126d33a91ee6eedc7f3197b53e87a2acdac63602c0f03a02dd69e4b138174"}, + {file = "rpds_py-0.20.0-cp312-none-win32.whl", hash = "sha256:8bc7690f7caee50b04a79bf017a8d020c1f48c2a1077ffe172abec59870f1139"}, + {file = "rpds_py-0.20.0-cp312-none-win_amd64.whl", hash = "sha256:0e13e6952ef264c40587d510ad676a988df19adea20444c2b295e536457bc585"}, + {file = "rpds_py-0.20.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:aa9a0521aeca7d4941499a73ad7d4f8ffa3d1affc50b9ea11d992cd7eff18a29"}, + {file = "rpds_py-0.20.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4a1f1d51eccb7e6c32ae89243cb352389228ea62f89cd80823ea7dd1b98e0b91"}, + {file = "rpds_py-0.20.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8a86a9b96070674fc88b6f9f71a97d2c1d3e5165574615d1f9168ecba4cecb24"}, + {file = "rpds_py-0.20.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6c8ef2ebf76df43f5750b46851ed1cdf8f109d7787ca40035fe19fbdc1acc5a7"}, + {file = "rpds_py-0.20.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b74b25f024b421d5859d156750ea9a65651793d51b76a2e9238c05c9d5f203a9"}, + {file = "rpds_py-0.20.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:57eb94a8c16ab08fef6404301c38318e2c5a32216bf5de453e2714c964c125c8"}, + {file = "rpds_py-0.20.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e1940dae14e715e2e02dfd5b0f64a52e8374a517a1e531ad9412319dc3ac7879"}, + {file = "rpds_py-0.20.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d20277fd62e1b992a50c43f13fbe13277a31f8c9f70d59759c88f644d66c619f"}, + {file = "rpds_py-0.20.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:06db23d43f26478303e954c34c75182356ca9aa7797d22c5345b16871ab9c45c"}, + {file = "rpds_py-0.20.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b2a5db5397d82fa847e4c624b0c98fe59d2d9b7cf0ce6de09e4d2e80f8f5b3f2"}, + {file = "rpds_py-0.20.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5a35df9f5548fd79cb2f52d27182108c3e6641a4feb0f39067911bf2adaa3e57"}, + {file = "rpds_py-0.20.0-cp313-none-win32.whl", hash = "sha256:fd2d84f40633bc475ef2d5490b9c19543fbf18596dcb1b291e3a12ea5d722f7a"}, + {file = "rpds_py-0.20.0-cp313-none-win_amd64.whl", hash = "sha256:9bc2d153989e3216b0559251b0c260cfd168ec78b1fac33dd485750a228db5a2"}, + {file = "rpds_py-0.20.0-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:f2fbf7db2012d4876fb0d66b5b9ba6591197b0f165db8d99371d976546472a24"}, + {file = "rpds_py-0.20.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:1e5f3cd7397c8f86c8cc72d5a791071431c108edd79872cdd96e00abd8497d29"}, + {file = "rpds_py-0.20.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ce9845054c13696f7af7f2b353e6b4f676dab1b4b215d7fe5e05c6f8bb06f965"}, + {file = "rpds_py-0.20.0-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c3e130fd0ec56cb76eb49ef52faead8ff09d13f4527e9b0c400307ff72b408e1"}, + {file = "rpds_py-0.20.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4b16aa0107ecb512b568244ef461f27697164d9a68d8b35090e9b0c1c8b27752"}, + {file = "rpds_py-0.20.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:aa7f429242aae2947246587d2964fad750b79e8c233a2367f71b554e9447949c"}, + {file = "rpds_py-0.20.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:af0fc424a5842a11e28956e69395fbbeab2c97c42253169d87e90aac2886d751"}, + {file = "rpds_py-0.20.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b8c00a3b1e70c1d3891f0db1b05292747f0dbcfb49c43f9244d04c70fbc40eb8"}, + {file = "rpds_py-0.20.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:40ce74fc86ee4645d0a225498d091d8bc61f39b709ebef8204cb8b5a464d3c0e"}, + {file = "rpds_py-0.20.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:4fe84294c7019456e56d93e8ababdad5a329cd25975be749c3f5f558abb48253"}, + {file = "rpds_py-0.20.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:338ca4539aad4ce70a656e5187a3a31c5204f261aef9f6ab50e50bcdffaf050a"}, + {file = "rpds_py-0.20.0-cp38-none-win32.whl", hash = "sha256:54b43a2b07db18314669092bb2de584524d1ef414588780261e31e85846c26a5"}, + {file = "rpds_py-0.20.0-cp38-none-win_amd64.whl", hash = "sha256:a1862d2d7ce1674cffa6d186d53ca95c6e17ed2b06b3f4c476173565c862d232"}, + {file = "rpds_py-0.20.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:3fde368e9140312b6e8b6c09fb9f8c8c2f00999d1823403ae90cc00480221b22"}, + {file = "rpds_py-0.20.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9824fb430c9cf9af743cf7aaf6707bf14323fb51ee74425c380f4c846ea70789"}, + {file = "rpds_py-0.20.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:11ef6ce74616342888b69878d45e9f779b95d4bd48b382a229fe624a409b72c5"}, + {file = "rpds_py-0.20.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c52d3f2f82b763a24ef52f5d24358553e8403ce05f893b5347098014f2d9eff2"}, + {file = "rpds_py-0.20.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9d35cef91e59ebbeaa45214861874bc6f19eb35de96db73e467a8358d701a96c"}, + {file = "rpds_py-0.20.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d72278a30111e5b5525c1dd96120d9e958464316f55adb030433ea905866f4de"}, + {file = "rpds_py-0.20.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b4c29cbbba378759ac5786730d1c3cb4ec6f8ababf5c42a9ce303dc4b3d08cda"}, + {file = "rpds_py-0.20.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6632f2d04f15d1bd6fe0eedd3b86d9061b836ddca4c03d5cf5c7e9e6b7c14580"}, + {file = "rpds_py-0.20.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:d0b67d87bb45ed1cd020e8fbf2307d449b68abc45402fe1a4ac9e46c3c8b192b"}, + {file = "rpds_py-0.20.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:ec31a99ca63bf3cd7f1a5ac9fe95c5e2d060d3c768a09bc1d16e235840861420"}, + {file = "rpds_py-0.20.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:22e6c9976e38f4d8c4a63bd8a8edac5307dffd3ee7e6026d97f3cc3a2dc02a0b"}, + {file = "rpds_py-0.20.0-cp39-none-win32.whl", hash = "sha256:569b3ea770c2717b730b61998b6c54996adee3cef69fc28d444f3e7920313cf7"}, + {file = "rpds_py-0.20.0-cp39-none-win_amd64.whl", hash = "sha256:e6900ecdd50ce0facf703f7a00df12374b74bbc8ad9fe0f6559947fb20f82364"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:617c7357272c67696fd052811e352ac54ed1d9b49ab370261a80d3b6ce385045"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:9426133526f69fcaba6e42146b4e12d6bc6c839b8b555097020e2b78ce908dcc"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:deb62214c42a261cb3eb04d474f7155279c1a8a8c30ac89b7dcb1721d92c3c02"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fcaeb7b57f1a1e071ebd748984359fef83ecb026325b9d4ca847c95bc7311c92"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d454b8749b4bd70dd0a79f428731ee263fa6995f83ccb8bada706e8d1d3ff89d"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d807dc2051abe041b6649681dce568f8e10668e3c1c6543ebae58f2d7e617855"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c3c20f0ddeb6e29126d45f89206b8291352b8c5b44384e78a6499d68b52ae511"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b7f19250ceef892adf27f0399b9e5afad019288e9be756d6919cb58892129f51"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:4f1ed4749a08379555cebf4650453f14452eaa9c43d0a95c49db50c18b7da075"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:dcedf0b42bcb4cfff4101d7771a10532415a6106062f005ab97d1d0ab5681c60"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:39ed0d010457a78f54090fafb5d108501b5aa5604cc22408fc1c0c77eac14344"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:bb273176be34a746bdac0b0d7e4e2c467323d13640b736c4c477881a3220a989"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f918a1a130a6dfe1d7fe0f105064141342e7dd1611f2e6a21cd2f5c8cb1cfb3e"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:f60012a73aa396be721558caa3a6fd49b3dd0033d1675c6d59c4502e870fcf0c"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3d2b1ad682a3dfda2a4e8ad8572f3100f95fad98cb99faf37ff0ddfe9cbf9d03"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:614fdafe9f5f19c63ea02817fa4861c606a59a604a77c8cdef5aa01d28b97921"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fa518bcd7600c584bf42e6617ee8132869e877db2f76bcdc281ec6a4113a53ab"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f0475242f447cc6cb8a9dd486d68b2ef7fbee84427124c232bff5f63b1fe11e5"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f90a4cd061914a60bd51c68bcb4357086991bd0bb93d8aa66a6da7701370708f"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:def7400461c3a3f26e49078302e1c1b38f6752342c77e3cf72ce91ca69fb1bc1"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:65794e4048ee837494aea3c21a28ad5fc080994dfba5b036cf84de37f7ad5074"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:faefcc78f53a88f3076b7f8be0a8f8d35133a3ecf7f3770895c25f8813460f08"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:5b4f105deeffa28bbcdff6c49b34e74903139afa690e35d2d9e3c2c2fba18cec"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:fdfc3a892927458d98f3d55428ae46b921d1f7543b89382fdb483f5640daaec8"}, + {file = "rpds_py-0.20.0.tar.gz", hash = "sha256:d72a210824facfdaf8768cf2d7ca25a042c30320b3020de2fa04640920d4e121"}, +] + +[[package]] +name = "setuptools" +version = "56.0.0" +description = "Easily download, build, install, upgrade, and uninstall Python packages" +optional = false +python-versions = ">=3.6" +files = [ + {file = "setuptools-56.0.0-py3-none-any.whl", hash = "sha256:7430499900e443375ba9449a9cc5d78506b801e929fef4a186496012f93683b5"}, + {file = "setuptools-56.0.0.tar.gz", hash = "sha256:08a1c0f99455307c48690f00d5c2ac2c1ccfab04df00454fef854ec145b81302"}, +] + +[package.extras] +certs = ["certifi (==2016.9.26)"] +docs = ["jaraco.packaging (>=8.2)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx", "sphinx-inline-tabs"] +ssl = ["wincertstore (==0.2)"] +testing = ["flake8-2020", "jaraco.envs", "jaraco.path (>=3.2.0)", "mock", "paver", "pip (>=19.1)", "pytest (>=4.6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.0.1)", "pytest-flake8", "pytest-mypy", "pytest-virtualenv (>=1.2.7)", "pytest-xdist", "sphinx", "virtualenv (>=13.0.0)", "wheel"] + +[[package]] +name = "six" +version = "1.16.0" +description = "Python 2 and 3 compatibility utilities" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +files = [ + {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, + {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, +] + +[[package]] +name = "sqlparse" +version = "0.5.1" +description = "A non-validating SQL parser." +optional = false +python-versions = ">=3.8" +files = [ + {file = "sqlparse-0.5.1-py3-none-any.whl", hash = "sha256:773dcbf9a5ab44a090f3441e2180efe2560220203dc2f8c0b0fa141e18b505e4"}, + {file = "sqlparse-0.5.1.tar.gz", hash = "sha256:bb6b4df465655ef332548e24f08e205afc81b9ab86cb1c45657a7ff173a3a00e"}, +] + +[package.extras] +dev = ["build", "hatch"] +doc = ["sphinx"] + +[[package]] +name = "tomli" +version = "2.0.1" +description = "A lil' TOML parser" +optional = false +python-versions = ">=3.7" +files = [ + {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, + {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, +] + +[[package]] +name = "typing-extensions" +version = "3.10.0.2" +description = "Backported and Experimental Type Hints for Python 3.5+" +optional = false +python-versions = "*" +files = [ + {file = "typing_extensions-3.10.0.2-py2-none-any.whl", hash = "sha256:d8226d10bc02a29bcc81df19a26e56a9647f8b0a6d4a83924139f4a8b01f17b7"}, + {file = "typing_extensions-3.10.0.2-py3-none-any.whl", hash = "sha256:f1d25edafde516b146ecd0613dabcc61409817af4766fbbcfb8d1ad4ec441a34"}, + {file = "typing_extensions-3.10.0.2.tar.gz", hash = "sha256:49f75d16ff11f1cd258e1b988ccff82a3ca5570217d7ad8c5f48205dd99a677e"}, +] + +[[package]] +name = "typing-inspect" +version = "0.9.0" +description = "Runtime inspection utilities for typing module." +optional = false +python-versions = "*" +files = [ + {file = "typing_inspect-0.9.0-py3-none-any.whl", hash = "sha256:9ee6fc59062311ef8547596ab6b955e1b8aa46242d854bfc78f4f6b0eff35f9f"}, + {file = "typing_inspect-0.9.0.tar.gz", hash = "sha256:b23fc42ff6f6ef6954e4852c1fb512cdd18dbea03134f91f856a95ccc9461f78"}, +] + +[package.dependencies] +mypy-extensions = ">=0.3.0" +typing-extensions = ">=3.7.4" + +[[package]] +name = "tzdata" +version = "2024.1" +description = "Provider of IANA time zone data" +optional = false +python-versions = ">=2" +files = [ + {file = "tzdata-2024.1-py2.py3-none-any.whl", hash = "sha256:9068bc196136463f5245e51efda838afa15aaeca9903f49050dfa2679db4d252"}, + {file = "tzdata-2024.1.tar.gz", hash = "sha256:2674120f8d891909751c38abcdfd386ac0a5a1127954fbc332af6b5ceae07efd"}, +] + +[[package]] +name = "urllib3" +version = "2.2.3" +description = "HTTP library with thread-safe connection pooling, file post, and more." +optional = false +python-versions = ">=3.8" +files = [ + {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, + {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, +] + +[package.extras] +brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] +h2 = ["h2 (>=4,<5)"] +socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] +zstd = ["zstandard (>=0.18.0)"] + +[[package]] +name = "wps-light" +version = "0.15.3" +description = "The strictest and most opinionated python linter ever (lighter fork)." +optional = false +python-versions = ">=3.6,<4.0" +files = [ + {file = "wps-light-0.15.3.tar.gz", hash = "sha256:e3040611340796427c346006298954c859ab12471cf31ec60d6254af95d70c37"}, + {file = "wps_light-0.15.3-py3-none-any.whl", hash = "sha256:1193bad23fd2bfd74c0cb2558f3dd66eb0619cfaee895a1c113252d1965d555e"}, +] + +[package.dependencies] +astor = ">=0.8,<0.9" +attrs = "*" +flake8 = ">=3.7,<4.0" +flake8-polyfill = ">=1.0.2,<2.0.0" +pygments = ">=2.4,<3.0" +typing_extensions = ">=3.6,<4.0" + +[[package]] +name = "wrapt" +version = "1.16.0" +description = "Module for decorators, wrappers and monkey patching." +optional = false +python-versions = ">=3.6" +files = [ + {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, + {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, + {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, + {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, + {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, + {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, + {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, + {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, + {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, + {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, + {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, + {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, + {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, + {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, + {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, + {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, + {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, + {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, + {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, + {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, + {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, + {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, + {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, + {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, + {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, + {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, + {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, + {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, + {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, + {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, + {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, + {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, + {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, + {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, + {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, + {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, + {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, + {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, + {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, + {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, + {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, + {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, + {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, + {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, + {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, + {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, + {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, + {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, + {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, + {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, + {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, + {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, + {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, + {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, + {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, + {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, + {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, + {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, + {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, + {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, + {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, + {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, + {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, + {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, + {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, + {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, + {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, + {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, + {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, + {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, +] + +[metadata] +lock-version = "2.0" +python-versions = "~3.10" +content-hash = "313305578f918bbeb47a11a96f72df48fbabca013ad8ad2222f5ceb9518bd357" diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 00000000..55fabe23 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,70 @@ +[tool.poetry] +name = "hyperstyle" +version = "1.5.0" +description = "A tool for running a set of pre-configured linters and evaluating code quality." +authors = ["Hyperskill Team"] +readme = "README.md" +keywords = ["code review"] +classifiers = [ + "Development Status :: 5 - Production/Stable", + "Environment :: Console", + "Intended Audience :: Developers", + "Intended Audience :: Education", + "Intended Audience :: Science/Research", + "License :: OSI Approved :: Apache Software License", + "Operating System :: OS Independent", + "Programming Language :: Python :: 3", + "Topic :: Education", +] + +[project.urls] +Homepage = "https://support.hyperskill.org/hc/en-us/articles/360049582712-Code-style-Code-quality" +Repository = "https://github.com/hyperskill/hyperstyle" + +[project.scripts] +review = "hyperstyle.src.python.review.run_tool:main" + +[tool.poetry.dependencies] +python = "~3.10" +setuptools = "56.0.0" +# python code analysis tools +pylint = "2.13.9" +pylint-django = "2.5.3" +flake8 = "3.9.0" +dataclasses-json="0.5.7" +# flake8 plugins +flake8-plugin-utils = "1.3.2" +flake8-bugbear = "21.4.3" +flake8-builtins = "1.5.3" +flake8-comprehensions = "3.4.0" +flake8-eradicate = "1.0.0" +flake8-import-order = "0.18.1" +flake8-polyfill = "1.0.2" +flake8-return = "1.1.2" +flake8-spellcheck = "0.24.0" +mccabe = "0.6.1" +pep8-naming = "0.11.1" +wps-light = "0.15.3" +flake8-broken-line = "0.3.0" +flake8-string-format = "0.3.0" +flake8-commas = "2.0.0" +cohesion = "1.0.0" +radon = "4.5.0" +# extra libraries and frameworks +argparse = "1.4.0" +django = "4.2.5" +requests = "2.32.3" +# grpc +grpcio-tools = "1.66.1" +protobuf = "5.27.2" + + +[tool.poetry.group.dev.dependencies] +pytest = "8.3.3" +pytest-runner = "6.0.1" +pytest-subtests = "0.13.1" +jsonschema = "4.23.0" + +[build-system] +requires = ["poetry-core"] +build-backend = "poetry.core.masonry.api" diff --git a/requirements-test.txt b/requirements-test.txt deleted file mode 100644 index 824641d9..00000000 --- a/requirements-test.txt +++ /dev/null @@ -1,4 +0,0 @@ -pytest==6.2.3 -pytest-runner==5.2 -pytest-subtests==0.4.0 -jsonschema==3.2.0 diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index fd49f0a6..00000000 --- a/requirements.txt +++ /dev/null @@ -1,30 +0,0 @@ -setuptools==56.0.0 - -# python code analysis tools -pylint==2.13.0 -pylint-django==2.5.3 -flake8==3.9.0 - -# flake8 plugins -flake8-plugin-utils==1.3.2 -flake8-bugbear==21.4.3 -flake8-builtins==1.5.3 -flake8-comprehensions==3.4.0 -flake8-eradicate==1.0.0 -flake8-import-order==0.18.1 -flake8-polyfill==1.0.2 -flake8-return==1.1.2 -flake8-spellcheck==0.24.0 -mccabe==0.6.1 -pep8-naming==0.11.1 -wps-light==0.15.2 -flake8-broken-line==0.3.0 -flake8-string-format==0.3.0 -flake8-commas==2.0.0 -cohesion==1.0.0 -radon==4.5.0 - -# extra libraries and frameworks -django==4.2.5 -requests==2.25.1 -argparse==1.4.0 \ No newline at end of file diff --git a/setup.py b/setup.py deleted file mode 100644 index 33ebde4e..00000000 --- a/setup.py +++ /dev/null @@ -1,76 +0,0 @@ -import os -from pathlib import Path -from typing import List - -from setuptools import find_packages, setup - -current_dir = Path(__file__).parent.absolute() - - -def get_long_description() -> str: - with open(current_dir / 'README.md', encoding='utf-8') as f: - return f.read() - - -def get_version() -> str: - with open(current_dir / 'VERSION.md') as version_file: - return version_file.read().replace('\n', '') - - -def get_inspectors_additional_files() -> List[str]: - inspectors_path = current_dir / 'hyperstyle' / 'src' / 'python' / 'review' / 'inspectors' - configs = ['xml', 'yml', 'eslintrc', 'flake8', 'txt', 'pylintrc'] - result = [] - for root, _, files in os.walk(inspectors_path): - for file in files: - if not file.endswith('.py') and file.split('.')[-1] in configs: - result.append(str(Path(root) / file)) - return result - - -def get_requires() -> List[str]: - with open(current_dir / 'requirements.txt') as requirements_file: - return requirements_file.read().split('\n') - - -setup( - name='hyperstyle', - version=get_version(), - description='A tool for running a set of pre-configured linters and evaluating code quality.', - long_description=get_long_description(), - long_description_content_type='text/markdown', - url='https://github.com/hyperskill/hyperstyle', - author='Stepik.org', - author_email='ivan.magda@stepik.org', - classifiers=[ - 'Development Status :: 3 - Alpha', - 'Intended Audience :: Developers', - 'Topic :: Software Development :: Build Tools', - 'License :: OSI Approved :: MIT License', - 'Programming Language :: Python :: 3', - 'Operating System :: OS Independent', - ], - keywords='code review', - python_requires='>=3.8, <4', - install_requires=get_requires(), - include_package_data=True, - packages=find_packages(exclude=[ - '*.unit_tests', - '*.unit_tests.*', - 'unit_tests.*', - 'unit_tests', - '*.functional_tests', - '*.functional_tests.*', - 'functional_tests.*', - 'functional_tests', - ]), - zip_safe=False, - package_data={ - '': get_inspectors_additional_files(), - }, - entry_points={ - 'console_scripts': [ - 'review=hyperstyle.src.python.review.run_tool:main', - ], - }, -) diff --git a/setup_environment.sh b/setup_environment.sh index cf2bbe85..a782d594 100755 --- a/setup_environment.sh +++ b/setup_environment.sh @@ -73,24 +73,13 @@ echo "The variables are defined." echo -read -p "Do you want to install Python requirements for the Hyperstyle project? (Y/n): " -r +read -p "Do you want to install Python development requirements for the Hyperstyle project? (Y/n): " -r if [[ $REPLY =~ ^[Yy]$ ]]; then - echo "Installing Python requirements..." - pip install --no-cache-dir -r requirements.txt - check_return_code $? "Python requirements installed." "Python requirements installation failed." + echo "Installing Python development requirements..." + pip install --no-cache-dir -r requirements-dev.txt + check_return_code $? "Python development requirements installed." "Python development requirements installation failed." else - echo "Python requirements installation skipped." -fi - -echo - -read -p "Do you want to install Python test requirements for the Hyperstyle project? (Y/n): " -r -if [[ $REPLY =~ ^[Yy]$ ]]; then - echo "Installing Python test requirements..." - pip install --no-cache-dir -r requirements-test.txt - check_return_code $? "Python test requirements installed." "Python test requirements installation failed." -else - echo "Python test requirements installation skipped." + echo "Python development requirements installation skipped." fi echo @@ -147,3 +136,7 @@ if need_to_install_linter "golangci-lint" "${GOLANG_LINT_DIRECTORY}"; then else echo "Golangci-lint ${GOLANG_LINT_VERSION} installation skipped." fi + +echo "Generating proto files ..." + export PROTO_PATH="hyperstyle/src/python/review/inspectors/common/inspector/proto" + python3 -m grpc_tools.protoc --proto_path=. --python_out=. --pyi_out=. --grpc_python_out=. ${PROTO_PATH}/model.proto diff --git a/test/python/functional_tests/conftest.py b/test/python/functional_tests/conftest.py index 89fac5e8..abeb3445 100644 --- a/test/python/functional_tests/conftest.py +++ b/test/python/functional_tests/conftest.py @@ -1,5 +1,8 @@ +import sys from dataclasses import dataclass, field from pathlib import Path + +from hyperstyle.src.python.review.inspectors.common.inspector.inspector_type import InspectorType from test.python import TEST_DATA_FOLDER from typing import List, Optional @@ -25,15 +28,20 @@ class LocalCommandBuilder: new_format: bool = False group_by_difficulty: bool = False history: Optional[str] = None + ij_config: Optional[str] = None def build(self) -> List[str]: assert self.path is not None command = [ - 'python3', (MAIN_FOLDER.parent / 'review/run_tool.py'), + sys.executable, (MAIN_FOLDER.parent / 'review/run_tool.py'), RunToolArgument.VERBOSITY.value.long_name, str(self.verbosity), ] + # TODO: remove after adding a test server + self.disable.append(InspectorType.IJ_PYTHON.value) + self.disable.append(InspectorType.IJ_KOTLIN.value) + if self.disable: command.extend([RunToolArgument.DISABLE.value.long_name, ','.join(self.disable)]) @@ -49,6 +57,9 @@ def build(self) -> List[str]: if self.history is not None: command.extend([RunToolArgument.HISTORY.value.long_name, self.history]) + if self.ij_config is not None: + command.extend([RunToolArgument.IJ_CONFIG.value.long_name, self.ij_config]) + if self.group_by_difficulty: command.append(RunToolArgument.GROUP_BY_DIFFICULTY.value.long_name) diff --git a/test/python/functional_tests/test_difficulty_levels.py b/test/python/functional_tests/test_difficulty_levels.py index fd138e32..b38e3b3c 100644 --- a/test/python/functional_tests/test_difficulty_levels.py +++ b/test/python/functional_tests/test_difficulty_levels.py @@ -4,7 +4,7 @@ from typing import Dict, Optional import pytest -from hyperstyle.src.python.review.inspectors.common.tips import get_cohesion_tip +from hyperstyle.src.python.review.inspectors.common.issue.tips import get_cohesion_tip def _get_output_json(local_command: LocalCommandBuilder, file_path: str, history: Optional[str] = None) -> Dict: diff --git a/test/python/inspectors/conftest.py b/test/python/inspectors/conftest.py index d7e9524c..c807bf2e 100644 --- a/test/python/inspectors/conftest.py +++ b/test/python/inspectors/conftest.py @@ -6,7 +6,7 @@ import pytest from hyperstyle.src.python.review.common.file_system import new_temp_dir -from hyperstyle.src.python.review.inspectors.issue import BaseIssue, IssueType +from hyperstyle.src.python.review.inspectors.common.issue.issue import BaseIssue, IssueType from hyperstyle.src.python.review.reviewers.utils.metadata_exploration import explore_file, FileMetadata diff --git a/test/python/inspectors/test_checkstyle_inspector.py b/test/python/inspectors/test_checkstyle_inspector.py index b0823e46..f60d1aec 100644 --- a/test/python/inspectors/test_checkstyle_inspector.py +++ b/test/python/inspectors/test_checkstyle_inspector.py @@ -7,7 +7,7 @@ from hyperstyle.src.python.review.common.language import Language from hyperstyle.src.python.review.inspectors.checkstyle.checkstyle import CheckstyleInspector from hyperstyle.src.python.review.inspectors.checkstyle.issue_configs import ISSUE_CONFIGS -from hyperstyle.src.python.review.inspectors.common.tips import ( +from hyperstyle.src.python.review.inspectors.common.issue.tips import ( get_bool_expr_len_tip, get_cyclomatic_complexity_tip, get_func_len_tip, @@ -15,8 +15,8 @@ get_magic_number_tip, ) from hyperstyle.src.python.review.inspectors.common.xml_parser import parse_xml_file_result -from hyperstyle.src.python.review.inspectors.inspector_type import InspectorType -from hyperstyle.src.python.review.inspectors.issue import ( +from hyperstyle.src.python.review.inspectors.common.inspector.inspector_type import InspectorType +from hyperstyle.src.python.review.inspectors.common.issue.issue import ( BoolExprLenIssue, CodeIssue, CyclomaticComplexityIssue, @@ -25,7 +25,7 @@ IssueType, LineLenIssue, ) -from hyperstyle.src.python.review.inspectors.issue_configs import IssueConfigsHandler +from hyperstyle.src.python.review.inspectors.common.issue.issue_configs import IssueConfigsHandler from hyperstyle.src.python.review.reviewers.utils.issues_filter import filter_low_measure_issues FILE_NAME_AND_ISSUES = [ diff --git a/test/python/inspectors/test_detekt_inspector.py b/test/python/inspectors/test_detekt_inspector.py index 40e8ceef..29c8291c 100644 --- a/test/python/inspectors/test_detekt_inspector.py +++ b/test/python/inspectors/test_detekt_inspector.py @@ -3,7 +3,7 @@ import pytest from hyperstyle.src.python.review.common.language import Language -from hyperstyle.src.python.review.inspectors.common.tips import ( +from hyperstyle.src.python.review.inspectors.common.issue.tips import ( get_bool_expr_len_tip, get_cyclomatic_complexity_tip, get_func_len_tip, diff --git a/test/python/inspectors/test_eslint_inspector.py b/test/python/inspectors/test_eslint_inspector.py index 81b77ffb..29229297 100644 --- a/test/python/inspectors/test_eslint_inspector.py +++ b/test/python/inspectors/test_eslint_inspector.py @@ -3,7 +3,7 @@ import pytest from hyperstyle.src.python.review.common.language import Language -from hyperstyle.src.python.review.inspectors.common.tips import get_cyclomatic_complexity_tip +from hyperstyle.src.python.review.inspectors.common.issue.tips import get_cyclomatic_complexity_tip from hyperstyle.src.python.review.inspectors.eslint.eslint import ESLintInspector from hyperstyle.src.python.review.reviewers.utils.issues_filter import filter_low_measure_issues diff --git a/test/python/inspectors/test_filter_duplicate_issues.py b/test/python/inspectors/test_filter_duplicate_issues.py index 92d17b4e..324c0754 100644 --- a/test/python/inspectors/test_filter_duplicate_issues.py +++ b/test/python/inspectors/test_filter_duplicate_issues.py @@ -1,7 +1,7 @@ from pathlib import Path -from hyperstyle.src.python.review.inspectors.inspector_type import InspectorType -from hyperstyle.src.python.review.inspectors.issue import CodeIssue, IssueDifficulty, IssueType +from hyperstyle.src.python.review.inspectors.common.inspector.inspector_type import InspectorType +from hyperstyle.src.python.review.inspectors.common.issue.issue import CodeIssue, IssueDifficulty, IssueType from hyperstyle.src.python.review.reviewers.utils.issues_filter import filter_duplicate_issues diff --git a/test/python/inspectors/test_flake8_inspector.py b/test/python/inspectors/test_flake8_inspector.py index 7435cb17..df290731 100644 --- a/test/python/inspectors/test_flake8_inspector.py +++ b/test/python/inspectors/test_flake8_inspector.py @@ -4,7 +4,7 @@ import pytest from hyperstyle.src.python.review.common.language import Language -from hyperstyle.src.python.review.inspectors.common.tips import ( +from hyperstyle.src.python.review.inspectors.common.issue.tips import ( get_augmented_assign_pattern_tip, get_cohesion_tip, get_cyclomatic_complexity_tip, @@ -12,7 +12,7 @@ get_magic_number_tip, ) from hyperstyle.src.python.review.inspectors.flake8.flake8 import Flake8Inspector -from hyperstyle.src.python.review.inspectors.issue import IssueType +from hyperstyle.src.python.review.inspectors.common.issue.issue import IssueType from hyperstyle.src.python.review.reviewers.utils.issues_filter import filter_low_measure_issues FILE_NAMES_AND_N_ISSUES = [ diff --git a/test/python/inspectors/test_golang_lint_inspector.py b/test/python/inspectors/test_golang_lint_inspector.py index c66a1fca..cc68e5a9 100644 --- a/test/python/inspectors/test_golang_lint_inspector.py +++ b/test/python/inspectors/test_golang_lint_inspector.py @@ -5,7 +5,7 @@ import pytest from hyperstyle.src.python.review.common.language import Language -from hyperstyle.src.python.review.inspectors.common.tips import ( +from hyperstyle.src.python.review.inspectors.common.issue.tips import ( get_cyclomatic_complexity_tip, get_func_len_tip, get_line_len_tip, @@ -13,8 +13,8 @@ get_maintainability_index_tip, ) from hyperstyle.src.python.review.inspectors.golang_lint.golang_lint import GolangLintInspector -from hyperstyle.src.python.review.inspectors.inspector_type import InspectorType -from hyperstyle.src.python.review.inspectors.issue import ( +from hyperstyle.src.python.review.inspectors.common.inspector.inspector_type import InspectorType +from hyperstyle.src.python.review.inspectors.common.issue.issue import ( CodeIssue, CyclomaticComplexityIssue, FuncLenIssue, diff --git a/test/python/inspectors/test_issue_configs.py b/test/python/inspectors/test_issue_configs.py index 63be075d..fba85966 100644 --- a/test/python/inspectors/test_issue_configs.py +++ b/test/python/inspectors/test_issue_configs.py @@ -2,7 +2,7 @@ from typing import Callable, Dict, List, Optional, Pattern, Tuple, Type, Union import pytest -from hyperstyle.src.python.review.inspectors.issue_configs import ( +from hyperstyle.src.python.review.inspectors.common.issue.issue_configs import ( IssueConfig, IssueConfigsHandler, IssueDescriptionParser, diff --git a/test/python/inspectors/test_local_review.py b/test/python/inspectors/test_local_review.py index 6fc09fa6..1004b776 100644 --- a/test/python/inspectors/test_local_review.py +++ b/test/python/inspectors/test_local_review.py @@ -1,5 +1,7 @@ import json from collections import namedtuple + +from hyperstyle.src.python.review.inspectors.common.inspector.inspector_type import InspectorType from test.python.inspectors import PYTHON_DATA_FOLDER import pytest @@ -19,7 +21,7 @@ @pytest.fixture def config() -> ApplicationConfig: return ApplicationConfig( - disabled_inspectors=set(), + disabled_inspectors={InspectorType.IJ_PYTHON}, allow_duplicates=False, n_cpu=1, inspectors_config={"n_cpu": 1}, diff --git a/test/python/inspectors/test_out_of_range_issues.py b/test/python/inspectors/test_out_of_range_issues.py index 0dc60493..89e6d4d5 100644 --- a/test/python/inspectors/test_out_of_range_issues.py +++ b/test/python/inspectors/test_out_of_range_issues.py @@ -1,7 +1,7 @@ from pathlib import Path -from hyperstyle.src.python.review.inspectors.inspector_type import InspectorType -from hyperstyle.src.python.review.inspectors.issue import BaseIssue, CodeIssue, IssueDifficulty, IssueType +from hyperstyle.src.python.review.inspectors.common.inspector.inspector_type import InspectorType +from hyperstyle.src.python.review.inspectors.common.issue.issue import BaseIssue, CodeIssue, IssueDifficulty, IssueType from hyperstyle.src.python.review.reviewers.common import filter_out_of_range_issues DEFAULT_PATH = Path('test_out_of_range_issues.py') diff --git a/test/python/inspectors/test_pmd_inspector.py b/test/python/inspectors/test_pmd_inspector.py index 94ea7d5f..7cc9e559 100644 --- a/test/python/inspectors/test_pmd_inspector.py +++ b/test/python/inspectors/test_pmd_inspector.py @@ -4,8 +4,8 @@ import pytest from hyperstyle.src.python.review.common.language_version import LanguageVersion -from hyperstyle.src.python.review.inspectors.inspector_type import InspectorType -from hyperstyle.src.python.review.inspectors.issue import CodeIssue, IssueDifficulty, IssueType +from hyperstyle.src.python.review.inspectors.common.inspector.inspector_type import InspectorType +from hyperstyle.src.python.review.inspectors.common.issue.issue import CodeIssue, IssueDifficulty, IssueType from hyperstyle.src.python.review.inspectors.pmd.pmd import DEFAULT_JAVA_VERSION, PMDInspector from .conftest import use_file_metadata diff --git a/test/python/inspectors/test_pylint_inspector.py b/test/python/inspectors/test_pylint_inspector.py index a25a4339..69c89d11 100644 --- a/test/python/inspectors/test_pylint_inspector.py +++ b/test/python/inspectors/test_pylint_inspector.py @@ -2,7 +2,7 @@ from test.python.inspectors import PYLINT_DATA_FOLDER, PYTHON_DATA_FOLDER import pytest -from hyperstyle.src.python.review.inspectors.issue import IssueType +from hyperstyle.src.python.review.inspectors.common.issue.issue import IssueType from hyperstyle.src.python.review.inspectors.pylint.pylint import PylintInspector from .conftest import use_file_metadata diff --git a/test/python/inspectors/test_python_ast.py b/test/python/inspectors/test_python_ast.py index 0d1e4692..1439af02 100644 --- a/test/python/inspectors/test_python_ast.py +++ b/test/python/inspectors/test_python_ast.py @@ -3,8 +3,8 @@ from test.python.inspectors.conftest import use_file_metadata import pytest -from hyperstyle.src.python.review.inspectors.common.tips import get_bool_expr_len_tip, get_func_len_tip -from hyperstyle.src.python.review.inspectors.inspector_type import InspectorType +from hyperstyle.src.python.review.inspectors.common.issue.tips import get_bool_expr_len_tip, get_func_len_tip +from hyperstyle.src.python.review.inspectors.common.inspector.inspector_type import InspectorType from hyperstyle.src.python.review.inspectors.pyast.python_ast import ( BoolExpressionLensGatherer, FunctionLensGatherer, diff --git a/test/python/inspectors/test_radon_inspector.py b/test/python/inspectors/test_radon_inspector.py index 420c768a..0d7e9404 100644 --- a/test/python/inspectors/test_radon_inspector.py +++ b/test/python/inspectors/test_radon_inspector.py @@ -4,8 +4,8 @@ import pytest from hyperstyle.src.python.review.common.language import Language -from hyperstyle.src.python.review.inspectors.common.tips import get_maintainability_index_tip -from hyperstyle.src.python.review.inspectors.issue import IssueType +from hyperstyle.src.python.review.inspectors.common.issue.tips import get_maintainability_index_tip +from hyperstyle.src.python.review.inspectors.common.issue.issue import IssueType from hyperstyle.src.python.review.inspectors.radon.radon import RadonInspector from hyperstyle.src.python.review.reviewers.utils.issues_filter import filter_low_measure_issues diff --git a/test/python/quality/test_penalty.py b/test/python/quality/test_penalty.py index 0947c46d..fcb941c7 100644 --- a/test/python/quality/test_penalty.py +++ b/test/python/quality/test_penalty.py @@ -2,8 +2,8 @@ from typing import List, Set import pytest -from hyperstyle.src.python.review.inspectors.inspector_type import InspectorType -from hyperstyle.src.python.review.inspectors.issue import BaseIssue, IssueDifficulty, IssueType +from hyperstyle.src.python.review.inspectors.common.inspector.inspector_type import InspectorType +from hyperstyle.src.python.review.inspectors.common.issue.issue import BaseIssue, IssueDifficulty, IssueType from hyperstyle.src.python.review.quality.penalty import categorize, PreviousIssue, Punisher punisher = Punisher([], []) diff --git a/test/resources/inspectors/python/case39_no_issues.py b/test/resources/inspectors/python/case39_no_issues.py index 1385fe3e..f7cf60e1 100644 --- a/test/resources/inspectors/python/case39_no_issues.py +++ b/test/resources/inspectors/python/case39_no_issues.py @@ -1 +1 @@ -print("Hello, world!") \ No newline at end of file +print("Hello, world!") diff --git a/whitelist.txt b/whitelist.txt index 50298483..ad4d1ecc 100644 --- a/whitelist.txt +++ b/whitelist.txt @@ -9,6 +9,7 @@ ECMA EXPR G10 IGNORECASE +IJ INTELLIJ Intelli JS @@ -33,6 +34,7 @@ astype atclause barmode bce +bdist bgcolor binarizer capsys @@ -42,6 +44,7 @@ cbo changelog checkstyle cloneable +cmdclass concat config configs @@ -91,6 +94,7 @@ exprs f1 file filemode +filepath fillna formatter fs @@ -106,12 +110,14 @@ getuid gradle groupby groupdict +grpc hashtable hline hyperstyle idiv idx ignorecase +ij iloc inerop initializer @@ -182,6 +188,7 @@ parametrize params parsers pathlib +pb2 pickler plotly pmd @@ -192,6 +199,8 @@ preprocess preprocessing pretrained println +proto +protoc punisher puppycrawl pyast @@ -207,6 +216,7 @@ removeprefix rfind rmdir runtime +sdist setdefault setslice showline