typeshed icon indicating copy to clipboard operation
typeshed copied to clipboard

Let `SupportsDunderLT` return `SupportsBool` instead of `bool`.

Open randolf-scholz opened this issue 1 year ago • 11 comments

Fixes #12562, alternative to #12573. Introduces a new protocol in _typeshed/__init__.pyi

class SupportsBool(Protocol):
    def __bool__(self) -> bool: ...

Changes SupportsDunderLT and variants to return SupportsBool instead of bool.

Note that an earlier comment by JelleZijlstra suggested that SupportsBool is equivalent to object in practice. This does not seem to quite be the case: Code sample in pyright playground

from typing import Protocol, runtime_checkable

@runtime_checkable
class SupportsBool(Protocol):
    def __bool__(self) -> bool: ...

x: SupportsBool = True
y: SupportsBool = object()  # mypy: ❌ pyright:  ❌

assert isinstance(x, SupportsBool)  # ✅
assert not isinstance(y, SupportsBool)  # ✅

Indeed, despite the documentation mentioning object.__bool__, this method is not defined on object. Rather, the truthiness of an object is defined roughly like:

if hasattr(obj, "__bool__"):
    return obj.__bool__()
if hasattr(obj, "__len__"):
   return bool(len(obj))
return True

randolf-scholz avatar Nov 01 '24 13:11 randolf-scholz

Diff from mypy_primer, showing the effect of this PR on open source code:

