python / python/mypy

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

Ouverte
#15,977 2 commentaires 0 réactions 0 personnes assignées Voir sur GitHub

Personne n'a encore pris cette issue.

bug
Langage dominant
Python
Étoiles
20.6k
Forks
3.3k
Métriques de merge des PR
Métriques de PR en attente

Description

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]

Guide de contribution

Ouvrir le guide de contribution

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Piste de recherche

Commencez par exécuter le Example Code avec mypy et comparez les erreurs signalées avec le type de retour du validateur. Étudiez la manière dont mypy représente le type déclaré du champ vectoriel et vérifiez si les informations de field_validator sont disponibles pour la vérification de types. Le travail est terminé lorsque les opérations de division et de soustraction présentées ne nécessitent plus les commentaires type: ignore indiqués, tout en conservant le comportement existant.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Évaluation

Stack technique
numpy, python
Domaine
devtools, tooling
Type d'issue
Bug
Difficulté
5/5
Temps estimé
Plus d'une semaine
Activité
À l'abandon
Clarté
Plutôt claire
Accessibilité débutants
25/100

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.