diff --git a/newsfragments/4241.misc.rst b/newsfragments/4241.misc.rst new file mode 100644 index 0000000000..ef6da2c323 --- /dev/null +++ b/newsfragments/4241.misc.rst @@ -0,0 +1 @@ +Improvements to `Path`-related type annotations when it could be ``str | PathLike`` -- by :user:`Avasam` diff --git a/setuptools/_normalization.py b/setuptools/_normalization.py index 8f211b8bfb..e858052ccd 100644 --- a/setuptools/_normalization.py +++ b/setuptools/_normalization.py @@ -4,13 +4,9 @@ """ import re -from pathlib import Path -from typing import Union from .extern import packaging -_Path = Union[str, Path] - # https://packaging.python.org/en/latest/specifications/core-metadata/#name _VALID_NAME = re.compile(r"^([A-Z0-9]|[A-Z0-9][A-Z0-9._-]*[A-Z0-9])$", re.I) _UNSAFE_NAME_CHARS = re.compile(r"[^A-Z0-9._-]+", re.I) diff --git a/setuptools/_path.py b/setuptools/_path.py index b99d9dadcf..fb8ef0e198 100644 --- a/setuptools/_path.py +++ b/setuptools/_path.py @@ -2,7 +2,10 @@ import sys from typing import Union -_Path = Union[str, os.PathLike] +if sys.version_info >= (3, 9): + StrPath = Union[str, os.PathLike[str]] # Same as _typeshed.StrPath +else: + StrPath = Union[str, os.PathLike] def ensure_directory(path): @@ -11,7 +14,7 @@ def ensure_directory(path): os.makedirs(dirname, exist_ok=True) -def same_path(p1: _Path, p2: _Path) -> bool: +def same_path(p1: StrPath, p2: StrPath) -> bool: """Differs from os.path.samefile because it does not require paths to exist. Purely string based (no comparison between i-nodes). >>> same_path("a/b", "./a/b") @@ -30,7 +33,7 @@ def same_path(p1: _Path, p2: _Path) -> bool: return normpath(p1) == normpath(p2) -def normpath(filename: _Path) -> str: +def normpath(filename: StrPath) -> str: """Normalize a file/dir name for comparison purposes.""" # See pkg_resources.normalize_path for notes about cygwin file = os.path.abspath(filename) if sys.platform == 'cygwin' else filename diff --git a/setuptools/command/editable_wheel.py b/setuptools/command/editable_wheel.py index 8a4ae7928f..a81fcd5bf9 100644 --- a/setuptools/command/editable_wheel.py +++ b/setuptools/command/editable_wheel.py @@ -33,7 +33,6 @@ Protocol, Tuple, TypeVar, - Union, ) from .. import ( @@ -43,6 +42,7 @@ errors, namespaces, ) +from .._path import StrPath from ..discovery import find_package_path from ..dist import Distribution from ..warnings import ( @@ -55,8 +55,7 @@ if TYPE_CHECKING: from wheel.wheelfile import WheelFile # noqa -_Path = Union[str, Path] -_P = TypeVar("_P", bound=_Path) +_P = TypeVar("_P", bound=StrPath) _logger = logging.getLogger(__name__) @@ -181,7 +180,7 @@ def _find_egg_info_dir(self) -> Optional[str]: return next(candidates, None) def _configure_build( - self, name: str, unpacked_wheel: _Path, build_lib: _Path, tmp_dir: _Path + self, name: str, unpacked_wheel: StrPath, build_lib: StrPath, tmp_dir: StrPath ): """Configure commands to behave in the following ways: @@ -256,7 +255,11 @@ def _collect_build_outputs(self) -> Tuple[List[str], Dict[str, str]]: return files, mapping def _run_build_commands( - self, dist_name: str, unpacked_wheel: _Path, build_lib: _Path, tmp_dir: _Path + self, + dist_name: str, + unpacked_wheel: StrPath, + build_lib: StrPath, + tmp_dir: StrPath, ) -> Tuple[List[str], Dict[str, str]]: self._configure_build(dist_name, unpacked_wheel, build_lib, tmp_dir) self._run_build_subcommands() @@ -354,7 +357,7 @@ def _select_strategy( self, name: str, tag: str, - build_lib: _Path, + build_lib: StrPath, ) -> "EditableStrategy": """Decides which strategy to use to implement an editable installation.""" build_name = f"__editable__.{name}-{tag}" @@ -424,8 +427,8 @@ def __init__( self, dist: Distribution, name: str, - auxiliary_dir: _Path, - build_lib: _Path, + auxiliary_dir: StrPath, + build_lib: StrPath, ): self.auxiliary_dir = Path(auxiliary_dir) self.build_lib = Path(build_lib).resolve() @@ -567,7 +570,7 @@ def _can_symlink_files(base_dir: Path) -> bool: def _simple_layout( - packages: Iterable[str], package_dir: Dict[str, str], project_dir: Path + packages: Iterable[str], package_dir: Dict[str, str], project_dir: StrPath ) -> bool: """Return ``True`` if: - all packages are contained by the same parent directory, **and** @@ -649,7 +652,7 @@ def _find_top_level_modules(dist: Distribution) -> Iterator[str]: def _find_package_roots( packages: Iterable[str], package_dir: Mapping[str, str], - src_root: _Path, + src_root: StrPath, ) -> Dict[str, str]: pkg_roots: Dict[str, str] = { pkg: _absolute_root(find_package_path(pkg, package_dir, src_root)) @@ -659,7 +662,7 @@ def _find_package_roots( return _remove_nested(pkg_roots) -def _absolute_root(path: _Path) -> str: +def _absolute_root(path: StrPath) -> str: """Works for packages and top-level modules""" path_ = Path(path) parent = path_.parent diff --git a/setuptools/config/_apply_pyprojecttoml.py b/setuptools/config/_apply_pyprojecttoml.py index 32fb00131e..7301bc65c1 100644 --- a/setuptools/config/_apply_pyprojecttoml.py +++ b/setuptools/config/_apply_pyprojecttoml.py @@ -29,7 +29,7 @@ Union, cast, ) - +from .._path import StrPath from ..errors import RemovedConfigError from ..warnings import SetuptoolsWarning @@ -38,15 +38,14 @@ from setuptools.dist import Distribution # noqa EMPTY: Mapping = MappingProxyType({}) # Immutable dict-like -_Path = Union[os.PathLike, str] _DictOrStr = Union[dict, str] -_CorrespFn = Callable[["Distribution", Any, _Path], None] +_CorrespFn = Callable[["Distribution", Any, StrPath], None] _Correspondence = Union[str, _CorrespFn] _logger = logging.getLogger(__name__) -def apply(dist: "Distribution", config: dict, filename: _Path) -> "Distribution": +def apply(dist: "Distribution", config: dict, filename: StrPath) -> "Distribution": """Apply configuration dict read with :func:`read_configuration`""" if not config: @@ -68,7 +67,7 @@ def apply(dist: "Distribution", config: dict, filename: _Path) -> "Distribution" return dist -def _apply_project_table(dist: "Distribution", config: dict, root_dir: _Path): +def _apply_project_table(dist: "Distribution", config: dict, root_dir: StrPath): project_table = config.get("project", {}).copy() if not project_table: return # short-circuit @@ -85,7 +84,7 @@ def _apply_project_table(dist: "Distribution", config: dict, root_dir: _Path): _set_config(dist, corresp, value) -def _apply_tool_table(dist: "Distribution", config: dict, filename: _Path): +def _apply_tool_table(dist: "Distribution", config: dict, filename: StrPath): tool_table = config.get("tool", {}).get("setuptools", {}) if not tool_table: return # short-circuit @@ -153,7 +152,7 @@ def _guess_content_type(file: str) -> Optional[str]: raise ValueError(f"Undefined content type for {file}, {msg}") -def _long_description(dist: "Distribution", val: _DictOrStr, root_dir: _Path): +def _long_description(dist: "Distribution", val: _DictOrStr, root_dir: StrPath): from setuptools.config import expand if isinstance(val, str): @@ -174,7 +173,7 @@ def _long_description(dist: "Distribution", val: _DictOrStr, root_dir: _Path): dist._referenced_files.add(cast(str, file)) -def _license(dist: "Distribution", val: dict, root_dir: _Path): +def _license(dist: "Distribution", val: dict, root_dir: StrPath): from setuptools.config import expand if "file" in val: @@ -184,7 +183,7 @@ def _license(dist: "Distribution", val: dict, root_dir: _Path): _set_config(dist, "license", val["text"]) -def _people(dist: "Distribution", val: List[dict], _root_dir: _Path, kind: str): +def _people(dist: "Distribution", val: List[dict], _root_dir: StrPath, kind: str): field = [] email_field = [] for person in val: @@ -244,7 +243,7 @@ def _unify_entry_points(project_table: dict): # intentional (for resetting configurations that are missing `dynamic`). -def _copy_command_options(pyproject: dict, dist: "Distribution", filename: _Path): +def _copy_command_options(pyproject: dict, dist: "Distribution", filename: StrPath): tool_table = pyproject.get("tool", {}) cmdclass = tool_table.get("setuptools", {}).get("cmdclass", {}) valid_options = _valid_command_options(cmdclass) diff --git a/setuptools/config/expand.py b/setuptools/config/expand.py index b48fc1187e..e23a762cf5 100644 --- a/setuptools/config/expand.py +++ b/setuptools/config/expand.py @@ -46,7 +46,7 @@ from distutils.errors import DistutilsOptionError -from .._path import same_path as _same_path +from .._path import same_path as _same_path, StrPath from ..warnings import SetuptoolsWarning if TYPE_CHECKING: @@ -55,7 +55,6 @@ from distutils.dist import DistributionMetadata # noqa chain_iter = chain.from_iterable -_Path = Union[str, os.PathLike] _K = TypeVar("_K") _V = TypeVar("_V", covariant=True) @@ -88,7 +87,7 @@ def __getattr__(self, attr): def glob_relative( - patterns: Iterable[str], root_dir: Optional[_Path] = None + patterns: Iterable[str], root_dir: Optional[StrPath] = None ) -> List[str]: """Expand the list of glob patterns, but preserving relative paths. @@ -120,7 +119,7 @@ def glob_relative( return expanded_values -def read_files(filepaths: Union[str, bytes, Iterable[_Path]], root_dir=None) -> str: +def read_files(filepaths: Union[str, bytes, Iterable[StrPath]], root_dir=None) -> str: """Return the content of the files concatenated using ``\n`` as str This function is sandboxed and won't reach anything outside ``root_dir`` @@ -138,7 +137,7 @@ def read_files(filepaths: Union[str, bytes, Iterable[_Path]], root_dir=None) -> ) -def _filter_existing_files(filepaths: Iterable[_Path]) -> Iterator[_Path]: +def _filter_existing_files(filepaths: Iterable[StrPath]) -> Iterator[StrPath]: for path in filepaths: if os.path.isfile(path): yield path @@ -146,12 +145,12 @@ def _filter_existing_files(filepaths: Iterable[_Path]) -> Iterator[_Path]: SetuptoolsWarning.emit(f"File {path!r} cannot be found") -def _read_file(filepath: Union[bytes, _Path]) -> str: +def _read_file(filepath: Union[bytes, StrPath]) -> str: with open(filepath, encoding='utf-8') as f: return f.read() -def _assert_local(filepath: _Path, root_dir: str): +def _assert_local(filepath: StrPath, root_dir: str): if Path(os.path.abspath(root_dir)) not in Path(os.path.abspath(filepath)).parents: msg = f"Cannot access {filepath!r} (or anything outside {root_dir!r})" raise DistutilsOptionError(msg) @@ -162,7 +161,7 @@ def _assert_local(filepath: _Path, root_dir: str): def read_attr( attr_desc: str, package_dir: Optional[Mapping[str, str]] = None, - root_dir: Optional[_Path] = None, + root_dir: Optional[StrPath] = None, ): """Reads the value of an attribute from a module. @@ -197,7 +196,7 @@ def read_attr( return getattr(module, attr_name) -def _find_spec(module_name: str, module_path: Optional[_Path]) -> ModuleSpec: +def _find_spec(module_name: str, module_path: Optional[StrPath]) -> ModuleSpec: spec = importlib.util.spec_from_file_location(module_name, module_path) spec = spec or importlib.util.find_spec(module_name) @@ -218,8 +217,8 @@ def _load_spec(spec: ModuleSpec, module_name: str) -> ModuleType: def _find_module( - module_name: str, package_dir: Optional[Mapping[str, str]], root_dir: _Path -) -> Tuple[_Path, Optional[str], str]: + module_name: str, package_dir: Optional[Mapping[str, str]], root_dir: StrPath +) -> Tuple[StrPath, Optional[str], str]: """Given a module (that could normally be imported by ``module_name`` after the build is complete), find the path to the parent directory where it is contained and the canonical name that could be used to import it @@ -254,7 +253,7 @@ def _find_module( def resolve_class( qualified_class_name: str, package_dir: Optional[Mapping[str, str]] = None, - root_dir: Optional[_Path] = None, + root_dir: Optional[StrPath] = None, ) -> Callable: """Given a qualified class name, return the associated class object""" root_dir = root_dir or os.getcwd() @@ -270,7 +269,7 @@ def resolve_class( def cmdclass( values: Dict[str, str], package_dir: Optional[Mapping[str, str]] = None, - root_dir: Optional[_Path] = None, + root_dir: Optional[StrPath] = None, ) -> Dict[str, Callable]: """Given a dictionary mapping command names to strings for qualified class names, apply :func:`resolve_class` to the dict values. @@ -282,7 +281,7 @@ def find_packages( *, namespaces=True, fill_package_dir: Optional[Dict[str, str]] = None, - root_dir: Optional[_Path] = None, + root_dir: Optional[StrPath] = None, **kwargs, ) -> List[str]: """Works similarly to :func:`setuptools.find_packages`, but with all @@ -331,7 +330,7 @@ def find_packages( return packages -def _nest_path(parent: _Path, path: _Path) -> str: +def _nest_path(parent: StrPath, path: StrPath) -> str: path = parent if path in {".", ""} else os.path.join(parent, path) return os.path.normpath(path) @@ -361,7 +360,7 @@ def canonic_package_data(package_data: dict) -> dict: def canonic_data_files( - data_files: Union[list, dict], root_dir: Optional[_Path] = None + data_files: Union[list, dict], root_dir: Optional[StrPath] = None ) -> List[Tuple[str, List[str]]]: """For compatibility with ``setup.py``, ``data_files`` should be a list of pairs instead of a dict. diff --git a/setuptools/config/pyprojecttoml.py b/setuptools/config/pyprojecttoml.py index 9b9788eff4..5eb9421f1f 100644 --- a/setuptools/config/pyprojecttoml.py +++ b/setuptools/config/pyprojecttoml.py @@ -13,8 +13,9 @@ import os from contextlib import contextmanager from functools import partial -from typing import TYPE_CHECKING, Callable, Dict, Mapping, Optional, Set, Union +from typing import TYPE_CHECKING, Callable, Dict, Mapping, Optional, Set +from .._path import StrPath from ..errors import FileError, InvalidConfigError from ..warnings import SetuptoolsWarning from . import expand as _expand @@ -24,18 +25,17 @@ if TYPE_CHECKING: from setuptools.dist import Distribution # noqa -_Path = Union[str, os.PathLike] _logger = logging.getLogger(__name__) -def load_file(filepath: _Path) -> dict: +def load_file(filepath: StrPath) -> dict: from ..compat.py310 import tomllib with open(filepath, "rb") as file: return tomllib.load(file) -def validate(config: dict, filepath: _Path) -> bool: +def validate(config: dict, filepath: StrPath) -> bool: from . import _validate_pyproject as validator trove_classifier = validator.FORMAT_FUNCTIONS.get("trove-classifier") @@ -58,7 +58,7 @@ def validate(config: dict, filepath: _Path) -> bool: def apply_configuration( dist: "Distribution", - filepath: _Path, + filepath: StrPath, ignore_option_errors=False, ) -> "Distribution": """Apply the configuration from a ``pyproject.toml`` file into an existing @@ -69,7 +69,7 @@ def apply_configuration( def read_configuration( - filepath: _Path, + filepath: StrPath, expand=True, ignore_option_errors=False, dist: Optional["Distribution"] = None, @@ -136,7 +136,7 @@ def read_configuration( def expand_configuration( config: dict, - root_dir: Optional[_Path] = None, + root_dir: Optional[StrPath] = None, ignore_option_errors: bool = False, dist: Optional["Distribution"] = None, ) -> dict: @@ -161,7 +161,7 @@ class _ConfigExpander: def __init__( self, config: dict, - root_dir: Optional[_Path] = None, + root_dir: Optional[StrPath] = None, ignore_option_errors: bool = False, dist: Optional["Distribution"] = None, ): diff --git a/setuptools/config/setupcfg.py b/setuptools/config/setupcfg.py index a7f02714cb..cfa43a57b5 100644 --- a/setuptools/config/setupcfg.py +++ b/setuptools/config/setupcfg.py @@ -30,6 +30,7 @@ Union, ) +from .._path import StrPath from ..errors import FileError, OptionError from ..extern.packaging.markers import default_environment as marker_env from ..extern.packaging.requirements import InvalidRequirement, Requirement @@ -43,7 +44,6 @@ from setuptools.dist import Distribution # noqa -_Path = Union[str, os.PathLike] SingleCommandOptions = Dict["str", Tuple["str", Any]] """Dict that associate the name of the options of a particular command to a tuple. The first element of the tuple indicates the origin of the option value @@ -55,7 +55,7 @@ def read_configuration( - filepath: _Path, find_others=False, ignore_option_errors=False + filepath: StrPath, find_others=False, ignore_option_errors=False ) -> dict: """Read given configuration file and returns options from it as a dict. @@ -80,7 +80,7 @@ def read_configuration( return configuration_to_dict(handlers) -def apply_configuration(dist: "Distribution", filepath: _Path) -> "Distribution": +def apply_configuration(dist: "Distribution", filepath: StrPath) -> "Distribution": """Apply the configuration from a ``setup.cfg`` file into an existing distribution object. """ @@ -91,8 +91,8 @@ def apply_configuration(dist: "Distribution", filepath: _Path) -> "Distribution" def _apply( dist: "Distribution", - filepath: _Path, - other_files: Iterable[_Path] = (), + filepath: StrPath, + other_files: Iterable[StrPath] = (), ignore_option_errors: bool = False, ) -> Tuple["ConfigHandler", ...]: """Read configuration from ``filepath`` and applies to the ``dist`` object.""" @@ -371,7 +371,7 @@ def parser(value): return parser - def _parse_file(self, value, root_dir: _Path): + def _parse_file(self, value, root_dir: StrPath): """Represents value as a string, allowing including text from nearest files using `file:` directive. @@ -397,7 +397,7 @@ def _parse_file(self, value, root_dir: _Path): self._referenced_files.update(filepaths) return expand.read_files(filepaths, root_dir) - def _parse_attr(self, value, package_dir, root_dir: _Path): + def _parse_attr(self, value, package_dir, root_dir: StrPath): """Represents value as a module attribute. Examples: @@ -539,7 +539,7 @@ def __init__( ignore_option_errors: bool, ensure_discovered: expand.EnsurePackagesDiscovered, package_dir: Optional[dict] = None, - root_dir: _Path = os.curdir, + root_dir: StrPath = os.curdir, ): super().__init__(target_obj, options, ignore_option_errors, ensure_discovered) self.package_dir = package_dir diff --git a/setuptools/discovery.py b/setuptools/discovery.py index 50a948750f..571be12bf4 100644 --- a/setuptools/discovery.py +++ b/setuptools/discovery.py @@ -51,15 +51,14 @@ Mapping, Optional, Tuple, - Union, ) import _distutils_hack.override # noqa: F401 +from ._path import StrPath from distutils import log from distutils.util import convert_path -_Path = Union[str, os.PathLike] StrIter = Iterator[str] chain_iter = itertools.chain.from_iterable @@ -68,7 +67,7 @@ from setuptools import Distribution # noqa -def _valid_name(path: _Path) -> bool: +def _valid_name(path: StrPath) -> bool: # Ignore invalid names that cannot be imported directly return os.path.basename(path).isidentifier() @@ -98,7 +97,7 @@ class _Finder: @classmethod def find( cls, - where: _Path = '.', + where: StrPath = '.', exclude: Iterable[str] = (), include: Iterable[str] = ('*',), ) -> List[str]: @@ -131,7 +130,7 @@ def find( ) @classmethod - def _find_iter(cls, where: _Path, exclude: _Filter, include: _Filter) -> StrIter: + def _find_iter(cls, where: StrPath, exclude: _Filter, include: _Filter) -> StrIter: raise NotImplementedError @@ -143,7 +142,7 @@ class PackageFinder(_Finder): ALWAYS_EXCLUDE = ("ez_setup", "*__pycache__") @classmethod - def _find_iter(cls, where: _Path, exclude: _Filter, include: _Filter) -> StrIter: + def _find_iter(cls, where: StrPath, exclude: _Filter, include: _Filter) -> StrIter: """ All the packages found in 'where' that pass the 'include' filter, but not the 'exclude' filter. @@ -175,14 +174,14 @@ def _find_iter(cls, where: _Path, exclude: _Filter, include: _Filter) -> StrIter dirs.append(dir) @staticmethod - def _looks_like_package(path: _Path, _package_name: str) -> bool: + def _looks_like_package(path: StrPath, _package_name: str) -> bool: """Does a directory look like a package?""" return os.path.isfile(os.path.join(path, '__init__.py')) class PEP420PackageFinder(PackageFinder): @staticmethod - def _looks_like_package(_path: _Path, _package_name: str) -> bool: + def _looks_like_package(_path: StrPath, _package_name: str) -> bool: return True @@ -192,7 +191,7 @@ class ModuleFinder(_Finder): """ @classmethod - def _find_iter(cls, where: _Path, exclude: _Filter, include: _Filter) -> StrIter: + def _find_iter(cls, where: StrPath, exclude: _Filter, include: _Filter) -> StrIter: for file in glob(os.path.join(where, "*.py")): module, _ext = os.path.splitext(os.path.basename(file)) @@ -255,7 +254,7 @@ class FlatLayoutPackageFinder(PEP420PackageFinder): """Reserved package names""" @staticmethod - def _looks_like_package(_path: _Path, package_name: str) -> bool: + def _looks_like_package(_path: StrPath, package_name: str) -> bool: names = package_name.split('.') # Consider PEP 561 root_pkg_is_valid = names[0].isidentifier() or names[0].endswith("-stubs") @@ -292,7 +291,7 @@ class FlatLayoutModuleFinder(ModuleFinder): """Reserved top-level module names""" -def _find_packages_within(root_pkg: str, pkg_dir: _Path) -> List[str]: +def _find_packages_within(root_pkg: str, pkg_dir: StrPath) -> List[str]: nested = PEP420PackageFinder.find(pkg_dir) return [root_pkg] + [".".join((root_pkg, n)) for n in nested] @@ -325,7 +324,7 @@ def _ignore_ext_modules(self): self._skip_ext_modules = True @property - def _root_dir(self) -> _Path: + def _root_dir(self) -> StrPath: # The best is to wait until `src_root` is set in dist, before using _root_dir. return self.dist.src_root or os.curdir @@ -551,7 +550,7 @@ def remove_stubs(packages: List[str]) -> List[str]: def find_parent_package( - packages: List[str], package_dir: Mapping[str, str], root_dir: _Path + packages: List[str], package_dir: Mapping[str, str], root_dir: StrPath ) -> Optional[str]: """Find the parent package that is not a namespace.""" packages = sorted(packages, key=len) @@ -575,7 +574,7 @@ def find_parent_package( def find_package_path( - name: str, package_dir: Mapping[str, str], root_dir: _Path + name: str, package_dir: Mapping[str, str], root_dir: StrPath ) -> str: """Given a package name, return the path where it should be found on disk, considering the ``package_dir`` option. @@ -608,7 +607,7 @@ def find_package_path( return os.path.join(root_dir, *parent.split("/"), *parts) -def construct_package_dir(packages: List[str], package_path: _Path) -> Dict[str, str]: +def construct_package_dir(packages: List[str], package_path: StrPath) -> Dict[str, str]: parent_pkgs = remove_nested_packages(packages) prefix = Path(package_path).parts return {pkg: "/".join([*prefix, *pkg.split(".")]) for pkg in parent_pkgs} diff --git a/setuptools/tests/config/test_pyprojecttoml.py b/setuptools/tests/config/test_pyprojecttoml.py index 318885a6bd..6a40f3bfd7 100644 --- a/setuptools/tests/config/test_pyprojecttoml.py +++ b/setuptools/tests/config/test_pyprojecttoml.py @@ -4,7 +4,7 @@ import pytest import tomli_w -from path import Path as _Path +from path import Path from setuptools.config.pyprojecttoml import ( read_configuration, @@ -352,7 +352,7 @@ def test_include_package_data_in_setuppy(tmp_path): setuppy = tmp_path / "setup.py" setuppy.write_text("__import__('setuptools').setup(include_package_data=False)") - with _Path(tmp_path): + with Path(tmp_path): dist = distutils.core.run_setup("setup.py", {}, stop_after="config") assert dist.get_name() == "myproj" diff --git a/setuptools/tests/test_config_discovery.py b/setuptools/tests/test_config_discovery.py index 85cb09730c..ef2979d4f5 100644 --- a/setuptools/tests/test_config_discovery.py +++ b/setuptools/tests/test_config_discovery.py @@ -13,7 +13,7 @@ import pytest import jaraco.path -from path import Path as _Path +from path import Path from .contexts import quiet from .integration.helpers import get_sdist_members, get_wheel_members, run @@ -304,7 +304,7 @@ def test_setupcfg_metadata(self, tmp_path, folder, opts): assert dist.package_dir package_path = find_package_path("pkg", dist.package_dir, tmp_path) assert os.path.exists(package_path) - assert folder in _Path(package_path).parts() + assert folder in Path(package_path).parts() _run_build(tmp_path, "--sdist") dist_file = tmp_path / "dist/pkg-42.tar.gz" @@ -607,14 +607,14 @@ def _get_dist(dist_path, attrs): script = dist_path / 'setup.py' if script.exists(): - with _Path(dist_path): + with Path(dist_path): dist = distutils.core.run_setup("setup.py", {}, stop_after="init") else: dist = Distribution(attrs) dist.src_root = root dist.script_name = "setup.py" - with _Path(dist_path): + with Path(dist_path): dist.parse_config_files() dist.set_defaults() @@ -627,7 +627,7 @@ def _run_sdist_programatically(dist_path, attrs): cmd.ensure_finalized() assert cmd.distribution.packages or cmd.distribution.py_modules - with quiet(), _Path(dist_path): + with quiet(), Path(dist_path): cmd.run() return dist, cmd diff --git a/tools/generate_validation_code.py b/tools/generate_validation_code.py index 53bc8ad650..b575fb1e1c 100644 --- a/tools/generate_validation_code.py +++ b/tools/generate_validation_code.py @@ -1,10 +1,12 @@ +from os import PathLike import subprocess import sys from pathlib import Path +from typing import Union -def generate_pyproject_validation(dest: Path): +def generate_pyproject_validation(dest: Union[str, PathLike]): """ Generates validation code for ``pyproject.toml`` based on JSON schemas and the ``validate-pyproject`` library.