ibis (https://github.com/ibis-project/ibis)
- ibis/expr/types/relations.py:2914: error: Value of type variable "SupportsRichComparisonT" of "sorted" cannot be "NumericValue | float"  [type-var]

jax (https://github.com/google/jax)
+ jax/_src/pallas/mosaic/pipeline.py:981: error: Unused "type: ignore" comment  [unused-ignore]

github-actions[bot] avatar Nov 01 '24 13:11 github-actions[bot]

Even though this technically doesn't cover all cases, I like this "explicit is better than implicit" approach, and I'm a big fan of structural typing solutions like these 👌🏻.

jorenham avatar Nov 01 '24 14:11 jorenham

self is considered positional-only by type checkers as far as I am aware of https://github.com/python/typing/issues/1355

On Fri, 1 Nov 2024, 15:45 Joren Hammudoglu, @.***> wrote:

Even though this technically doesn't cover all cases, I like this "explicit is better than implicit" approach, and I'm a big fan of structural typing solutions like these 👌🏻.

— Reply to this email directly, view it on GitHub https://github.com/python/typeshed/pull/12939#issuecomment-2451995485, or unsubscribe https://github.com/notifications/unsubscribe-auth/AJO3RGFNL23MLRPRRWMDBU3Z6OHY5AVCNFSM6AAAAABRAJIIOOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDINJRHE4TKNBYGU . You are receiving this because you authored the thread.Message ID: @.***>

randolf-scholz avatar Nov 01 '24 15:11 randolf-scholz

@randolf-scholz ahh good to know 👍🏻

jorenham avatar Nov 01 '24 15:11 jorenham

Diff from mypy_primer, showing the effect of this PR on open source code:

ibis (https://github.com/ibis-project/ibis)
- ibis/expr/types/relations.py:2914: error: Value of type variable "SupportsRichComparisonT" of "sorted" cannot be "NumericValue | float"  [type-var]

jax (https://github.com/google/jax)
+ jax/_src/pallas/mosaic/pipeline.py:981: error: Unused "type: ignore" comment  [unused-ignore]

github-actions[bot] avatar Nov 05 '24 08:11 github-actions[bot]

Ibis can easily fix the issue by adding __bool__ to the BooleanValue class (via Value.__ge__, the superclass of NumericValue)

randolf-scholz avatar Nov 05 '24 08:11 randolf-scholz

Diff from mypy_primer, showing the effect of this PR on open source code:

ibis (https://github.com/ibis-project/ibis)
- ibis/expr/types/relations.py:2924: error: Value of type variable "SupportsRichComparisonT" of "sorted" cannot be "NumericValue | float"  [type-var]

jax (https://github.com/google/jax)
+ jax/_src/pallas/mosaic/pipeline.py:981: error: Unused "type: ignore" comment  [unused-ignore]

github-actions[bot] avatar Nov 19 '24 11:11 github-actions[bot]

Diff from mypy_primer, showing the effect of this PR on open source code:

ibis (https://github.com/ibis-project/ibis)
- ibis/expr/types/relations.py:2924: error: Value of type variable "SupportsRichComparisonT" of "sorted" cannot be "NumericValue | float"  [type-var]

jax (https://github.com/google/jax)
+ jax/_src/pallas/mosaic/pipeline.py:981: error: Unused "type: ignore" comment  [unused-ignore]

github-actions[bot] avatar Nov 21 '24 21:11 github-actions[bot]

Diff from mypy_primer, showing the effect of this PR on open source code:

ibis (https://github.com/ibis-project/ibis)
- ibis/expr/types/relations.py:2946: error: Value of type variable "SupportsRichComparisonT" of "sorted" cannot be "NumericValue | float"  [type-var]

scipy (https://github.com/scipy/scipy)
- scipy/spatial/tests/test_spherical_voronoi.py:194: error: Value of type variable "SupportsRichComparisonT" of "sorted" cannot be "floating[Any]"  [type-var]

jax (https://github.com/google/jax)
+ jax/_src/pallas/mosaic/pipeline.py:982: error: Unused "type: ignore" comment  [unused-ignore]

rclip (https://github.com/yurijmikhalevich/rclip)
- rclip/model.py:212: error: Argument "key" to "sorted" has incompatible type "Callable[[tuple[floating[Any], int]], floating[Any]]"; expected "Callable[[tuple[floating[Any], int]], SupportsDunderLT[Any] | SupportsDunderGT[Any]]"  [arg-type]
- rclip/model.py:212: error: Incompatible return value type (got "floating[Any]", expected "SupportsDunderLT[Any] | SupportsDunderGT[Any]")  [return-value]

github-actions[bot] avatar Jan 06 '25 13:01 github-actions[bot]

Diff from mypy_primer, showing the effect of this PR on open source code:

ibis (https://github.com/ibis-project/ibis)
- ibis/expr/types/relations.py:2946: error: Value of type variable "SupportsRichComparisonT" of "sorted" cannot be "NumericValue | float"  [type-var]

scipy (https://github.com/scipy/scipy)
- scipy/spatial/tests/test_spherical_voronoi.py:194: error: Value of type variable "SupportsRichComparisonT" of "sorted" cannot be "floating[Any]"  [type-var]

rclip (https://github.com/yurijmikhalevich/rclip)
- rclip/model.py:212: error: Argument "key" to "sorted" has incompatible type "Callable[[tuple[float64, int]], float64]"; expected "Callable[[tuple[float64, int]], SupportsDunderLT[Any] | SupportsDunderGT[Any]]"  [arg-type]
- rclip/model.py:212: error: Incompatible return value type (got "float64", expected "SupportsDunderLT[Any] | SupportsDunderGT[Any]")  [return-value]

jax (https://github.com/google/jax)
+ jax/_src/pallas/mosaic/pipeline.py:982: error: Unused "type: ignore" comment  [unused-ignore]

github-actions[bot] avatar Jan 22 '25 10:01 github-actions[bot]

Diff from mypy_primer, showing the effect of this PR on open source code:

colour (https://github.com/colour-science/colour)
- colour/algebra/interpolation.py:692: error: Value of type variable "SupportsRichComparisonT" of "min" cannot be "floating[_16Bit] | floating[_32Bit] | float64"  [type-var]
- colour/algebra/interpolation.py:693: error: Value of type variable "SupportsRichComparisonT" of "max" cannot be "floating[_16Bit] | floating[_32Bit] | float64"  [type-var]
- colour/algebra/interpolation.py:700: error: Value of type variable "SupportsRichComparisonT" of "min" cannot be "floating[_16Bit] | floating[_32Bit] | float64"  [type-var]
- colour/colorimetry/spectrum.py:1180: error: Value of type variable "SupportsRichComparisonT" of "max" cannot be "int | float | floating[_16Bit] | floating[_32Bit]"  [type-var]
- colour/colorimetry/spectrum.py:1181: error: Value of type variable "SupportsRichComparisonT" of "min" cannot be "int | float | floating[_16Bit] | floating[_32Bit]"  [type-var]
- colour/colorimetry/spectrum.py:1611: error: Value of type variable "SupportsRichComparisonT" of "max" cannot be "floating[_16Bit] | floating[_32Bit] | float64"  [type-var]
- colour/plotting/volume.py:261: error: Value of type variable "SupportsRichComparisonT" of "sorted" cannot be "floating[_16Bit] | floating[_32Bit] | float64"  [type-var]
- colour/plotting/colorimetry.py:195: error: No overload variant of "max" matches argument types "floating[_16Bit] | floating[_32Bit] | float64", "floating[_16Bit] | floating[_32Bit] | float64"  [call-overload]
- colour/plotting/colorimetry.py:195: note: Possible overload variants:
- colour/plotting/colorimetry.py:195: note:     def [SupportsRichComparisonT: SupportsDunderLT[Any] | SupportsDunderGT[Any]] max(SupportsRichComparisonT, SupportsRichComparisonT, /, *_args: SupportsRichComparisonT, key: None = ...) -> SupportsRichComparisonT
- colour/plotting/colorimetry.py:195: note:     def [_T] max(_T, _T, /, *_args: _T, key: Callable[[_T], SupportsDunderLT[Any] | SupportsDunderGT[Any]]) -> _T
- colour/plotting/colorimetry.py:195: note:     def [SupportsRichComparisonT: SupportsDunderLT[Any] | SupportsDunderGT[Any]] max(Iterable[SupportsRichComparisonT], /, *, key: None = ...) -> SupportsRichComparisonT
- colour/plotting/colorimetry.py:195: note:     def [_T] max(Iterable[_T], /, *, key: Callable[[_T], SupportsDunderLT[Any] | SupportsDunderGT[Any]]) -> _T
- colour/plotting/colorimetry.py:195: note:     def [SupportsRichComparisonT: SupportsDunderLT[Any] | SupportsDunderGT[Any], _T] max(Iterable[SupportsRichComparisonT], /, *, key: None = ..., default: _T) -> SupportsRichComparisonT | _T
- colour/plotting/colorimetry.py:195: note:     def [_T1, _T2] max(Iterable[_T1], /, *, key: Callable[[_T1], SupportsDunderLT[Any] | SupportsDunderGT[Any]], default: _T2) -> _T1 | _T2
- colour/plotting/colorimetry.py:195: error: Value of type variable "SupportsRichComparisonT" of "min" cannot be "floating[_16Bit] | floating[_32Bit] | float64"  [type-var]
- colour/plotting/colorimetry.py:196: error: No overload variant of "min" matches argument types "floating[_16Bit] | floating[_32Bit] | float64", "floating[_16Bit] | floating[_32Bit] | float64"  [call-overload]
- colour/plotting/colorimetry.py:196: note: Possible overload variants:
- colour/plotting/colorimetry.py:196: note:     def [SupportsRichComparisonT: SupportsDunderLT[Any] | SupportsDunderGT[Any]] min(SupportsRichComparisonT, SupportsRichComparisonT, /, *_args: SupportsRichComparisonT, key: None = ...) -> SupportsRichComparisonT
- colour/plotting/colorimetry.py:196: note:     def [_T] min(_T, _T, /, *_args: _T, key: Callable[[_T], SupportsDunderLT[Any] | SupportsDunderGT[Any]]) -> _T
- colour/plotting/colorimetry.py:196: note:     def [SupportsRichComparisonT: SupportsDunderLT[Any] | SupportsDunderGT[Any]] min(Iterable[SupportsRichComparisonT], /, *, key: None = ...) -> SupportsRichComparisonT
- colour/plotting/colorimetry.py:196: note:     def [_T] min(Iterable[_T], /, *, key: Callable[[_T], SupportsDunderLT[Any] | SupportsDunderGT[Any]]) -> _T
- colour/plotting/colorimetry.py:196: note:     def [SupportsRichComparisonT: SupportsDunderLT[Any] | SupportsDunderGT[Any], _T] min(Iterable[SupportsRichComparisonT], /, *, key: None = ..., default: _T) -> SupportsRichComparisonT | _T
- colour/plotting/colorimetry.py:196: note:     def [_T1, _T2] min(Iterable[_T1], /, *, key: Callable[[_T1], SupportsDunderLT[Any] | SupportsDunderGT[Any]], default: _T2) -> _T1 | _T2
- colour/plotting/colorimetry.py:196: error: Value of type variable "SupportsRichComparisonT" of "max" cannot be "floating[_16Bit] | floating[_32Bit] | float64"  [type-var]
- colour/plotting/colorimetry.py:223: error: Value of type variable "SupportsRichComparisonT" of "min" cannot be "floating[_16Bit] | floating[_32Bit] | float64"  [type-var]
- colour/plotting/colorimetry.py:223: error: Value of type variable "SupportsRichComparisonT" of "max" cannot be "floating[_16Bit] | floating[_32Bit] | float64"  [type-var]
- colour/plotting/colorimetry.py:224: error: Value of type variable "SupportsRichComparisonT" of "max" cannot be "floating[_16Bit] | floating[_32Bit] | float64"  [type-var]
- colour/plotting/colorimetry.py:229: error: List item 0 has incompatible type "tuple[floating[_16Bit] | floating[_32Bit] | float64, int]"; expected "_SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]]"  [list-item]
- colour/plotting/colorimetry.py:231: error: List item 2 has incompatible type "tuple[floating[_16Bit] | floating[_32Bit] | float64, int]"; expected "_SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]]"  [list-item]
- colour/plotting/colorimetry.py:243: error: Value of type variable "SupportsRichComparisonT" of "max" cannot be "floating[_16Bit] | floating[_32Bit] | float64"  [type-var]
- colour/plotting/colorimetry.py:406: error: Value of type variable "SupportsRichComparisonT" of "min" cannot be "floating[_16Bit] | floating[_32Bit] | float64"  [type-var]
- colour/plotting/colorimetry.py:407: error: Value of type variable "SupportsRichComparisonT" of "max" cannot be "floating[_16Bit] | floating[_32Bit] | float64"  [type-var]
- colour/plotting/colorimetry.py:423: error: Value of type variable "SupportsRichComparisonT" of "min" cannot be "floating[_16Bit] | floating[_32Bit] | float64"  [type-var]
- colour/plotting/colorimetry.py:424: error: Value of type variable "SupportsRichComparisonT" of "max" cannot be "floating[_16Bit] | floating[_32Bit] | float64"  [type-var]
- colour/plotting/colorimetry.py:565: error: Value of type variable "SupportsRichComparisonT" of "min" cannot be "floating[_16Bit] | floating[_32Bit] | float64"  [type-var]
- colour/plotting/colorimetry.py:566: error: Value of type variable "SupportsRichComparisonT" of "max" cannot be "floating[_16Bit] | floating[_32Bit] | float64"  [type-var]
- colour/plotting/colorimetry.py:768: error: Value of type variable "SupportsRichComparisonT" of "min" cannot be "floating[_16Bit] | floating[_32Bit] | float64"  [type-var]
- colour/plotting/colorimetry.py:768: error: Value of type variable "SupportsRichComparisonT" of "max" cannot be "floating[_16Bit] | floating[_32Bit] | float64"  [type-var]
- colour/examples/algebra/examples_interpolation.py:142: error: Value of type variable "SupportsRichComparisonT" of "min" cannot be "floating[_16Bit] | floating[_32Bit] | float64"  [type-var]
- colour/examples/algebra/examples_interpolation.py:143: error: Value of type variable "SupportsRichComparisonT" of "max" cannot be "floating[_16Bit] | floating[_32Bit] | float64"  [type-var]
- colour/examples/algebra/examples_interpolation.py:155: error: Value of type variable "SupportsRichComparisonT" of "min" cannot be "floating[_16Bit] | floating[_32Bit] | float64"  [type-var]
- colour/examples/algebra/examples_interpolation.py:156: error: Value of type variable "SupportsRichComparisonT" of "max" cannot be "floating[_16Bit] | floating[_32Bit] | float64"  [type-var]

jax (https://github.com/google/jax)
+ jax/_src/pallas/mosaic/pipeline.py:1233: error: Unused "type: ignore" comment  [unused-ignore]

rclip (https://github.com/yurijmikhalevich/rclip)
- rclip/model.py:218: error: Argument "key" to "sorted" has incompatible type "Callable[[tuple[float64, int]], float64]"; expected "Callable[[tuple[float64, int]], SupportsDunderLT[Any] | SupportsDunderGT[Any]]"  [arg-type]
- rclip/model.py:218: error: Incompatible return value type (got "float64", expected "SupportsDunderLT[Any] | SupportsDunderGT[Any]")  [return-value]

hydpy (https://github.com/hydpy-dev/hydpy)
- hydpy/auxs/ppolytools.py:253: error: Value of type variable "_AnyShapeT" of "__call__" of "_ConstructorEmpty" cannot be "tuple[int, signedinteger[_64Bit]]"  [type-var]
- hydpy/auxs/ppolytools.py:253: error: Value of type variable "SupportsRichComparisonT" of "max" cannot be "signedinteger[_64Bit]"  [type-var]

ibis (https://github.com/ibis-project/ibis)
- ibis/expr/types/relations.py:2962: error: Value of type variable "SupportsRichComparisonT" of "sorted" cannot be "NumericValue | float"  [type-var]

scipy (https://github.com/scipy/scipy)
- scipy/spatial/tests/test_spherical_voronoi.py:194: error: Value of type variable "SupportsRichComparisonT" of "sorted" cannot be "floating[Any]"  [type-var]

arviz (https://github.com/arviz-devs/arviz)
- arviz/stats/ecdf_utils.py:72: error: Value of type variable "SupportsRichComparisonT" of "min" cannot be "Any | float64"  [type-var]

github-actions[bot] avatar Jun 13 '25 12:06 github-actions[bot]

Diff from mypy_primer, showing the effect of this PR on open source code:

colour (https://github.com/colour-science/colour)
- colour/plotting/colorimetry.py:565: error: Value of type variable "SupportsRichComparisonT" of "min" cannot be "floating[_16Bit] | floating[_32Bit] | float64"  [type-var]
- colour/plotting/colorimetry.py:566: error: Value of type variable "SupportsRichComparisonT" of "max" cannot be "floating[_16Bit] | floating[_32Bit] | float64"  [type-var]

jax (https://github.com/google/jax)
+ jax/_src/pallas/mosaic/pipeline.py:1546: error: Unused "type: ignore" comment  [unused-ignore]

ibis (https://github.com/ibis-project/ibis)
- ibis/expr/types/relations.py:2986: error: Value of type variable "SupportsRichComparisonT" of "sorted" cannot be "NumericValue | float"  [type-var]

arviz (https://github.com/arviz-devs/arviz)
- arviz/stats/ecdf_utils.py:72: error: Value of type variable "SupportsRichComparisonT" of "min" cannot be "Any | float64"  [type-var]

github-actions[bot] avatar Jul 07 '25 14:07 github-actions[bot]

Huh, primer output is much smaller now. Still I think this is worthwhile.

srittau avatar Jul 07 '25 14:07 srittau