-
-
Notifications
You must be signed in to change notification settings - Fork 49
Replaced os.path with pathlib
#182
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
base: master
Are you sure you want to change the base?
Changes from all commits
cd06660
257428c
b275221
7cbdd3b
c5ab0e8
a026063
3b3c764
98b9501
90c9dd8
ab493c8
6c6d020
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -2,13 +2,14 @@ | |||||
| # Copyright 2020 Lynn Root | ||||||
|
|
||||||
| import codecs | ||||||
| import os | ||||||
| import re | ||||||
|
|
||||||
| from pathlib import Path | ||||||
|
|
||||||
| from setuptools import find_packages, setup | ||||||
|
|
||||||
|
|
||||||
| HERE = os.path.abspath(os.path.dirname(__file__)) | ||||||
| HERE = Path(__file__).parent.absolute() | ||||||
|
|
||||||
|
|
||||||
| ##### | ||||||
|
|
@@ -23,7 +24,7 @@ def read(*filenames, **kwargs): | |||||
| sep = kwargs.get("sep", "\n") | ||||||
| buf = [] | ||||||
| for fl in filenames: | ||||||
| with codecs.open(os.path.join(HERE, fl), "rb", encoding) as f: | ||||||
| with codecs.open(HERE / fl, "rb", encoding) as f: | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
You should open the file in text mode, not binary mode and then apply the encoding. Path objects provide a Since when is the abbreviation of filename |
||||||
| buf.append(f.read()) | ||||||
| return sep.join(buf) | ||||||
|
|
||||||
|
|
@@ -43,7 +44,7 @@ def find_meta(meta): | |||||
| NAME = "interrogate" | ||||||
| PACKAGE_NAME = "interrogate" | ||||||
| PACKAGES = find_packages(where="src") | ||||||
| META_PATH = os.path.join("src", PACKAGE_NAME, "__init__.py") | ||||||
| META_PATH = Path("src") / PACKAGE_NAME / "__init__.py" | ||||||
|
|
||||||
| META_FILE = read(META_PATH) | ||||||
| KEYWORDS = ["documentation", "coverage", "quality"] | ||||||
|
|
||||||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -5,14 +5,17 @@ | |||||
| """ | ||||||
| from __future__ import annotations | ||||||
|
|
||||||
| import os | ||||||
| import sys | ||||||
|
|
||||||
| from importlib import resources | ||||||
| from typing import Union | ||||||
| from pathlib import Path | ||||||
| from typing import TYPE_CHECKING, Union | ||||||
| from xml.dom import minidom | ||||||
|
|
||||||
|
|
||||||
| if TYPE_CHECKING: | ||||||
| from os import PathLike | ||||||
|
|
||||||
| try: | ||||||
| import cairosvg | ||||||
| except ImportError: # pragma: no cover | ||||||
|
|
@@ -80,8 +83,8 @@ | |||||
|
|
||||||
|
|
||||||
| def save_badge( | ||||||
| badge: str, output: str, output_format: str | None = None | ||||||
| ) -> str: | ||||||
| badge: str, output: PathLike[str] | str, output_format: str | None = None | ||||||
| ) -> Path: | ||||||
| """Save badge to the specified path. | ||||||
|
|
||||||
| .. versionadded:: 1.4.0 new ``output_format`` keyword argument | ||||||
|
|
@@ -96,10 +99,10 @@ def save_badge( | |||||
| if output_format is None: | ||||||
| output_format = "svg" | ||||||
|
|
||||||
| if output_format == "svg": | ||||||
| with open(output, "w") as f: | ||||||
| f.write(badge) | ||||||
| output = Path(output) | ||||||
|
|
||||||
| if output_format == "svg": | ||||||
| output.write_text(badge) | ||||||
| return output | ||||||
|
|
||||||
| if cairosvg is None: | ||||||
|
|
@@ -110,16 +113,14 @@ def save_badge( | |||||
|
|
||||||
| # need to write the badge as an svg first in order to convert it to | ||||||
| # another format | ||||||
| tmp_output_file = f"{os.path.splitext(output)[0]}.tmp.svg" | ||||||
| tmp_output_file = Path(f"{output.parent / output.stem}.tmp.svg") | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Source: https://docs.python.org/3/library/pathlib.html#pathlib.PurePath.with_suffix |
||||||
| try: | ||||||
| with open(tmp_output_file, "w") as f: | ||||||
| f.write(badge) | ||||||
|
|
||||||
| tmp_output_file.write_text(badge) | ||||||
| cairosvg.svg2png(url=tmp_output_file, write_to=output, scale=2) | ||||||
|
|
||||||
| finally: | ||||||
| try: | ||||||
| os.remove(tmp_output_file) | ||||||
| tmp_output_file.unlink() | ||||||
| except Exception: # pragma: no cover | ||||||
| pass | ||||||
|
|
||||||
|
|
@@ -183,7 +184,9 @@ def get_badge(result: float, color: str, style: str | None = None) -> str: | |||||
| return tmpl | ||||||
|
|
||||||
|
|
||||||
| def should_generate_badge(output: str, color: str, result: float) -> bool: | ||||||
| def should_generate_badge( | ||||||
| output: PathLike[str] | str, color: str, result: float | ||||||
| ) -> bool: | ||||||
| """Detect if existing badge needs updating. | ||||||
|
|
||||||
| This is to help avoid unnecessary newline updates. See | ||||||
|
|
@@ -203,14 +206,16 @@ def should_generate_badge(output: str, color: str, result: float) -> bool: | |||||
| :return: Whether or not the badge SVG file should be generated. | ||||||
| :rtype: bool | ||||||
| """ | ||||||
| if not os.path.exists(output): | ||||||
| output = Path(output) | ||||||
|
|
||||||
| if not output.exists(): | ||||||
| return True | ||||||
|
|
||||||
| if not output.endswith(".svg"): | ||||||
| if output.suffix != ".svg": | ||||||
| return True | ||||||
|
|
||||||
| try: | ||||||
| badge = minidom.parse(output) | ||||||
| badge = minidom.parse(str(output)) | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
minidom accepts file-like objects: https://docs.python.org/3/library/xml.dom.minidom.html#xml.dom.minidom.parse |
||||||
| except Exception: | ||||||
| # an exception might happen when a file is not an SVG file but has | ||||||
| # `.svg` extension (perhaps a png image was generated with the wrong | ||||||
|
|
@@ -260,11 +265,11 @@ def get_color(result: float) -> str: | |||||
|
|
||||||
|
|
||||||
| def create( | ||||||
| output: str, | ||||||
| output: PathLike[str] | str, | ||||||
| result: InterrogateResults, | ||||||
| output_format: str | None = None, | ||||||
| output_style: str | None = None, | ||||||
| ) -> str: | ||||||
| ) -> Path: | ||||||
| """Create a status badge. | ||||||
|
|
||||||
| The badge file will only be written if it doesn't exist, or if the | ||||||
|
|
@@ -290,9 +295,10 @@ def create( | |||||
| """ | ||||||
| if output_format is None: | ||||||
| output_format = "svg" | ||||||
| if os.path.isdir(output): | ||||||
| output = Path(output) | ||||||
| if output.is_dir(): | ||||||
| filename = DEFAULT_FILENAME + "." + output_format | ||||||
| output = os.path.join(output, filename) | ||||||
| output /= filename | ||||||
|
|
||||||
| result_perc = result.perc_covered | ||||||
| color = get_color(result_perc) | ||||||
|
|
||||||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -7,21 +7,23 @@ | |||||
| from __future__ import annotations | ||||||
|
|
||||||
| import configparser | ||||||
| import os | ||||||
| import pathlib | ||||||
| import re | ||||||
|
|
||||||
| from collections.abc import Sequence | ||||||
| from typing import Any | ||||||
| from pathlib import Path | ||||||
| from typing import TYPE_CHECKING, Any | ||||||
|
|
||||||
| import attr | ||||||
| import click | ||||||
|
|
||||||
|
|
||||||
| if TYPE_CHECKING: | ||||||
| from os import PathLike | ||||||
|
|
||||||
| try: | ||||||
| import tomllib | ||||||
| except ImportError: | ||||||
| import tomli as tomllib # type: ignore | ||||||
| import tomli as tomllib | ||||||
|
|
||||||
|
|
||||||
| # TODO: idea: break out InterrogateConfig into two classes: one for | ||||||
|
|
@@ -86,17 +88,17 @@ def _check_style(self, attribute: str, value: str) -> None: | |||||
| ) | ||||||
|
|
||||||
|
|
||||||
| def find_project_root(srcs: Sequence[str]) -> pathlib.Path: | ||||||
| def find_project_root(srcs: Sequence[PathLike[str] | str]) -> Path: | ||||||
| """Return a directory containing .git, .hg, or pyproject.toml. | ||||||
| That directory can be one of the directories passed in `srcs` or their | ||||||
| common parent. | ||||||
| If no directory in the tree contains a marker that would specify it's the | ||||||
| project root, the root of the file system is returned. | ||||||
| """ | ||||||
| if not srcs: | ||||||
| return pathlib.Path("/").resolve() | ||||||
| return Path("/").resolve() | ||||||
|
|
||||||
| common_base = min(pathlib.Path(src).resolve() for src in srcs) | ||||||
| common_base = min(Path(src).resolve() for src in srcs) | ||||||
| if common_base.is_dir(): | ||||||
| # Append a fake file so `parents` below returns `common_base_dir`, too. | ||||||
| common_base /= "fake-file" | ||||||
|
|
@@ -114,7 +116,9 @@ def find_project_root(srcs: Sequence[str]) -> pathlib.Path: | |||||
| return directory | ||||||
|
|
||||||
|
|
||||||
| def find_project_config(path_search_start: Sequence[str]) -> str | None: | ||||||
| def find_project_config( | ||||||
| path_search_start: Sequence[PathLike[str] | str], | ||||||
| ) -> str | None: | ||||||
| """Find the absolute filepath to a pyproject.toml if it exists.""" | ||||||
| project_root = find_project_root(path_search_start) | ||||||
| pyproject_toml = project_root / "pyproject.toml" | ||||||
|
|
@@ -125,7 +129,7 @@ def find_project_config(path_search_start: Sequence[str]) -> str | None: | |||||
| return str(setup_cfg) if setup_cfg.is_file() else None | ||||||
|
|
||||||
|
|
||||||
| def parse_pyproject_toml(path_config: str) -> dict[str, Any]: | ||||||
| def parse_pyproject_toml(path_config: PathLike[str] | str) -> dict[str, Any]: | ||||||
| """Parse ``pyproject.toml`` file and return relevant parts for Interrogate. | ||||||
|
|
||||||
| :param str path_config: Path to ``pyproject.toml`` file. | ||||||
|
|
@@ -134,8 +138,7 @@ def parse_pyproject_toml(path_config: str) -> dict[str, Any]: | |||||
| :raise OSError: an I/O-related error when opening ``pyproject.toml``. | ||||||
| :raise tomllib.TOMLDecodeError: unable to load ``pyproject.toml``. | ||||||
| """ | ||||||
| with open(path_config, "rb") as f: | ||||||
| pyproject_toml = tomllib.load(f) | ||||||
| pyproject_toml = tomllib.loads(Path(path_config).read_text()) | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
No encoding is specified. |
||||||
| config = pyproject_toml.get("tool", {}).get("interrogate", {}) | ||||||
| return { | ||||||
| k.replace("--", "").replace("-", "_"): v for k, v in config.items() | ||||||
|
|
@@ -221,7 +224,7 @@ def read_config_file( | |||||
| if not value: | ||||||
| paths = ctx.params.get("paths") | ||||||
| if not paths: | ||||||
| paths = (os.path.abspath(os.getcwd()),) | ||||||
| paths = (Path.cwd(),) | ||||||
| value = find_project_config(paths) | ||||||
| if value is None: | ||||||
| return None | ||||||
|
|
||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to convert to a
str, almost every open function/method accepts path-like objects. Don't open a file in binary when you apply an encoding.Other parts use
HERE.