Skip to content

Commit

Permalink
Use pathlib instead of os.path module
Browse files Browse the repository at this point in the history
  • Loading branch information
Secrus committed Nov 26, 2023
1 parent 1ee19a5 commit 73ae2ee
Show file tree
Hide file tree
Showing 15 changed files with 93 additions and 105 deletions.
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,10 @@ extend-select = [
"UP", # pyupgrade
"I", # isort
"PGH", # pygrep
"PTH" # flake8-use-pathlib
]
ignore = [
"B904", # use 'raise ... from err'
"B905", # use explicit 'strict=' parameter with 'zip()'
"N818" # Exception name should be named with an Error suffix
]

Expand Down
8 changes: 4 additions & 4 deletions src/poetry/core/masonry/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def get_requires_for_build_wheel(
def prepare_metadata_for_build_wheel(
metadata_directory: str, config_settings: dict[str, Any] | None = None
) -> str:
poetry = Factory().create_poetry(Path(".").resolve(), with_groups=False)
poetry = Factory().create_poetry(Path().resolve(), with_groups=False)
builder = WheelBuilder(poetry)
metadata_path = Path(metadata_directory)
dist_info = builder.prepare_metadata(metadata_path)
Expand All @@ -52,7 +52,7 @@ def build_wheel(
metadata_directory: str | None = None,
) -> str:
"""Builds a wheel, places it in wheel_directory"""
poetry = Factory().create_poetry(Path(".").resolve(), with_groups=False)
poetry = Factory().create_poetry(Path().resolve(), with_groups=False)
metadata_path = None if metadata_directory is None else Path(metadata_directory)

return WheelBuilder.make_in(
Expand All @@ -64,7 +64,7 @@ def build_sdist(
sdist_directory: str, config_settings: dict[str, Any] | None = None
) -> str:
"""Builds an sdist, places it in sdist_directory"""
poetry = Factory().create_poetry(Path(".").resolve(), with_groups=False)
poetry = Factory().create_poetry(Path().resolve(), with_groups=False)

path = SdistBuilder(poetry).build(Path(sdist_directory))

Expand All @@ -76,7 +76,7 @@ def build_editable(
config_settings: dict[str, Any] | None = None,
metadata_directory: str | None = None,
) -> str:
poetry = Factory().create_poetry(Path(".").resolve(), with_groups=False)
poetry = Factory().create_poetry(Path().resolve(), with_groups=False)
metadata_path = None if metadata_directory is None else Path(metadata_directory)

return WheelBuilder.make_in(
Expand Down
12 changes: 6 additions & 6 deletions src/poetry/core/masonry/builders/sdist.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ def build_setup(self) -> bytes:
pkg_root = os.path.relpath(pkg_dir, str(self._path))
if "" in package_dir:
package_dir.update(
(p, os.path.join(pkg_root, p.replace(".", "/")))
(p, (Path(pkg_root) / p.replace(".", "/")).as_posix())
for p in _packages
)
else:
Expand Down Expand Up @@ -261,18 +261,18 @@ def find_packages(
subpkg_paths = set()

def find_nearest_pkg(rel_path: str) -> tuple[str, str]:
parts = rel_path.split(os.sep)
parts = Path(rel_path).parts
for i in reversed(range(1, len(parts))):
ancestor = "/".join(parts[:i])
if ancestor in subpkg_paths:
pkg = ".".join([pkg_name] + parts[:i])
pkg = ".".join([pkg_name, *parts[:i]])
return pkg, "/".join(parts[i:])

# Relative to the top-level package
return pkg_name, Path(rel_path).as_posix()

for path, _dirnames, filenames in os.walk(str(base), topdown=True):
if os.path.basename(path) == "__pycache__":
for path, _dirnames, filenames in os.walk(base, topdown=True):
if Path(path).name == "__pycache__":
continue

from_top_level = os.path.relpath(path, base)
Expand All @@ -288,7 +288,7 @@ def find_nearest_pkg(rel_path: str) -> tuple[str, str]:
)
if is_subpkg:
subpkg_paths.add(from_top_level)
parts = from_top_level.split(os.sep)
parts = Path(from_top_level).parts
packages.append(".".join([pkg_name, *parts]))
else:
pkg, from_nearest_pkg = find_nearest_pkg(from_top_level)
Expand Down
9 changes: 5 additions & 4 deletions src/poetry/core/masonry/builders/wheel.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,11 +104,12 @@ def build(
if not target_dir.exists():
target_dir.mkdir()

fd, temp_path = tempfile.mkstemp(suffix=".whl")
fd, temp = tempfile.mkstemp(suffix=".whl")

st_mode = os.stat(temp_path).st_mode
temp_path = Path(temp)
st_mode = temp_path.stat().st_mode
new_mode = normalize_file_permissions(st_mode)
os.chmod(temp_path, new_mode)
temp_path.chmod(new_mode)

with os.fdopen(fd, "w+b") as fd_file, zipfile.ZipFile(
fd_file, mode="w", compression=zipfile.ZIP_DEFLATED
Expand Down Expand Up @@ -137,7 +138,7 @@ def build(
wheel_path = target_dir / self.wheel_filename
if wheel_path.exists():
wheel_path.unlink()
shutil.move(temp_path, str(wheel_path))
shutil.move(str(temp_path), str(wheel_path))

logger.info(f"Built {self.wheel_filename}")
return wheel_path
Expand Down
4 changes: 2 additions & 2 deletions src/poetry/core/packages/dependency.py
Original file line number Diff line number Diff line change
Expand Up @@ -401,9 +401,9 @@ def create_from_pep_508(
elif req.url:
link = Link(req.url)
else:
path_str = os.path.normpath(os.path.abspath(name))
path_str = os.path.normpath(os.path.abspath(name)) # noqa: PTH100
p, extras = strip_extras(path_str)
if os.path.isdir(p) and (os.path.sep in name or name.startswith(".")):
if p.is_dir() and (os.path.sep in name or name.startswith(".")):
if not is_python_project(Path(name)):
raise ValueError(
f"Directory {name!r} is not installable. File 'setup.[py|cfg]' "
Expand Down
3 changes: 2 additions & 1 deletion src/poetry/core/packages/utils/link.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import warnings

from functools import cached_property
from pathlib import Path
from typing import TYPE_CHECKING

from poetry.core.packages.utils.utils import path_to_url
Expand Down Expand Up @@ -133,7 +134,7 @@ def path(self) -> str:
return urlparse.unquote(urlparse.urlsplit(self.url)[2])

def splitext(self) -> tuple[str, str]:
return splitext(posixpath.basename(self.path.rstrip("/")))
return splitext(Path(posixpath.basename(self.path.rstrip("/"))))

@cached_property
def ext(self) -> str:
Expand Down
13 changes: 6 additions & 7 deletions src/poetry/core/packages/utils/utils.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from __future__ import annotations

import functools
import posixpath
import re
import sys

Expand Down Expand Up @@ -107,7 +106,7 @@ def is_url(name: str) -> bool:
]


def strip_extras(path: str) -> tuple[str, str | None]:
def strip_extras(path: str) -> tuple[Path, str | None]:
m = re.match(r"^(.+)(\[[^\]]+\])$", path)
extras = None
if m:
Expand All @@ -116,7 +115,7 @@ def strip_extras(path: str) -> tuple[str, str | None]:
else:
path_no_extras = path

return path_no_extras, extras
return Path(path_no_extras), extras


@functools.lru_cache(maxsize=None)
Expand All @@ -137,19 +136,19 @@ def is_python_project(path: Path) -> bool:
return supports_pep517 or supports_poetry


def is_archive_file(name: str) -> bool:
def is_archive_file(name: Path) -> bool:
"""Return True if `name` is a considered as an archive file."""
ext = splitext(name)[1].lower()
if ext in ARCHIVE_EXTENSIONS:
return True
return False


def splitext(path: str) -> tuple[str, str]:
def splitext(path: Path) -> tuple[str, str]:
"""Like os.path.splitext, but take off .tar too"""
base, ext = posixpath.splitext(path)
base, ext = path.stem, path.suffix
if base.lower().endswith(".tar"):
ext = base[-4:] + ext
ext = f"{base[-4:]}{ext}"
base = base[:-4]
return base, ext

Expand Down
12 changes: 6 additions & 6 deletions src/poetry/core/utils/helpers.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from __future__ import annotations

import os
import shutil
import stat
import sys
Expand Down Expand Up @@ -41,16 +40,16 @@ def normalize_version(version: str) -> str:


@contextmanager
def temporary_directory(*args: Any, **kwargs: Any) -> Iterator[str]:
def temporary_directory(*args: Any, **kwargs: Any) -> Iterator[Path]:
if sys.version_info >= (3, 10):
# mypy reports an error if ignore_cleanup_errors is
# specified literally in the call
kwargs["ignore_cleanup_errors"] = True
with tempfile.TemporaryDirectory(*args, **kwargs) as name:
yield name
yield Path(name)
else:
name = tempfile.mkdtemp(*args, **kwargs)
yield name
yield Path(name)
robust_rmtree(name)


Expand Down Expand Up @@ -92,10 +91,11 @@ def parse_requires(requires: str) -> list[str]:


def _on_rm_error(func: Any, path: str | Path, exc_info: Any) -> None:
if not os.path.exists(path):
path = Path(path)
if not path.exists():
return

os.chmod(path, stat.S_IWRITE)
path.chmod(stat.S_IWRITE)
func(path)


Expand Down
2 changes: 1 addition & 1 deletion tests/integration/test_pep517_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def test_pip_install(

# Append dynamic `build-system` section to `pyproject.toml` in the temporary
# project directory.
with open(temp_pep_517_backend_path / "pyproject.toml", "a") as f:
with (temp_pep_517_backend_path / "pyproject.toml").open(mode="a") as f:
f.write(
BUILD_SYSTEM_TEMPLATE.format(project_path=project_source_root.as_posix())
)
Expand Down
3 changes: 1 addition & 2 deletions tests/masonry/builders/test_complete.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from __future__ import annotations

import csv
import os
import platform
import re
import shutil
Expand Down Expand Up @@ -117,7 +116,7 @@ def test_complete(no_vcs: bool) -> None:

assert whl.exists()
if sys.platform != "win32":
assert (os.stat(str(whl)).st_mode & 0o777) == 0o644
assert (whl.stat().st_mode & 0o777) == 0o644

expected_name_list = [
"my_package/__init__.py",
Expand Down
2 changes: 1 addition & 1 deletion tests/masonry/builders/test_sdist.py
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ def test_setup_py_context() -> None:
assert setup.exists()
assert project_setup_py == setup

with open(str(setup), "rb") as f:
with setup.open(mode="rb") as f:
# we convert to string and replace line endings here for compatibility
data = f.read().decode().replace("\r\n", "\n")
assert data == builder.build_setup().decode()
Expand Down
Loading

0 comments on commit 73ae2ee

Please sign in to comment.