Skip to content

Commit

Permalink
Merge branch 'main' into pyright-initial-config
Browse files Browse the repository at this point in the history
  • Loading branch information
Avasam authored Jun 17, 2024
2 parents b33d4a0 + 8aa9855 commit c957935
Show file tree
Hide file tree
Showing 17 changed files with 149 additions and 110 deletions.
1 change: 1 addition & 0 deletions newsfragments/4382.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Prevent a ``TypeError: 'NoneType' object is not callable`` when ``shutil_rmtree`` is called without an ``onexc`` parameter on Python<=3.11 -- by :user:`Avasam`
1 change: 1 addition & 0 deletions newsfragments/4403.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Replace use of mktemp with can_symlink from the stdlib test suite.
2 changes: 2 additions & 0 deletions newsfragments/4405.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Improvement for ``attr:`` directives in configuration to handle
more edge cases related to complex ``package_dir``.
1 change: 1 addition & 0 deletions newsfragments/4411.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix accidental implicit string concatenation.
87 changes: 54 additions & 33 deletions pkg_resources/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
MutableSequence,
NamedTuple,
NoReturn,
Sequence,
Set,
Tuple,
Type,
Expand All @@ -49,6 +48,7 @@
Iterable,
Optional,
TypeVar,
overload,
)
import zipfile
import zipimport
Expand Down Expand Up @@ -99,7 +99,7 @@
from pkg_resources.extern.platformdirs import user_cache_dir as _user_cache_dir

if TYPE_CHECKING:
from _typeshed import StrPath
from _typeshed import StrPath, StrOrBytesPath, BytesPath

warnings.warn(
"pkg_resources is deprecated as an API. "
Expand All @@ -109,7 +109,7 @@
)


T = TypeVar("T")
_T = TypeVar("_T")
# Type aliases
_NestedStr = Union[str, Iterable[Union[str, Iterable["_NestedStr"]]]]
_InstallerType = Callable[["Requirement"], Optional["Distribution"]]
Expand All @@ -118,7 +118,12 @@
_MetadataType = Optional["IResourceProvider"]
# Any object works, but let's indicate we expect something like a module (optionally has __loader__ or __file__)
_ModuleLike = Union[object, types.ModuleType]
_AdapterType = Callable[..., Any] # Incomplete
_ProviderFactoryType = Callable[[_ModuleLike], "IResourceProvider"]
_DistFinderType = Callable[[_T, str, bool], Iterable["Distribution"]]
_NSHandlerType = Callable[[_T, str, str, types.ModuleType], Optional[str]]
_AdapterT = TypeVar(
"_AdapterT", _DistFinderType[Any], _ProviderFactoryType, _NSHandlerType[Any]
)


# Use _typeshed.importlib.LoaderProtocol once available https://github.com/python/typeshed/pull/11890
Expand All @@ -142,7 +147,7 @@ class PEP440Warning(RuntimeWarning):
_state_vars: Dict[str, str] = {}


def _declare_state(vartype: str, varname: str, initial_value: T) -> T:
def _declare_state(vartype: str, varname: str, initial_value: _T) -> _T:
_state_vars[varname] = vartype
return initial_value

Expand Down Expand Up @@ -377,7 +382,7 @@ class UnknownExtra(ResolutionError):
"""Distribution doesn't have an "extra feature" of the given name"""


_provider_factories: Dict[Type[_ModuleLike], _AdapterType] = {}
_provider_factories: Dict[Type[_ModuleLike], _ProviderFactoryType] = {}

PY_MAJOR = '{}.{}'.format(*sys.version_info)
EGG_DIST = 3
Expand All @@ -388,7 +393,7 @@ class UnknownExtra(ResolutionError):


def register_loader_type(
loader_type: Type[_ModuleLike], provider_factory: _AdapterType
loader_type: Type[_ModuleLike], provider_factory: _ProviderFactoryType
):
"""Register `provider_factory` to make providers for `loader_type`
Expand Down Expand Up @@ -1041,7 +1046,7 @@ class Environment:

def __init__(
self,
search_path: Optional[Sequence[str]] = None,
search_path: Optional[Iterable[str]] = None,
platform: Optional[str] = get_supported_platform(),
python: Optional[str] = PY_MAJOR,
):
Expand Down Expand Up @@ -1084,7 +1089,7 @@ def remove(self, dist: "Distribution"):
"""Remove `dist` from the environment"""
self._distmap[dist.key].remove(dist)

def scan(self, search_path: Optional[Sequence[str]] = None):
def scan(self, search_path: Optional[Iterable[str]] = None):
"""Scan `search_path` for distributions usable in this environment
Any distributions found are added to the environment.
Expand Down Expand Up @@ -1288,7 +1293,7 @@ def extraction_error(self) -> NoReturn:
err.original_error = old_exc
raise err

