Skip to content

Commit

Permalink
Fix most mypy attr-defined by explicitly defining attributes on classes
Browse files Browse the repository at this point in the history
  • Loading branch information
Avasam committed Aug 8, 2024
1 parent d13f9c5 commit a0cf7e1
Show file tree
Hide file tree
Showing 15 changed files with 44 additions and 12 deletions.
6 changes: 3 additions & 3 deletions mypy.ini
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ exclude = (?x)(
# Too many false-positives
disable_error_code = overload-overlap

# Ignoring attr-defined because setuptools wraps a lot of distutils classes, adding new attributes,
# w/o updating all the attributes and return types from the base classes for type-checkers to understand
# Especially with setuptools.dist.command vs distutils.dist.command vs setuptools._distutils.dist.command
# DistributionMetadata.license_files and DistributionMetadata.license_file
# are dynamically patched in setuptools/_core_metadata.py
# and no DistributionMetadata subclass exists in setuptools
[mypy-setuptools.*]
disable_error_code = attr-defined

Expand Down
2 changes: 2 additions & 0 deletions setuptools/command/build_ext.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from distutils.sysconfig import customize_compiler, get_config_var
from distutils import log

from setuptools.dist import Distribution
from setuptools.errors import BaseError
from setuptools.extension import Extension, Library

Expand Down Expand Up @@ -84,6 +85,7 @@ def get_abi3_suffix():


class build_ext(_build_ext):
distribution: Distribution # override distutils.dist.Distribution with setuptools.dist.Distribution
editable_mode: bool = False
inplace: bool = False

Expand Down
4 changes: 3 additions & 1 deletion setuptools/command/build_py.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@
from typing import Iterable, Iterator

from more_itertools import unique_everseen
from ..warnings import SetuptoolsDeprecationWarning

from ..dist import Distribution
from ..warnings import SetuptoolsDeprecationWarning

_IMPLICIT_DATA_FILES = ('*.pyi', 'py.typed')

Expand All @@ -34,6 +35,7 @@ class build_py(orig.build_py):
'py_modules' and 'packages' in the same setup operation.
"""

distribution: Distribution # override distutils.dist.Distribution with setuptools.dist.Distribution
editable_mode: bool = False
existing_egg_info_dir: str | None = None #: Private API, internal use only.

Expand Down
1 change: 1 addition & 0 deletions setuptools/command/editable_wheel.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ def run(self):
self._create_wheel_file(bdist_wheel)
except Exception:
traceback.print_exc()
# TODO: Fix false-positive [attr-defined] in typeshed
project = self.distribution.name or self.distribution.get_name()
_DebuggingTips.emit(project=project)
raise
Expand Down
6 changes: 4 additions & 2 deletions setuptools/command/egg_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,14 @@
from setuptools.command.sdist import walk_revctrl
from setuptools.command.setopt import edit_config
from setuptools.command import bdist_egg
from setuptools.dist import Distribution
import setuptools.unicode_utils as unicode_utils
from setuptools.glob import glob

import packaging
import packaging.requirements
import packaging.version
from ..warnings import SetuptoolsDeprecationWarning


PY_MAJOR = '{}.{}'.format(*sys.version_info)


Expand Down Expand Up @@ -520,6 +521,7 @@ def _safe_path(self, path):


class manifest_maker(sdist):
distribution: Distribution # override distutils.dist.Distribution with setuptools.dist.Distribution
template = "MANIFEST.in"

def initialize_options(self):
Expand Down
3 changes: 3 additions & 0 deletions setuptools/command/install.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from typing import Any, ClassVar, cast

import setuptools
from ..dist import Distribution
from ..warnings import SetuptoolsDeprecationWarning, SetuptoolsWarning
from .bdist_egg import bdist_egg as bdist_egg_cls

Expand All @@ -20,6 +21,8 @@
class install(orig.install):
"""Use easy_install to install the package, w/dependencies"""

distribution: Distribution # override distutils.dist.Distribution with setuptools.dist.Distribution

user_options = orig.install.user_options + [
('old-and-unmanageable', None, "Try not to use this!"),
(
Expand Down
4 changes: 4 additions & 0 deletions setuptools/command/install_lib.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,16 @@
import sys
from itertools import product, starmap
import distutils.command.install_lib as orig

from .._path import StrPath
from ..dist import Distribution


class install_lib(orig.install_lib):
"""Don't add compiled flags to filenames of non-Python files"""

distribution: Distribution # override distutils.dist.Distribution with setuptools.dist.Distribution

def run(self):
self.build()
outfiles = self.install()
Expand Down
3 changes: 3 additions & 0 deletions setuptools/command/install_scripts.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,14 @@
import sys

from .._path import ensure_directory
from ..dist import Distribution


class install_scripts(orig.install_scripts):
"""Do normal script install, plus any egg_info wrapper scripts"""

distribution: Distribution # override distutils.dist.Distribution with setuptools.dist.Distribution

def initialize_options(self):
orig.install_scripts.initialize_options(self)
self.no_ep = False
Expand Down
2 changes: 2 additions & 0 deletions setuptools/command/sdist.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from itertools import chain

from .._importlib import metadata
from ..dist import Distribution
from .build import _ORIGINAL_SUBCOMMANDS

_default_revctrl = list
Expand Down Expand Up @@ -43,6 +44,7 @@ class sdist(orig.sdist):
),
]

