Python 3.10 est disponible

50
4
août
2021
Python

Python 3.10 (rc1) est sorti le 2 août 2021, après quinze mois de développement (dont cinq à cheval sur les bêta et les rc de Python 3.9). Il reste deux mois avec des candidats (RC) avant la sortie définitive, prévue le 4 octobre 2021.

Voyons ce que cette version apporte comme nouveautés…

Logo Python

Sommaire

Cette version comporte pas moins de onze nouveautés et une correction par rapport à la version 3.9 sortie le 5 octobre 2020.
Une correction (changement de défaut) n’a finalement pas été incluse dans cette version.

PEP 623 − Préparation de la suppression de wstr dans PyUnicodeObject

PEP 623 : il n’y a plus aucune raison de garder la compatibilité avec les chaînes à larges caractères (wide string) dans l’implémentation Unicode de Python.

En effet, wstr et wstr_length avaient été introduits pour une meilleure compatibilité des extensions en C pour Python 2 et 3. Vu que Python 2 est maintenant déclaré mort, il n’y a plus besoin de garder ces API qui seront marquées comme dépréciées à partir de Python 3.10 et supprimées en version 3.12.

Le gain en mémoire est de 8 octets par chaîne de caractères, ce qui n’est pas rien.

PEP 604 − Écrire les unions de types plus facilement

PEP 604 : avant, pour écrire l’union de type en Python, il fallait écrire Union[X, Y].

Il fallait donc importer Union de typing pour pouvoir faire une union, et la lecture n’était pas limpide.

Cette proposition permet d’écrire X | Y, ce qui apporte à la fois les avantages d’une lecture simplifiée, et d’un import de moins.

Cela parait simple au niveau grammaire, mais pour que ça fonctionne au niveau du code, il a fallu ajouter la méthode magique __or__ à la super-classe/l’objet type.

Du coup on gagne aussi dans d’autres domaines, comme les écritures suivantes :

isinstance(5, int | str)
isinstance(None, int | None)

PEP 612 − Amélioration du typage pour les décorateurs

PEP 612 : la PEP 484 et la PEP 544 permettent de décrire des fonctions de retour d’appel (callback).

Sur un décorateur, en définissant un TypeVar, on peut définir une valeur de retour pour le décorateur qui correspond au type de la fonction décorée. Il n’était toutefois pas possible de faire la même chose avec les arguments.

La PEP 612 comble ce manque en introduisant ParamSpec qui englobe la définition d’arguments. ParamSpec contient notamment les attributs args et kwargs qui correspondent respectivement aux types des arguments positionnels et nommés.

Exemple :

from typing import Awaitable, Callable, ParamSpec, TypeVar

P = ParamSpec("P")
R = TypeVar("R")

def add_logging(f: Callable[P, R]) -> Callable[P, Awaitable[R]]:
  async def inner(*args: P.args, **kwargs: P.kwargs) -> R:
    await log_to_database()
    return f(*args, **kwargs)
  return inner

@add_logging
def takes_int_str(x: int, y: str) -> int:
  return x + 7

await takes_int_str(1, "A")  # accepté
await takes_int_str("B", 2)  # rejeté par le vérifieur de type

PEP 626 − Numéro de ligne précis pour les débugueurs et autres outils

PEP 626 : les attributs f_lineno et co_lnotab d’une pile (frame) d’exécution ne donnent pas toujours le bon numéro de ligne du code source dans certains cas.

La correction consiste à marquer des bytecodes comme virtuels et n’ayant pas de ligne dans le code source.

Afin de garantir la compatibilité avec les outils existants, rien n’est modifié sur co_lnotab mais une nouvelle méthode co_lines() est disponible. co_lnotab sera donc toujours disponible mais généré à la demande.

PEP 618 − Ajout d’une vérification optionnelle des longueurs dans zip

PEP 618 : sécurisation optionnelle de l’utilisation de la fonction zip.

La fonction zip permet d’itérer sur plusieurs séquences ou générateurs à la fois et de retourner un tuple de valeurs des différents itérateurs.

Si un itérateur n’a plus d’élément à itérer, zip s’arrête sans erreur, même si un autre itérateur a encore des éléments à itérer. Cette PEP rajoute une option pour déclencher une erreur dans une telle situation.

Exemple :

>>> list(zip(range(3), range(2, 5)))
[(0, 2), (1, 3), (2, 4)]
>>> list(zip(range(3), range(2, 4)))
[(0, 2), (1, 3)]
>>> list(zip(range(3), range(2, 4), strict=True))
ValueError: zip() argument 2 is shorter than argument 1

