Skip to content

Commit

Permalink
Merge branch 'main' into ruff-all-pyflakes-and-perf-rules
Browse files Browse the repository at this point in the history
  • Loading branch information
Avasam authored Oct 21, 2024
2 parents 01c7ce4 + 99c75c9 commit cccadd2
Show file tree
Hide file tree
Showing 34 changed files with 301 additions and 145 deletions.
2 changes: 1 addition & 1 deletion .bumpversion.cfg
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[bumpversion]
current_version = 75.1.1
current_version = 75.2.0
commit = True
tag = True

Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/pyright.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ env:
# For help with static-typing issues, or pyright update, ping @Avasam
#
# An exact version from https://github.com/microsoft/pyright/releases or "latest"
PYRIGHT_VERSION: "1.1.377"
PYRIGHT_VERSION: "1.1.385"

# Environment variable to support color support (jaraco/skeleton#66)
FORCE_COLOR: 1
Expand Down Expand Up @@ -73,4 +73,5 @@ jobs:
uses: jakebailey/pyright-action@v2
with:
version: ${{ env.PYRIGHT_VERSION }}
python-version: ${{ matrix.python }}
extra-args: --threads
17 changes: 17 additions & 0 deletions NEWS.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,20 @@
v75.2.0
=======

Features
--------

