La version 3.3 de Python est sortie ce 29 septembre. Pour rappel, Python « est un langage de programmation multi‐paradigme. Il favorise la programmation impérative structurée et orientée objet. Il est doté d’un typage dynamique fort, d’une gestion automatique de la mémoire par ramasse‐miettes et d’un système de gestion d’exceptions ; il est ainsi similaire à Perl, Ruby, Scheme, Smalltalk et Tcl ». Merci Wikipédia.
Cette version 3.3 est donc la nouvelle version de production de la branche 3. Elle cohabite avec la version 2.7.3 de la branche 2.7. Cette nouvelle version apporte, entre autres, les fonctionnalités suivantes :
- amélioration de la syntaxe des générateurs ;
- un module venv capable de créer des environnement Python virtuels, tout comme VirtualEnv ;
- revue du stockage interne des caractères, ce qui permet d’économiser de la mémoire ;
- nouvelle façon de définir et placer les paquets d’un projet Python ;
- des améliorations concernant l’API du module
os
, ainsi qu’une remise à plat desExceptions
concernant les entrées‐sorties ; - amélioration de l’intégration Windows ;
- fonction de hachage aléatoire activée par défaut (permettant de se prémunir contre l’attaque des dictionnaires et des tables de hachage) ;
- et bien d’autres…
Retrouvez en seconde partie de dépêche une liste plus complète des nouveautés.
NdA : Merci à FlashCode, Antoine, Victor Stinner, Laurent Pointal, Emmanuel C, jcr83, Amine « nh2 » Brikci‐Nigassa, GeneralZod, crep4ever, Nÿco et Le Cancre Las pour leur participation active à cette rédaction en collaboration.
Sommaire
-
Nouveautés de Python 3.3
- PEP 380 — Générateurs
- PEP 405 — VirtualEnv
- PEP 3155
- Compression
- PEP 417 Tests unitaires
- Fonction sendfile
- PEP 393 — Stockage des chaînes de caractères
- PEP 414 — Transition Unicode Py2 vers Py3
- Standardisation de la procédure d’importation
- PEP 3144 — Gestion des adresses IP
- PEP 3151 — Exceptions entrées‐sorties
- PEP 397 — Lanceur Python pour Windows
- PEP 418 — Fonctions de gestion du temps
- PEP 420 — Empaquetage
- PEP 362 — inspect.getsignature()
- Module décimal
- Module os
- Fonctions de hachage
- Gestionnaire d’erreur faulthandler
- Divers
Nouveautés de Python 3.3
PEP 380 — Générateurs
La nouvelle syntaxe yield from <expr>
permet à un générateur de renvoyer directement les valeurs d’un autre générateur. Cette nouvelle construction autorise le chaînage de générateurs (et plus généralement d’itérateurs), simplement. Cela permettra d’écrire des générateurs, dont le code se trouve découpé dans plusieurs fonctions, elles‐mêmes génératrices (et évitera d’avoir de trop grosses fonctions monolithiques dédiées à cette tâche).
PEP 405 — VirtualEnv
Le nouveau module venv
permet la création d’environnements virtuels Python à la manière du célèbre virtualenv de Ian Bicking. Un environnement virtuel est une installation isolée de Python dans un répertoire spécifique du système de fichiers, comprenant son propre interpréteur, ses propres paquets et scripts, avec un éventuel lien vers l’installation du système. Du fait de la prise en compte par les développeurs de cet usage, il sera maintenant plus simple de manipuler ces environnements, avec de futurs outils sans doute mieux intégrés. À cet effet, une nouvelle commande a été introduite : pyvenv
.
PEP 3155
Les fonctions et les classes ont un nouvel attribut __qualname__
représentant le chemin depuis le module de plus haut niveau jusqu’à leur définition.
Compression
- lzma : le nouveau module
lzma
fournit la compression et la décompression utilisant l’algorithme LZMA (algorithme de 7-zip), incluant la prise en charge des formats de fichier.xz
et.lzma
; - bz2 : le module
bz2
a été complètement réécrit, et gère désormais tout objet offrant une interface de type fichier. Il gère également la compression et la décompression en parallèle des flux.
PEP 417 Tests unitaires
Le framework de tests unitaires unittest
, inclus dans la bibliothèque standard, a été enrichi d’un module de mock : unittest.mock
.
Les objets factices (Mock Objects) permettent de simuler le comportement des objets dans certaines conditions. Cette technique facilite l’écriture des tests unitaires et peut également accélérer leur exécution dans certains cas.
Fonction sendfile
Le module os
dispose d’une nouvelle fonction sendfile()
qui fournit une manière efficace zero‐copy, permettant de copier les données d’un descripteur de fichier (ou socket) à un autre. L’expression « zero‐copy » fait référence au fait que toute la copie entre les deux descripteurs est entièrement effectuée par le noyau, sans passage par l’espace utilisateur. sendfile()
est utile pour copier efficacement le contenu d’un fichier du disque vers une socket réseau, par exemple pour envoyer un fichier à un pair. À noter que l’appel système sendfile()
n’étant pas normalisé, l’utilisation de cette nouvelle fonction sera dépendante des contraintes de la plate‐forme (tous les types de descripteurs de fichiers ne sont pas admis en entrée comme en sortie, par exemple). Voir la page man de l’appel système sous‐jacent pour plus de détails.
PEP 393 — Stockage des chaînes de caractères
Le stockage des chaînes de caractères a été optimisé. Pour toute chaîne, une taille fixe de 1, 2 ou 4 octets par caractère est dorénavant utilisée, selon le plus haut codepoint stocké dans celle‐ci. Par exemple, les chaînes ne contenant que de l’ASCII (codes 0 à 127) n’utilisent ainsi qu’un octet par caractère, les chaînes en latin1
et latin9
, deux octets.
L’utilisation mémoire est deux à trois fois meilleure par rapport à Python 3.2 et se rapproche des performances de Python 2.7.
PEP 414 — Transition Unicode Py2 vers Py3
La notation u"texte"
, qui est utilisée dans Python 2.x, pour dénoter des littéraux chaînes Unicode, est de retour dans Python 3.3 afin de faciliter l’écriture de code fonctionnant sur des versions 2 et 3 de Python. Cette PEP a été proposée par Armin Ronacher, et acceptée en moins de 15 jours.
Standardisation de la procédure d’importation
import
est implémenté à l’aide du module importlib
, ce qui, à terme, devrait éliminer les différences de comportement entre les diverses implémentations. De même, l’importation des modules utilise maintenant un verrou par module et n’est plus global pour l’importation de tous les modules.
PEP 3144 — Gestion des adresses IP
Le nouveau module ipaddress
permet de manipuler des adresses IPv4 et IPv6. Il est basé sur le module ipaddr-py
de Google.
PEP 3151 — Exceptions entrées‐sorties
La hiérarchie des exceptions liées à l’OS et aux entrées‐sorties a été simplifiée. Désormais, elles dérivent toutes de OSError
(IOError
, EnvironmentError
, etc., restent pour la compatibilité et sont des alias d’OSError
) et sont typées plus finement pour connaître le type exact de l’erreur. Par exemple, ouvrir un fichier inexistant lève l’exception FileNotFoundError
.
PEP 397 — Lanceur Python pour Windows
Un lanceur Python pour Windows fait son arrivée, se basant sur le shebang placé en tête des modules Python pour identifier la version de l’interpréteur à utiliser (comme sous les Unix), avec deux lanceurs (comme il y avait un python.exe
et un pythonw.exe
) permettant de démarrer Python avec ou sans la console (scripts en .py
ou .pyw
). Le lanceur est installé dans le répertoire de Windows (et est donc automatiquement dans le PATH
qui liste les exécutables – mais nécessite des droits d’administration pour être installé).
PEP 418 — Fonctions de gestion du temps
Nouvelles fonctions de mesure du temps apparaissent dans le module time
: monotonic()
(non touchée par des ajustements de l’horloge, par exemple par NTP), perf_counter()
(temps précis), process_time()
(consommation de temps processeur utilisateur et système pour le processus).
PEP 420 — Empaquetage
Un module Python, sous forme de répertoire, n’a plus besoin de la présence d’un fichier __init__.py
en son sein pour obtenir le statut de module. De plus, il peut être réparti sur plusieurs dossiers.
PEP 362 — inspect.getsignature()
inspect.getsignature()
offre un format simple et standard pour lire la signature d’une fonction (notamment ses arguments).
Module décimal
Le module decimal
a été réécrit en C et est maintenant jusqu’à 120 fois plus rapide pour les applications qui utilisent intensément les décimales.
Module os
La plupart des fonctions du module os
prenant un nom de fichier en paramètre acceptent maintenant un descripteur de fichier, quand le système de fichiers le supporte. Ceci permet de se prémunir des attaques de type symlink attack, la fonction shutil.rmtree()
est maintenant sûre.
Fonctions de hachage
Le hash randomization est activé par défaut. Il limite les exploits liés aux collisions dans les fonctions de hachage. Voir le courriel http://mail.python.org/pipermail/python-dev/2011-December/115116.html pour plus de détails.
Gestionnaire d’erreur faulthandler
Un nouveau module faulthandler
permet d’afficher le traceback Python (pile d’appels) lors d’un crash.
Divers
- ajout du mode x à la fonction
open()
.open("fichier.txt", "x")
crée le fichier ou échoue s’il existe déjà (création atomique du fichier) ; print("Affiche moi ça immédiatement !", flush=True, end="")
écrit directement la chaîne dans la console (en vidant le cache) ;- les méthodes
subprocess.Popen.communicate()
etthreading.Lock.acquire()
acceptent désormais un argument optionneltimeout
, facilitant la programmation concurrentielle ; - nouvelle méthode
datetime.datetime.timestamp()
qui convertit untimestamp
au format Epoch, l’inverse dedatetime.datetime.fromtimestamp(epoch)
.
On constate avec cette nouvelle version de Python 3 un allègement de la consommation mémoire, grâce au nouveau stockage des chaînes Unicode et grâce aux dictionnaires d’attributs — PEP 393 et 412 respectivement.
Note : les PEP, ou Python Enhancement Proposals sont les documents proposés à la communauté pour les changements / améliorations dans le langage et les bibliothèques, un peu comme les RFC pour les protocoles de l’Internet. Le PEP 001 décrit cette organisation.
Enfin, à l’occasion de cette nouvelle sortie, le thème de la documentation a été entièrement revu, avec des couleurs plus neutres : comparez le thème pour la branche 3.x à celui de la branche 2.x.
# Module 'venv'
Posté par Larry Cow . Évalué à 6.
Cela me semble une bonne nouvelle de voir le Python "officiel" entériner une pratique déjà bien implantée sur le terrain. Mais qu'apporte (ou enlève?) le nouveau module 'venv' par rapport à l'actuel 'virtualenv'? Mis à part le fait de ne pas avoir besoin d'être installé, évidemment…
[^] # Re: Module 'venv'
Posté par GeneralZod . Évalué à 3.
L'intérêt c'est de fournir également les fondations pour construire des outils de plus haut-niveau par dessus comme virtualenvwrapper & cie …
[^] # Re: Module 'venv'
Posté par Antoine . Évalué à 5.
L'intérêt est aussi de ne pas être basé sur des hacks, puisque la mécanique nécessaire à la reconnaissance des environnements virtuels est intégrée à l'interpréteur : là où
virtualenv
recopie des tas de fichiers de la bibliothèque standard (et en patche au moins un),pyvenv
se contente de créer quelques liens symboliques et un fichier de config léger.[^] # Re: Module 'venv'
Posté par Julien Duponchelle (site web personnel) . Évalué à 1.
Moins de bricolage pour les administrateurs système. On peut l'utiliser direct sans avoir besoin de changer des variables d'environnements.
# Enfin !
Posté par morgotth . Évalué à 2.
Excellente nouvelle que cette sortie pour tous les utilisateurs Python, en espérant que les nouveautés tel que le support de la notation u"mon texte" permettent de convaincre les derniers projets à passer à p3k (à suivre sur Hall of Shame).
[^] # Re: Enfin !
Posté par claudex . Évalué à 4.
Sait-on pourquoi ça avait été retiré ?
« Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche
[^] # Re: Enfin !
Posté par Antoine . Évalué à 7.
Parce que les chaînes étant unicode par défaut dans Python 3, l'ancienne notation était sémantiquement superflue (
u"foo"
désigne exactement la même chose que"foo"
).[^] # Re: Enfin !
Posté par claudex . Évalué à 3.
Merci.
« Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche
# speed
Posté par Francky (site web personnel) . Évalué à 1.
le module decimal a été réécrit en C et est désormais bien plus rapide.
La place mémoire réduite pour les chaînes de caractères se traduit aussi par de meilleures performances en terme de vitesse.
Francky, fan de speed sur SPOJ
# Pour tester Python (et apprendre)
Posté par lolop (site web personnel) . Évalué à 8.
Le site Python Tutor permet de tester et tracer des scripts Python2 et Python3 (2.7 et 3.2 pour le moment). L'interface d'exécution pas à pas est très sympa.
info via B.Cordeau
Votez les 30 juin et 7 juillet, en connaissance de cause. http://www.pointal.net/VotesDeputesRN
[^] # Re: Pour tester Python (et apprendre)
Posté par Phil_S . Évalué à 2.
Génial, je ne connaissais pas!
Pour les élèves de la spécialité informatique ISN, ce sera plus simple que le debugger d'Eclipse.
Un grand merci pour eux.
# Journal
Posté par Victor STINNER (site web personnel) . Évalué à 5.
Voir aussi le journal d'Antoine annonçant la release candidate 2 :
https://linuxfr.org/users/pitrou/journaux/python-3-3-0-release-candidate-2
(notamment pour voir les commentaires)
# Python 2, c'est fini
Posté par flan (site web personnel) . Évalué à 7.
Au passage, il n'y aura pas de Python 2.8, et il n'y aura plus de nouvelles fonctionnalités sur la branche 2.7.
Il n'y a plus qu'à attendre que les grandes bibliothèques passent toutes à Python 3 pour vraiment lancer le mouvement (PyQt est déjà compatible, Django 1.5 le sera, SQLAlchemy fonctionne, Matplotlib est bien avancé, il semble rester encore du boulot pour Twisted, PiL n'est pas être prête).
# Made in France
Posté par Philippe F (site web personnel) . Évalué à 3.
Python est un projet collaboratif international, mais je salue quand même le travail considérable qui a été fait par nos deux développeurs français sur cette version, à savoir Antoine Pitrou et Victor Stinner. Et en plus, ils lisent linuxfr !
Petite question sur le yield from: est-ce que c'est juste de la simplification de syntaxe, ou est-ce que on peut en attendre des légers gains de vitesse si on l'utilise par rapport à l'ancien idiome ?
[^] # Re: Made in France
Posté par El Titi . Évalué à 3.
Et Tarek Ziadé non ?
[^] # Re: Made in France
Posté par GeneralZod . Évalué à 3.
Il n'a qu'à venir mouler icitte plus souvent ! :P
# strings: Optimisation mémoire vs cpu?
Posté par NilugeKiWi . Évalué à 2.
L'optimisation en occupation mémoire des chaînes de caractères n'a-t-elle pas un impact en performance cpu?
Par exmple il y a probablement plus de conversions à la volée maintenant lorsqu'on itère sur les caractères non?
Ou encore la concaténation de chaînes stockées sur différentes tailles de caractères…
Y a-t-il des benchmarks sur ce point?
[^] # Re: strings: Optimisation mémoire vs cpu?
Posté par Michaël (site web personnel) . Évalué à 2. Dernière modification le 03 octobre 2012 à 17:35.
Je pense que toutes les chaînes sont probablement codées en interne dans un format bien défini (je veux dire, choisi une fois pour toutes), il n'y a donc pas de conversion à la volée en lecture des caractères (hormis du padding).
L'expression latin1 ou latin9 du texte signifie probablement que les caractères sont ceux du latin1 ou latin9, pas que la chaîne et codée en interne dans l'un ou l'autre de ces codages.
Enfin, comme Python est plutôt un langage de haut niveau, je suspecte la concaténation des chaînes de se faire en temps constant, sans copie de caractères, jsute en se souvenant qu'après la chaîne a il y a la cahine b. Cela n'est possible que parceque les chaînes sont constantes, et signifie que la lecture des caractères se fait avec une indirection.
[^] # Re: strings: Optimisation mémoire vs cpu?
Posté par NilugeKiWi . Évalué à 2.
D'après la PEP-393 il y a bien plusieurs représentations possibles de la string en interne.
Cependant ça concerne uniquement la représentation unicode. La PEP parle d'ascii car c'est un sous ensemble de l'UTF-8: toute chaîne de caractère ascii peut être lue comme une chaîne UTF-8.
Il y a donc bien une conversion à la volée des caractères entre l'encodage interne qui peut être de l'UTF-8, UTF-16 ou UTF-32, et la représentation publique, au moins dans les cas où on accède aux caractères directement (ils sont convertis en code-point unicode). Cela dit cette conversion était aussi faite avant.
Pour la concaténation effectivement je ne sais pas si c'est réellement un problème.
Cependant dans la PEP ils précisent:
> A new function PyUnicode_AsUTF8 is provided to access the UTF-8 representation. It is thus identical to the existing _PyUnicode_AsString, which is removed. The function will compute the utf8 representation when first called. Since this representation will consume memory until the string object is released, applications should use the existing PyUnicode_AsUTF8String where possible (which generates a new string object every time). APIs that implicitly converts a string to a char* (such as the ParseTuple functions) will use PyUnicode_AsUTF8 to compute a conversion.
Ce qui veut bien dire qu'il y a des méthodes utilisées qui font de la conversion à la volée.
Cf aussi la liste des fonctions et macros de leur nouvelle API.
[^] # Re: strings: Optimisation mémoire vs cpu?
Posté par Michaël (site web personnel) . Évalué à 2.
Le choix de UTF-8 16 ou 32 pour la représentation interne est fait pour que tu n'utilises jamais un codage multi mot (le mot fait 8 bits en UTF-8, 16 bits en UTF-16 et 32 bits en UTF-32): la conversion en question est juste d'ajouter les bits nuls manquant à tes points unicode. Je ne parlerais pas vraiment de conversion mais plutôt de convention pour accéder à la mémoire. (Au niveau assembleur, tu fais xor eax, eax pour annuler eax, puis tu choisis de lire ton caractère de 8 16 ou 32 bits en faisant un mov vers ah, ax ou eax et puis c'est tout.)
Je ne sais pas très bien ce que tu veux dire par «à la volée» mais cela me semble raisonnable qu'une fonction explicitement appelée déclenche un calcul.
[^] # Re: strings: Optimisation mémoire vs cpu?
Posté par Antoine . Évalué à 5. Dernière modification le 03 octobre 2012 à 20:29.
Itérer sur les caractères est une opération triviale et, dans ce cas, c'est la boucle d'évaluation de CPython qui sera le facteur dominant.
Par contre, là où ça peut être plus lent, c'est dans certaines créations de chaînes en combinant des chaînes utilisant des représentations différentes (par exemple : une concaténation, ou bien un appel à la méthode str.replace()). Cela ne se remarquera vraiment que sur des chaînes très longues, donc pas les cas les plus courants.
(en contrepartie, il y a aussi certaines opérations qui deviennent plus rapides, par exemple décoder en utf-8 une chaîne d'octets qui s'avérerait être purement ASCII : ce cas est optimisé comme un simple memcpy())
[^] # Re: strings: Optimisation mémoire vs cpu?
Posté par Victor STINNER (site web personnel) . Évalué à 7.
L'optimisation en occupation mémoire des chaînes de caractères n'a-t-elle pas un impact en performance cpu?
Côté positif : certaines opérations sont beaucoup plus rapide, notamment quand on manipule des chaînes de caractère "ASCII" :
http://docs.python.org/dev/whatsnew/3.3.html#optimizations
En gros : copier N caractères ASCII (stockés dans le format "UCS-1") nécessite de copier N octets, alors que copier N caractères stockés dans le format UCS-4 (Python 3.2 sous Linux) nécessite de copier 4*N octets. Par exemple, str[a:b] copie des caractères. Et comme l'a écrit Antoine : encoder une chaîne Unicode "de type ASCII" en UTF-8 revient simplement à faire un "memcpy" (en gros), ce qui est ultra rapide (comparé à l'encodeur de Python 2.7 et 3.2).
Côté négatif : les opérations manipulant des chaînes utilisant différents formats nécessitent de convertir les chaînes vers le même format. Par exemple, "10€".replace("", " ") nécessite de convertir "_" du format UCS-1 au format UCS-2. Idem pour "10 " + "€".
Créer une chaîne de caractère nécessite de connaître le caractère "maximum" (code Unicode le plus grand), ce qui nécessite de lire l'ensemble des caractères de la chaîne. Cette opération est coûteuse.
Le bilan est mitigé car certaines opérations sont plus lentes, mais d'un autre, certaines fonctions ont été optimisées. Dans le meilleur des cas, certaines opérations Unicode avec Python 3.3 sont désormais plus rapides que ces opérations sur des octets avec Python 2.7 !
Je ne connais pas de benchmark "global". Il existe divers micro-benchmarks qui ne sont pas représentatifs. En tout cas, il est sûr que la consommation mémoire est bien meilleure !
# Packaging
Posté par sifu . Évalué à 3.
Il n'était pas sensé y avoir des nouveautés sur le packaging.
J'ai vu lu quelques truc sur sujet mais j'avoue ne pas trop savoir où cela va …
[^] # Re: Packaging
Posté par Antoine . Évalué à 4.
Malheureusement, le nouveau module packaging, qui était censé remplacer distutils en l'améliorant, a été retiré au dernier moment :
http://mail.python.org/pipermail/python-dev/2012-June/120430.html
Le projet existe toujours de manière indépendante (sous le nom distutils2), mais le moins qu'on puisse dire est que son développement est très léthargique :
https://bitbucket.org/python_mirrors/distutils2/
[^] # Re: Packaging
Posté par sifu . Évalué à 2.
C'est le moins qu'on puisse dire ;)
Le lien http://docs.python.org/dev/packaging qu'on retrouve un peu partout est HS.
Le guide proposé ici http://guide.python-distribute.org/index.html que j'avais trouvé fort pratique ne me semble plus trop d'actualité.
J'ai trouvé quelques éléments ici:
https://groups.google.com/forum/#!msg/python-ideas/WgTcHUwtEoU/y_bj-bxWM9EJ
Et là:
https://plus.google.com/u/0/115362263245161504841/posts/UcBQK8P4jw3
Tarek Ziadé avait fait quelques posts sur son blog pour faire un peu bouger les choses.
Mais, j'ai l'impression que les choses sont toujours un peu floue.
C'est ballot, j'ai l'impression que cela manque un peu à Python. J'ai souvenir que j'avais un peu souffert de l'installation de pip sous Windows et je m'étais dit à l'époque qu'il manquait cela aux batteries de Python.
[^] # Re: Packaging
Posté par Antoine . Évalué à 3.
Oui, c'est un gros gâchis, surtout qu'il a été décidé, quand packaging a été lancé, de ne plus toucher à distutils, même pour corriger certains bugs (au prétexte que cela risquerait de casser la compatibilité).
On se retrouve donc sans packaging et sans améliorations dans distutils non plus.
Du coup, un autre projet a été lancé, distlib (*), qui vise à fournir certaines briques de base de packaging sous forme d'API utilisables par d'autres outils, afin de contourner (temporairement) le problème du remplacement de distutils. À suivre…
(*) https://bitbucket.org/vinay.sajip/distlib/src
[^] # Re: Packaging
Posté par flan (site web personnel) . Évalué à 1.
Just par curiosité, quels sont les problèmes de distutils ? Je m'en sers régulièrement (pour faire des .deb et des .tar.gz de mes modules Python), et je trouve que cela fonctionne plutôt bien :)
# Concertant l'empaquetage (PEP 420)
Posté par godzom . Évalué à 6.
Il est dit dans la dépêche:
« Un module Python, sous forme de répertoire, n’a plus besoin de la présence d’un fichier
__init__.py
en son sein pour obtenir le statut de module. De plus, il peut être réparti sur plusieurs dossiers. »Je pense que c'est une erreur, l'auteur a certainement voulu parler de package. Ajourd'hui un package est un répertoire contenant un fichier
__init__.py
(qui peut être vide), et selon la PEP 420 les packages peuvent maintenant être répartis sur plusieurs répertoires.Le module c'est le fichier .py
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.