distribution: Distribution # override distutils.dist.Distribution with setuptools.dist.Distribution
negative_opt = {}

README_EXTENSIONS = ['', '.rst', '.txt', '.md']
Expand Down
3 changes: 3 additions & 0 deletions setuptools/command/upload.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
from distutils import log
from distutils.command import upload as orig

from setuptools.dist import Distribution
from setuptools.errors import RemovedCommandError


class upload(orig.upload):
"""Formerly used to upload packages to PyPI."""

distribution: Distribution # override distutils.dist.Distribution with setuptools.dist.Distribution

def run(self):
msg = (
"The upload command has been removed, use twine to upload "
Expand Down
2 changes: 1 addition & 1 deletion setuptools/config/pyprojecttoml.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ def read_configuration(
# the default would be an improvement.
# `ini2toml` backfills include_package_data=False when nothing is explicitly given,
# therefore setting a default here is backwards compatible.
if dist and getattr(dist, "include_package_data", None) is not None:
if dist and dist.include_package_data is not None:
setuptools_table.setdefault("include-package-data", dist.include_package_data)
else:
setuptools_table.setdefault("include-package-data", True)
Expand Down
2 changes: 2 additions & 0 deletions setuptools/dist.py
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,8 @@ def __init__(self, attrs: MutableMapping | None = None) -> None:
self.package_data: dict[str, list[str]] = {}
attrs = attrs or {}
self.dist_files: list[tuple[str, str, str]] = []
self.include_package_data: bool | None = None
self.exclude_package_data: dict[str, list[str]] | None = None
# Filter-out setuptools' specific options.
self.src_root = attrs.pop("src_root", None)
self.dependency_links = attrs.pop('dependency_links', [])
Expand Down
8 changes: 8 additions & 0 deletions setuptools/extension.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,14 @@ class Extension(_Extension):
specified on Windows. (since v63)
"""

# These 4 are set and used in setuptools/command/build_ext.py
# The lack of a default value and risk of `AttributeError` is purposeful
# to avoid people forgetting to call finalize_options if they modify the extension list
_full_name: str #: Private API, internal use only.
_links_to_dynamic: bool #: Private API, internal use only.
_needs_stub: bool #: Private API, internal use only.
_file_name: str #: Private API, internal use only.

def __init__(self, name, sources, *args, **kw):
# The *args is needed for compatibility as calls may use positional
# arguments. py_limited_api may be set only via keyword.
Expand Down
9 changes: 4 additions & 5 deletions setuptools/tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,9 @@

__all__ = ['fail_on_ascii']

locale_encoding = (
locale.getencoding()
if sys.version_info >= (3, 11)
else locale.getpreferredencoding(False)
)
if sys.version_info >= (3, 11):
locale_encoding = locale.getencoding()
else:
locale_encoding = locale.getpreferredencoding(False)
is_ascii = locale_encoding == 'ANSI_X3.4-1968'
fail_on_ascii = pytest.mark.xfail(is_ascii, reason="Test fails in this locale")
1 change: 1 addition & 0 deletions setuptools/tests/test_build_ext.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ def get_build_ext_cmd(self, optional: bool, **opts):
dist = Distribution(dict(ext_modules=[extension]))
dist.script_name = 'setup.py'
cmd = build_ext(dist)
# TODO: False-positive [attr-defined], raise upstream
vars(cmd).update(build_lib=".build/lib", build_temp=".build/tmp", **opts)
cmd.ensure_finalized()
return cmd
Expand Down

0 comments on commit a0cf7e1

Please sign in to comment.