- Made errors when parsing ``Distribution`` data more explicit about the expected type (``tuple[str, ...] | list[str]``) -- by :user:`Avasam` (#4578)


Bugfixes
--------

- Fix a `TypeError` when a ``Distribution``'s old included attribute was a `tuple` -- by :user:`Avasam` (#4578)
- Add workaround for ``bdist_wheel --dist-info-dir`` errors
when customisation does not inherit from setuptools. (#4684)


v75.1.1
=======

Expand Down
23 changes: 17 additions & 6 deletions mypy.ini
Original file line number Diff line number Diff line change
@@ -1,17 +1,27 @@
[mypy]
# CI should test for all versions, local development gets hints for oldest supported
# But our testing setup doesn't allow passing CLI arguments, so local devs have to set this manually.
# python_version = 3.8
## upstream

# Is the project well-typed?
strict = False

# Early opt-in even when strict = False
warn_unused_ignores = True
warn_redundant_casts = True
# required to support namespace packages: https://github.com/python/mypy/issues/14057
enable_error_code = ignore-without-code

# Support namespace packages per https://github.com/python/mypy/issues/14057
explicit_package_bases = True

disable_error_code =
# Disable due to many false positives
overload-overlap,

## local

# CI should test for all versions, local development gets hints for oldest supported
# But our testing setup doesn't allow passing CLI arguments, so local devs have to set this manually.
# python_version = 3.8

exclude = (?x)(
# Avoid scanning Python files in generated folders
^build/
Expand Down Expand Up @@ -42,18 +52,19 @@ disable_error_code = import-not-found
# for setuptools to import `_distutils` directly
# - or non-stdlib distutils typings are exposed
# - The following are not marked as py.typed:
# - jaraco: Since mypy 1.12, the root name of the untyped namespace package gets called-out too
# - jaraco.develop: https://github.com/jaraco/jaraco.develop/issues/22
# - jaraco.envs: https://github.com/jaraco/jaraco.envs/issues/7
# - jaraco.packaging: https://github.com/jaraco/jaraco.packaging/issues/20
# - jaraco.path: https://github.com/jaraco/jaraco.path/issues/2
# - jaraco.test: https://github.com/jaraco/jaraco.test/issues/7
# - jaraco.text: https://github.com/jaraco/jaraco.text/issues/17
# - wheel: does not intend on exposing a programmatic API https://github.com/pypa/wheel/pull/610#issuecomment-2081687671
[mypy-distutils.*,jaraco.develop,jaraco.envs,jaraco.packaging.*,jaraco.path,jaraco.test.*,jaraco.text,wheel.*]
[mypy-distutils.*,jaraco,jaraco.develop,jaraco.envs,jaraco.packaging.*,jaraco.path,jaraco.test.*,jaraco.text,wheel.*]
ignore_missing_imports = True

# Even when excluding a module, import issues can show up due to following import
# https://github.com/python/mypy/issues/11936#issuecomment-1466764006
[mypy-setuptools.config._validate_pyproject.*,setuptools._distutils.*]
[mypy-setuptools.config._validate_pyproject.*,setuptools._vendor.*,setuptools._distutils.*]
follow_imports = silent
# silent => ignore errors when following imports
1 change: 1 addition & 0 deletions newsfragments/4560.misc.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Bumped declared ``platformdirs`` dependency to ``>= 4.2.2`` to help platforms lacking `ctypes` support install setuptools seamlessly -- by :user:`Avasam`
4 changes: 4 additions & 0 deletions newsfragments/4567.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Ensured methods in ``setuptools.modified`` preferably raise a consistent
``distutils.errors.DistutilsError`` type
(except in the deprecated use case of ``SETUPTOOLS_USE_DISTUTILS=stdlib``)
-- by :user:`Avasam`
1 change: 1 addition & 0 deletions newsfragments/4575.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Allowed using `dict` as an ordered type in ``setuptools.dist.check_requirements`` -- by :user:`Avasam`
4 changes: 4 additions & 0 deletions newsfragments/4696.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Fix clashes for ``optional-dependencies`` in ``pyproject.toml`` and
``extra_requires`` in ``setup.cfg/setup.py``.
As per PEP 621, ``optional-dependencies`` has to be honoured and dynamic
behaviour is not allowed.
2 changes: 1 addition & 1 deletion pkg_resources/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2777,7 +2777,7 @@ def load(
if require:
# We could pass `env` and `installer` directly,
# but keeping `*args` and `**kwargs` for backwards compatibility
self.require(*args, **kwargs) # type: ignore
self.require(*args, **kwargs) # type: ignore[arg-type]
return self.resolve()

def resolve(self) -> _ResolvedEntryPoint:
Expand Down
10 changes: 3 additions & 7 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ backend-path = ["."]

[project]
name = "setuptools"
version = "75.1.1"
version = "75.2.0"
authors = [
{ name = "Python Packaging Authority", email = "distutils-sig@python.org" },
]
Expand Down Expand Up @@ -99,7 +99,7 @@ core = [
"wheel>=0.43.0",

# pkg_resources
"platformdirs >= 2.6.2",
"platformdirs >= 4.2.2", # Made ctypes optional (see #4461)

# for distutils
"jaraco.collections",
Expand Down Expand Up @@ -136,7 +136,7 @@ type = [
# pin mypy version so a new version doesn't suddenly cause the CI to fail,
# until types-setuptools is removed from typeshed.
# For help with static-typing issues, or mypy update, ping @Avasam
"mypy==1.11.*",
"mypy==1.12.*",
# Typing fixes in version newer than we require at runtime
"importlib_metadata>=7.0.2; python_version < '3.10'",
# Imported unconditionally in tools/finalize.py
Expand Down Expand Up @@ -216,7 +216,3 @@ formats = "zip"


[tool.setuptools_scm]


[tool.pytest-enabler.mypy]
# Disabled due to jaraco/skeleton#143
1 change: 1 addition & 0 deletions ruff.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ ignore = [
"TRY003", # raise-vanilla-args, avoid multitude of exception classes
"TRY301", # raise-within-try, it's handy
"UP015", # redundant-open-modes, explicit is preferred
"UP027", # unpacked-list-comprehension, is actually slower for cases relevant to unpacking, set for deprecation: https://github.com/astral-sh/ruff/issues/12754
"UP030", # temporarily disabled
"UP031", # temporarily disabled
"UP032", # temporarily disabled
Expand Down
3 changes: 2 additions & 1 deletion setuptools/_path.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@

from more_itertools import unique_everseen

if sys.version_info >= (3, 9):
if TYPE_CHECKING:
StrPath: TypeAlias = Union[str, os.PathLike[str]] # Same as _typeshed.StrPath
else:
# Python 3.8 support
StrPath: TypeAlias = Union[str, os.PathLike]


Expand Down
43 changes: 32 additions & 11 deletions setuptools/build_meta.py
Original file line number Diff line number Diff line change
Expand Up @@ -417,17 +417,27 @@ def build_wheel(
config_settings: _ConfigSettings = None,
metadata_directory: StrPath | None = None,
):
cmd = ['bdist_wheel']
if metadata_directory:
cmd.extend(['--dist-info-dir', metadata_directory])
with suppress_known_deprecation():
return self._build_with_temp_dir(
cmd,
'.whl',
wheel_directory,
config_settings,
self._arbitrary_args(config_settings),
)
def _build(cmd: list[str]):
with suppress_known_deprecation():
return self._build_with_temp_dir(
cmd,
'.whl',
wheel_directory,
config_settings,
self._arbitrary_args(config_settings),
)

if metadata_directory is None:
return _build(['bdist_wheel'])

try:
return _build(['bdist_wheel', '--dist-info-dir', str(metadata_directory)])
except SystemExit as ex: # pragma: nocover
# pypa/setuptools#4683
if "--dist-info-dir not recognized" not in str(ex):
raise
_IncompatibleBdistWheel.emit()
return _build(['bdist_wheel'])

def build_sdist(
self, sdist_directory: StrPath, config_settings: _ConfigSettings = None
Expand Down Expand Up @@ -514,6 +524,17 @@ def run_setup(self, setup_script='setup.py'):
sys.argv[0] = sys_argv_0


class _IncompatibleBdistWheel(SetuptoolsDeprecationWarning):
_SUMMARY = "wheel.bdist_wheel is deprecated, please import it from setuptools"
_DETAILS = """
Ensure that any custom bdist_wheel implementation is a subclass of
setuptools.command.bdist_wheel.bdist_wheel.
"""
_DUE_DATE = (2025, 10, 15)
# Initially introduced in 2024/10/15, but maybe too disruptive to be enforced?
_SEE_URL = "https://github.com/pypa/wheel/pull/631"


# The primary backend
_BACKEND = _BuildMetaBackend()

Expand Down
10 changes: 9 additions & 1 deletion setuptools/command/__init__.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
# mypy: disable_error_code=call-overload
# pyright: reportCallIssue=false, reportArgumentType=false
# Can't disable on the exact line because distutils doesn't exists on Python 3.12
# and type-checkers aren't aware of distutils_hack,
# causing distutils.command.bdist.bdist.format_commands to be Any.

import sys

from distutils.command.bdist import bdist

if 'egg' not in bdist.format_commands:
try:
# format_commands is a dict in vendored distutils
# It used to be a list in older (stdlib) distutils
# We support both for backwards compatibility
bdist.format_commands['egg'] = ('bdist_egg', "Python .egg file")
except TypeError:
# For backward compatibility with older distutils (stdlib)
bdist.format_command['egg'] = ('bdist_egg', "Python .egg file")
bdist.format_commands.append('egg')

Expand Down
3 changes: 1 addition & 2 deletions setuptools/command/_requirestxt.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,11 @@
from packaging.requirements import Requirement

from .. import _reqs
from .._reqs import _StrOrIter

# dict can work as an ordered set
_T = TypeVar("_T")
_Ordered = Dict[_T, None]
_ordered = dict
_StrOrIter = _reqs._StrOrIter


def _prepare(
Expand Down
9 changes: 1 addition & 8 deletions setuptools/command/build_clib.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,10 @@
from ..dist import Distribution
from ..modified import newer_pairwise_group

import distutils.command.build_clib as orig
from distutils import log
from distutils.errors import DistutilsSetupError

try:
from distutils._modified import ( # pyright: ignore[reportMissingImports]
newer_pairwise_group,
)
except ImportError:
# fallback for SETUPTOOLS_USE_DISTUTILS=stdlib
from .._distutils._modified import newer_pairwise_group


class build_clib(orig.build_clib):
"""
Expand Down
5 changes: 1 addition & 4 deletions setuptools/command/egg_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
Create a distribution's .egg-info directory and contents"""

import collections
import functools
import os
import re
Expand Down Expand Up @@ -211,11 +210,9 @@ def save_version_info(self, filename):
build tag. Install build keys in a deterministic order
to avoid arbitrary reordering on subsequent builds.
"""
egg_info = collections.OrderedDict()
# follow the order these keys would have been added
# when PYTHONHASHSEED=0
egg_info['tag_build'] = self.tags()
egg_info['tag_date'] = 0
egg_info = dict(tag_build=self.tags(), tag_date=0)
edit_config(filename, dict(egg_info=egg_info))

def finalize_options(self):
Expand Down
3 changes: 2 additions & 1 deletion setuptools/command/sdist.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import os
import re
from itertools import chain
from typing import ClassVar

from .._importlib import metadata
from ..dist import Distribution
Expand Down Expand Up @@ -49,7 +50,7 @@ class sdist(orig.sdist):
]

distribution: Distribution # override distutils.dist.Distribution with setuptools.dist.Distribution
negative_opt: dict[str, str] = {}
negative_opt: ClassVar[dict[str, str]] = {}

README_EXTENSIONS = ['', '.rst', '.txt', '.md']
READMES = tuple('README{0}'.format(ext) for ext in README_EXTENSIONS)
Expand Down
6 changes: 4 additions & 2 deletions setuptools/config/_apply_pyprojecttoml.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,8 +217,10 @@ def _dependencies(dist: Distribution, val: list, _root_dir):


def _optional_dependencies(dist: Distribution, val: dict, _root_dir):
existing = getattr(dist, "extras_require", None) or {}
dist.extras_require = {**existing, **val}
if getattr(dist, "extras_require", None):
msg = "`extras_require` overwritten in `pyproject.toml` (optional-dependencies)"
SetuptoolsWarning.emit(msg)
dist.extras_require = val


def _ext_modules(dist: Distribution, val: list[dict]) -> list[Extension]:
Expand Down
13 changes: 8 additions & 5 deletions setuptools/config/expand.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,8 @@ def _load_spec(spec: ModuleSpec, module_name: str) -> ModuleType:
return sys.modules[name]
module = importlib.util.module_from_spec(spec)
sys.modules[name] = module # cache (it also ensures `==` works on loaded items)
spec.loader.exec_module(module) # type: ignore
assert spec.loader is not None
spec.loader.exec_module(module)
return module


Expand Down Expand Up @@ -285,10 +286,11 @@ def find_packages(

from setuptools.discovery import construct_package_dir

if namespaces:
from setuptools.discovery import PEP420PackageFinder as PackageFinder
# check "not namespaces" first due to python/mypy#6232
if not namespaces:
from setuptools.discovery import PackageFinder
else:
from setuptools.discovery import PackageFinder # type: ignore
from setuptools.discovery import PEP420PackageFinder as PackageFinder

root_dir = root_dir or os.curdir
where = kwargs.pop('where', ['.'])
Expand Down Expand Up @@ -359,7 +361,8 @@ def entry_points(text: str, text_source="entry-points") -> dict[str, dict]:
entry-point names, and the second level values are references to objects
(that correspond to the entry-point value).
"""
parser = ConfigParser(default_section=None, delimiters=("=",)) # type: ignore
# Using undocumented behaviour, see python/typeshed#12700
parser = ConfigParser(default_section=None, delimiters=("=",)) # type: ignore[call-overload]
parser.optionxform = str # case sensitive
parser.read_string(text, text_source)
groups = {k: dict(v.items()) for k, v in parser.items()}
Expand Down
4 changes: 2 additions & 2 deletions setuptools/config/pyprojecttoml.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ def validate(config: dict, filepath: StrPath) -> bool:

trove_classifier = validator.FORMAT_FUNCTIONS.get("trove-classifier")
if hasattr(trove_classifier, "_disable_download"):
# Improve reproducibility by default. See issue 31 for validate-pyproject.
trove_classifier._disable_download() # type: ignore
# Improve reproducibility by default. See abravalheri/validate-pyproject#31
trove_classifier._disable_download() # type: ignore[union-attr]

try:
return validator.validate(config)
Expand Down
Loading

0 comments on commit cccadd2

Please sign in to comment.