From 00244b608c879197f287578fecee307c18b185e3 Mon Sep 17 00:00:00 2001 From: Meni Yakove Date: Thu, 25 Apr 2024 11:34:52 +0300 Subject: [PATCH 1/2] Do python typing right --- apps/polarion/polarion_utils.py | 14 +++---- .../polarion_verify_tc_requirements.py | 3 +- apps/unused_code/unused_code.py | 42 +++++++++---------- apps/utils.py | 6 +-- poetry.lock | 5 ++- pyproject.toml | 14 ++++--- pytest.ini | 2 +- tox.ini | 6 +-- 8 files changed, 46 insertions(+), 46 deletions(-) diff --git a/apps/polarion/polarion_utils.py b/apps/polarion/polarion_utils.py index 0562b93..9432e94 100644 --- a/apps/polarion/polarion_utils.py +++ b/apps/polarion/polarion_utils.py @@ -2,18 +2,18 @@ import shlex import subprocess from pylero.exceptions import PyleroLibException -from typing import Any +from typing import Dict, List LOGGER = get_logger(name=__name__) -def git_diff() -> Any: +def git_diff() -> str: data = subprocess.check_output(shlex.split("git diff HEAD^-1")) return data.decode("utf-8") -def git_diff_lines() -> dict: - diff: dict = {} +def git_diff_lines() -> Dict[str, List[str]]: + diff: Dict[str, List[str]] = {} for line in git_diff().splitlines(): LOGGER.debug(line) if line.startswith("+"): @@ -22,12 +22,12 @@ def git_diff_lines() -> dict: def validate_polarion_requirements( - polarion_test_ids: list, + polarion_test_ids: List[str], polarion_project_id: str, -) -> list: +) -> List[str]: from pylero.work_item import TestCase, Requirement - tests_with_missing_requirements = [] + tests_with_missing_requirements: List[str] = [] for _id in polarion_test_ids: has_req = False diff --git a/apps/polarion/polarion_verify_tc_requirements.py b/apps/polarion/polarion_verify_tc_requirements.py index dd6a46e..10075c6 100644 --- a/apps/polarion/polarion_verify_tc_requirements.py +++ b/apps/polarion/polarion_verify_tc_requirements.py @@ -8,7 +8,6 @@ validate_polarion_requirements, ) from apps.utils import get_util_config -from typing import Any LOGGER = get_logger(name="polarion-verify-tc-requirements") @@ -22,7 +21,7 @@ ) @click.option("--project-id", "-p", help="Provide the polarion project id") @click.option("--verbosity", default=False, is_flag=True) -def has_verify(config_file_path: Any, project_id: str, verbosity: bool) -> Any: +def has_verify(config_file_path: str, project_id: str, verbosity: bool) -> None: if verbosity: LOGGER.setLevel(logging.DEBUG) diff --git a/apps/unused_code/unused_code.py b/apps/unused_code/unused_code.py index eaeb45e..06073b3 100644 --- a/apps/unused_code/unused_code.py +++ b/apps/unused_code/unused_code.py @@ -6,44 +6,38 @@ from simple_logger.logger import get_logger from apps.utils import all_python_files, ListParamType, get_util_config -from typing import Any +from typing import Any, Iterable, List LOGGER = get_logger(name=__name__) -def is_fixture_autouse(func: Any) -> Any: - if func.decorator_list: - for deco in func.decorator_list: - if not hasattr(deco, "func"): - continue +def is_fixture_autouse(func: ast.FunctionDef) -> bool: + deco_list: List[Any] = func.decorator_list + for deco in deco_list or []: + if not hasattr(deco, "func"): + continue - if getattr(deco.func, "attr", None) and getattr(deco.func, "value", None): - if deco.func.attr == "fixture" and deco.func.value.id == "pytest": - for _key in deco.keywords: - if _key.arg == "autouse": - return _key.value.s + if getattr(deco.func, "attr", None) and getattr(deco.func, "value", None): + if deco.func.attr == "fixture" and deco.func.value.id == "pytest": + for _key in deco.keywords: + if _key.arg == "autouse": + return True + return False -def _iter_functions(tree: Any) -> Any: +def _iter_functions(tree: ast.Module) -> Iterable[ast.FunctionDef]: """ Get all function from python file """ - - def is_func(_elm: Any) -> Any: - return isinstance(_elm, ast.FunctionDef) - - def is_test(_elm: Any) -> Any: - return _elm.name.startswith("test_") - for elm in tree.body: - if is_func(_elm=elm): - if is_test(_elm=elm): + if isinstance(elm, ast.FunctionDef): + if elm.name.startswith("test_"): continue yield elm -def is_ignore_function_list(ignore_prefix_list: list, function: Any) -> Any: +def is_ignore_function_list(ignore_prefix_list: List[str], function: ast.FunctionDef) -> bool: ignore_function_lists = [ function.name for ignore_prefix in ignore_prefix_list if function.name.startswith(ignore_prefix) ] @@ -51,6 +45,8 @@ def is_ignore_function_list(ignore_prefix_list: list, function: Any) -> Any: LOGGER.debug(f"Following functions are getting skipped: {ignore_function_lists}") return True + return False + @click.command() @click.option( @@ -77,10 +73,12 @@ def get_unused_functions( LOGGER.setLevel(logging.DEBUG) else: logging.disable(logging.CRITICAL) + _unused_functions = [] unused_code_config = get_util_config(util_name="pyutils-unusedcode", config_file_path=config_file_path) func_ignore_prefix = exclude_function_prefixes or unused_code_config.get("exclude_function_prefix", []) file_ignore_list = exclude_files or unused_code_config.get("exclude_files", []) + for py_file in all_python_files(): if os.path.basename(py_file) in file_ignore_list: continue diff --git a/apps/utils.py b/apps/utils.py index c8a40ce..8ddaecb 100644 --- a/apps/utils.py +++ b/apps/utils.py @@ -5,12 +5,12 @@ from simple_logger.logger import get_logger import json import click -from typing import Any +from typing import Any, Dict, Iterable LOGGER = get_logger(name=__name__) -def get_util_config(util_name: str, config_file_path: Any) -> dict: +def get_util_config(util_name: str, config_file_path: str) -> Dict[str, Any]: if os.path.exists(config_file_path): with open(config_file_path) as _file: return yaml.safe_load(_file).get(util_name, {}) @@ -72,7 +72,7 @@ def convert(self, cli_value: Any, param: click.Parameter | None, ctx: click.Cont ) -def all_python_files() -> Any: +def all_python_files() -> Iterable[str]: """ Get all python files from current directory and subdirectories """ diff --git a/poetry.lock b/poetry.lock index 70a0c46..87ca0bd 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand. [[package]] name = "appnope" @@ -529,6 +529,7 @@ files = [ {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, + {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, @@ -655,4 +656,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "^3.8" -content-hash = "8612714aeffd41089a2202a293ee6e7916343830dfba6187512de185e7900ea0" +content-hash = "79b868779998ea2c3bb3b967fd103cbb86a4705ed35fe8b5363ef1452271f602" diff --git a/pyproject.toml b/pyproject.toml index c150911..75a9144 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -2,13 +2,20 @@ omit = ["tests/*"] [tool.coverage.report] -fail_under = 60 +fail_under = 75 skip_empty = true [tool.coverage.html] directory = ".tests_coverage" show_contexts = true +[tool.mypy] +check_untyped_defs = true +disallow_any_generics = true +disallow_incomplete_defs = true +disallow_untyped_defs = true +no_implicit_optional = true + [tool.ruff] preview = true line-length = 120 @@ -39,14 +46,13 @@ packages = [{ include = "apps" }] pyutils-unusedcode = "apps.unused_code.unused_code:get_unused_functions" pyutils-polarion-verify-tc-requirements = "apps.polarion.polarion_verify_tc_requirements:has_verify" - [tool.poetry.dependencies] python = "^3.8" python-simple-logger = "^1.0.8" pylero = "^0.0.8" -pyyaml = "*" pyhelper-utils = "^0.0.3" pytest-mock = "^3.14.0" +pyyaml = "^6.0.1" [tool.poetry.group.dev.dependencies] ipdb = "^0.13.13" @@ -57,8 +63,6 @@ ipython = "*" enable = true pattern = "((?P\\d+)!)?(?P\\d+(\\.\\d+)*)" - - [tool.poetry.group.test.dependencies] pytest = "^8.0.0" pytest-cov = "^4.1.0" diff --git a/pytest.ini b/pytest.ini index 86b9178..0bd7867 100644 --- a/pytest.ini +++ b/pytest.ini @@ -1,3 +1,3 @@ [pytest] addopts = - --cov-config=pyproject.toml --cov-report=html --cov-report=term --cov=. + --cov-config=pyproject.toml --cov-report=html --cov-report=term --cov=apps diff --git a/tox.ini b/tox.ini index 0601998..86dddb7 100644 --- a/tox.ini +++ b/tox.ini @@ -1,9 +1,9 @@ [tox] +envlist = {py38,py39,py310,py311,py312}-{unittest}, skipsdist = True -[testenv:unittests] -basepython = python3 +[testenv] setenv = PYTHONPATH = {toxinidir} deps = @@ -11,5 +11,3 @@ deps = commands = poetry install poetry run pytest tests -allowlist_externals = - poetry From e81f27d5ec261f2059384fb15b8755107bbfee1f Mon Sep 17 00:00:00 2001 From: Meni Yakove Date: Thu, 25 Apr 2024 11:43:02 +0300 Subject: [PATCH 2/2] remove default `utf-8` --- apps/polarion/polarion_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/polarion/polarion_utils.py b/apps/polarion/polarion_utils.py index 9432e94..b474a51 100644 --- a/apps/polarion/polarion_utils.py +++ b/apps/polarion/polarion_utils.py @@ -9,7 +9,7 @@ def git_diff() -> str: data = subprocess.check_output(shlex.split("git diff HEAD^-1")) - return data.decode("utf-8") + return data.decode() def git_diff_lines() -> Dict[str, List[str]]: