diff --git a/.github/workflows/lint_and_test.yaml b/.github/workflows/lint_and_test.yaml index 1d870d5..a76325a 100644 --- a/.github/workflows/lint_and_test.yaml +++ b/.github/workflows/lint_and_test.yaml @@ -31,12 +31,11 @@ jobs: env: UV_PYTHON: ${{ matrix.python-version }} - - name: Run linters - run: make lint + - name: Run all checks + run: make all env: UV_PYTHON: ${{ matrix.python-version }} - - name: Run tests - run: make test - env: - UV_PYTHON: ${{ matrix.python-version }} + - name: Check if code was reformatted + if: always() + run: git diff --exit-code diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c815a8f..4e06d7b 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -73,3 +73,10 @@ repos: language: system entry: make test pass_filenames: false + + - id: make-dead-code + name: make dead-code (pre-push) + stages: [pre-push] + language: system + entry: make dead-code + pass_filenames: false diff --git a/CHANGELOG.md b/CHANGELOG.md index b799215..6707cb5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,5 @@ +## [0.3.1-rc.1](https://github.com/disafronov/python-logging-objects-with-schema/compare/v0.3.0...v0.3.1-rc.1) (2025-12-10) + ## [0.3.0](https://github.com/disafronov/python-logging-objects-with-schema/compare/v0.2.0...v0.3.0) (2025-12-09) ### Features diff --git a/Makefile b/Makefile index 8e3ef20..124cb20 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ PYTEST_CMD = uv run python -m pytest -v COVERAGE_OPTS = --cov --cov-report=term-missing --cov-report=html # Phony targets -.PHONY: all clean format help install lint test test-coverage +.PHONY: all clean dead-code format help install lint test test-coverage # Default target help: ## Show this help message @@ -28,6 +28,10 @@ lint: ## Run linting tools @echo "Running linting tools..." uv run black --check . && uv run isort --check-only . && uv run flake8 . && uv run mypy . && uv run bandit -r -c pyproject.toml . +dead-code: ## Check for dead code using vulture + @echo "Checking for dead code..." + uv run vulture + # Testing test: ## Run tests @echo "Running tests..." @@ -38,7 +42,7 @@ test-coverage: ## Run tests with coverage $(PYTEST_CMD) $(COVERAGE_OPTS) # Combined operations -all: format lint test ## Run format, lint, and test +all: format lint test dead-code ## Run format, lint, test, and dead-code check @echo "All checks completed successfully!" # Maintenance diff --git a/pyproject.toml b/pyproject.toml index 887e471..71b49c8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "uv_build" [project] name = "logging-objects-with-schema" -version = "0.3.0" +version = "0.3.1rc1" description = "Proxy logging wrapper that validates extra fields against a JSON schema." readme = "README.md" requires-python = ">=3.10" @@ -45,7 +45,8 @@ classifiers = [ "flake8-pyproject>=1.2.3", "mypy>=1.18.1", "bandit>=1.8.6", - "pre-commit>=3.5.0" + "pre-commit>=3.5.0", + "vulture>=2.0.0" ] [project.urls] @@ -115,3 +116,9 @@ skip_covered = false [tool.coverage.html] directory = "htmlcov" + +[tool.vulture] +min_confidence = 80 +exclude = [ "__pycache__" ] +ignore_names = [ "cls" ] +paths = [ "src" ] diff --git a/src/logging_objects_with_schema/schema_loader.py b/src/logging_objects_with_schema/schema_loader.py index 168cb58..f51757b 100644 --- a/src/logging_objects_with_schema/schema_loader.py +++ b/src/logging_objects_with_schema/schema_loader.py @@ -177,24 +177,31 @@ def _check_cached_found_file_path() -> Path | None: When a schema file was found, its absolute path is cached as CWD-independent. This function checks if the cached path still exists on disk. + Note: This function must be called while holding _path_cache_lock. + Returns: Cached path if file still exists, None if file was deleted (cache invalidated). """ global _resolved_schema_path - with _path_cache_lock: - if _resolved_schema_path is None: - return None - - # Schema file was found, absolute path doesn't depend on CWD - # Return it if it still exists - if _resolved_schema_path.exists(): - return _resolved_schema_path + if _resolved_schema_path is None: + return None - # Cached file no longer exists; invalidate cache so caller will re-search - _resolved_schema_path = None + # Check if this is actually a found file cache (not missing file cache) + # by checking _cached_cwd. We don't need 'global' here since we only read it. + if _cached_cwd is not None: + # This path was cached as missing file, not found file return None + # Schema file was found, absolute path doesn't depend on CWD + # Return it if it still exists + if _resolved_schema_path.exists(): + return _resolved_schema_path + + # Cached file no longer exists; invalidate cache so caller will re-search + _resolved_schema_path = None + return None + def _check_cached_missing_file_path() -> Path | None: """Check if cached path for a missing file is still valid. @@ -202,26 +209,27 @@ def _check_cached_missing_file_path() -> Path | None: When a schema file was not found, a path based on CWD is cached. This function checks if CWD has changed since caching. + Note: This function must be called while holding _path_cache_lock. + Returns: Cached path if CWD unchanged, None if CWD changed (cache invalidated). """ global _resolved_schema_path, _cached_cwd - with _path_cache_lock: - if _resolved_schema_path is None or _cached_cwd is None: - return None + if _resolved_schema_path is None or _cached_cwd is None: + return None - # Cached path is based on CWD when file was not found, - # check if CWD changed - current_cwd = _get_current_working_directory() - if current_cwd != _cached_cwd: - # CWD changed, invalidate cache and re-search from new CWD - _resolved_schema_path = None - _cached_cwd = None - return None + # Cached path is based on CWD when file was not found, + # check if CWD changed + current_cwd = _get_current_working_directory() + if current_cwd != _cached_cwd: + # CWD changed, invalidate cache and re-search from new CWD + _resolved_schema_path = None + _cached_cwd = None + return None - # CWD unchanged, return cached path - return _resolved_schema_path + # CWD unchanged, return cached path + return _resolved_schema_path def _cache_and_return_found_path(found_path: Path) -> Path: @@ -800,8 +808,8 @@ def _compile_schema_internal( given path and forbidden keys set has been observed (including the cases when it is missing or invalid), subsequent calls always return the cached result without re-reading or re-compiling the schema. To pick up on-disk - changes to the schema, the application must restart the process. See the - README section \"Schema caching and thread safety\" for more details. + changes to the schema, the application must restart the process. The schema + is cached process-wide and is thread-safe. Args: forbidden_keys: Additional forbidden root keys to check against. diff --git a/uv.lock b/uv.lock index dd2a94c..6a702a0 100644 --- a/uv.lock +++ b/uv.lock @@ -1394,7 +1394,7 @@ version = "0.6.3" [[package]] name = "logging-objects-with-schema" -version = "0.3.0" +version = "0.3.1rc1" [package.source] editable = "." @@ -1426,6 +1426,9 @@ name = "pytest" [[package.optional-dependencies.dev]] name = "pytest-cov" +[[package.optional-dependencies.dev]] +name = "vulture" + [package.metadata] provides-extras = [ "dev" ] @@ -1474,6 +1477,11 @@ name = "pytest-cov" marker = "extra == 'dev'" specifier = ">=4.0.0" + [[package.metadata.requires-dist]] + name = "vulture" + marker = "extra == 'dev'" + specifier = ">=2.0.0" + [[package]] name = "markdown-it-py" version = "4.0.0" @@ -2747,3 +2755,26 @@ version = "20.35.4" hash = "sha256:c21c9cede36c9753eeade68ba7d523529f228a403463376cf821eaae2b650f1b" size = 6_005_095 upload-time = "2025-10-29T06:57:37.598Z" + +[[package]] +name = "vulture" +version = "2.14" + + [package.source] + registry = "https://pypi.org/simple" + + [[package.dependencies]] + name = "tomli" + marker = "python_full_version < '3.11'" + + [package.sdist] + url = "https://files.pythonhosted.org/packages/8e/25/925f35db758a0f9199113aaf61d703de891676b082bd7cf73ea01d6000f7/vulture-2.14.tar.gz" + hash = "sha256:cb8277902a1138deeab796ec5bef7076a6e0248ca3607a3f3dee0b6d9e9b8415" + size = 58_823 + upload-time = "2024-12-08T17:39:43.319Z" + + [[package.wheels]] + url = "https://files.pythonhosted.org/packages/a0/56/0cc15b8ff2613c1d5c3dc1f3f576ede1c43868c1bc2e5ccaa2d4bcd7974d/vulture-2.14-py2.py3-none-any.whl" + hash = "sha256:d9a90dba89607489548a49d557f8bac8112bd25d3cbc8aeef23e860811bd5ed9" + size = 28_915 + upload-time = "2024-12-08T17:39:40.573Z"