From 4a5788fdad5ac1e02e795a94792505d9facd6cd1 Mon Sep 17 00:00:00 2001 From: Evan Doyle Date: Fri, 21 Jun 2024 12:35:41 -0700 Subject: [PATCH 1/2] Fix exclusion behavior after adjusting traversal to source root --- python/tach/check.py | 22 ++++++++++++++------ python/tach/cli.py | 5 ----- python/tach/filesystem/service.py | 34 ++++--------------------------- tach.yml | 1 + 4 files changed, 21 insertions(+), 41 deletions(-) diff --git a/python/tach/check.py b/python/tach/check.py index b7267f84..64b15864 100644 --- a/python/tach/check.py +++ b/python/tach/check.py @@ -1,11 +1,13 @@ from __future__ import annotations +import re from dataclasses import dataclass, field from pathlib import Path from typing import TYPE_CHECKING from tach import errors from tach import filesystem as fs +from tach.constants import ROOT_MODULE_SENTINEL_TAG from tach.core import ModuleConfig from tach.extension import get_project_imports, set_excluded_paths from tach.parsing import build_module_tree @@ -136,7 +138,7 @@ def validate_project_modules( ) -> ProjectModuleValidationResult: result = ProjectModuleValidationResult() for module in modules: - if fs.module_to_pyfile_or_dir_path( + if module.path == ROOT_MODULE_SENTINEL_TAG or fs.module_to_pyfile_or_dir_path( source_root=source_root, module_path=module.path ): result.valid_modules.append(module) @@ -145,6 +147,13 @@ def validate_project_modules( return result +def is_path_excluded(path: Path, exclude_paths: list[str]) -> bool: + dirpath_for_matching = f"{path}/" + return any( + re.match(exclude_path, dirpath_for_matching) for exclude_path in exclude_paths + ) + + def check( project_root: Path, project_config: ProjectConfig, @@ -181,11 +190,12 @@ def check( # This informs the Rust extension ahead-of-time which paths are excluded. # The extension builds regexes and uses them during `get_project_imports` set_excluded_paths(exclude_paths=exclude_paths or []) - for file_path in fs.walk_pyfiles( - project_root, - exclude_paths=exclude_paths, - ): - abs_file_path = project_root / file_path + for file_path in fs.walk_pyfiles(source_root): + abs_file_path = source_root / file_path + rel_file_path = abs_file_path.relative_to(project_root) + if is_path_excluded(rel_file_path, exclude_paths=exclude_paths or []): + continue + mod_path = fs.file_to_module_path( source_root=source_root, file_path=abs_file_path ) diff --git a/python/tach/cli.py b/python/tach/cli.py index c3ffbb0e..0aefe129 100644 --- a/python/tach/cli.py +++ b/python/tach/cli.py @@ -243,11 +243,6 @@ def tach_check( exact |= project_config.exact - if exclude_paths is not None and project_config.exclude is not None: - exclude_paths.extend(project_config.exclude) - else: - exclude_paths = project_config.exclude - check_result = check( project_root=project_root, project_config=project_config, diff --git a/python/tach/filesystem/service.py b/python/tach/filesystem/service.py index d77be742..7de36027 100644 --- a/python/tach/filesystem/service.py +++ b/python/tach/filesystem/service.py @@ -2,7 +2,6 @@ import ast import os -import re import stat import threading from collections import defaultdict @@ -157,29 +156,19 @@ def parse_ast(path: str) -> ast.AST: def walk( - root: Path, - depth: int | None = None, - exclude_paths: list[str] | None = None, + root: Path, depth: int | None = None ) -> Generator[tuple[Path, list[Path]], None, None]: if depth is not None and depth <= 0: return root = root.resolve() for dirpath, dirnames, filenames in os.walk(root): rel_dirpath = Path(dirpath).relative_to(root) - dirpath_for_matching = f"{rel_dirpath}/" if rel_dirpath.name.startswith("."): # This prevents recursing into child directories of hidden paths del dirnames[:] continue - if exclude_paths is not None and any( - re.match(exclude_path, dirpath_for_matching) - for exclude_path in exclude_paths - ): - # Treat excluded paths as invisible - continue - if depth: # Ignore anything past requested depth current_depth = len(rel_dirpath.parts) - 1 @@ -187,28 +176,13 @@ def walk( continue def filter_filename(filename: str) -> bool: - if filename.startswith("."): - return False - file_path = rel_dirpath / filename - if exclude_paths is not None and any( - re.match(exclude_path, str(file_path)) for exclude_path in exclude_paths - ): - return False - return True + return not filename.startswith(".") yield rel_dirpath, list(map(Path, filter(filter_filename, filenames))) -def walk_pyfiles( - root: Path, - depth: int | None = None, - exclude_paths: list[str] | None = None, -) -> Generator[Path, None, None]: - for dirpath, filepaths in walk( - root, - depth=depth, - exclude_paths=exclude_paths, - ): +def walk_pyfiles(root: Path, depth: int | None = None) -> Generator[Path, None, None]: + for dirpath, filepaths in walk(root, depth=depth): for filepath in filepaths: if filepath.name.endswith(".py"): yield dirpath / filepath diff --git a/tach.yml b/tach.yml index 381236f1..807e0a2c 100644 --- a/tach.yml +++ b/tach.yml @@ -13,6 +13,7 @@ modules: strict: true - path: tach.check depends_on: + - tach.constants - tach.core - tach.errors - tach.filesystem From e31ba515cb9538d1c0ade2b578ce5885373e033b Mon Sep 17 00:00:00 2001 From: Evan Doyle Date: Fri, 21 Jun 2024 12:36:23 -0700 Subject: [PATCH 2/2] Bump to 0.6.1 --- Cargo.lock | 2 +- Cargo.toml | 2 +- docs/usage.md | 2 +- pyproject.toml | 2 +- python/tach/__init__.py | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 98f88ba0..ddb23051 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1097,7 +1097,7 @@ dependencies = [ [[package]] name = "tach" -version = "0.6.0" +version = "0.6.1" dependencies = [ "criterion", "once_cell", diff --git a/Cargo.toml b/Cargo.toml index b37dc210..dac856db 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "tach" -version = "0.6.0" +version = "0.6.1" edition = "2021" [lib] diff --git a/docs/usage.md b/docs/usage.md index b2d0f722..342b2590 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -114,7 +114,7 @@ If you use the [pre-commit framework](https://github.com/pre-commit/pre-commit), ```yaml repos: - repo: https://github.com/gauge-sh/tach-pre-commit - rev: v0.6.0 # change this to the latest tag! + rev: v0.6.1 # change this to the latest tag! hooks: - id: tach ``` diff --git a/pyproject.toml b/pyproject.toml index 69f8a815..3d94f2c7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "tach" -version = "0.6.0" +version = "0.6.1" authors = [ { name="Caelean Barnes", email="caeleanb@gmail.com" }, { name="Evan Doyle", email="evanmdoyle@gmail.com" }, diff --git a/python/tach/__init__.py b/python/tach/__init__.py index cd0653cf..c28d4098 100644 --- a/python/tach/__init__.py +++ b/python/tach/__init__.py @@ -1,5 +1,5 @@ from __future__ import annotations -__version__ = "0.6.0" +__version__ = "0.6.1" __all__ = ["__version__"]