Numpy: Indication / annotation de type (PEP 484) pour ndarray, dtype et ufunc

Créé le 2 mars 2016  ·  70Commentaires  ·  Source: numpy/numpy

Demande de fonctionnalité: Prise en charge organique de PEP 484 avec des structures de données Numpy.

Quelqu'un a-t-il implémenté l'indication de type pour la classe numpy.ndarray spécifique?

En ce moment, j'utilise la saisie, n'importe quoi, mais ce serait bien d'avoir quelque chose de plus spécifique.

Par exemple, si les personnes numpy ont ajouté un alias de type pour leur classe d'objets array_like. Mieux encore, implémentez le support au niveau dtype, de sorte que d'autres objets soient pris en charge, ainsi que ufunc.

question SO originale

01 - Enhancement static typing

Commentaire le plus utile

Je voulais le pousser à nouveau pour voir si les discussions avaient progressé, en particulier en ce qui concerne les informations de forme d'indication de type, ce qui serait particulièrement utile dans beaucoup de mes applications. Existe-t-il un suivi de l'état ou n'est-ce pas une priorité suffisamment élevée pour que des ressources y soient dédiées?

Tous les 70 commentaires

Je pense que personne n'y a pensé. Aimeriez-vous? :-)

Je vais également suggérer que si vous voulez faire un suivi à ce sujet, nous fermons le problème gh et déplaçons la discussion vers la liste de diffusion, car elle est mieux adaptée aux discussions de conception ouvertes.

Après avoir obtenu cette réponse sur SO, j'ai décidé de fermer le problème.

Pour être clair, nous n'avons en fait aucune objection à prendre en charge de nouvelles fonctionnalités python intéressantes ou quoi que ce soit (plutôt le contraire); c'est juste que nous sommes un projet géré par des bénévoles sans beaucoup de ressources, donc les choses n'arrivent que si quelqu'un qui est intéressé se lance pour le faire.

La liste de diffusion est généralement le meilleur endroit si vous essayez de commencer à travailler sur quelque chose ou si vous espérez recruter d'autres personnes intéressées pour vous aider.

Merci, @njsmith. J'ai décidé de commencer ici en raison du suivi plus ordonné des problèmes, par opposition à une liste de diffusion non structurée (je cherchais une balise `` demande de fonctionnalité '', entre autres fonctionnalités ...)

Depuis que le gars qui m'a répondu sur SO m'a répondu avec une solution viable, j'ai décidé de laisser le sujet.
Peut-être que la documentation Numpy devrait être mise à jour pour inclure sa réponse (assurez-vous de lui en donner le crédit si vous le faites).

Merci encore!

Bonjour gars! Je me demandais simplement s'il y avait eu des progrès sur cette question. Merci.

Il y a une discussion à ce sujet sur la liste de diffusion ici .

Je rouvre ce numéro à ceux qui souhaitent en discuter davantage.

Je pense que cela serait certainement souhaitable pour NumPy, mais il y a en effet quelques aspects délicats de l'API NumPy pour trier, comme la façon dont NumPy accepte actuellement des objets arbitraires dans le constructeur np.array (même si nous voulons nettoyez ceci, voir https://github.com/numpy/numpy/issues/5353).

Un bon travail est en cours ici: https://github.com/machinalis/mypy-data

Il y a une discussion sur l'opportunité de pousser le travail en amont vers numpy ou typé: https://github.com/machinalis/mypy-data/issues/16

CC @mrocklin

Ce serait vraiment un excellent ajout à NumPy. Quelles seraient les prochaines étapes pour pousser cela vers typé ou NumPy? Même un talon incomplet serait utile et je suis heureux de vous aider avec un peu de direction?

@henryJack Le meilleur endroit pour commencer serait probablement l'outillage: découvrez comment nous pouvons intégrer des annotations de type de base dans le référentiel NumPy (et idéalement les tester) d'une manière qui fonctionne avec mypy et prend en charge leur ajout incrémental.

