diff --git a/.github/workflows/mypy.yml b/.github/workflows/mypy.yml new file mode 100644 index 000000000..f1b4a6f4e --- /dev/null +++ b/.github/workflows/mypy.yml @@ -0,0 +1,29 @@ +name: "mypy check" +on: [pull_request] + +jobs: + + static-type-check: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-python@v3 + with: + python-version: '3.x' + - run: pip install mypy + - name: Get Python changed files + id: changed-py-files + uses: tj-actions/changed-files@v23 + with: + files: | + *.py + **/*.py + + - name: Run if any of the listed files above is changed + if: steps.changed-py-files.outputs.any_changed == 'true' + run: mypy ${{ steps.changed-py-files.outputs.all_changed_files}} --install-types --non-interactive + + - name: Set warning if previous step failed + if: failure() + # run: echo "::warning::The previous step failed but we are continuing." + run: echo "::warning file=app.py,line=10,col=5::Code formatting issues detected" diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml new file mode 100644 index 000000000..f3d8d8b5f --- /dev/null +++ b/.github/workflows/pre-commit.yml @@ -0,0 +1,25 @@ +name: pre-commit + +on: + pull_request: + push: + branches: [main] + +jobs: + pre-commit: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: 3.x + + - name: Fetch repository + run: git fetch origin + + - uses: pre-commit/action@v3.0.1 + with: + # extra_args: --from-ref origin/HEAD --to-ref HEAD + # extra_args: --from-ref main --to-ref HEAD + # extra_args: --from-ref main + extra_args: --from-ref origin/main --to-ref HEAD diff --git a/.mypy.ini b/.mypy.ini index 976ba0294..f882692d0 100644 --- a/.mypy.ini +++ b/.mypy.ini @@ -1,2 +1,3 @@ [mypy] ignore_missing_imports = True +allow_untyped_globals = True diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 000000000..39fcbf2a2 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,93 @@ +# HOWTO: https://pre-commit.com/#usage +# pip3 install pre-commit +# pre-commit install -t pre-commit -t pre-push + +repos: + # - repo: https://github.com/psf/black + # rev: 23.11.0 + # hooks: + # - id: black + # - repo: https://github.com/pre-commit/mirrors-prettier + # rev: v3.1.0 + # hooks: + # - id: prettier + # exclude: tests_recording/test_data/ + # - repo: https://github.com/pre-commit/pre-commit-hooks + # rev: v4.5.0 + # hooks: + # - id: check-added-large-files + # exclude: tests_recording/test_data/test_api/ + # - id: check-ast + # - id: check-builtin-literals + # - id: check-docstring-first + # - id: check-executables-have-shebangs + # exclude: (files/bash-completion/packit|tests/data/) + # - id: check-merge-conflict + # - id: check-symlinks + # - id: check-yaml + # - id: detect-private-key + # exclude: tests/integration/conftest.py + # - id: end-of-file-fixer + # exclude: ^(tests/data/patches|tests/.+\.patch) + # - id: mixed-line-ending + # - id: trailing-whitespace + # exclude: ^(tests/data/patches|tests/.+\.patch) + # - repo: https://github.com/astral-sh/ruff-pre-commit + # rev: v0.1.6 + # hooks: + # - id: ruff + # args: [--fix, --exit-non-zero-on-fix] + - repo: https://github.com/pre-commit/mirrors-mypy + rev: v1.7.1 + hooks: + - id: mypy + args: + [ + --no-strict-optional, + --ignore-missing-imports, + --explicit-package-bases, + ] + additional_dependencies: + [ + types-six, + types-requests, + types-setuptools, + types-mock, + types-decorator, + types-pytz, + # types-click, + # types-pkg_resources, + # types-requests, + # types-tabulate, + # types-Deprecated, + # types-PyYAML, + # types-cachetools, + ] + # - repo: https://github.com/teemtee/tmt.git + # rev: 1.29.0 + # hooks: + # - id: tmt-lint + # - repo: https://github.com/packit/pre-commit-hooks + # rev: v1.2.0 + # hooks: + # - id: validate-config # passes when packit not installed (e.g. in CI) + # - id: check-rebase + # args: + # - https://github.com/packit/packit.git + # stages: [manual, push] + # - repo: https://github.com/python-jsonschema/check-jsonschema + # rev: 0.28.0 + # hooks: + # - id: check-github-workflows + # args: ["--verbose"] + # - repo: https://github.com/Lucas-C/pre-commit-hooks + # rev: v1.5.5 + # hooks: + # - id: insert-license + # files: \.py$ + # exclude: (tests/data/|tests_recording/test_data/) + # args: + # - --license-filepath + # - LICENSE_HEADER.txt + # - --comment-style + # - "#" diff --git a/cli/copr_cli/main.py b/cli/copr_cli/main.py index 1a070a5aa..c071045f2 100644 --- a/cli/copr_cli/main.py +++ b/cli/copr_cli/main.py @@ -25,7 +25,7 @@ try: import argcomplete except ImportError: - argcomplete = None + pass import copr.exceptions as copr_exceptions from copr.v3 import ( @@ -62,11 +62,6 @@ None: "default", } -try: - input = raw_input -except NameError: - pass - class FrontendOutdatedCliException(Exception): """ @@ -1900,7 +1895,7 @@ def __call__(self, parser, args, argument, option_string=None): # package monitoring cli_monitor_parser(subparsers) - if argcomplete: + if "argcomplete" in sys.modules: argcomplete.autocomplete(parser) return parser diff --git a/frontend/coprs_frontend/coprs/__init__.py b/frontend/coprs_frontend/coprs/__init__.py index d6b8f5ae4..848567bcb 100644 --- a/frontend/coprs_frontend/coprs/__init__.py +++ b/frontend/coprs_frontend/coprs/__init__.py @@ -19,7 +19,7 @@ from coprs.redis_session import RedisSessionInterface from coprs.request import get_request_class -app = flask.Flask(__name__) +app : flask.Flask = flask.Flask(__name__) if "COPRS_ENVIRON_PRODUCTION" in os.environ: app.config.from_object("coprs.config.ProductionConfig") elif "COPRS_ENVIRON_UNITTEST" in os.environ: @@ -42,7 +42,7 @@ session = Session(app) # Set `future=True` to ensure compatibility between SQLAlchemy 1.x and 2.0 -db = SQLAlchemy(app, engine_options={"future": True}) +db : SQLAlchemy = SQLAlchemy(app, engine_options={"future": True}) @contextmanager def db_session_scope(): diff --git a/keygen/run/dev_run.py b/keygen/run/dev_run.py deleted file mode 100755 index 3f75e4efe..000000000 --- a/keygen/run/dev_run.py +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/python3 - -import sys -sys.path.append("../src/") - -import os -import glob -os.environ["COPR_KEYGEN_CONFIG"] = glob.glob("./run/dev_run.conf") - -for d in [ - "/tmp/copr-keygen/var/lib/copr-keygen/phrases/", - "/tmp/copr-keygen/var/lib/copr-keygen/gnupg", - "/tmp/copr-keygen/var/log/copr-keygen" -]: - if not os.path.exists(d): - os.makedirs(d) - -from copr_keygen import app - -import logging - -logging.basicConfig( - level=logging.DEBUG, - format= '[%(asctime)s] {%(pathname)s:%(lineno)d} %(levelname)s - %(message)s', - datefmt='%H:%M:%S' -) - -if __name__ == '__main__': - app.run() diff --git a/python/copr/v3/auth/base.py b/python/copr/v3/auth/base.py index 2f3e45480..2b62a0ab1 100644 --- a/python/copr/v3/auth/base.py +++ b/python/copr/v3/auth/base.py @@ -11,7 +11,7 @@ try: from urllib.parse import urlparse except ImportError: - from urlparse import urlparse + from urlparse import urlparse # type: ignore [no-redef] class BaseAuth(object): diff --git a/python/copr/v3/pagination.py b/python/copr/v3/pagination.py index a145d8220..9032d45ad 100644 --- a/python/copr/v3/pagination.py +++ b/python/copr/v3/pagination.py @@ -5,7 +5,7 @@ try: import urlparse - from urllib import urlencode + from urllib import urlencode # type: ignore [attr-defined] except ImportError: import urllib.parse as urlparse from urllib.parse import urlencode diff --git a/rpmbuild/copr_rpmbuild/providers/__init__.py b/rpmbuild/copr_rpmbuild/providers/__init__.py index 4178bd9c3..9bb294cc4 100644 --- a/rpmbuild/copr_rpmbuild/providers/__init__.py +++ b/rpmbuild/copr_rpmbuild/providers/__init__.py @@ -8,10 +8,6 @@ from .distgit import DistGitProvider -__all__ = [RubyGemsProvider, PyPIProvider, - UrlProvider, ScmProvider] - - def factory(source_type): try: return { diff --git a/rpmbuild/tests/test_base.py b/rpmbuild/tests/test_base.py index 5ecbd1e60..a8ca9903e 100644 --- a/rpmbuild/tests/test_base.py +++ b/rpmbuild/tests/test_base.py @@ -10,7 +10,7 @@ builtins = 'builtins' except ImportError: # Python 2 version depends on mock - import mock + import mock # type: ignore [no-redef] builtins = '__builtin__' class TestProvider(TestCase): diff --git a/rpmbuild/tests/test_distgit.py b/rpmbuild/tests/test_distgit.py index 08fa6c987..c9d128b5c 100644 --- a/rpmbuild/tests/test_distgit.py +++ b/rpmbuild/tests/test_distgit.py @@ -18,7 +18,7 @@ from unittest import mock except ImportError: # Python 2 version depends on mock - import mock + import mock # type: ignore [no-redef] from tests import TestCase diff --git a/rpmbuild/tests/test_main.py b/rpmbuild/tests/test_main.py index 17f2e1d37..9214d23cb 100644 --- a/rpmbuild/tests/test_main.py +++ b/rpmbuild/tests/test_main.py @@ -12,7 +12,7 @@ from unittest import mock except ImportError: # Python 2 version depends on mock - import mock + import mock # type: ignore [no-redef] class TestTmpCleanup(TestCase): diff --git a/rpmbuild/tests/test_mock.py b/rpmbuild/tests/test_mock.py index 9b6cc7a98..522d92943 100644 --- a/rpmbuild/tests/test_mock.py +++ b/rpmbuild/tests/test_mock.py @@ -14,7 +14,7 @@ builtins = 'builtins' except ImportError: # Python 2 version depends on mock - import mock + import mock # type: ignore [no-redef] builtins = '__builtin__' @pytest.yield_fixture diff --git a/rpmbuild/tests/test_pypi.py b/rpmbuild/tests/test_pypi.py index 34443bfe9..0477d8b72 100644 --- a/rpmbuild/tests/test_pypi.py +++ b/rpmbuild/tests/test_pypi.py @@ -6,7 +6,7 @@ builtins = 'builtins' except ImportError: # Python 2 version depends on mock - import mock + import mock # type: ignore [no-redef] builtins = '__builtin__' diff --git a/rpmbuild/tests/test_rubygems.py b/rpmbuild/tests/test_rubygems.py index 495bd2ca6..0f280b410 100644 --- a/rpmbuild/tests/test_rubygems.py +++ b/rpmbuild/tests/test_rubygems.py @@ -9,7 +9,7 @@ builtins = 'builtins' except ImportError: # Python 2 version depends on mock - import mock + import mock # type: ignore [no-redef] builtins = '__builtin__' diff --git a/rpmbuild/tests/test_scm.py b/rpmbuild/tests/test_scm.py index 801d42202..15a7c7588 100644 --- a/rpmbuild/tests/test_scm.py +++ b/rpmbuild/tests/test_scm.py @@ -13,7 +13,7 @@ builtins = 'builtins' except ImportError: # Python 2 version depends on mock - import mock + import mock # type: ignore [no-redef] builtins = '__builtin__' RPKG_CONF_JINJA = """ diff --git a/rpmbuild/tests/test_spec.py b/rpmbuild/tests/test_spec.py index e74983700..cb6269c96 100644 --- a/rpmbuild/tests/test_spec.py +++ b/rpmbuild/tests/test_spec.py @@ -23,7 +23,7 @@ def example_com_match(url, request): builtins = 'builtins' except ImportError: # Python 2 version depends on mock - import mock + import mock # type: ignore [no-redef] builtins = '__builtin__'