{"id":38649,"date":"2019-10-31T22:25:04","date_gmt":"2019-10-31T19:25:04","guid":{"rendered":"https:\/\/prohoster.info\/blog\/put-k-proverke-tipov-4-millionov-strok-python-koda-chast-3\/"},"modified":"2019-10-31T22:25:04","modified_gmt":"2019-10-31T19:25:04","slug":"put-k-proverke-tipov-4-millionov-strok-python-koda-chast-3","status":"publish","type":"post","link":"https:\/\/prohoster.info\/fr\/blog\/administrirovanie\/put-k-proverke-tipov-4-millionov-strok-python-koda-chast-3","title":{"rendered":"Le chemin vers la v\u00e9rification des types de 4 millions de lignes de code Python. Partie 3","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Nous vous pr\u00e9sentons la troisi\u00e8me partie de la traduction du mat\u00e9riel sur le chemin parcouru par l'entreprise Dropbox lors de la mise en \u0153uvre d'un syst\u00e8me de v\u00e9rification des types du code Python.<\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/ruvds\/blog\/468237\/\"><img decoding=\"async\" alt=\"Le chemin vers la v\u00e9rification des types de 4 millions de lignes de code Python. Partie 3\" src=\"\/wp-content\/uploads\/2019\/10\/757669265e870de604388c66adef814d.png\" style=\"display:block;margin: 0 auto;\" \/><\/a><\/noindex><\/p>\n<p>\u2192 Parties pr\u00e9c\u00e9dentes : <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/ruvds\/blog\/468233\/\">la premi\u00e8re<\/a><\/noindex> et <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/ruvds\/blog\/468235\/\">la deuxi\u00e8me<\/a><\/noindex><br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2>Atteindre 4 millions de lignes de code typ\u00e9es<\/h2>\n<p>\nUne autre t\u00e2che importante (c'\u00e9tait le deuxi\u00e8me probl\u00e8me le plus populaire, pr\u00e9occupant ceux qui participaient aux enqu\u00eates internes) \u00e9tait d'augmenter le volume de code dans Dropbox couvert par des v\u00e9rifications de types. Nous avons essay\u00e9 plusieurs approches pour relever ce d\u00e9fi - allant de la croissance naturelle du volume de la base de code typ\u00e9e \u00e0 la concentration des efforts des membres de l'\u00e9quipe mypy sur l'inf\u00e9rence de type statique et dynamique automatis\u00e9e. Au final, il semblait qu'il n'y avait pas de strat\u00e9gie gagnante simple, mais nous avons r\u00e9ussi \u00e0 atteindre une croissance rapide du volume de code annot\u00e9 en combinant plusieurs approches.<\/p>\n<p>En cons\u00e9quence, dans notre plus grand d\u00e9p\u00f4t Python (avec le code back-end), le nombre de lignes de code annot\u00e9 a atteint presque 4 millions. Le travail de typage statique du code a \u00e9t\u00e9 r\u00e9alis\u00e9 en environ trois ans. Mypy prend d\u00e9sormais en charge divers types de rapports sur la couverture du code par des types, qui facilitent le suivi de l'avancement de la typisation. En particulier, nous pouvons g\u00e9n\u00e9rer des rapports sur le code comportant des incertitudes de type, telles que l'utilisation explicite de type <code>Any<\/code> dans les annotations, qui ne peuvent pas \u00eatre v\u00e9rifi\u00e9es, ou telles que l'importation de biblioth\u00e8ques tierces, pour lesquelles il n'y a pas d'annotations de types. Dans le cadre de notre projet visant \u00e0 am\u00e9liorer la pr\u00e9cision des v\u00e9rifications de types dans Dropbox, nous avons contribu\u00e9 \u00e0 l'am\u00e9lioration des d\u00e9finitions de types (les soi-disant fichiers stub) pour certaines biblioth\u00e8ques open source populaires dans le d\u00e9p\u00f4t Python centralis\u00e9 <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/python\/typeshed\">typeshed<\/a><\/noindex>.<\/p>\n<p>Nous avons mis en \u0153uvre (et normalis\u00e9 dans les PEP suivants) de nouvelles fonctionnalit\u00e9s du syst\u00e8me de types, permettant d'utiliser des types plus pr\u00e9cis pour certains mod\u00e8les Python sp\u00e9cifiques. Un exemple notable de cela est <code>TypeDict<\/code>, qui fournit des types pour les dictionnaires similaires \u00e0 JSON ayant un ensemble fixe de cl\u00e9s de cha\u00eene, chacune ayant une valeur de son propre type. Nous continuerons \u00e0 d\u00e9velopper le syst\u00e8me de types. Il est probable que notre prochaine \u00e9tape sera d'am\u00e9liorer le support des fonctionnalit\u00e9s Python en mati\u00e8re de traitement des nombres.<\/p>\n<p><img decoding=\"async\" alt=\"Le chemin vers la v\u00e9rification des types de 4 millions de lignes de code Python. Partie 3\" src=\"\/wp-content\/uploads\/2019\/10\/297b9e823141d6cb0d2f19f9a78a1153.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Nombre de lignes de code annot\u00e9es : serveur<\/i><\/p>\n<p><img decoding=\"async\" alt=\"Le chemin vers la v\u00e9rification des types de 4 millions de lignes de code Python. Partie 3\" src=\"\/wp-content\/uploads\/2019\/10\/c183a9227e51d847bfdb2b8f6153684f.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Nombre de lignes de code annot\u00e9es : client<\/i><\/p>\n<p><img decoding=\"async\" alt=\"Le chemin vers la v\u00e9rification des types de 4 millions de lignes de code Python. Partie 3\" src=\"\/wp-content\/uploads\/2019\/10\/0a8b936fa454a34c09a9c6a2694485c9.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Nombre total de lignes de code annot\u00e9es<\/i><\/p>\n<p>Voici un aper\u00e7u des principales caract\u00e9ristiques des actions que nous avons men\u00e9es pour augmenter le volume de code annot\u00e9 dans Dropbox :<\/p>\n<p>Rigueur de l'annotation. Nous avons progressivement augment\u00e9 les exigences de rigueur pour l'annotation du nouveau code. Nous avons commenc\u00e9 par des conseils de linter qui sugg\u00e9raient d'ajouter des annotations dans les fichiers d\u00e9j\u00e0 annot\u00e9s. Maintenant, nous exigeons la pr\u00e9sence d'annotations de type dans les nouveaux fichiers Python et dans la plupart des fichiers existants.<\/p>\n<p>Rapports de typage. Nous envoyons chaque semaine des rapports aux \u00e9quipes sur le niveau de typage de leur code et fournissons des conseils sur ce qu'il convient d'annoter en priorit\u00e9.<\/p>\n<p>Promotion de mypy. Nous parlons de mypy lors de divers \u00e9v\u00e9nements et \u00e9changeons avec les \u00e9quipes pour les aider \u00e0 commencer \u00e0 utiliser des annotations de type.<\/p>\n<p>Sondages. Nous menons des sondages p\u00e9riodiques aupr\u00e8s des utilisateurs pour identifier les probl\u00e8mes majeurs. Nous sommes pr\u00eats \u00e0 aller assez loin pour r\u00e9soudre ces probl\u00e8mes (jusqu'\u00e0 cr\u00e9er un nouveau langage pour acc\u00e9l\u00e9rer mypy !).<\/p>\n<p>Performance. Nous avons consid\u00e9rablement am\u00e9lior\u00e9 les performances de mypy gr\u00e2ce \u00e0 l'utilisation d'un daemon et de mypyc. Cela a \u00e9t\u00e9 fait pour r\u00e9duire les d\u00e9sagr\u00e9ments rencontr\u00e9s lors de l'annotation et pour pouvoir travailler avec de grands volumes de code.<\/p>\n<p>Int\u00e9gration avec les \u00e9diteurs. Nous avons cr\u00e9\u00e9 des outils pour prendre en charge l'ex\u00e9cution de mypy dans les \u00e9diteurs populaires chez Dropbox. Cela inclut PyCharm, Vim et VS Code. Cela a consid\u00e9rablement simplifi\u00e9 le processus d'annotation du code et de v\u00e9rification de sa fonctionnalit\u00e9. De telles actions sont g\u00e9n\u00e9ralement caract\u00e9ristiques de l'annotation de code existant.<\/p>\n<p>Analyse statique. Nous avons cr\u00e9\u00e9 un outil pour g\u00e9n\u00e9rer des signatures de fonction en utilisant des m\u00e9thodes d'analyse statique. Cet outil ne fonctionne que dans des situations relativement simples, mais il nous a aid\u00e9s \u00e0 augmenter sans effort la couverture du code par des types.<\/p>\n<p>Support pour les biblioth\u00e8ques tierces. Dans de nombreux projets, nous utilisons l'ensemble d'outils SQLAlchemy. Il exploite les capacit\u00e9s dynamiques de Python, que les types PEP 484 ne peuvent pas mod\u00e9liser directement. Conform\u00e9ment \u00e0 PEP 561, nous avons cr\u00e9\u00e9 un fichier stub correspondant et \u00e9crit un plugin pour mypy (<noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/dropbox\/sqlalchemy-stubs\">open source<\/a><\/noindex>), am\u00e9liorant le support de SQLAlchemy.<\/p>\n<h2>Les difficult\u00e9s rencontr\u00e9es<\/h2>\n<p>\nLe chemin vers 4 millions de lignes de code typ\u00e9 n'a pas toujours \u00e9t\u00e9 facile. Sur cette route, nous avons rencontr\u00e9 de nombreux obstacles et commis quelques erreurs. Voici quelques-uns des probl\u00e8mes que nous avons rencontr\u00e9s. Nous esp\u00e9rons que notre r\u00e9cit aidera d'autres \u00e0 \u00e9viter des probl\u00e8mes similaires.<\/p>\n<p>Fichiers manquants. Nous avons commenc\u00e9 \u00e0 travailler en v\u00e9rifiant un petit volume de fichiers. Tout ce qui ne faisait pas partie de ces fichiers n'\u00e9tait pas v\u00e9rifi\u00e9. Les fichiers \u00e9taient ajout\u00e9s \u00e0 la liste de v\u00e9rification lorsqu'ils recevaient leurs premi\u00e8res annotations. Si quelque chose \u00e9tait import\u00e9 d'un module situ\u00e9 en dehors de la zone de v\u00e9rification, il s'agissait de travailler avec des valeurs de type <code>Any<\/code>, qui n'\u00e9taient pas du tout v\u00e9rifi\u00e9es. Cela a conduit \u00e0 une perte significative de pr\u00e9cision de typage, surtout au d\u00e9but de la migration. Cette approche a n\u00e9anmoins fonctionn\u00e9 de mani\u00e8re \u00e9tonnamment efficace, bien qu'il soit courant que l'ajout de fichiers \u00e0 la zone de v\u00e9rification r\u00e9v\u00e8le des probl\u00e8mes dans d'autres parties de la base de code. Dans le pire des cas, lorsque deux zones de code isol\u00e9es, dans lesquelles les types avaient d\u00e9j\u00e0 \u00e9t\u00e9 v\u00e9rifi\u00e9s de mani\u00e8re ind\u00e9pendante, \u00e9taient fusionn\u00e9es, il s'est av\u00e9r\u00e9 que les types de ces zones \u00e9taient incompatibles. Cela a n\u00e9cessit\u00e9 de nombreuses modifications dans les annotations. En regardant en arri\u00e8re, nous comprenons maintenant que nous aurions d\u00fb ajouter le module de biblioth\u00e8que de base \u00e0 la zone de v\u00e9rification des types mypy le plus t\u00f4t possible. Cela aurait rendu notre travail beaucoup plus pr\u00e9visible.<\/p>\n<p>Annotation du code ancien. Lorsque nous avons commenc\u00e9, nous avions environ 4 millions de lignes de code Python existant. Il \u00e9tait clair que l'annotation de tout ce code \u00e9tait une t\u00e2che complexe. Nous avons cr\u00e9\u00e9 un outil appel\u00e9 PyAnnotate, qui peut collecter des informations sur les types pendant l'ex\u00e9cution des tests et ajouter des annotations de types au code, bas\u00e9es sur les informations recueillies. Cependant, nous n'avons pas constat\u00e9 une adoption particuli\u00e8rement large de cet outil. La collecte d'informations sur les types \u00e9tait lente, et les annotations g\u00e9n\u00e9r\u00e9es automatiquement n\u00e9cessitaient souvent de nombreux ajustements manuels. Nous avons envisag\u00e9 d'ex\u00e9cuter cet outil automatiquement \u00e0 chaque v\u00e9rification de code, ou de collecter des informations sur les types en nous basant sur l'analyse d'un petit volume de requ\u00eates r\u00e9seau r\u00e9elles, mais avons finalement d\u00e9cid\u00e9 de ne pas le faire, car chacun de ces approches \u00e9tait trop risqu\u00e9.<\/p>\n<p>En fin de compte, on peut noter que la majorit\u00e9 du code a \u00e9t\u00e9 annot\u00e9e manuellement par ses propri\u00e9taires. Pour orienter ce processus dans la bonne direction, nous pr\u00e9parons des rapports sur des modules et fonctions particuli\u00e8rement importants \u00e0 annoter. Par exemple, il est essentiel d'annoter le module de biblioth\u00e8que utilis\u00e9 dans des centaines d'endroits. En revanche, annoter un ancien service qui est remplac\u00e9 par un nouveau est moins crucial. De plus, nous exp\u00e9rimentons l'utilisation de l'analyse statique pour g\u00e9n\u00e9rer des annotations de types pour le code ancien.<\/p>\n<p>Importations circulaires. J'ai mentionn\u00e9 plus haut les importations circulaires (les \u00ab n\u0153uds de d\u00e9pendances \u00bb), dont l'existence a compliqu\u00e9 l'acc\u00e9l\u00e9ration de mypy. De plus, nous avons d\u00fb travailler s\u00e9rieusement pour fournir \u00e0 mypy une prise en charge de tous les types d'idiomes, dont l'origine est due \u00e0 ces importations circulaires. R\u00e9cemment, nous avons termin\u00e9 un grand projet de refonte du syst\u00e8me qui a r\u00e9solu la plupart des probl\u00e8mes de mypy li\u00e9s aux importations circulaires. Ces probl\u00e8mes provenaient en r\u00e9alit\u00e9 des premiers jours du projet, depuis Alore, le langage d'apprentissage sur lequel mypy \u00e9tait initialement bas\u00e9. La syntaxe d'Alore permettait de r\u00e9soudre facilement les probl\u00e8mes des cycles d'importation. Le mypy moderne a h\u00e9rit\u00e9 de certaines limitations de sa premi\u00e8re impl\u00e9mentation rudimentaire (qui convenait parfaitement \u00e0 Alore). Python complique la gestion des importations circulaires principalement en raison de l'ambigu\u00eft\u00e9 des expressions. Par exemple, lors d'une op\u00e9ration d'assignation, un alias de type peut en r\u00e9alit\u00e9 \u00eatre d\u00e9fini. Mypy ne parvient pas toujours \u00e0 d\u00e9tecter ce genre de choses tant que la majeure partie du cycle d'importation n'est pas trait\u00e9e. Dans Alore, ces ambigu\u00eft\u00e9s n'existaient pas. Les solutions inappropri\u00e9es prises aux premiers stades de d\u00e9veloppement du syst\u00e8me peuvent r\u00e9server des surprises d\u00e9sagr\u00e9ables au programmeur des ann\u00e9es plus tard.<\/p>\n<h2>Bilan : le chemin vers 5 millions de lignes de code et de nouveaux horizons<\/h2>\n<p>\nLe projet mypy a parcouru un long chemin \u2014 des premiers prototypes \u00e0 un syst\u00e8me qui contr\u00f4le les types d'un code de production de 4 millions de lignes. Au fur et \u00e0 mesure de l'\u00e9volution de mypy, une normalisation des annotations de types en Python a \u00e9t\u00e9 r\u00e9alis\u00e9e. Aujourd'hui, une puissante \u00e9cosyst\u00e8me s'est d\u00e9velopp\u00e9e autour de la typage du code Python. Elle inclut le soutien de biblioth\u00e8ques, des outils auxiliaires pour les IDE et les \u00e9diteurs, et plusieurs syst\u00e8mes de v\u00e9rification des types, chacun ayant ses avantages et ses inconv\u00e9nients.<\/p>\n<p>Bien que la v\u00e9rification des types soit d\u00e9j\u00e0 per\u00e7ue chez Dropbox comme un acquis, je suis convaincu que nous vivons encore \u00e0 l'aube de la typage du code Python. Je pense que les technologies de v\u00e9rification des types continueront \u00e0 \u00e9voluer et \u00e0 s'am\u00e9liorer.<\/p>\n<p>Si vous n'avez pas encore utilis\u00e9 les v\u00e9rifications de types dans votre projet Python \u00e0 grande \u00e9chelle, sachez que c'est le moment id\u00e9al pour commencer la transition vers la typage statique. J'ai discut\u00e9 avec ceux qui ont fait ce changement. Aucun d'entre eux ne le regrette. Le contr\u00f4le des types transforme Python en un langage beaucoup plus adapt\u00e9 \u00e0 la d\u00e9veloppement de grands projets que le \u00ab Python classique \u00bb.<\/p>\n<p><b>Chers lecteurs !<\/b> Utilisez-vous le contr\u00f4le des types dans vos projets Python ?<\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/ruvds.com\/vps_start\/\"><img decoding=\"async\" alt=\"Le chemin vers la v\u00e9rification des types de 4 millions de lignes de code Python. Partie 3\" src=\"\/wp-content\/uploads\/2019\/10\/bf2bc557ce4481dd87398515bff60e3f.png\" style=\"display:block;margin: 0 auto;\" \/><\/a><\/noindex><br \/>\n<noindex><a rel=\"nofollow\" href=\"https:\/\/ruvds.com\/ru-rub\/#order\"><img decoding=\"async\" alt=\"Le chemin vers la v\u00e9rification des types de 4 millions de lignes de code Python. Partie 3\" src=\"\/wp-content\/uploads\/2019\/10\/098d481c25b3afaba9534c686e8f943a.png\" style=\"display:block;margin: 0 auto;\" \/><\/a><\/noindex><br \/>\n<br \/>Source : <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/ruvds\/blog\/468237\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u0432\u0430\u0448\u0435\u043c\u0443 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044e \u0442\u0440\u0435\u0442\u044c\u044e \u0447\u0430\u0441\u0442\u044c \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0430 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u0430 \u043e \u043f\u0443\u0442\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u043e\u0448\u043b\u0430 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u044f Dropbox, \u0432\u043d\u0435\u0434\u0440\u044f\u044f \u0443 \u0441\u0435\u0431\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0442\u0438\u043f\u043e\u0432 Python-\u043a\u043e\u0434\u0430. \u2192 \u041f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0435 \u0447\u0430\u0441\u0442\u0438: \u043f\u0435\u0440\u0432\u0430\u044f \u0438 \u0432\u0442\u043e\u0440\u0430\u044f \u0414\u043e\u0441\u0442\u0438\u0436\u0435\u043d\u0438\u0435 4 \u043c\u0438\u043b\u043b\u0438\u043e\u043d\u043e\u0432 \u0441\u0442\u0440\u043e\u043a \u0442\u0438\u043f\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430 \u0415\u0449\u0451 \u043e\u0434\u043d\u043e\u0439 \u0432\u0430\u0436\u043d\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0435\u0439 (\u044d\u0442\u043e \u0431\u044b\u043b \u0432\u0442\u043e\u0440\u0430\u044f \u043f\u043e \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u043e\u0441\u0442\u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430, \u0432\u043e\u043b\u043d\u043e\u0432\u0430\u0432\u0448\u0430\u044f \u0442\u0435\u0445, \u043a\u0442\u043e \u0443\u0447\u0430\u0441\u0442\u0432\u043e\u0432\u0430\u043b \u0432\u043e \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0445 \u043e\u043f\u0440\u043e\u0441\u0430\u0445) \u0431\u044b\u043b\u043e \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u0435 \u043e\u0431\u044a\u0451\u043c\u0430 \u043a\u043e\u0434\u0430 \u0432 Dropbox, [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":28992,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-38649","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.2.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u0432\u0430\u0448\u0435\u043c\u0443 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044e \u0442\u0440\u0435\u0442\u044c\u044e \u0447\u0430\u0441\u0442\u044c \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0430 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u0430 \u043e \u043f\u0443\u0442\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u043e\u0448\u043b\u0430 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u044f Dropbox, \u0432\u043d\u0435\u0434\u0440\u044f\u044f \u0443 \u0441\u0435\u0431\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0442\u0438\u043f\u043e\u0432 Python-\u043a\u043e\u0434\u0430.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/fr\/blog\/administrirovanie\/put-k-proverke-tipov-4-millionov-strok-python-koda-chast-3\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.2.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"fr_FR\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u041f\u0443\u0442\u044c \u043a \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0435 \u0442\u0438\u043f\u043e\u0432 4 \u043c\u0438\u043b\u043b\u0438\u043e\u043d\u043e\u0432 \u0441\u0442\u0440\u043e\u043a Python-\u043a\u043e\u0434\u0430. \u0427\u0430\u0441\u0442\u044c 3 | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u0432\u0430\u0448\u0435\u043c\u0443 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044e \u0442\u0440\u0435\u0442\u044c\u044e \u0447\u0430\u0441\u0442\u044c \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0430 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u0430 \u043e \u043f\u0443\u0442\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u043e\u0448\u043b\u0430 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u044f Dropbox, \u0432\u043d\u0435\u0434\u0440\u044f\u044f \u0443 \u0441\u0435\u0431\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0442\u0438\u043f\u043e\u0432 Python-\u043a\u043e\u0434\u0430.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/fr\/blog\/administrirovanie\/put-k-proverke-tipov-4-millionov-strok-python-koda-chast-3\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-10-31T19:25:04+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2019-10-31T19:25:04+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Le chemin vers la v\u00e9rification des types de 4 millions de lignes de code Python. Partie 3 | ProHoster","description":"Nous vous pr\u00e9sentons la troisi\u00e8me partie de la traduction du mat\u00e9riel sur le chemin parcouru par l'entreprise Dropbox lors de la mise en \u0153uvre d'un syst\u00e8me de v\u00e9rification des types du code Python.","canonical_url":"https:\/\/prohoster.info\/fr\/blog\/administrirovanie\/put-k-proverke-tipov-4-millionov-strok-python-koda-chast-3","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"fr_FR","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u041f\u0443\u0442\u044c \u043a \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0435 \u0442\u0438\u043f\u043e\u0432 4 \u043c\u0438\u043b\u043b\u0438\u043e\u043d\u043e\u0432 \u0441\u0442\u0440\u043e\u043a Python-\u043a\u043e\u0434\u0430. \u0427\u0430\u0441\u0442\u044c 3 | ProHoster","og:description":"\u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u0432\u0430\u0448\u0435\u043c\u0443 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044e \u0442\u0440\u0435\u0442\u044c\u044e \u0447\u0430\u0441\u0442\u044c \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0430 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u0430 \u043e \u043f\u0443\u0442\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u043e\u0448\u043b\u0430 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u044f Dropbox, \u0432\u043d\u0435\u0434\u0440\u044f\u044f \u0443 \u0441\u0435\u0431\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0442\u0438\u043f\u043e\u0432 Python-\u043a\u043e\u0434\u0430.","og:url":"https:\/\/prohoster.info\/fr\/blog\/administrirovanie\/put-k-proverke-tipov-4-millionov-strok-python-koda-chast-3","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2019-10-31T19:25:04+00:00","article:modified_time":"2019-10-31T19:25:04+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"38649","title":null,"description":null,"keywords":null,"keyphrases":{"focus":[],"additional":[]},"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":"2026-01-23 22:54:19","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-03-01 01:05:23","updated":"2026-08-11 12:50:30","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/posts\/38649","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/comments?post=38649"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/posts\/38649\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/media\/28992"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/media?parent=38649"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/categories?post=38649"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/tags?post=38649"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}