Ensuite, commencez avec des annotations extrêmement minimales et nous pouvons partir de là. En particulier, je sauterais les annotations dtype pour l'instant car nous n'avons pas de bon moyen de les spécifier (c'est-à-dire, ne faites que ndarray , pas ndarray[int] ).

Si cela est utile, j'ai une version alternative des annotations que j'ai écrites pour une utilisation chez Google et que je pourrais ouvrir la source. Mais nous avons notre propre système de construction unique et faisons la vérification de type avec pytype , donc il y aurait probablement des bizarreries à le porter en amont.

Je suppose que le seul moyen de tester les annotations pour exécuter mypy sur des extraits de code d'exemple et vérifier la sortie?

Serait-il préférable que les annotations soient intégrées au code ou sous forme de stubs séparés?

Je suppose que nous devrions également apprendre de Dropbox et des pandas que nous devrions commencer par les feuilles de la base de code par rapport aux structures de données de base?

@shoyer figure out how we can integrate basic type annotations
Ne serait pas simplement mettre https://github.com/machinalis/mypy-data/blob/master/numpy-mypy/numpy/__init__.pyi dans le répertoire de base du module numpy faire exactement cela .. Dans une version expérimentale d'une sorte au moins

Serait-il préférable que les annotations soient intégrées au code ou sous forme de stubs séparés?

L'intégration avec le code serait bien, mais je ne pense pas que ce soit encore possible pour NumPy. Même avec la version de chaîne de commentaire des annotations de type, nous aurions besoin d'importer à partir de typing sur Python 2, et l'ajout de dépendances à NumPy est quasiment hors de propos.

De plus, la plupart des structures de données et des fonctions de base (des choses comme ndarray et array ) sont définies dans des modules d'extension, nous devrons de toute façon utiliser des stubs.

Ne serait pas simplement mettre https://github.com/machinalis/mypy-data/blob/master/numpy-mypy/numpy/__init__.pyi dans le répertoire de base du module numpy faire exactement cela .. Dans une version expérimentale d'une sorte au moins

Oui, je pense que ce serait suffisant pour le code externe. Mais comment mypy gère-t-il les bibliothèques avec des annotations de type incomplètes?

Si possible, nous pourrions annoter numpy.core.multiarray directement, plutôt qu'au niveau supérieur. ( multiarray est le module d'extension où les types de base de NumPy comme ndarray sont définis.) Je pense que cela permettrait à NumPy lui-même d'utiliser la vérification de type pour certains de ses modules pur-Python.

Je suis curieux, quel est le type de np.empty(shape=(5, 5), dtype='float32') ?

Quel est le type de np.linalg.svd ?

Il semble que les types sont paramétrés, est-ce avec leur dtype? Est-il également possible de paramétrer avec leur dimension ou leur forme? Quelle est la sophistication prise en charge par le module de saisie de Python?

Oui, ils sont paramétrés par leur type. Je ne suis pas un expert du module de saisie, mais je pense que vous pourriez simplement avoir le type ndarray hériter de Generic[dtype, int] pour paramétrer sur ndim . Je crois que c'est ce que fait Julia. Je ne suis pas sûr que vous puissiez facilement paramétrer la forme. Je ne suis pas non plus sûr des avantages que cela apporterait ou des raisons pour lesquelles cela n'a pas été fait de cette façon au départ.

Peut-on utiliser des dtypes numpy dans le paramètre dtype ou cela peut-il uniquement taper
types de modules?

Il est également étrange que numpy.empty renvoie un tableau de type Any. Je soupçonne
il est difficile d'interagir et de prendre le type de la valeur du mot clé dtype =?

Le 1 septembre 2017 à 18h42, "Jacques Kvam" [email protected] a écrit:

Oui, ils sont paramétrés par leur type. Je ne suis pas un expert de la frappe
module mais je pense que vous pourriez simplement avoir le type ndarray hériter de Generic [dtype,
int] pour paramétrer sur ndim. Je crois que c'est ce que fait Julia. je ne suis pas
sûr si vous pouvez facilement paramétrer la forme. Je ne suis pas sûr non plus de quoi
avantages qui apporteraient ou pourquoi il n'a pas été fait que pourquoi en premier lieu.

-
Vous recevez cela parce que vous avez été mentionné.
Répondez directement à cet e-mail, affichez-le sur GitHub
https://github.com/numpy/numpy/issues/7370#issuecomment-326698639 , ou muet
le fil
https://github.com/notifications/unsubscribe-auth/AASszMlYO7iHdoPE_GU--njIYICSVVZ0ks5seIhFgaJpZM4Hm_CR
.

