From 140bba3425229a69cf4d5ccf7f5348ff85f66c16 Mon Sep 17 00:00:00 2001 From: Avasam Date: Tue, 14 Feb 2023 08:11:56 -0500 Subject: [PATCH] Add comments when subclassing Any (#9732) --- stdlib/distutils/command/check.pyi | 2 ++ stdlib/unittest/mock.pyi | 2 ++ stubs/Pillow/PIL/ImageQt.pyi | 5 ++++- stubs/mock/mock/mock.pyi | 2 ++ tests/mypy_test.py | 4 +++- 5 files changed, 13 insertions(+), 2 deletions(-) diff --git a/stdlib/distutils/command/check.pyi b/stdlib/distutils/command/check.pyi index cdbe40fff..9cbcc6c87 100644 --- a/stdlib/distutils/command/check.pyi +++ b/stdlib/distutils/command/check.pyi @@ -6,6 +6,8 @@ from ..cmd import Command _Reporter: TypeAlias = Any # really docutils.utils.Reporter # Only defined if docutils is installed. +# Depends on a third-party stub. Since distutils is deprecated anyway, +# it's easier to just suppress the "any subclassing" error. class SilentReporter(_Reporter): messages: Any def __init__( diff --git a/stdlib/unittest/mock.pyi b/stdlib/unittest/mock.pyi index 12ce2d2c7..f0345c903 100644 --- a/stdlib/unittest/mock.pyi +++ b/stdlib/unittest/mock.pyi @@ -101,6 +101,8 @@ class _CallList(list[_Call]): class Base: def __init__(self, *args: Any, **kwargs: Any) -> None: ... +# We subclass with "Any" because mocks are explicitly designed to stand in for other types, +# something that can't be expressed with our static type system. class NonCallableMock(Base, Any): def __new__(__cls, *args: Any, **kw: Any) -> Self: ... def __init__( diff --git a/stubs/Pillow/PIL/ImageQt.pyi b/stubs/Pillow/PIL/ImageQt.pyi index 434ba4d7e..f11ae150e 100644 --- a/stubs/Pillow/PIL/ImageQt.pyi +++ b/stubs/Pillow/PIL/ImageQt.pyi @@ -3,7 +3,10 @@ from typing_extensions import Literal, TypeAlias from .Image import Image -_QImage: TypeAlias = Any # imported from either of {PyQt6,PySide6,PyQt5,PySide2}.QtGui +# imported from either of {PyQt6,PySide6,PyQt5,PySide2}.QtGui +# These are way too complex, with 4 different possible sources (2 deprecated) +# And we don't want to force the user to install PyQt or Pyside when they may not even use it. +_QImage: TypeAlias = Any _QPixmap: TypeAlias = Any qt_versions: Any diff --git a/stubs/mock/mock/mock.pyi b/stubs/mock/mock/mock.pyi index 5fd3bdefd..cff36eb81 100644 --- a/stubs/mock/mock/mock.pyi +++ b/stubs/mock/mock/mock.pyi @@ -81,6 +81,8 @@ class _CallList(list[_Call]): class Base: def __init__(self, *args: Any, **kwargs: Any) -> None: ... +# We subclass with "Any" because mocks are explicitly designed to stand in for other types, +# something that can't be expressed with our static type system. class NonCallableMock(Base, Any): def __new__( cls: type[Self], diff --git a/tests/mypy_test.py b/tests/mypy_test.py index 3f81e82e5..56ad56842 100644 --- a/tests/mypy_test.py +++ b/tests/mypy_test.py @@ -263,7 +263,9 @@ def run_mypy( # Stub completion is checked by pyright (--allow-*-defs) "--allow-untyped-defs", "--allow-incomplete-defs", - "--allow-subclassing-any", # See #9491 + # See https://github.com/python/typeshed/pull/9491#issuecomment-1381574946 + # for discussion and reasoning to keep "--allow-subclassing-any" + "--allow-subclassing-any", "--enable-error-code", "ignore-without-code", "--config-file",