def get_cache_path(self, archive_name: str, names: Iterable[str] = ()):
def get_cache_path(self, archive_name: str, names: Iterable["StrPath"] = ()):
"""Return absolute location in cache for `archive_name` and `names`
The parent directory of the resulting path will be created if it does
Expand Down Expand Up @@ -1340,7 +1345,7 @@ def _warn_unsafe_extraction_path(path):
).format(**locals())
warnings.warn(msg, UserWarning)

def postprocess(self, tempname: str, filename: str):
def postprocess(self, tempname: "StrOrBytesPath", filename: "StrOrBytesPath"):
"""Perform any platform-specific postprocessing of `tempname`
This is where Mac header rewrites should be done; other platforms don't
Expand Down Expand Up @@ -2097,12 +2102,12 @@ def __init__(self, importer: zipimport.zipimporter):
self._setup_prefix()


_distribution_finders: Dict[
type, Callable[[object, str, bool], Iterable["Distribution"]]
] = _declare_state('dict', '_distribution_finders', {})
_distribution_finders: Dict[type, _DistFinderType[Any]] = _declare_state(
'dict', '_distribution_finders', {}
)


def register_finder(importer_type: type, distribution_finder: _AdapterType):
def register_finder(importer_type: Type[_T], distribution_finder: _DistFinderType[_T]):
"""Register `distribution_finder` to find distributions in sys.path items
`importer_type` is the type or class of a PEP 302 "Importer" (sys.path item
Expand Down Expand Up @@ -2276,15 +2281,17 @@ def resolve_egg_link(path):

register_finder(importlib.machinery.FileFinder, find_on_path)

_namespace_handlers: Dict[
type, Callable[[object, str, str, types.ModuleType], Optional[str]]
] = _declare_state('dict', '_namespace_handlers', {})
_namespace_handlers: Dict[type, _NSHandlerType[Any]] = _declare_state(
'dict', '_namespace_handlers', {}
)
_namespace_packages: Dict[Optional[str], List[str]] = _declare_state(
'dict', '_namespace_packages', {}
)


def register_namespace_handler(importer_type: type, namespace_handler: _AdapterType):
def register_namespace_handler(
importer_type: Type[_T], namespace_handler: _NSHandlerType[_T]
):
"""Register `namespace_handler` to declare namespace packages
`importer_type` is the type or class of a PEP 302 "Importer" (sys.path item
Expand Down Expand Up @@ -2429,9 +2436,9 @@ def fixup_namespace_packages(path_item: str, parent: Optional[str] = None):


def file_ns_handler(
importer: Optional[importlib.abc.PathEntryFinder],
path_item,
packageName,
importer: object,
path_item: "StrPath",
packageName: str,
module: types.ModuleType,
):
"""Compute an ns-package subpath for a filesystem or zipfile importer"""
Expand All @@ -2454,7 +2461,7 @@ def file_ns_handler(


def null_ns_handler(
importer: Optional[importlib.abc.PathEntryFinder],
importer: object,
path_item: Optional[str],
packageName: Optional[str],
module: Optional[_ModuleLike],
Expand All @@ -2465,12 +2472,16 @@ def null_ns_handler(
register_namespace_handler(object, null_ns_handler)


def normalize_path(filename: "StrPath"):
@overload
def normalize_path(filename: "StrPath") -> str: ...
@overload
def normalize_path(filename: "BytesPath") -> bytes: ...
def normalize_path(filename: "StrOrBytesPath"):
"""Normalize a file/dir name for comparison purposes"""
return os.path.normcase(os.path.realpath(os.path.normpath(_cygwin_patch(filename))))


def _cygwin_patch(filename: "StrPath"): # pragma: nocover
def _cygwin_patch(filename: "StrOrBytesPath"): # pragma: nocover
"""
Contrary to POSIX 2008, on Cygwin, getcwd (3) contains
symlink components. Using
Expand All @@ -2481,9 +2492,19 @@ def _cygwin_patch(filename: "StrPath"): # pragma: nocover
return os.path.abspath(filename) if sys.platform == 'cygwin' else filename


@functools.lru_cache(maxsize=None)
def _normalize_cached(filename):
return normalize_path(filename)
if TYPE_CHECKING:
# https://github.com/python/mypy/issues/16261
# https://github.com/python/typeshed/issues/6347
@overload
def _normalize_cached(filename: "StrPath") -> str: ...
@overload
def _normalize_cached(filename: "BytesPath") -> bytes: ...
def _normalize_cached(filename: "StrOrBytesPath") -> Union[str, bytes]: ...
else:

@functools.lru_cache(maxsize=None)
def _normalize_cached(filename):
return normalize_path(filename)


def _is_egg_path(path):
Expand Down Expand Up @@ -2680,7 +2701,7 @@ def parse_map(
_data = data.items()
else:
_data = split_sections(data)
maps: Dict[str, Dict[str, "EntryPoint"]] = {}
maps: Dict[str, Dict[str, EntryPoint]] = {}
for group, lines in _data:
if group is None:
if not lines:
Expand Down Expand Up @@ -2736,7 +2757,7 @@ def __init__(
def from_location(
cls,
location: str,
basename: str,
basename: "StrPath",
metadata: _MetadataType = None,
**kw: int, # We could set `precedence` explicitly, but keeping this as `**kw` for full backwards and subclassing compatibility
):
Expand Down Expand Up @@ -2996,7 +3017,7 @@ def __dir__(self):
@classmethod
def from_filename(
cls,
filename: str,
filename: "StrPath",
metadata: _MetadataType = None,
**kw: int, # We could set `precedence` explicitly, but keeping this as `**kw` for full backwards and subclassing compatibility
):
Expand Down Expand Up @@ -3321,7 +3342,7 @@ def _always_object(classes):
return classes


def _find_adapter(registry: Mapping[type, _AdapterType], ob: object):
def _find_adapter(registry: Mapping[type, _AdapterT], ob: object) -> _AdapterT:
"""Return an adapter factory for `ob` from `registry`"""
types = _always_object(inspect.getmro(getattr(ob, '__class__', type(ob))))
for t in types:
Expand All @@ -3332,7 +3353,7 @@ def _find_adapter(registry: Mapping[type, _AdapterType], ob: object):
raise TypeError(f"Could not find adapter for {registry} and {ob}")


def ensure_directory(path: str):
def ensure_directory(path: "StrOrBytesPath"):
"""Ensure that the parent directory of `path` exists"""
dirname = os.path.dirname(path)
os.makedirs(dirname, exist_ok=True)
Expand Down
2 changes: 2 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ testing = [

# workaround for pypa/setuptools#4333
"pyproject-hooks!=1.1",

"jaraco.test",
]
docs = [
# upstream
Expand Down
34 changes: 22 additions & 12 deletions setuptools/build_meta.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,12 @@
import tempfile
import warnings
from pathlib import Path
from typing import Dict, Iterator, List, Optional, Union
from typing import Dict, Iterator, List, Optional, Tuple, Union, Iterable

import setuptools
import distutils
from . import errors
from ._path import same_path
from ._path import same_path, StrPath
from ._reqs import parse_strings
from .warnings import SetuptoolsDeprecationWarning
from distutils.util import strtobool
Expand Down Expand Up @@ -113,7 +113,7 @@ def _get_immediate_subdirectories(a_dir):
]


def _file_with_extension(directory, extension):
def _file_with_extension(directory: StrPath, extension: Union[str, Tuple[str, ...]]):
matching = (f for f in os.listdir(directory) if f.endswith(extension))
try:
(file,) = matching
Expand Down Expand Up @@ -370,11 +370,11 @@ def prepare_metadata_for_build_wheel(

def _build_with_temp_dir(
self,
setup_command,
result_extension,
result_directory,
config_settings,
arbitrary_args=(),
setup_command: Iterable[str],
result_extension: Union[str, Tuple[str, ...]],
result_directory: StrPath,
config_settings: _ConfigSettings,
arbitrary_args: Iterable[str] = (),
):
result_directory = os.path.abspath(result_directory)

Expand Down Expand Up @@ -404,7 +404,10 @@ def _build_with_temp_dir(
return result_basename

def build_wheel(
self, wheel_directory, config_settings=None, metadata_directory=None
self,
wheel_directory: StrPath,
config_settings: _ConfigSettings = None,
metadata_directory: Optional[StrPath] = None,
):
with suppress_known_deprecation():
return self._build_with_temp_dir(
Expand All @@ -415,12 +418,16 @@ def build_wheel(
self._arbitrary_args(config_settings),
)

def build_sdist(self, sdist_directory, config_settings=None):
def build_sdist(
self, sdist_directory: StrPath, config_settings: _ConfigSettings = None
):
return self._build_with_temp_dir(
['sdist', '--formats', 'gztar'], '.tar.gz', sdist_directory, config_settings
)

def _get_dist_info_dir(self, metadata_directory: Optional[str]) -> Optional[str]:
def _get_dist_info_dir(
self, metadata_directory: Optional[StrPath]
) -> Optional[str]:
if not metadata_directory:
return None
dist_info_candidates = list(Path(metadata_directory).glob("*.dist-info"))
Expand All @@ -433,7 +440,10 @@ def _get_dist_info_dir(self, metadata_directory: Optional[str]) -> Optional[str]
# get_requires_for_build_editable
# prepare_metadata_for_build_editable
def build_editable(
self, wheel_directory, config_settings=None, metadata_directory=None
self,
wheel_directory: StrPath,
config_settings: _ConfigSettings = None,
metadata_directory: Optional[str] = None,
):
# XXX can or should we hide our editable_wheel command normally?
info_dir = self._get_dist_info_dir(metadata_directory)
Expand Down
3 changes: 2 additions & 1 deletion setuptools/command/bdist_egg.py
Original file line number Diff line number Diff line change
Expand Up @@ -382,8 +382,9 @@ def scan_module(egg_dir, base, name, stubs):
for bad in [
'getsource',
'getabsfile',
'getfile',
'getsourcefile',
'getfile' 'getsourcelines',
'getsourcelines',
'findsource',
'getcomments',
'getframeinfo',
Expand Down
Loading

0 comments on commit c957935

Please sign in to comment.