Vous pouvez utiliser des dtypes numpy, il suffit de les définir. Cela a été fait ici avec floating avec np.std.

https://github.com/kjyv/mypy-data/blob/24ea87d952a98ef62680e812440aaa5bf49753ae/numpy-mypy/numpy/__init__.pyi#L198

Je ne suis pas sûr, je ne pense pas que ce soit possible. Je ne pense pas que vous puissiez modifier le type de sortie en fonction de la valeur d'un argument. Je pense que le mieux que nous puissions faire est de surcharger la fonction avec toutes les spécialisations de type qui nous intéressent.

https://docs.python.org/3/library/typing.html#typing.overload

Une autre option pourrait être d'introduire des alias de type strict, donc np.empty[dtype] est une fonction avec la signature (ShapeType) -> ndarray[dtype] .

Il y a déjà un précédent pour cela avec la fonction inhabituelle np.cast[dtype](x)

@jwkvam OK, alors peut-être que les annotations dtype sont faisables - je suggérais simplement de commencer simplement et de partir de là.

Je pense que TypeVar pourrait éventuellement être utilisé à la place de surcharges, peut-être:

D = TypeVar('D', np.float64, np.complex128, np.int64, ...)  # every numpy generic type
def empty(dtype: Type[D]) -> ndarray[Type[D]]: ...

Si je comprends bien cela, cela impliquerait empty(np.float64) -> ndarray[np.float64] .

Ce serait également génial de pouvoir taper des informations de forme et de dimensionnalité de vérification, mais je ne pense pas que les vérificateurs de type actuels soient à la hauteur. Generic[int] est une erreur, par exemple - les arguments de Generic doivent être des instances de TypeVar :
https://github.com/python/cpython/blob/868710158910fa38e285ce0e6d50026e1d0b2a8c/Lib/typing.py#L1131 -L1133

Nous aurions également besoin d'exprimer des signatures impliquant des dimensions. Par exemple, np.expand_dims maps ndim -> ndim+1 .

Je suppose qu'une approche qui fonctionnerait est de définir des classes pour chaque entier non négatif, par exemple Zero , One , Two , Three , .. puis définissez les surcharges pour chacun. Cela deviendrait vite fatiguant.

Dans TensorFlow, tf.Dimension() et tf.TensorShape() vous permettent d'exprimer statiquement des formes. Mais ce n'est pas quelque chose qui se fait dans le système de types. Au contraire, chaque fonction est associée à un assistant qui détermine la forme statique des sorties à partir de la forme des entrées et de tous les arguments non tensoriels. Je pense que nous aurions besoin de quelque chose de similaire si nous espérions faire cela avec NumPy, mais il n'y a rien dans le système de typage Pythons qui suggère ce genre de flexibilité.

@shoyer Je vois, oui c'est décevant. J'ai pu pirater ce qui suit

_A = TypeVar('_A')
_B = TypeVar('_B', int, np.int64, np.int32)

class Abs(Generic[_A, _B]):
    pass

class Conc(Abs[_A, int]):
    pass

Mais je ne pense pas que cela mène nulle part ...

Il semble que votre exemple fonctionne! Il semblait que cela fonctionnait mieux sans les contraintes de type. Je pourrais tester des dtypes comme str . J'ai dû supprimer l'argument par défaut, je ne savais pas comment faire fonctionner cela.

D = TypeVar('D')
def empty(shape: ShapeType, dtype: Type[D], order: str='C') -> ndarray[D]: ...

et code

def hello() -> np.ndarray[int]:
    return np.empty(5, dtype=float)

Je reçois

error: Argument 2 to "empty" has incompatible type Type[float]; expected Type[int]

Je suis un peu confus car si j'échange les types:

def hello() -> np.ndarray[float]:
    return np.empty(5, dtype=int)

Je n'obtiens aucune erreur. Même si je ne pense pas que quelque chose soit marqué comme covariant.

Même si le système de type n'est pas aussi sophistiqué que nous le souhaiterions. Pensez-vous que cela en vaut toujours la peine? Un avantage que j'apprécierais est une meilleure complétion du code grâce à Jedi.

Je suis un peu confus car si j'échange les types:

Je crois que le problème ici est que les instances int sont implicitement considérées comme valides pour les annotations float . Voir les notes sur la tour numérique dans le PEP de typage:
https://www.python.org/dev/peps/pep-0484/#the -numeric-tower

