From 041091f37f9ab615e121d5aafa37bf23ef72ba13 Mon Sep 17 00:00:00 2001 From: "John L. Villalovos" Date: Tue, 7 Dec 2021 14:16:04 -0800 Subject: [PATCH 1/3] chore: add initial pylint check Initial pylint check is added. A LONG list of disabled checks is also added. In the future we should work through the list and resolve the errors or disable them on a more granular level. --- .github/workflows/lint.yml | 2 + .pre-commit-config.yaml | 9 ++++ gitlab/v4/objects/merge_request_approvals.py | 17 +++---- gitlab/v4/objects/projects.py | 17 ++++--- pyproject.toml | 47 ++++++++++++++++++++ requirements-lint.txt | 4 +- tox.ini | 22 ++++++--- 7 files changed, 97 insertions(+), 21 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index ceb0f5d1e..259cd7186 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -35,3 +35,5 @@ jobs: run: tox -e mypy - name: Run isort import order checker (https://pycqa.github.io/isort/) run: tox -e isort -- --check + - name: Run pylint Python code static checker (https://www.pylint.org/) + run: tox -e pylint diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 21f832948..56420c775 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -20,6 +20,15 @@ repos: rev: 5.9.3 hooks: - id: isort + - repo: https://github.com/pycqa/pylint + rev: v2.12.2 + hooks: + - id: pylint + additional_dependencies: + - argcomplete==1.12.3 + - requests==2.26.0 + - requests-toolbelt==0.9.1 + files: 'gitlab/' - repo: https://github.com/pre-commit/mirrors-mypy rev: v0.910 hooks: diff --git a/gitlab/v4/objects/merge_request_approvals.py b/gitlab/v4/objects/merge_request_approvals.py index 0882edc59..f05b9778e 100644 --- a/gitlab/v4/objects/merge_request_approvals.py +++ b/gitlab/v4/objects/merge_request_approvals.py @@ -140,7 +140,7 @@ def set_approvers( approval_rules: ProjectMergeRequestApprovalRuleManager = ( self._parent.approval_rules ) - """ update any existing approval rule matching the name""" + # update any existing approval rule matching the name existing_approval_rules = approval_rules.list() for ar in existing_approval_rules: if ar.name == approval_rule_name: @@ -149,7 +149,7 @@ def set_approvers( ar.group_ids = data["group_ids"] ar.save() return ar - """ if there was no rule matching the rule name, create a new one""" + # if there was no rule matching the rule name, create a new one return approval_rules.create(data=data) @@ -171,13 +171,13 @@ def save(self, **kwargs: Any) -> None: GitlabAuthenticationError: If authentication is not correct GitlabUpdateError: If the server cannot perform the request """ - # There is a mismatch between the name of our id attribute and the put REST API name for the - # project_id, so we override it here. + # There is a mismatch between the name of our id attribute and the put + # REST API name for the project_id, so we override it here. self.approval_rule_id = self.id self.merge_request_iid = self._parent_attrs["mr_iid"] self.id = self._parent_attrs["project_id"] - # save will update self.id with the result from the server, so no need to overwrite with - # what it was before we overwrote it.""" + # save will update self.id with the result from the server, so no need + # to overwrite with what it was before we overwrote it. SaveMixin.save(self, **kwargs) @@ -198,8 +198,9 @@ class ProjectMergeRequestApprovalRuleManager( ), optional=("user_ids", "group_ids"), ) - # Important: When approval_project_rule_id is set, the name, users and groups of - # project-level rule will be copied. The approvals_required specified will be used. """ + # Important: When approval_project_rule_id is set, the name, users and + # groups of project-level rule will be copied. The approvals_required + # specified will be used. _create_attrs = RequiredOptional( required=("id", "merge_request_iid", "name", "approvals_required"), optional=("approval_project_rule_id", "user_ids", "group_ids"), diff --git a/gitlab/v4/objects/projects.py b/gitlab/v4/objects/projects.py index 3c26935d3..14519dbc5 100644 --- a/gitlab/v4/objects/projects.py +++ b/gitlab/v4/objects/projects.py @@ -597,10 +597,12 @@ def artifact( chunk_size: int = 1024, **kwargs: Any, ) -> Optional[bytes]: - """Download a single artifact file from a specific tag or branch from within the job’s artifacts archive. + """Download a single artifact file from a specific tag or branch from + within the job’s artifacts archive. Args: - ref_name: Branch or tag name in repository. HEAD or SHA references are not supported. + ref_name: Branch or tag name in repository. HEAD or SHA references + are not supported. artifact_path: Path to a file inside the artifacts archive. job: The name of the job. streamed: If True the data will be processed by chunks of @@ -619,7 +621,10 @@ def artifact( The artifacts if `streamed` is False, None otherwise. """ - path = f"/projects/{self.get_id()}/jobs/artifacts/{ref_name}/raw/{artifact_path}?job={job}" + path = ( + f"/projects/{self.get_id()}/jobs/artifacts/{ref_name}/raw/" + f"{artifact_path}?job={job}" + ) result = self.manager.gitlab.http_get( path, streamed=streamed, raw=True, **kwargs ) @@ -857,7 +862,8 @@ def import_bitbucket_server( .. note:: This request may take longer than most other API requests. - So this method will specify a 60 second default timeout if none is specified. + So this method will specify a 60 second default timeout if none is + specified. A timeout can be specified via kwargs to override this functionality. Args: @@ -945,7 +951,8 @@ def import_github( .. note:: This request may take longer than most other API requests. - So this method will specify a 60 second default timeout if none is specified. + So this method will specify a 60 second default timeout if none is + specified. A timeout can be specified via kwargs to override this functionality. Args: diff --git a/pyproject.toml b/pyproject.toml index 62e0bfbeb..6e83a2eed 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -41,3 +41,50 @@ branch = "main" version_variable = "gitlab/__version__.py:__version__" commit_subject = "chore: release v{version}" commit_message = "" + +[tool.pylint.messages_control] +max-line-length = 88 +# TODO(jlvilla): Work on removing these disables over time. +disable = [ + "arguments-differ", + "arguments-renamed", + "attribute-defined-outside-init", + "broad-except", + "consider-using-f-string", + "consider-using-generator", + "consider-using-sys-exit", + "cyclic-import", + "duplicate-code", + "expression-not-assigned", + "fixme", + "implicit-str-concat", + "import-outside-toplevel", + "invalid-name", + "missing-class-docstring", + "missing-function-docstring", + "missing-module-docstring", + "no-else-return", + "no-self-use", + "protected-access", + "raise-missing-from", + "redefined-builtin", + "redefined-outer-name", + "signature-differs", + "super-with-arguments", + "too-few-public-methods", + "too-many-ancestors", + "too-many-arguments", + "too-many-branches", + "too-many-instance-attributes", + "too-many-lines", + "too-many-locals", + "too-many-statements", + "unexpected-keyword-arg", + "unnecessary-pass", + "unspecified-encoding", + "unsubscriptable-object", + "unused-argument", + "useless-import-alias", + "useless-object-inheritance", + +] diff --git a/requirements-lint.txt b/requirements-lint.txt index d5e05215d..de4d0d05c 100644 --- a/requirements-lint.txt +++ b/requirements-lint.txt @@ -1,8 +1,10 @@ +argcomplete==1.12.3 black==21.12b0 flake8==4.0.1 isort==5.10.1 mypy==0.910 -pytest +pylint==2.12.2 +pytest==6.2.5 types-PyYAML==6.0.1 types-requests==2.26.1 types-setuptools==57.4.4 diff --git a/tox.ini b/tox.ini index 4d8ead20c..1606471c8 100644 --- a/tox.ini +++ b/tox.ini @@ -9,19 +9,13 @@ setenv = VIRTUAL_ENV={envdir} whitelist_externals = true usedevelop = True install_command = pip install {opts} {packages} +isolated_build = True deps = -r{toxinidir}/requirements.txt -r{toxinidir}/requirements-test.txt commands = pytest tests/unit tests/meta {posargs} -[testenv:pep8] -basepython = python3 -envdir={toxworkdir}/lint -deps = -r{toxinidir}/requirements-lint.txt -commands = - flake8 {posargs} . - [testenv:black] basepython = python3 envdir={toxworkdir}/lint @@ -43,6 +37,20 @@ deps = -r{toxinidir}/requirements-lint.txt commands = mypy {posargs} +[testenv:pep8] +basepython = python3 +envdir={toxworkdir}/lint +deps = -r{toxinidir}/requirements-lint.txt +commands = + flake8 {posargs} . + +[testenv:pylint] +basepython = python3 +envdir={toxworkdir}/lint +deps = -r{toxinidir}/requirements-lint.txt +commands = + pylint {posargs} gitlab/ + [testenv:twine-check] basepython = python3 deps = -r{toxinidir}/requirements.txt From 5f10b3b96d83033805757d72269ad0a771d797d4 Mon Sep 17 00:00:00 2001 From: "John L. Villalovos" Date: Tue, 7 Dec 2021 14:09:41 -0800 Subject: [PATCH 2/3] chore: run pre-commit on changes to the config file If .pre-commit-config.yaml or .github/workflows/pre_commit.yml are updated then run pre-commit. --- .github/workflows/pre_commit.yml | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 .github/workflows/pre_commit.yml diff --git a/.github/workflows/pre_commit.yml b/.github/workflows/pre_commit.yml new file mode 100644 index 000000000..87f6387d6 --- /dev/null +++ b/.github/workflows/pre_commit.yml @@ -0,0 +1,32 @@ +name: pre_commit + +on: + push: + branches: + - main + paths: + .github/workflows/pre_commit.yml + .pre-commit-config.yaml + pull_request: + branches: + - main + - master + paths: + - .github/workflows/pre_commit.yml + - .pre-commit-config.yaml + +env: + PY_COLORS: 1 + +jobs: + + pre_commit: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-python@v2 + - run: pip install --upgrade -r requirements.txt -r requirements-lint.txt pre-commit + - name: Run pre-commit install + run: pre-commit install + - name: pre-commit run all-files + run: pre-commit run --all-files From b67a6ad1f81dce4670f9820750b411facc01a048 Mon Sep 17 00:00:00 2001 From: "John L. Villalovos" Date: Tue, 7 Dec 2021 15:11:55 -0800 Subject: [PATCH 3/3] chore: set pre-commit mypy args to empty list https://github.com/pre-commit/mirrors-mypy/blob/master/.pre-commit-hooks.yaml Sets some default args which seem to be interfering with things. Plus we set all of our args in the `pyproject.toml` file. --- .pre-commit-config.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 56420c775..66bf0451f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -33,6 +33,7 @@ repos: rev: v0.910 hooks: - id: mypy + args: [] additional_dependencies: - types-PyYAML==6.0.1 - types-requests==2.26.1