python / python/mypy

mypy seems to use type from field definition instead of type of field_validator

Offen
#15,977 2 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

bug
Vorherrschende Sprache
Python
Sterne
20.6k
Forks
3.3k
PR-Merge-Kennzahlen
PR-Kennzahlen ausstehend

Beschreibung

Description
I created a class that accepts a field with both a list[float] and a NDArray which converts it to NDArray after field validation (set to always via ConfigDict(validate_assignment = True)). However mypy complains about divide and substract operations over the vector field which should not as the field cannot be of type list[float] after validation.

At the moment I am using the # type: ignore[call-overload, operator] (Without those I get mypy errors).

image

Note: I have raised same issue in pydantic (https://github.com/pydantic/pydantic/issues/7262)

Example Code

import numpy as np
from numpy.typing import NDArray
from pydantic import BaseModel, ConfigDict, Field, computed_field, field_validator

class Vector(BaseModel):
    model_config = ConfigDict(arbitrary_types_allowed=True, validate_assignment=True)

    vector: NDArray[np.float64] | list[float] = Field(default=np.array([0.0, 0.0, 0.0]), min_length=3, max_length=3)

    @field_validator("vector")
    @classmethod
    def vector_validator(cls, v: NDArray[np.float64] | list[float]) -> NDArray:
        if isinstance(v, list):
            return np.array(v)
        return v

    @computed_field  # type: ignore[misc]
    @property
    def x(self) -> NDArray:
        return self.vector[0]

    @x.setter
    def x(self, value: float) -> None:
        self.vector[0] = value

    @computed_field  # type: ignore[misc]
    @property
    def y(self) -> NDArray:
        return self.vector[1]

    @y.setter
    def y(self, value: float) -> None:
        self.vector[1] = value

    @computed_field  # type: ignore[misc]
    @property
    def z(self) -> NDArray:
        return self.vector[2]

    @z.setter
    def z(self, value: float) -> None:
        self.vector[2] = value

    def to_unit(self) -> "Vector":
        return Vector(vector=self.vector / np.linalg.norm(self.vector))  # type: ignore[call-overload, operator]

    def __add__(self, other: "Vector") -> "Vector":
        return Vector(vector=self.vector + other.vector)

    def __sub__(self, other: "Vector") -> "Vector":
        return Vector(vector=self.vector - other.vector)  # type: ignore[operator]

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Rechercherichtung

Führe zunächst den Example Code mit mypy aus und vergleiche die gemeldeten Fehler mit dem Rückgabetyp des Validators. Untersuche, wie mypy den deklarierten Vektorfeldtyp darstellt und ob Informationen zu field_validator für die Typprüfung verfügbar sind. Die Aufgabe ist erledigt, wenn die gezeigten Divisions- und Subtraktionsoperationen die aufgeführten Kommentare type: ignore nicht mehr benötigen und das bestehende Verhalten erhalten bleibt.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
numpy, python
Bereich
devtools, tooling
Issue-Typ
Bug
Schwierigkeit
5/5
Geschätzter Aufwand
Über eine Woche
Aktivitätsstatus
Veraltet
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
25/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.