python / python/mypy

Treating all numpy floating and complex types as interchangeable in overloads

Abierto
#20,141 3 comentarios 1 reacción 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

bug false-positive topic-overloads
Lenguaje dominante
Python
Estrellas
20.6k
Forks
3.3k
Métricas de merge de PR
Métricas de PR pendientes

Descripción

Bug Report

I am trying to specify that a function takes either an array of np.floating or np.complexfloating, and returns an array of the same type, using overloads. However, it seems like mypy is currently treating floating and complexfloating as completely interchangeable, instead of floating being a more specific type than complexfloating. As shown below, it also treats other numpy floating/complex types as interchangeable, e.g. np.float32 and np.complex128.

To Reproduce

from __future__ import annotations

from typing import overload

import numpy as np
from numpy.typing import NDArray


@overload
def test_type1(a: NDArray[np.floating]) -> NDArray[np.floating]:  ...
@overload
def test_type1(a: NDArray[np.complexfloating]) -> NDArray[np.complexfloating]: ...
def test_type1(a: NDArray[np.floating] | NDArray[np.complexfloating]) -> NDArray[np.floating] | NDArray[np.complexfloating]:
    return a


@overload
def test_type2(a: NDArray[np.complexfloating]) -> NDArray[np.complexfloating]: ...
@overload
def test_type2(a: NDArray[np.floating]) -> NDArray[np.floating]:  ...
def test_type2(a: NDArray[np.floating] | NDArray[np.complexfloating]) -> NDArray[np.floating] | NDArray[np.complexfloating]:
    return a


@overload
def test_type3(a: np.floating) -> np.floating:  ...
@overload
def test_type3(a: np.complexfloating) -> np.complexfloating: ...
def test_type3(a: np.floating | np.complexfloating) -> np.floating | np.complexfloating:
    return a


@overload
def test_type4(a: np.complexfloating) -> np.floating:  ...
@overload
def test_type4(a: np.floating) -> np.floating: ...
def test_type4(a: np.floating | np.complexfloating) -> np.floating | np.complexfloating:
    return a


@overload
def test_type5(a: np.float32) -> np.float32:  ...
@overload
def test_type5(a: np.complex128) -> np.complex128: ...
def test_type5(a: np.float32 | np.complex128) -> np.float32 | np.complex128:
    return a


@overload
def test_type6(a: float) -> float: ...
@overload
def test_type6(a: complex) -> float:  ...
def test_type6(a: float | complex) -> float | complex:
    # the only one that passes mypy
    return a

Actual Behavior

In version 1.15.0 the code above passes mypy. In version 1.16.0 and later, it gives:

mypy_test.py:12: error: Overloaded function signature 2 will never be matched: signature 1's parameter type(s) are the same or broader [overload-cannot-match] mypy_test.py:20: error: Overloaded function signature 2 will never be matched: signature 1's parameter type(s) are the same or broader [overload-cannot-match] mypy_test.py:28: error: Overloaded function signature 2 will never be matched: signature 1's parameter type(s) are the same or broader [overload-cannot-match] mypy_test.py:36: error: Overloaded function signature 2 will never be matched: signature 1's parameter type(s) are the same or broader [overload-cannot-match] mypy_test.py:44: error: Overloaded function signature 2 will never be matched: signature 1's parameter type(s) are the same or broader [overload-cannot-match]

Expected Behavior

The errors for line 20 and 36 (test_type2 and test_type4) are correct errors as I understand the intended function of this warning. test_type6 correctly passes, consistent with the documented behavior of this check. However, the other 3 functions should pass with no warning, but are generating one.

Your Environment

I have tested and get the errors with mypy versions 1.16.0 and 1.18.2. The numpy version is 2.2.6 and python 3.13.7.

Guía de contribución

Abrir la guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Línea de trabajo

Reproduce los diagnósticos informados de mypy_test.py usando los ejemplos de overload proporcionados y compara el comportamiento entre las versiones de mypy mencionadas. Rastrea la comprobación overload-cannot-match y verifica después que test_type1, test_type3 y test_type5 pasen, mientras que test_type2 y test_type4 sigan informando errores.

Escrito por el modelo de indexación a partir del texto del issue.

Evaluación

Stack tecnológico
numpy, python
Área
devtools, tooling
Tipo de issue
Error
Dificultad
4/5
Tiempo estimado
3-5 días
Estado de actividad
Estancado
Claridad
Bastante claro
Aptitud para principiantes
42/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.