Je pense que cela pourrait être évité si nous insistons sur les types scalaires NumPy au lieu des types Python génériques pour les annotations, par exemple np.ndarray[np.integer] plutôt que np.ndarray[int] .

C'est en fait un peu plus facile que je ne le pensais car TypeVar a un argument bound . Donc en révisant mon exemple:

D = TypeVar('D', bound=np.generic)
def empty(dtype: Type[D]) -> ndarray[D]: ...

J'ai dû supprimer l'argument par défaut, je ne savais pas comment faire fonctionner cela.

Je ne sais pas trop dans quoi vous vouliez en venir?

J'ai juste essayé d'encoder la valeur par défaut de dtype dans le stub. Ils l'ont fait dans le repo mypy-data.

def empty(shape: ShapeType, dtype: DtypeType=float, order: str='C') -> ndarray[Any]: ...

depuis https://github.com/kjyv/mypy-data/blob/master/numpy-mypy/numpy/__init__.pyi#L523

En suivant votre exemple, je n'ai pas pu faire fonctionner mypy avec un argument par défaut pour dtype. J'ai essayé dtype: Type[D]=float et dtype: Type[D]=Type[float] .

Je pense que dtype doit également devenir un type générique, puis vous devez définir la valeur par défaut sur une sous-classe générique numpy comme np.float64 plutôt que float , par exemple,

# totally untested!
D = TypeVar('D', bound=np.generic)

class dtype(Generic[D]):
    <strong i="9">@property</strong>
    def type(self) -> Type[D]: ...

class ndarray(Generic[D]):
    <strong i="10">@property</strong>
    def dtype(self) -> dtype[D]: ...

DtypeLike = Union[dtype[D], D]  # both are coercible to a dtype
ShapeLike = Tuple[int, ...]

def empty(shape: ShapeLike, dtype: DtypeLike[D] = np.float64) -> ndarray[D]: ...

Ce n'est pas juste. D == type(dtype.type) == type , donc votre paramétrage de type est inutile, car le seul paramètre utilisé est D = type .

@ eric-wieser oups, je pense que c'est corrigé maintenant.