Bug 12782 − Groupement des gestionnaires de contexte avec des parenthèses

BPO 12782 : grouper des gestionnaires de contexte avec des parenthèses est désormais officiellement autorisé.

Contrairement aux autres mots-clés, il n’était pas possible d’utiliser les parenthèses avec with:

with (open("a_really_long_foo") as foo,
      open("a_really_long_bar") as bar):
    pass
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "demo.py", line 19
    with (open("a_really_long_foo") as foo,
                                    ^
SyntaxError: invalid syntax

Il fallait s’en remettre aux \ pour sauter des lignes:

with open("a_really_long_foo") as foo, \
      open("a_really_long_bar") as bar:
    pass

Désormais, la première syntaxe sera valide, comme on peut légitimement s’y attendre, renforçant la cohérence du langage. Cette fonctionnalité a pu être introduite facilement grâce au nouveau PEG parser ajouté dans Python 3.9.

PEP 632 − Dépréciation du module distutils

PEP 632 : le module distutils est déprécié car une version est maintenant intégrée dans setuptools qui ne dépend plus de la librairie standard de Python.

distutils n’était pas très documenté ni maintenu dans la librairie standard de toutes façons.

Ça laisse également le champ libre pour la PEP 517 qui veut construire un système de construction indépendant.

PEP 613 − Alias de types explicites

PEP 613 : ajout d’un type « Alias de type » pour permettre de définir les alias de type de manière explicite.

Jusqu’à présent la différence entre une affectation d’une valeur à une variable et d’une définition d’alias de type était assez ténue et ambiguë.

Exemple d’ambiguïté :

MonType = "ClassName"
def foo() -> MonType:
    pass

Ici, il est difficile de savoir si MonType est une variable dont la valeur est une string ClassName ou si c’est un alias de type sur la classe ClassName qui sera définie plus tard. Les vérifieurs de types se trompant souvent et rapportant de fausses erreurs, il a fallu se rendre à l’évidence : cette notation n’est pas assez explicite.

Cette PEP, propose :

MonType: TypeAlias = "ClassName"
def foo() -> MonType:
    pass

Là, plus d’ambiguïté.

PEP 634/635/636 − Ajout du mot-clé match pour faire du filtrage par motif.

PEP 634, PEP 635 et  PEP 636: filtrage par motif grâce au mot-clé match.

Cette PEP a été divisée en trois parties : définition, justification, tutoriel. La lecture du tutoriel est un bon point de départ pour lire ces PEP.

L’amélioration vient du constat suivant : il est souvent nécessaire de faire une suite de if … elif … elif … else qui concerne un même élément. Ces tests peuvent porter sur du duck-typing (est-ce que cet objet couac comme un canard), sur de l’héritage, sur une liste de valeurs (comparaison sur des strings ou des numériques par exemple), sur une taille de séquence (liste, tuple) et d’autres tests.

Cela fonctionne très bien avec des if mais c’est pas toujours super lisible parfois, et comme ce schéma se répète souvent dans les projets Python, il a été décidé d’aider les développeurs (ceux qui écrivent mais surtout ceux qui lisent) avec l’aide des mots-clés match et case (et copier ce qu’on peut trouver sur d’autres langages)

Les mots-clés match et case ne sont pas des termes réservés, on peut donc toujours les utiliser dans des noms de variables, le parseur faisant la différence de construction. Le code pré-python-3.10 reste donc compatible. Python parle de soft keywords.

Le concept de filtrage par motifs s’explique par le fait que la variable (ou l’expression) à tester est comparée à des motifs et permet de sélectionner exclusivement un bloc de code.

Exemple de code gérant un jeu de rôle par entrée textuelle :

command = input("Que voulez-vous faire ? ")
match command.split():
    case ["quitter"]:
        print("Au revoir !")
        quit_game()
    case ["regarder"] | ["scruter"]:
        current_room.describe()
    case ["aller", "côté", ("Nord" | "Sud" | "Est" | "Ouest") as direction] | [("Nord" | "Sud" | "Est" | "Ouest") as direction] if direction in current_room.exits:
        current_room = current_room.neighbor(direction)
    case [("Nord" | "Sud" | "Est" | "Ouest")] | [_]:
        print("Désolé, il n’y a pas de sortie dans cette direction")
    case ["prendre", obj] | ["ramasser", obj] | ["mettre", obj, "dans", "le", "sac"]:
        character.get(obj, current_room)
    case ["lâcher", *objects]:
        for obj in objects:
            character.drop(obj, current_room)
    case _:
        print(f"Désolé, je ne comprends pas ce que veut dire {command!r}")

On peut comprendre le code en un clin d’œil, ce qui ne serait pas forcément le cas avec des if. De plus on peut voir que la syntaxe de déconstruction permet de valider le format attendu, mais également de récupérer des variables liées (bind en anglais). Si des alternatives sont présentes dans le motif, alors chaque alternative doit lier les mêmes variables. L’utilisation de l’expression if condition après le motif permet de garder le bloc sous une condition spéciale, supplémentaire au motif, et évaluée après la correspondance au motif et après les bind.

Enfin l’utilisation de la variable _ permet de définir des cas par défaut. En effet il est de convention en Python d’utiliser _ pour définir une variable que l’on ne va pas utiliser et qui sert de variable fictive (placeholder).

On peut également utiliser la notation avec une ou deux étoiles pour récupérer une liste d’éléments ou un dictionnaire. Notations *lst ou **d comme on peut le faire dans la syntaxe de déconstruction classique.

Les comparaisons de motifs peuvent se faire en profondeur. L’égalité (==) est utilisée pour comparer les objets et littéraux, sauf pour True, False et None ou c’est l’identité (is).

Il est également possible de comparer avec des classes en utilisant cette syntaxe :

match event.get():
    case Click(position=(x, y)):
        handle_click_at(x, y)
    case KeyPress(key_name="Q") | Quit():
        game.quit()
    case KeyPress(key_name="up arrow"):
        game.go_north()
    ...
    case KeyPress():
        pass # Ignore other keystrokes
    case other_event:
        raise ValueError(f"Unrecognized event: {other_event}")

Ici on va vérifier le type de retour de event.get() avec les types d’objets indiqués dans les différents case. Attention, même si la syntaxe donne l’impression que des objets sont créés (Click(position=(x, y)), Quit()) il n’en est rien.

Ce qui est donné entre parenthèses restreint le motif à une classe qui hérite de la classe indiquée (exemple Click) et qui contient un attribut position dont le motif correspond à un tuple de deux éléments qui seront liés aux variables x et y.

On peut bien évidemment mixer tous ces types de motifs. L’expressivité créée par cette PEP est énorme et des tests menés par Python montre une meilleure lisibilité sur une grosse partie du code source des modules Python et une réduction du nombre de lignes.

Bref, après des années de demande pour avoir un switch/case en Python, en voilà un sous stéroïdes !

PEP 644 − OpenSSL 1.1.1 ou plus récent est maintenant requis

PEP 644 : OpenSSL (version 1.1.1 ou supérieure) sera nécessaire pour Python 3.10.

Il existe trop de différences entre les versions d’openssl (1.0.2, 1.1.0 et 1.1.1) pour que les deux experts qui gèrent ça chez Python puissent fournir un code compatible avec toutes. C’est la même raison pour libressl qui ne sera plus pris en charge à partir de Python 3.10.

Pour résumer, seule l’API d’openssl 1.1.1 est prise en charge.

Ça ne devrait pas trop impacter les distributions selon la PEP 644 car openssl 1.1.1 est la version par défaut sur la plupart des plateformes et distributions (Linux et BSD). Les rares distributions qui utilisent LibreSSL devraient probablement avoir migré sur OpenSSL d’ici à ce que Python 3.10 sorte.

PEP 624 − Retrait des API d’encodage Py_UNICODE

PEP 624 : planification du retrait des API inutilisée PyUnicode_* pour Python 3.11.

Cette PEP sort donc pour Python 3.10 mais n’aura d’effet que pour la version suivante.

PEP 597 − Ajout d’un EncodingWarning optionnel

PEP 597 : ajout d’un EncodingWarning optionnel lors de l’ouverture d’un fichier en mode texte.

En effet sous Linux, BSD et MacOS, l’encodage par défaut des fichiers est très généralement UTF-8. Mais ce n’est pas toujours le cas. Quand on ouvre un fichier en mode texte, c’est l’encodage par défaut du système qui est utilisé (qui peut être surchargé avec la variable d’environnement LANG par exemple).

On peut préciser/forcer l’encodage à utiliser pour les caractères/octets en le spécifiant dans un paramètre encoding. Celui-ci existe depuis fort longtemps, mais force est de constater que la plupart des bibliothèques et codes en python ne le précisent pas.

Cette PEP vise à ajouter un avertissement EncodingWarning quand le paramètre encoding n’a pas été précisé pour un fichier ouvert en mode texte.

Afin d’activer cet avertissement, il faut invoquer Python avec les paramètres -X warn_default_encoding ou bien définir la variable d’environnement PYTHONWARNDEFAULTENCODING à 1.

Illustration de code correct (ne générant pas le warning) :

with open(`my_file.txt`, encoding='utf-8') as f:
    content = f.read()

--

Bug 38605 − Évaluation retardée des annotations (non-inclus dans Python 3.10)

BPO 38605 : l’évaluation retardée des annotations, qui est disponible depuis Python 3.7 en utilisant une ligne from __future__ import annotations est maintenant disponible par défaut.

Pour rappel, la PEP 563 permet d’évaluer les annotations au lancement et pas simplement lors de la définition/compilation.

Les annotations sont présentes dans __annotations__. On peut les lire avec get_type_hints de typing. Les annotations sont toujours présentées comme du code python valide.

On peut par exemple les lire à l’exécution comme suit :

>>> import typing
>>> def x(a: 'int'): pass
>>> typing.get_type_hints(x)
{'a': ForwardRef('int')}

** /!\ Cette modification a été repoussée à Python 3.11 en raison de certaines incompatibilités **
Plus d’info

Pour tester

Pas envie d’attendre que ce soit disponible dans votre distribution ? Deux options : utiliser un conteneur ou compiler depuis les sources.

Utilisation d’un conteneur

$ docker run --rm -it python:3.10.0rc1-slim

Compilation depuis les sources

En fait c’est pas si compliqué du tout et ça se compile assez vite, donc c’est une option viable, même pour tester.

Dépendances nécessaires : expat, bzip2, gdbm, openssl, libffi, zlib, tk, sqlite, bluez-libs, mpdecimal
Sous Debian/Ubuntu c’est : expat libbz2-dev liblzma-dev libgdbm-dev libdb5.3-dev libdb5.3++-dev libssl-dev libffi-dev zlib1g-dev tk-dev libsqlite3-dev libbluetooth-dev libncurses-dev libreadline-dev

Ensuite il suffit de récupérer le tarball et de lancer la compilation et l’installation (c’est tiré du paquet AUR sur ArchLinux) :

$ wget 'https://www.python.org/ftp/python/3.10.0/Python-3.10.0rc1.tar.xz'
$ tar xf Python-3.10.0rc1.tar.xz
$ cd Python-3.10.0rc1
$ rm -rf Modules/{expat,zlib} Modules/_ctypes/{darwin,libffi}*
$ # Vous pouvez vous passer de enable-optimizations pour compiler plus vite si vous voulez
$ ./configure --prefix=/usr \
              --enable-shared \
              --with-computed-gotos \
              --enable-ipv6 \
              --with-system-expat \
              --enable-loadable-sqlite-extensions \
              --without-ensurepip \
              --enable-optimizations
$ make
$ mkdir -p pkg
$ sudo make DESTDIR="$PWD/pkg" altinstall maninstall
$ sudo rm -f "$PWD/pkg/usr/lib/libpython3.so" "$PWD/pkg/usr/share/man/man1/python3.1"
$ sudo ln -sf ../../libpython3.10m.so \
    "$PWD/pkg/usr/lib/python3.10/config-3.10-$(uname -m)-linux-gnu/libpython3.10m.so"
$ sudo ln -sf python3.10m-config "$PWD/pkg/usr/bin/python3.10-config"
$ sudo install -dm755 "$PWD/pkg/usr/lib/python3.10/Tools"/{i18n,scripts}
$ sudo install -m755 Tools/i18n/{msgfmt,pygettext}.py "$PWD/pkg/usr/lib/python3.10/Tools/i18n/"
$ sudo install -m755 Tools/scripts/{README,*py} "$PWD/pkg/usr/lib/python3.10/Tools/scripts/"
$ sudo cp -a pkg/* /
$ python3.10

Compatibilité

Python 3.10 est grandement compatible avec les versions précédentes. Ça devrait donc être très facile de passer à cette version pour votre projet.
Il y a toutefois quelques limitations temporaires :

  • Certains paquets Python compilés ne fournissent par encore de wheel (paquets binaires) pour Python 3.10 et donc l’installation d’un tel paquet va demander une compilation.
    Le paquet numpy, ainsi que pandas qui en dépend, fait partie de cette catégorie. La compilation peut s’avérer compliquée si vous êtes sur une distribution qui fait du morcelage de paquets (-dev, -doc, …). Il vous faudra alors installer une myriade de paquets systèmes (en plus du compilateur) pour pouvoir installer votre paquet python compilé.
    Donc changer uniquement votre environnement en Python 3.10 n’est pas forcément suffisant. Ceci est bien sûr temporaire et les auteurs de ces bibliothèques fourniront pour sûr des wheels prochainement.
  • Certains paquets Python n’ont pas pensé que la version mineure de Python pouvait tenir sur deux chiffres au lieu d’un.
    Je pense notamment à uwsgi. Mais c’est corrigé sur la branche principale et une version va voir le jour.

Ce ne sont que de petites contraintes qui vont se corriger d’ici que la finale sorte début octobre, mais en attendant, si vous voulez tester/anticiper, vous savez à quoi vous attendre.

Aller plus loin

  • # Bizarre (zip)

    Posté par  (site web personnel) . Évalué à 3.

    Dans l'exemple

    >>> list(zip(range(3), range(2, 4)), strict=True)
    ValueError: zip() argument 2 is shorter than argument 1

    Le strict est placé dans l'appel à list(), pas dans l'appel à zip().

    Python 3 - Apprendre à programmer dans l'écosystème Python → https://www.dunod.com/EAN/9782100809141

    • [^] # Re: Bizarre (zip)

      Posté par  (site web personnel, Mastodon) . Évalué à 2.

      Ah oui j’ai pas vu l’erreur, merci pour la correction. Si un modérateur peut modifier la dépêche c’est cool, mais sinon c’est pas grâve.

      • [^] # Re: Bizarre (zip)

        Posté par  (site web personnel, Mastodon) . Évalué à 2.

        Tu peux même avoir recours à une modératrice pour ce faire, mais faut lui expliquer lentement et en détail où et comment exactement vu qu'elle ne comprend pas grand chose (euphémisme) au code.

        « Tak ne veut pas quʼon pense à lui, il veut quʼon pense », Terry Pratchett, Déraillé.

        • [^] # Re: Bizarre (zip)

          Posté par  (site web personnel, Mastodon) . Évalué à 2. Dernière modification le 04 août 2021 à 16:41.

          Ahaha
          Ok, c’est pas bien compliqué en fait. Dans la dépêche il est écrit :
          list(zip(range(3), range(2, 4)), strict=True)

          En fait ça doit plutôt être :
          list(zip(range(3), range(2, 4), strict=True))

          La parenthèse fermante était mal placée.

          • [^] # Re: Bizarre (zip)

            Posté par  (site web personnel, Mastodon) . Évalué à 10.

            C'est fait (j'ai toujours peur de faire des âneries sur le code vu que je ne comprends pas ce que je fais).

            « Tak ne veut pas quʼon pense à lui, il veut quʼon pense », Terry Pratchett, Déraillé.

            • [^] # Re: Bizarre (zip)

              Posté par  (site web personnel) . Évalué à 10.

              Ne te stresses pas pour ça, c'est aussi le cas de plein de développeurs.

              • [^] # Re: Bizarre (zip)

                Posté par  . Évalué à 10.

                … et d'encore plus d'hommes politiques.  ;-)
                Ah, et aussi d'économistes (qui pratiquent la seule science exacte qui prévoit ce qui va arriver seulement après que ça soit arrivé).

                Ysabeau, au moins, elle demande, avant de faire un truc qu'elle ne comprend pas, ce qui la place en tête des gens avisés :-)

              • [^] # Re: Bizarre (zip)

                Posté par  (site web personnel) . Évalué à 5. Dernière modification le 13 septembre 2021 à 19:10.

                Et les pires ce sont ceux qui ne veulent pas comprendre …

                Un collègue, dont le métier et de faire des états (avec Crystal Report … ) ce qui normalement le place assez proche des requêtes SQL et des base de données, et bètement j'ai voulu lui expliquer comment voir le plan d'éxécution de ses requetes.
                Et ainsi comprendre comment optimiser certains états.

                Réponse : je ne vois pas trop ce que le plan d’exécution m’apportera comme information

                Pour les néophytes :
                Pour aller d'un point à un autre, je prend ma bagnole et je trace tout droit, jamais je me pose la question de savoir si la cargaison dépasse la capacité du véhicule et même si il y a une route carrossable.

  • # switching cases finally

    Posté par  (site web personnel, Mastodon) . Évalué à 10.

    On dit qu'il n'y a que les bourricots qui ne changent pas d'avis… Ravi qu'après des années à expliquer que c'est complétement inutile et que ce langage n'aurait jamais cette construction, de voir débarquer ces soft keywords

    “It is seldom that liberty of any kind is lost all at once.” ― David Hume

    • [^] # Re: switching cases finally

      Posté par  (site web personnel) . Évalué à 4.

      Never say Never … comme dirait le grand philosophe Justin Bieber

      En tout cas cela valait le coup d'attendre. Ce "match" permet pas mal de choses apparemment … difficile de dire aujourd'hui si cela ne va pas changer la manière d'appréhender un script.

      En tout cas l'abscence de structure avant cette version parfois amenait a réflechir différemment.

      Le plus drole c'est que Godot avec son GDScript qui a repris pas mal de truc du langage python a déjà une structure 'match'

      Qui a influencé qui ? … mais c'est aussi la force et la beauté de l'open source …

    • [^] # Re: switching cases finally

      Posté par  . Évalué à 7. Dernière modification le 06 août 2021 à 11:05.

      Vendredi, je m'autorise à marcher dedans…

      Il n'a jamais été dit que python n'aurait jamais cette construction.

      Guido a même proposé, puis rejeté une pep pour l'ajout d'un switch case pour cause d’impopularité. On notera que la proposition était très loin de ce qui est ajouté ici.

      Bref, personne n'a changé d'avis.. et dire que python n'aurait jamais cette construction était juste une erreur d’interprétation.

      • [^] # Re: switching cases finally

        Posté par  (site web personnel, Mastodon) . Évalué à 4.

        Il n'a jamais été dit que python n'aurait jamais cette construction.

        Guido a même proposé, puis rejeté une pep pour l'ajout d'un switch case pour cause d’impopularité.

        Au temps pour moi.
        Je lis en effet sur net-informations.com :
        « Python doesn't have a switch/case statement because of Unsatisfactory Proposals . Nobody has been able to suggest an implementation that works well with Python's syntax and established coding style. There have been many proposals, some of which you can see in PEP 3103—A Switch/Case Statement . »
        Et je lis sur docs.python.org :
        « You can do this easily enough with a sequence of if... elif... elif... else. There have been some proposals for switch statement syntax, but there is no consensus (yet) on whether and how to do range tests. See PEP 275 for complete details and the current status. »
        Il y avait eu aussi PEP 622 (lu sur SO…)

        Bref, personne n'a changé d'avis.. et dire que python n'aurait jamais cette construction était juste une erreur d’interprétation.

        Ça fait longtemps et je ne sais pas si je peux encore retrouver les références. Quand j'avais commencé à apprendre le langage, j'ai souvenir qu'on n'expliquait pas aussi bien (implémentation satisfaisante et cohérence syntaxique) mais on parlait d'avoir un langage simple où il ne devait pas y avoir plusieurs façons de faire la même chose… Par rapport à cela, il faisait sens de ne pas avoir de structures alternatives quand if... elif... elif... else fait l'affaire. Dans certains cas on peut s'en sortir en jouant avec des maping/dico (de lambda c'est encore mieux) …même si j'ai déjà vu des trucs plus sioux/créatifs

        “It is seldom that liberty of any kind is lost all at once.” ― David Hume

        • [^] # Re: switching cases finally

          Posté par  . Évalué à 6. Dernière modification le 06 août 2021 à 18:17.

          Note que ce qui est intégré ici c’est pas un simple switch/case, c’est du pattern matching comme tu peux en trouver en Rust par exemple.

          • [^] # Re: switching cases finally

            Posté par  . Évalué à 2. Dernière modification le 16 août 2021 à 00:03.

            Oui, tout comme ML, haskell, etc. Et sauf qu'il manque /juste/ l'étude de cas qui rend cet outil vraiment puissant, par exemple en vérifiant l'exhaustion des combinaisons (pour détecter, à la compilation, les bugs du à des cas non-traités).

            De plus, n'y a-t-il pas une contradiction avec l'adage "si ça vole comme un canard et que ça fait quack, alors c'est un canard" ? Comment fonctionne case Canard((_)) as obj: si l'objet n'est pas un canard mais vole comme un canard ? Après une lecture rapide de la PEP, je n'arrive pas à répondre à cette question. Je n'y trouve aucune mention de sub-typing ou de classe dérivée.

            Mon impression c'est qu'on est en train de rendre le langage python beaucoup plus complexe pour le faire ressembler à certains langages compilés, mais sans obtenir aucune aide que les compilateurs de ces langages offrent. En quelque sorte, on perd sur les 2 tableaux… Autant apprendre un langage de type scala, qui finalement offre une syntaxe très agréable (c'était finalement le principal argument qui a engendré la popularité de python) avec les avantages d'un compilateur fonctionnel de haut niveau qui possède aussi un très large éco-système de bibliothèques.

            • [^] # Re: switching cases finally

              Posté par  (site web personnel, Mastodon) . Évalué à 4.

              case Canard() veut un objet dont la classe Canard se trouve dans la mro (method resolution order) de la classe de l’objet testé. En gros, suffit que ça hérite d’une façon ou d’une autre.

              C’est un exemple, c’est très utile avec les frameworks qui génèrent une hiérarchie d’objets correspondant à une pile graphique/de widgets par exemple.

              Si tu veux faire un test qui permet de tester si ça couac comme un canard, tu peux le faire en faisant case obj if hasattr(obj, 'couac'):. L’instruction isinstance de Python n’a pas empêcher d’utiliser le duck-typing par ailleurs.

  • # Titre de la dépêche

    Posté par  (site web personnel, Mastodon) . Évalué à 10.

    Le titre de la dépêche pourrait-il être modifié pour ajouter (rc1) ? La version 3.10.0rc1 n'est pas la 3.10.0, qui n'est pas encore sortie.

    WeeChat, the extensible chat client

    • [^] # Re: Titre de la dépêche

      Posté par  (site web personnel, Mastodon) . Évalué à -3.

      Stricto-sensu c’est vrai c’est pas la finale, mais il n’y aura aucun changement d’ABI d’ici la finale, juste des corrections mineures. Ça reste une 3.10.0 candidate.

      • [^] # Re: Titre de la dépêche

        Posté par  (site web personnel, Mastodon) . Évalué à -2. Dernière modification le 05 août 2021 à 18:53.

        Et, de toute façon, le titre est Python 3.10 pas Python 3.10.quelque chose et la dépêche commence par

        Python 3.10 (rc1)

        « Tak ne veut pas quʼon pense à lui, il veut quʼon pense », Terry Pratchett, Déraillé.

        • [^] # Commentaire supprimé

          Posté par  . Évalué à 10.

          Ce commentaire a été supprimé par l’équipe de modération.

          • [^] # Re: Titre de la dépêche

            Posté par  (site web personnel, Mastodon) . Évalué à -2.

            Faut-il rappeler ce qu’est une RC ?
            RC veut dire littéralement Release Candidate, sortie de type candidat.

            Donc Python 3.10 est effectivement disponible. Si rien de particulier n’est trouvé durant deux mois, c’est la même version qui sera renommée en 3.10.0, sans RC.

            • [^] # Commentaire supprimé

              Posté par  . Évalué à 10.

              Ce commentaire a été supprimé par l’équipe de modération.

              • [^] # Re: Titre de la dépêche

                Posté par  (site web personnel, Mastodon) . Évalué à 0.

                Admettons.

                Mais par contre non le nombre de RC n’est pas illimité. Selon ce qui est écrit dans la PEP 619 il ne peut y avoir que 2 RC maximum.

              • [^] # Re: Titre de la dépêche

                Posté par  (site web personnel, Mastodon) . Évalué à 4.

                Je plussois : potentiellement ou très prochainement ou en passe d'être etc. Entre la RC et la finale il peut y avoir encore des corrections, et puis la mention n'est pas pour faire beau : on indique le gel d'ajout de fonctionnalité et le fait que ce n'est pas encore validé pour le passage en production (ce que laisse croire le titre de la dépêche.)

                “It is seldom that liberty of any kind is lost all at once.” ― David Hume

          • [^] # Re: Titre de la dépêche

            Posté par  . Évalué à 10.

            C’est probablement frustrant pour ceux et celles qui ont écrit la dépêche, mais je pense qu’elle aurait du rester en rédaction jusqu’à la sortie officielle.

            • [^] # Re: Titre de la dépêche

              Posté par  . Évalué à 5.

              Je suis d'accord avec ça.

              Merci à l'auteur pour la dépêche, ne suivant pas de près le développement de python, cette dépêche m'a permis de découvrir plein de fonctionnalité sympa qui vont arriver bientôt.

              Cependant, il va y avoir un délai avant la publication officielle, suite à quoi il va y avoir un délai jusqu'à ce que ce soit empaqueté par les distributions, puis encore un délai avant que les serveurs d'entreprises soient patchés. Bref, avant que je puisse utiliser cette version au boulot, il va se passer des mois et des mois. Et encore ce sont des cas d'usage qui ne sont pas si communs, et donc il peu encore s'écouler des mois jusqu'à ce que j'aie un cas d'usage.

              Est-ce que je me souviendrais encore qu'on peut faire des matchs ou des unions dans 6 mois ? Un an ? Je n'en sais rien, mais ce n'est pas garanti.

            • [^] # Re: Titre de la dépêche

              Posté par  (site web personnel) . Évalué à 4.

              En tant que développeur de Python, je trouve ça chouette d'encourager les gens à tester la version RC1 pour qu'un maximum de bugs soient remontés avant la version 3.10.0 finale !

              • [^] # Re: Titre de la dépêche

                Posté par  . Évalué à 2.

                La coutume voulait que ce soit dans un journal que l'on fasse les appels à tests et c'est utile de décrire comment remonter les problèmes (souvent la remontée de bugs pendant les phases de rc est un peu différente). Et puis bon surtout la dépêche n'appelle pas à tester. Ce qui est dommage c'est que du coup on va faire quoi pour la sortie ? Republier la même dépêche ?

                https://linuxfr.org/users/barmic/journaux/y-en-a-marre-de-ce-gros-troll

                • [^] # Re: Titre de la dépêche

                  Posté par  (site web personnel, Mastodon) . Évalué à 3.

                  Désolé hein, personne ne m’a rien dit. La dépêche est bien passée en modération.

                  On va faire quoi quand la 10.0.0 finale sortira : ben on poussera en prod les trucs qu’on est en train de tester en dev/recette, c’est tout non ?

                  • [^] # Re: Titre de la dépêche

                    Posté par  . Évalué à 5.

                    La question c'est pourquoi est-ce qu'on communique ?

                    Si c'est pour faire l'annonce des nouveautés de python, c'est dommage de présenter une version qui n'est pas considérée comme prête pour tout le monde.

                    Si c'est pour faire un appel aux tests, je ne vois pas où c'est indiqué dans la dépêche.

                    On évite généralement de publier en grande pompe (en dépêche donc en première page republié sur les réseau sociaux) des versions non testées car cela peut poser des problèmes aux développeurs comme aux utilisateurs. Il y a bien sûr une grande exception à cela, c'est les logiciels dont le développement est très long ou qui n'ont jamais eu de version prête pour tout le monde (comme hurd par exemple).

                    Ma seconde remarque c'est qu'il est toujours utile pour les développeurs comme pour les projets, de faire de la communication à la sortie. Ça permet d'un peu évènementialiser la sortie et donc pousse les gens à migrer, etc. Si tout à était dis cela va être très redondant, alors que la dépêche de cette forme est parfaite pour annoncer une sortie de version stable.

                    Désolé hein, personne ne m’a rien dit. La dépêche est bien passée en modération.

                    Il n'y a pas à être désolé ni à chercher des excuses. Tu fais bien ce que tu veux et la modération aussi. J'explique juste ce qui me semble avoir toujours était la pratique et pourquoi cette pratique me semble être une bonne idée.

                    https://linuxfr.org/users/barmic/journaux/y-en-a-marre-de-ce-gros-troll

    • [^] # Re: Titre de la dépêche

      Posté par  (site web personnel, Mastodon) . Évalué à 3.

      Ça y est la version finale est sortie.

  • # Traduction de « deprecated »

    Posté par  (site web personnel) . Évalué à 10.

    C'est un combat d'arrière-garde, mais « deprecated » se traduit par « obsolète ». Les fonctionnalités en question n'ont pas perdu de leur valeur financière ! :)

    La dépréciation, c'est « depreciated » en anglais, avec un i.

  • # Numpy

    Posté par  (site web personnel, Mastodon) . Évalué à 3.

    Numpy a sorti une version 1.21.2 avec un wheel publié sur Pypi pour Python 3.10, pour Linux.

    Ceci permet de considérablement réduire le temps de récupération (et de compilation) des dépendances d’un projet requérant Numpy en Python 3.10.

  • # soft keywords ???

    Posté par  . Évalué à 4.

    Avertissement : Je sais bien que c’est pas trolldi, mais je me sens d’humeur >:D

    Simplement une question, est-ce que ce n’est pas encore un mauvais coup de python sur la volonté de rétro-compatibilité que cette notion de soft keywords ?

    Ça m’a l’air d’être relativement complexe à implémenter correctement au niveau du compilateur, et puis si le match en bénéficie, pourquoi pas le if, ou le for, puis à ce train là, pourquoi tous les keywords ne seraient-ils pas soft ?

    Est-ce qu’on aurait pas eu intérêt à casser ça dès maintenant, quitte à se prendre un petit tollé tout de suite, que de risquer de se le prendre plus fort plus tard en réalisant qu’on ne peut pas continuer dans cette direction, à l’instar de python 2 ? :)

    Est-ce qu’il y a des langages qui implémentent déjà des mécanismes similaires sur les mot-clefs, et dont python pourrait s’inspirer (ou s’inspire!) pour faire les choses le mieux possible, pour maintenant et plus tard ?

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.