Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replaced os.path with pathlib #182

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
Prev Previous commit
Next Next commit
Made remaining coverage code use pathlib
trag1c committed May 22, 2024

Verified

This commit was signed with the committer’s verified signature.
commit 98b9501d2fe00d01e913a4347ad6e61a2353163c
72 changes: 43 additions & 29 deletions src/interrogate/coverage.py
Original file line number Diff line number Diff line change
@@ -64,7 +64,7 @@ class InterrogateFileResult(BaseInterrogateResult):
:param list[visit.CovNode] nodes: visited AST nodes.
"""

filename: str = attr.ib(default=None)
filename: Path = attr.ib(default=None)
ignore_module: bool = attr.ib(default=False)
nodes: list[visit.CovNode] = attr.ib(repr=False, default=None)

@@ -125,7 +125,7 @@ def __init__(
paths: list[PathLike[str] | str],
conf: config.InterrogateConfig | None = None,
excluded: tuple[str] | None = None,
extensions: tuple[PathLike[str] | str] | None = None,
extensions: tuple[str] | None = None,
):
self.paths = list(map(Path, paths))
self.extensions = {f".{ext.lstrip('.')}" for ext in extensions or ()}
@@ -144,7 +144,7 @@ def _add_common_exclude(self) -> None:
str(path / i) for i in self.COMMON_EXCLUDE
)

def _filter_files(self, files: list[str]) -> Iterator[str]:
def _filter_files(self, files: list[Path]) -> Iterator[Path]:
"""Filter files that are explicitly excluded."""
for f in files:
has_valid_ext = any([f.suffix == ext for ext in self.extensions])
@@ -155,9 +155,9 @@ def _filter_files(self, files: list[str]) -> Iterator[str]:
continue
if any(f.match(exc + "*") for exc in self.excluded):
continue
yield str(f)
yield f

def get_filenames_from_paths(self) -> list[str]:
def get_filenames_from_paths(self) -> list[Path]:
"""Find all files to measure for docstring coverage."""
filenames = []
for path in self.paths:
@@ -173,7 +173,7 @@ def get_filenames_from_paths(self) -> list[str]:
)
click.echo(msg, err=True)
return sys.exit(1)
filenames.append(str(path))
filenames.append(path)
continue
for root, dirs, fs in os.walk(path):
full_paths = [Path(root) / f for f in fs]
@@ -246,14 +246,13 @@ def _set_google_style(self, nodes: list[visit.CovNode]) -> None:
setattr(node.parent, "covered", True)

def _get_file_coverage(
self, filename: str
self, filename: Path
) -> InterrogateFileResult | None:
"""Get coverage results for a particular file."""
with open(filename, encoding="utf-8") as f:
source_tree = f.read()
source_tree = filename.read_text(encoding="utf-8")

parsed_tree = ast.parse(source_tree)
visitor = visit.CoverageVisitor(filename=filename, config=self.config)
visitor = visit.CoverageVisitor(filename=str(filename), config=self.config)
visitor.visit(parsed_tree)

filtered_nodes = self._filter_nodes(visitor.nodes)
@@ -278,7 +277,7 @@ def _get_file_coverage(
results.combine()
return results

def _get_coverage(self, filenames: list[str]) -> InterrogateResults:
def _get_coverage(self, filenames: list[Path]) -> InterrogateResults:
"""Get coverage results."""
results = InterrogateResults()
file_results = []
@@ -304,27 +303,27 @@ def get_coverage(self) -> InterrogateResults:
filenames = self.get_filenames_from_paths()
return self._get_coverage(filenames)

def _get_filename(self, filename: str) -> str:
def _get_filename(self, filename: Path) -> str:
"""Get filename for output information.

If only one file is being interrogated, then ``self.common_base``
and ``filename`` will be the same. Therefore, take the file
``os.path.basename`` as the return ``filename``.
``Path.name`` as the return ``filename``.
"""
if filename == self.common_base:
return os.path.basename(filename)
return filename[len(self.common_base) + 1 :]
if str(filename) == self.common_base:
return filename.name
return str(filename)[len(self.common_base) + 1 :]

def _get_detailed_row(
self, node: visit.CovNode, filename: str
self, node: visit.CovNode, filename: Path
) -> list[str]:
"""Generate a row of data for the detailed view."""
filename = self._get_filename(filename)
filename_ = self._get_filename(filename)

if node.node_type == "Module":
if self.config.ignore_module:
return [filename, ""]
name = f"{filename} (module)"
return [filename_, ""]
name = f"{filename_} (module)"
else:
name = node.path.split(":")[-1]
name = f"{name} (L{node.lineno})"
@@ -461,21 +460,36 @@ def _sort_results(results: InterrogateResults) -> InterrogateResults:
all_filenames_map = {r.filename: r for r in results.file_results}
all_dirs = sorted(
{
os.path.dirname(r.filename)
r.filename.parent
for r in results.file_results
if os.path.dirname(r.filename) != ""
if r.filename.parent
}
)

sorted_results = []
# cnt = 0

# def log(obj: object) -> None:
# nonlocal cnt
# cnt += 1
# pth = Path.home() / "dev/download/interrogate/log.txt"
# with pth.open("a") as f:
# f.write(f"{cnt} {obj!r}\n")

# log(all_filenames_map) # 1
# log(all_filenames_map_paths) # 2
# log(all_dirs) # 3
# log(all_dirs_paths) # 4

sorted_results: list[Path] = []
while all_dirs:
current_dir = all_dirs.pop(0)
files = []
for p in os.listdir(current_dir):
path = os.path.join(current_dir, p)
if path in all_filenames_map.keys():
files.append(path)
files = sorted(files)
files = sorted(
[
path
for path in current_dir.iterdir()
if path in all_filenames_map
]
)
sorted_results.extend(files)

sorted_res = []