Il y a eu des discussions sur le suivi des problèmes de mypy (principalement python / mypy # 3540). Là, nous percevons que le principal problème est que les tableaux numpy incluent conceptuellement leurs dimensions dans leur type, et le système de type actuel ne le prend pas vraiment en charge. Si les projets mypy ou typeshed peuvent aider de quelque manière que ce soit à faire fonctionner la saisie pour numpy, veuillez nous en informer!

Il y a eu des discussions sur le suivi des problèmes de mypy (principalement python / mypy # 3540). Là, nous percevons que le principal problème est que les tableaux numpy incluent conceptuellement leurs dimensions dans leur type, et le système de type actuel ne le prend pas vraiment en charge. Si les projets mypy ou typeshed peuvent aider de quelque manière que ce soit à faire fonctionner la saisie pour numpy, veuillez nous en informer!

Je pourrais imaginer encoder plus ou moins d'informations dans des types paramétrés ici. Par exemple, un tableau comme np.empty((2, 3)) peut être de l'un des types suivants:

  1. Array[float64, (2, 3)]
  2. Array[float64, (n, m)]
  3. Array[float64, ndim=2]
  4. Array[float64]
  5. Array

@JelleZijlstra quelle est votre opinion ici sur les outils comme mypy qui seront probablement capables de gérer? À quel point pouvons-nous devenir sophistiqués?

Il semble assez clair qu'un travail important dans le système de type serait nécessaire pour prendre en charge les formes et la dimensionnalité. J'apprécierais cela (et j'ai juste écrit un tas d'idées en python / mypy # 3540), mais pour l'instant, appelons cela hors de portée de NumPy. Faire fonctionner ndarray[float64] semble déjà assez difficile, étant donné la hiérarchie complexe des types de numpy et les défis des types génériques.

Oui, je pense que la première étape serait simplement d'obtenir un support de frappe de base pour numpy (et Pandas et sklearn), sans prendre en compte les formes et autres contraintes supplémentaires sur ces types.

Le problème avec d'autres contraintes supplémentaires est qu'il ne suffit pas de décrire simplement un dtype (forme = 5,6), mais il doit y avoir un langage pour décrire une contrainte sur cette forme. Vous pouvez imaginer que vous voulez définir une fonction qui n'accepte que des formes numpy carrées comme entrées, ou une fonction où une dimension doit être 2x l'autre.

Quelque chose comme ça a été fait dans le projet de contrats .

Je pense aussi que PEP 472 serait génial à supporter ici, car alors on pourrait vraiment faire des choses comme Array[float64, ndim=2] .

En effet, PEP 472 serait bien pour la saisie, même si ce serait probablement l'un des correctifs les plus faciles pour y parvenir! (Veuillez m'envoyer un ping si vous souhaitez redémarrer la discussion à ce sujet, car je pense qu'il existe également des cas d'utilisation convaincants pour les dimensions nommées dans l'indexation.)

Je ne sais pas comment je contribue, mais je pense vraiment que ce serait une fonctionnalité géniale pour plusieurs raisons. Mais, nous allons dans cette direction, alors il semble que [] devienne simplement une manière différente d'appeler un objet. Donc object(*args, **kwargs) fait quelque chose, object[*args, **kwargs] autre chose, et ensuite nous pouvons même généraliser et aussi avoir object{*args, **kwags} et object<*args, **kwargs> . ;-)

@mitar : En regardant les choses dans l'autre sens, peut-être devrions-nous simplement annoter avec quelque chose comme ndarray[float].constrain(ndim=2) . Nous avons déjà beaucoup de syntaxe disponible, et contrairement aux décorateurs, les annotations n'ont aucune restriction

J'ai en fait essayé la syntaxe suivante: ndarray[float](ndim=2) , donc surcharger que sur les génériques __call__ retourne à nouveau une classe, et non une instance d'une classe. Mais c'est devenu délicat pour les types qui ne sont pas génériques.

Je pense que le principal problème est avec le support ndarray[float] , car ndarray[float] n'est pas quelque chose qui existe vraiment dans ndarray , il faudrait changer ndarray lui-même, ce qui Je ne suis pas sûr que ce soit un bon principe général à faire (changer le code en amont pour prendre en charge une meilleure saisie).

Une autre approche pourrait être d'avoir un nouveau type de variables de type, ConstrainedTypeVar , où vous pourriez faire quelque chose comme ConstrainedTypeVar('A', bound=ndarray, dtype=float, ndim=2) ou quelque chose comme ça, puis vous utiliseriez A comme un var dans la signature de la fonction. Mais cela devient très verbeux.

J'ai rédigé un document avec quelques idées sur ce à quoi les formes de tableau de frappe pourraient ressembler avec la diffusion et une notion d'identité de dimension.

Les idées principales comprennent:

  1. Ajout d'une primitive DimensionVar qui permet des identités symboliques pour les dimensions du tableau
  2. Reconnaître ... ( Ellipsis ) comme une diffusion de tableau indicateur.

Par exemple, pour taper np.matmul / @ :

from typing import DimensionVar, NDArray, overload

I = DimensionVar('I')
J = DimensionVar('J')
K = DimensionVar('K')

<strong i="17">@overload</strong>
def matmul(a: NDArray[..., I, J], b: NDArray[..., J, K]) -> NDArray[..., I, K]: ...

<strong i="18">@overload</strong>
def matmul(a: NDArray[J], b: NDArray[..., J, K]) -> NDArray[..., K]: ...

<strong i="19">@overload</strong>
def matmul(a: NDArray[..., I, J], b: NDArray[J]) -> NDArray[..., I]: ...

Celles-ci seraient suffisantes pour permettre de taper des ufuncs généralisés . Voir le doc pour plus de détails et d'exemples.

Une solution possible pour prendre en charge à la fois les dtypes et les formes, si nous choisissons déjà de garder NDArray et ndarray distincts:

NDArray[float].shape[I, J, K]
NDArray[float]
NDArray.shape[I, J, K]

Juste une pensée, serait-il logique d'avoir également un raccourci comme celui-ci?

NDArray.ndim[2]  # NDArray.shape[..., ...]
NDArray[float].ndim[2]  # NDArray[float].shape[..., ...]

- ce qui pourrait simplifier un certain nombre de signatures, en particulier dans le code en aval.

@aldanor Je pense que vous voulez dire NDArray.shape[:, :] ( ... signifie "zéro ou plus de dimensions", ce qui n'est pas tout à fait correct dans ce contexte). Mais oui, cela semble raisonnable.


Mise à jour rapide sur la saisie des dtypes: j'ai écrit un module jouet en utilisant l'approche que j'ai décrite ci-dessus qui utilise des sous-classes np.generic avec Generic pour les types ndarray / dtype .

Cela semble principalement fonctionner avec mypy comme je m'y attendais, y compris l'inférence de type avec l'équivalent de np.empty(..., dtype=np.float32) . Il ne parvient pas à détecter l'une de mes erreurs de type intentionnelles impliquant un type Union (je déposerai un rapport de bogue plus tard).

Je pense que ce serait probablement assez bon pour les dtypes. Sans la prise en charge de la saisie des valeurs littérales, nous ne pourrions pas faire d'inférence de type avec dtype spécifié sous forme de chaînes ( dtype='float32' ). Peut-être plus problématique, il ne gère pas non plus l'inférence de type à partir de types Python comme dtype=float . Mais ces types peuvent être ambigus (par exemple, dtype=int correspond à np.int64 sous Linux et np.int32 sous Windows), il est donc préférable d'utiliser de toute façon des types génériques explicites. Ce n'est pas grave si l'inférence de type ne fonctionne pas dans tous les cas possibles, tant que les spécifications dtype=float sont déduites comme un type de Any plutôt que de déclencher une erreur.

Mais ces types peuvent être ambigus (par exemple, dtype = int correspond à np.int64 sous Linux et np.int32 sous Windows)

Ce n'est pas ambigu - dans tous les cas, cela correspond à np.int_ , qui est le type C long .

J'ai écrit la liste de diffusion pour obtenir un consensus sur l'écriture de stubs de type pour NumPy dans un package séparé:
https://mail.python.org/pipermail/numpy-discussion/2017-November/077429.html

Incroyable, merci @shoyer !

Selon le consensus sur la liste de diffusion, je voudrais déclarer https://github.com/numpy/numpy_stubs ouvert aux affaires!

Nous allons commencer par les annotations de base (pas de support dtype). Si quelqu'un veut mettre en place un PR de base pour ajouter l'échafaudage PEP 561 pour le repo, ce serait apprécié!

OUI, OUI, 1000X OUI!

Attention à tous ceux qui suivent ce problème: j'ai ouvert deux problèmes sur le tracker python / typing:

  • typage ndarray en général (https://github.com/python/typing/issues/513)
  • syntaxe pour le typage ndarray (https://github.com/python/typing/issues/516)

Quelle est l'heure de sortie prévue pour la fonction de saisie?
Y a-t-il une raison d'essayer de maintenir la compatibilité 2.7?
Un premier commentaire mentionnait des difficultés d'intégration avec python 2. Depuis, il semble que numpy ait changé de position.

Les choses sont des cibles mobiles, je sais, mais serait-il judicieux de cibler quelque chose comme Python 3.4-3.6?

Quelle est l'heure de sortie prévue pour la fonction de saisie?

Il y a eu plusieurs discussions à ce sujet (génériques entiers aka types dépendants simples) à PyCon, j'écrirai bientôt un proto-PEP basé sur ces discussions et le document original écrit par @shoyer . Mon objectif est d'obtenir le PEP écrit, implémenté dans mypy et accepté à temps pour Python 3.8 beta 1 (également le backport ultérieur des nouveaux types dans typing pour Python 2 est très probable)

@hmaarrfk en ce qui concerne l'écriture d'annotations de type pour NumPy lui-même, nous avons commencé à le faire dans un référentiel séparé: https://github.com/numpy/numpy-stubs. Vous devriez pouvoir installer et utiliser ces stubs dans l'état actuel (avec la dernière version de mypy), mais ils sont loin d'être complets. Une aide serait appréciée!

Bien sûr, je suis heureux d'aider là où je peux, et j'ai vu le référentiel. Je sais juste que ces choses prennent du temps.
J'ai vu le repo et remarqué un commit mentionné la compatibilité 2.7, c'est pourquoi j'ai demandé.

La version bêta de Python 3.8 est à la mi-2019 . Numpy a mentionné qu'ils arrêteraient les nouvelles fonctionnalités à la fin de 2018 .

La frappe semble être une fonctionnalité "agréable à avoir" pour numpy par opposition à un "must-have". En tant que tel, cibler deux langues semble un peu difficile, surtout si la fonctionnalité commence à apparaître bien au-delà de la date limite de support de numpy.

Je serai intéressé de lire ce que @ilevkivskyi a à dire dans le PEP.

@hmaarrfk Vous soulevez un bon point sur le support de Python 2.7. Pour être honnête, je n'y ai pas encore réfléchi complètement. Je m'attends à ce que nous finissions par le supprimer, mais probablement pas avant que mypy lui-même n'abandonne le support de Python 2.7, étant donné qu'un cas d'utilisation majeur pour la saisie est l'écriture de code compatible Python 2/3.

Pour l'instant, il ne semble pas nécessiter de nombreux compromis pour prendre en charge Python 2 dans nos annotations de type, donc je suis heureux de le laisser, d'autant plus qu'il provenait d'un contributeur qui s'y intéressait manifestement.

Je voulais le pousser à nouveau pour voir si les discussions avaient progressé, en particulier en ce qui concerne les informations de forme d'indication de type, ce qui serait particulièrement utile dans beaucoup de mes applications. Existe-t-il un suivi de l'état ou n'est-ce pas une priorité suffisamment élevée pour que des ressources y soient dédiées?

Dans transonic , un projet pour généraliser les accélérateurs numpy, nous avons une syntaxe d'indication de type comme alternative aux annotations Pythran qui utilise des commentaires . Cela ne fonctionne pas bien avec mypy pour le moment, mais je me demande si cela est utile. Voir un exemple: https://transonic.readthedocs.io/en/latest/examples/type_hints.html

Au cas où cela serait utile pour ce problème, je mentionnerai que j'ai créé un outil pour convertir des docstrings en commentaires de type: https://pypi.org/project/doc484/

J'utilise ceci avec le pré-commit dans plusieurs projets pour garder les docstrings synchronisés avec les commentaires de type.

Vous devrez toujours convertir les types de vos docstrings pour qu'ils soient conformes à PEP484.

Bonjour à tous,

Je voulais faire ma part, j'ai donc forké le repo et commencé à ajouter des indices de type. Mon idée était de travailler de bas en haut, alors commencez par les fonctions «simples» et travaillez vers le haut à partir de là. (En commençant par les fruits à portée de main)

Par exemple, dans _string_helpers.py , j'ai ajouté des indices de type à certaines variables et fonctions.

LOWER_TABLE: str = "".join(_all_chars[:65] + _ascii_lower + _all_chars[65 + 26:])
UPPER_TABLE: str = "".join(_all_chars[:97] + _ascii_upper + _all_chars[97 + 26:])

def english_lower(s: str) -> str:
    """ Apply English case rules to convert ASCII strings to all lower case.
   ...
    """
    lowered = s.translate(LOWER_TABLE)
    return lowered

Que penses-tu de cela?

Je recommanderais de faire un peu et d'ouvrir un PR pour obtenir des commentaires. numpy cible les pythons plus anciens (annotations introduites par 3.5, IIRC) et cela briserait ces versions, alors peut-être envisager d'écrire des fichiers .pyi ou vérifier les documents mypy pour voir s'il y a un peu plus de conseils sur les meilleures pratiques.

Nous avons fait des annotations jusqu'à présent dans les stubs numpy-stubs séparés
référentiel, mais cela a été un processus lent.

Le jeudi 14 novembre 2019 à 9h57, Ben Samuel [email protected] a écrit:

Je recommanderais de faire un peu et d'ouvrir un PR pour obtenir des commentaires. engourdi
cible les pythons plus anciens (3.5 annotations introduites, IIRC) et ce
briserait ces compilations, alors peut-être envisager d'écrire des fichiers .pyi ou vérifier
les documents mypy pour voir s'il existe un peu plus de conseils sur les meilleures pratiques.

-
Vous recevez cela parce que vous avez été mentionné.
Répondez directement à cet e-mail, affichez-le sur GitHub
https://github.com/numpy/numpy/issues/7370?email_source=notifications&email_token=AAJJFVVH5CLAHPJKWJHDQ73QTVRMXA5CNFSM4B436CI2YY3PNVWWK3TUL52HS4VMDFVECH5CNFSM4B436CI2YY3PNVWWK3TUL52HS4VMVECCEX63-8WWWK3TUL52HS4VMVECCEX63-8WWWK3TUL52HS4VMVECCEX63NVWWK3TUL52HS4VMVECCEX63NVWWK3TUL52HS4VMVECCEX63
ou se désinscrire
https://github.com/notifications/unsubscribe-auth/AAJJFVTWTKLP63AK2C2IUW3QTVRMXANCNFSM4B436CIQ
.

@ bsamuel-ui numpy nécessite actuellement Python 3.5+, et le NEP-29 [1] déclare qu'il devrait être correct de le passer à 3.6+
[1] https://numpy.org/neps/nep-0029-deprecation_policy.html

Les annotations (pour les arguments de fonction et les types de retour) sont en fait prises en charge dans toutes les versions de Python 3; 3.6 n'a introduit que des annotations variables. Dans la première version de Python 3 (<3.5), vous devez utiliser un backport du module typing .

J'ai ajouté une demande d'extraction avec mon premier fichier .pyi. Cela nécessite du travail, mais ce serait bien si vous pouviez y jeter un coup d'œil pour que je puisse avoir un premier retour

Comme mentionné dans gh-14905, nous avons les débuts d'une bibliothèque de stub dans https://github.com/numpy/numpy-stubs. Ce serait formidable de faire cela avec des tests appropriés, puis nous pourrions décider de la meilleure façon de le conditionner ou de le fusionner dans numpy / numpy proprement dit.

Mon mauvais @mattip. Je vais supprimer la pull request de numpy et en ajouter une nouvelle à numpy-stubs

il est toujours ouvert, mais je pense que numpy prend déjà en charge cela dans la version principale

Salut,
J'essaie de définir un alias de type aa pour le vecteur 3d, donc un tableau numpy de forme (3,) de dtype int32.

(Je sais que je peux taper un indice avec np.ndarray, mais comment puis-je être plus précis? J'ai tout lu ici et je ne l'ai pas compris, je recherche également un didacticiel sur la façon d'utiliser les types numpy pour taper en Python, mais je ne l'ai pas trouver n'importe quoi. )

Comme il est possible d'écrire:

from typing import Tuple
VectorType = Tuple[int, int, int]

J'ai essayé de faire:

VectorType = np.ndarray(shape=(3,), dtype=np.int32)

Est-ce la bonne façon de faire?

Quelqu'un ici peut-il me montrer un tutoriel ou un exemple s'il vous plaît?

De plus, j'ai trouvé ce dépôt qui est "Indices de type pour Numpy": https://github.com/ramonhagenaars/nptyping

Est-ce que Numpy intégrera cela?
@ramonhagenaars

@mattip

Comme mentionné dans gh-14905, nous avons les débuts d'une bibliothèque de stub dans https://github.com/numpy/numpy-stubs.

Il semble que cela ait été fusionné dans le repo principal. Cela a-t-il été publié ou figure-t-il sur la feuille de route? Essayer de décider si nous devons explorer quelque chose de tiers comme https://github.com/ramonhagenaars/nptyping ou (idéalement) attendre / utiliser des indices de type officiellement pris en charge.

Merci.

Nous avons fusionné la plupart des stubs numyp dans la branche de développement. Vous pouvez suivre la progression en recherchant l' étiquette de saisie statique . Espérons que cela fera partie de la prochaine version. Vous pouvez essayer ce qui est actuellement fusionné en utilisant une version HEAD de numpy. Nous sommes toujours à la recherche de contributeurs: une revue constructive, de la documentation et des commentaires sur les problèmes et les pull requests sont quelques moyens d'aider.

(Je sais que je peux taper un indice avec np.ndarray, mais comment puis-je être plus précis? J'ai tout lu ici et je ne l'ai pas compris, je recherche également un didacticiel sur la façon d'utiliser les types numpy pour taper en Python, mais je ne l'ai pas trouver n'importe quoi. )

Il y a beaucoup d'intérêt dans ce domaine, mais un typage plus spécifique (dtypes et dimensions) pour les tableaux NumPy n'est pas encore pris en charge.

@ GilShoshan94 FWIW que j'ai déposé https://github.com/ramonhagenaars/nptyping/issues/27

Cette page vous a été utile?
0 / 5 - 0 notes