{"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\/sq\/blog\/administrirovanie\/put-k-proverke-tipov-4-millionov-strok-python-koda-chast-3","title":{"rendered":"Rruga drejt kontrollit t\u00eb tipeve t\u00eb 4 milion rreshtave t\u00eb kodit Python. Pjesa 3","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Ju hapim\u00eb t\u00eb paraqesim pjes\u00ebn e tret\u00eb t\u00eb p\u00ebrkthimit t\u00eb materialit mbi udh\u00ebn q\u00eb ka ndjekur kompania Dropbox, duke implementuar sistemin e verifikimit t\u00eb llojeve t\u00eb kodit Python.<\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/ruvds\/blog\/468237\/\"><img decoding=\"async\" alt=\"Rruga drejt kontrollit t\u00eb tipeve t\u00eb 4 milion rreshtave t\u00eb kodit Python. Pjesa 3\" src=\"\/wp-content\/uploads\/2019\/10\/757669265e870de604388c66adef814d.png\" style=\"display:block;margin: 0 auto;\" \/><\/a><\/noindex><\/p>\n<p>\u2192 Pjes\u00ebt e m\u00ebparshme: <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/ruvds\/blog\/468233\/\">e par\u00eb<\/a><\/noindex> dhe <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/ruvds\/blog\/468235\/\">e dyta<\/a><\/noindex><br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2>Arritja e 4 milion linjave t\u00eb kodit t\u00eb tipizuar<\/h2>\n<p>\nNj\u00eb tjet\u00ebr detyr\u00eb e r\u00ebnd\u00ebsishme (kjo ishte problemi i dyt\u00eb m\u00eb i popullarizuar, q\u00eb shqet\u00ebsonte ata q\u00eb mor\u00ebn pjes\u00eb n\u00eb anketat e brendshme) ishte t\u00eb rritej sasia e kodit n\u00eb Dropbox q\u00eb ishte mbuluar nga kontrolli i llojeve. Ne provuam disa qasje p\u00ebr t\u00eb zgjidhur k\u00ebt\u00eb detyr\u00eb - nga rritja natyrale e baz\u00ebs s\u00eb kodit t\u00eb tipizuar deri te p\u00ebrqendrimi i p\u00ebrpjekjeve t\u00eb an\u00ebtar\u00ebve t\u00eb ekipit mypy n\u00eb nxjerrjen automatike statike dhe dinamike t\u00eb llojeve. N\u00eb p\u00ebrfundim, krijohej nj\u00eb p\u00ebrshtypje se nuk kishte nj\u00eb strategji t\u00eb thjesht\u00eb fituese, por arrit\u00ebm nj\u00eb rritje t\u00eb shpejt\u00eb t\u00eb sasis\u00eb s\u00eb kodit t\u00eb annotuar, duke kombinuar shum\u00eb qasje.<\/p>\n<p>Si n\u00eb rezultat\u00eb, n\u00eb depozit\u00ebn ton\u00eb m\u00eb t\u00eb madhe t\u00eb Python-it (me kodin e backend-it), numri i rreshtave t\u00eb kodit t\u00eb annotuar arriti pothuajse n\u00eb 4 milion. Puna p\u00ebr tipizimin statik t\u00eb kodit u b\u00eb p\u00ebr rreth tre vjet. Mypy tani mb\u00ebshtet lloje t\u00eb ndryshme raportesh p\u00ebr mbulimin e kodeve me tipe, t\u00eb cilat thjeshtojn\u00eb v\u00ebzhgimin e p\u00ebrparimit t\u00eb tipizimit. N\u00eb ve\u00e7anti, ne mund t\u00eb formulojm\u00eb raporte p\u00ebr kodin me pasiguri n\u00eb tipe, si ato, p\u00ebr shembull, me p\u00ebrdorimin e qart\u00eb t\u00eb tipeve <code>\u00c7do<\/code> n\u00eb annotimet, t\u00eb cilat nuk mund t\u00eb verifikohen, ose me ato, si importet e bibliotekave t\u00eb jashtme, n\u00eb t\u00eb cilat nuk ka annotime tipesh. Ne, n\u00eb kuad\u00ebr t\u00eb projektit p\u00ebr p\u00ebrmir\u00ebsimin e sakt\u00ebsis\u00eb s\u00eb verifikimit t\u00eb tipave n\u00eb Dropbox, kontribuam n\u00eb p\u00ebrmir\u00ebsimin e definicioneve t\u00eb tipave (t\u00eb ashtuquajturat skedar\u00eb stub) p\u00ebr disa biblioteka t\u00eb njohura open-source n\u00eb depozit\u00ebn qendrore t\u00eb Python-it <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/python\/typeshed\">typeshed<\/a><\/noindex>.<\/p>\n<p>Ne implementuam (dhe standardizuam n\u00eb PEP-t\u00eb e m\u00ebvonshme) mund\u00ebsi t\u00eb reja t\u00eb sistemit t\u00eb tipeve, t\u00eb cilat lejojn\u00eb p\u00ebrdorimin e tipeve m\u00eb t\u00eb sakta p\u00ebr disa modele specifike t\u00eb Python-it. Nj\u00eb shembull i duksh\u00ebm i k\u00ebsaj \u00ebsht\u00eb <code>TypeDict<\/code>, i cili ofron lloje p\u00ebr fjalor\u00eb q\u00eb ngjajn\u00eb me JSON, duke pasur nj\u00eb grup t\u00eb caktuar \u00e7el\u00ebsash string, secili prej t\u00eb cil\u00ebve ka vler\u00ebn e vet tipi. Ne do t\u00eb vazhdojm\u00eb t\u00eb zgjeruam sistemin e tipeve. Me siguri, hapi yn\u00eb i ardhsh\u00ebm do t\u00eb jet\u00eb p\u00ebrmir\u00ebsimi i mb\u00ebshtetjes p\u00ebr funksionalitetet e Python n\u00eb pun\u00ebn me numra.<\/p>\n<p><img decoding=\"async\" alt=\"Rruga drejt kontrollit t\u00eb tipeve t\u00eb 4 milion rreshtave t\u00eb kodit Python. Pjesa 3\" src=\"\/wp-content\/uploads\/2019\/10\/297b9e823141d6cb0d2f19f9a78a1153.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Numri i linjave t\u00eb kodit t\u00eb annotuar: server<\/i><\/p>\n<p><img decoding=\"async\" alt=\"Rruga drejt kontrollit t\u00eb tipeve t\u00eb 4 milion rreshtave t\u00eb kodit Python. Pjesa 3\" src=\"\/wp-content\/uploads\/2019\/10\/c183a9227e51d847bfdb2b8f6153684f.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Numri i linjave t\u00eb kodit t\u00eb annotuar: klient<\/i><\/p>\n<p><img decoding=\"async\" alt=\"Rruga drejt kontrollit t\u00eb tipeve t\u00eb 4 milion rreshtave t\u00eb kodit Python. Pjesa 3\" src=\"\/wp-content\/uploads\/2019\/10\/0a8b936fa454a34c09a9c6a2694485c9.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Numri total i linjave t\u00eb kodit t\u00eb annotuar<\/i><\/p>\n<p>Ja nj\u00eb p\u00ebrmbledhje e karakteristikave kryesore t\u00eb veprimeve q\u00eb kemi b\u00ebr\u00eb p\u00ebr t\u00eb rritur sasin\u00eb e kodit t\u00eb annotuar n\u00eb Dropbox:<\/p>\n<p>Rrept\u00ebsia e annotimit. Ne kemi rritur gradualisht k\u00ebrkesat p\u00ebr rrept\u00ebsin\u00eb e annotimit t\u00eb kodeve t\u00eb reja. Filluam me k\u00ebshilla p\u00ebr linters, q\u00eb sugjeronin shtimin e annotimeve n\u00eb skedar\u00ebt q\u00eb tashm\u00eb kan\u00eb disa annotime. Tani ne k\u00ebrkojm\u00eb q\u00eb t\u00eb ket\u00eb annotime tipesh n\u00eb skedar\u00ebt e rinj Python dhe n\u00eb shumic\u00ebn e skedar\u00ebve ekzistues.<\/p>\n<p>Raportet mbi tipet. Ne d\u00ebrgojm\u00eb raporte \u00e7do jav\u00eb ekipeve mbi nivelin e tipizimit t\u00eb kodit t\u00eb tyre dhe ofrojm\u00eb k\u00ebshilla p\u00ebr at\u00eb q\u00eb duhet t\u00eb annotohet fillimisht.<\/p>\n<p>Promovimi i mypy. Ne flasim p\u00ebr mypy n\u00eb ngjarje t\u00eb ndryshme dhe komunikojm\u00eb me ekipet, duke i ndihmuar ata t\u00eb fillojn\u00eb t\u00eb p\u00ebrdorin anotimet e tipeve.<\/p>\n<p>Anketat. Ne realizojm\u00eb anketa periodike t\u00eb p\u00ebrdoruesve p\u00ebr t\u00eb identifikuar problemet kryesore. Jemi t\u00eb gatsh\u00ebm t\u00eb shkojm\u00eb mjaft larg n\u00eb zgjidhjen e k\u00ebtyre problemeve (madje deri n\u00eb krijimin e nj\u00eb gjuhe t\u00eb re p\u00ebr t\u00eb p\u00ebrshpejtuar mypy!).<\/p>\n<p>Performanca. Ne kemi p\u00ebrmir\u00ebsuar ndjesh\u00ebm performanc\u00ebn e mypy p\u00ebrmes p\u00ebrdorimit t\u00eb demonit dhe mypyc. Kjo \u00ebsht\u00eb b\u00ebr\u00eb p\u00ebr t\u00eb zbutur pengesat q\u00eb ndodhin gjat\u00eb procesit t\u00eb anotimit dhe p\u00ebr t\u00eb pasur mund\u00ebsin\u00eb t\u00eb punojm\u00eb me volume t\u00eb m\u00ebdha kodi.<\/p>\n<p>Integrimi me redaktor\u00ebt. Ne krijuam mjete p\u00ebr t\u00eb mb\u00ebshtetur ekzekutimin e mypy n\u00eb redaktor\u00ebt q\u00eb jan\u00eb t\u00eb njohur n\u00eb Dropbox. K\u00ebtu p\u00ebrfshihen PyCharm, Vim dhe VS Code. Kjo e b\u00ebri procesin e pun\u00ebs p\u00ebr anotimin e kodit dhe verifikimin e funksionalitetit t\u00eb tij shum\u00eb m\u00eb t\u00eb leht\u00eb. Aktivitetet e tilla zakonisht karakterizojn\u00eb anotimin e kodit ekzistues.<\/p>\n<p>Analiza statike. Ne kemi krijuar nj\u00eb mjet p\u00ebr t\u00eb nxjerr\u00eb n\u00ebnshkrimet e funksioneve duke p\u00ebrdorur mjete t\u00eb analiz\u00ebs statike. Ky mjet mund t\u00eb punoj\u00eb vet\u00ebm n\u00eb situata relativisht t\u00eb thjeshta, por na ka ndihmuar pa shum\u00eb p\u00ebrpjekje t\u00eb rrisim mbulimin e kodit me tipe.<\/p>\n<p>Mb\u00ebshtetje p\u00ebr biblioteka t\u00eb jashtme. N\u00eb shum\u00eb nga projektet tona p\u00ebrdoret nj\u00eb set mjetesh SQLAlchemy. Aty p\u00ebrdoren mund\u00ebsit\u00eb dinamike t\u00eb Python, t\u00eb cilat tipet PEP 484 nuk mund t\u00eb modelojn\u00eb drejtp\u00ebrdrejt. N\u00eb p\u00ebrputhje me PEP 561, ne krijuam nj\u00eb skedar stub p\u00ebrkat\u00ebs dhe shkruam nj\u00eb plugin p\u00ebr mypy (<noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/dropbox\/sqlalchemy-stubs\">open source<\/a><\/noindex>), q\u00eb p\u00ebrmir\u00ebson mb\u00ebshtetjen p\u00ebr SQLAlchemy.<\/p>\n<h2>Sfidat me t\u00eb cilat u p\u00ebrball\u00ebm<\/h2>\n<p>\nRruga drejt 4 milion linjave t\u00eb kodit t\u00eb tipizuar nuk ishte gjithmon\u00eb e leht\u00eb p\u00ebr ne. N\u00eb k\u00ebt\u00eb rrug\u00eb has\u00ebm shum\u00eb gropa dhe b\u00ebm\u00eb disa gabime. K\u00ebtu jan\u00eb disa nga problemet me t\u00eb cilat u p\u00ebrball\u00ebm. Shpresojm\u00eb se tregimi yn\u00eb p\u00ebr to do t'u ndihmoj\u00eb t\u00eb tjer\u00ebve t\u00eb shmangin probleme t\u00eb ngjashme.<\/p>\n<p>Skedar t\u00eb humbur. Ne filluam pun\u00ebn me verifikimin e nj\u00eb sasi t\u00eb vog\u00ebl skedar\u00ebsh. Gjith\u00e7ka q\u00eb nuk p\u00ebrfshihej n\u00eb k\u00ebta skedar\u00eb, nuk u kontrollua. Skedar\u00ebt u shtuan n\u00eb list\u00ebn e verifikimit kur ato mor\u00ebn sh\u00ebnime t\u00eb para. N\u00ebse di\u00e7ka importohej nga nj\u00eb modul q\u00eb ndodhej jasht\u00eb zon\u00ebs s\u00eb verifikimit, at\u00ebher\u00eb flitej p\u00ebr pun\u00ebn me vlerat e natyr\u00ebs <code>\u00c7do<\/code>, t\u00eb cilat nuk ishin kontrolluar fare. Kjo shkaktoi nj\u00eb humbje t\u00eb konsiderueshme t\u00eb sakt\u00ebsis\u00eb s\u00eb tipizimit, ve\u00e7an\u00ebrisht n\u00eb fazat e hershme t\u00eb migrimit. Ky qasje ka funksionuar n\u00eb m\u00ebnyr\u00eb befasuese mir\u00eb, megjithat\u00eb, situata tipike ishte ajo kur shtimi i skedar\u00ebve n\u00eb zon\u00ebn e kontrollit zbulonte probleme n\u00eb pjes\u00eb t\u00eb tjera t\u00eb baz\u00ebs s\u00eb kodit. N\u00eb rastin m\u00eb t\u00eb keq, kur dy zona t\u00eb izoluara t\u00eb kodit bashkoheshin, n\u00eb t\u00eb cilat, ndaras, tipet ishin tashm\u00eb verifikuar, rezultonte se k\u00ebto tipe ishin t\u00eb papajtueshme me nj\u00ebra-tjetr\u00ebn. Kjo \u00e7onte n\u00eb nevoj\u00ebn p\u00ebr t\u00eb b\u00ebr\u00eb shum\u00eb ndryshime n\u00eb komentet. Tani, duke u kthyer mbrapa, ne kuptojm\u00eb se na duhej t\u00eb kishim shtuar sa m\u00eb par\u00eb modulet baz\u00eb t\u00eb bibliotek\u00ebs n\u00eb zon\u00ebn e kontrollit t\u00eb tipave mypy. Kjo do ta b\u00ebnte pun\u00ebn ton\u00eb shum\u00eb m\u00eb t\u00eb parashikueshme.<\/p>\n<p>Anotimi i kodit t\u00eb vjet\u00ebr. Kur filluam pun\u00ebn, kishim rreth 4 milion\u00eb rreshta kod Python t\u00eb ekzistuesh\u00ebm. Ishte e qart\u00eb se anotimi i k\u00ebtij kodi ishte nj\u00eb detyr\u00eb e v\u00ebshtir\u00eb. Ne krijuam nj\u00eb mjet, t\u00eb quajtur PyAnnotate, i cili mund t\u00eb mbledh\u00eb informacione mbi llojet gjat\u00eb ekzekutimit t\u00eb testeve dhe di t\u00eb shtoj\u00eb n\u00eb kod anotime llojesh duke u bazuar n\u00eb informacionet e mbledhura. Megjithat\u00eb, nuk kemi v\u00ebrejtur ndonj\u00eb adoptim t\u00eb gjer\u00eb t\u00eb k\u00ebtij instrumenti. Mbledhja e informacionit t\u00eb llojeve ishte e ngadalshme, dhe anotimet e gjeneruara automatikisht shpesh k\u00ebrkonin shum\u00eb rregullime manuale. Menduam p\u00ebr t\u00eb ekzekutuar automatikisht k\u00ebt\u00eb mjet p\u00ebr \u00e7do verifikim t\u00eb kodit, ose p\u00ebr t\u00eb mbledhur informacionet e llojeve duke u bazuar n\u00eb analiz\u00ebn e nj\u00eb volume t\u00eb vog\u00ebl t\u00eb k\u00ebrkesave t\u00eb v\u00ebrteta n\u00eb internet, por vendos\u00ebm t\u00eb mos e b\u00ebnim k\u00ebt\u00eb, pasi \u00e7do qasje e till\u00eb ishte shum\u00eb e rrezikshme.<\/p>\n<p>N\u00eb p\u00ebrfundim, mund t\u00eb theksojm\u00eb se shumica e kodit \u00ebsht\u00eb annotuar manualisht nga pronar\u00ebt e tij. Ne, p\u00ebr ta drejtuar k\u00ebt\u00eb proces n\u00eb rrug\u00ebn e duhur, p\u00ebrgatisim raporte p\u00ebr modulet dhe funksionet m\u00eb t\u00eb r\u00ebnd\u00ebsishme q\u00eb duhet t\u00eb annotohen. P\u00ebr shembull, \u00ebsht\u00eb e r\u00ebnd\u00ebsishme t\u00eb sigurohen anotacione p\u00ebr llojet n\u00eb modulin e bibliotek\u00ebs, i cili p\u00ebrdoret n\u00eb qindra vende. Nd\u00ebrsa sh\u00ebrbimi i vjet\u00ebr, i cili z\u00ebvend\u00ebsohet nga nj\u00ebri i ri, nuk \u00ebsht\u00eb kaq i r\u00ebnd\u00ebsish\u00ebm p\u00ebr t'u annotuar. P\u00ebrve\u00e7 k\u00ebsaj, ne jemi duke eksperimentuar me p\u00ebrdorimin e analiz\u00ebs statike p\u00ebr t\u00eb gjeneruar anotacione llojesh p\u00ebr kodin e vjet\u00ebr.<\/p>\n<p>Importet ciklike. M\u00eb lart kam folur p\u00ebr importet ciklike (p\u00ebr \"t\u00eb endurat e var\u00ebsive\"), ekzistenca e t\u00eb cilave e ka komplikuar p\u00ebrshpejtimin e mypy. Ne gjithashtu pat\u00ebm nevoj\u00eb p\u00ebr t\u00eb punuar seriozisht p\u00ebr t\u00eb ofruar mb\u00ebshtetje p\u00ebr t\u00eb gjitha llojet e idiomave, shkak i krijimit t\u00eb t\u00eb cilave jan\u00eb k\u00ebto importet ciklike. S\u00eb fundmi p\u00ebrfunduam nj\u00eb projekt t\u00eb madh p\u00ebr rind\u00ebrtimin e sistemit, q\u00eb zgjidhi shumic\u00ebn e problemeve t\u00eb mypy lidhur me importet ciklike. K\u00ebto probleme, n\u00eb t\u00eb v\u00ebrtet\u00eb, kan\u00eb rrjedhur nga dit\u00ebt e hershme t\u00eb projektit, q\u00eb nga Alore, gjuha m\u00ebsimore p\u00ebr t\u00eb cil\u00ebn ishte fokusuar fillimisht projekti mypy. Sintaksa e Alore lejon t\u00eb zgjidhen leht\u00ebsisht problemet e komandave ciklike t\u00eb importit. Mypy modern trash\u00ebgoi disa kufizime nga implementimi i tij i hersh\u00ebm, i cili ishte shum\u00eb i p\u00ebrshtatsh\u00ebm p\u00ebr Alore. Python e komplikon pun\u00ebn me importet ciklike kryesisht p\u00ebr shkak t\u00eb pasiguris\u00eb s\u00eb shprehjeve. P\u00ebr shembull, gjat\u00eb nj\u00eb operacioni t\u00eb caktimit t\u00eb vlerave, mund t\u00eb p\u00ebrcaktohet n\u00eb t\u00eb v\u00ebrtet\u00eb nj\u00eb pseudonim tipi. Mypy nuk \u00ebsht\u00eb gjithmon\u00eb n\u00eb gjendje t\u00eb zbuloj\u00eb t\u00eb tilla gj\u00ebra derisa nj\u00eb pjes\u00eb e madhe e ciklit t\u00eb importit t\u00eb jet\u00eb p\u00ebrpunuar. N\u00eb Alore nuk kishte t\u00eb tilla pasiguri. Zgjedhjet e d\u00ebshtuara t\u00eb marra n\u00eb fazat e hershme t\u00eb zhvillimit t\u00eb sistemit mund t\u00eb sjellin nj\u00eb surpriz\u00eb t\u00eb pak\u00ebndshme p\u00ebr programuesin pas shum\u00eb vitesh.<\/p>\n<h2>P\u00ebrfundimet: rruga drejt 5 milion rreshtave t\u00eb kodit dhe horizonteve t\u00eb reja<\/h2>\n<p>\nProjekti mypy ka kaluar nj\u00eb rrug\u00eb t\u00eb gjat\u00eb \u2014 nga prototipat e hersh\u00ebm, deri n\u00eb sistemin q\u00eb kontrollon tipet e kodit t\u00eb prodhimit me nj\u00eb volum prej 4 milion rreshtash. Gjat\u00eb zhvillimit t\u00eb mypy u realizua standardizimi i sugjerimeve p\u00ebr tipet n\u00eb Python. Sot p\u00ebrreth tipizimit t\u00eb kodit Python \u00ebsht\u00eb formuar nj\u00eb ekosistem i fuqish\u00ebm. K\u00ebtu kishte vend p\u00ebr mb\u00ebshtetje bibliotekash, mjetet ndihm\u00ebse p\u00ebr IDE dhe redaktor\u00ebt, si dhe disa sisteme kontrolli t\u00eb tipave, secili me avantazhe dhe disavantazhe t\u00eb veta.<\/p>\n<p>Megjithat\u00eb, ndon\u00ebse kontrolli i tipeve tashm\u00eb perceptohet n\u00eb Dropbox si di\u00e7ka e natyrshme, un\u00eb besoj se ne ende jetojm\u00eb n\u00eb agun e tipizimit t\u00eb kodit Python. Mendoj se teknologjit\u00eb e kontrollit t\u00eb tipeve do t\u00eb vazhdojn\u00eb t\u00eb zhvillohen dhe p\u00ebrmir\u00ebsohen.<\/p>\n<p>N\u00ebse nuk e keni p\u00ebrdorur kontrollet e tipeve n\u00eb projektin tuaj t\u00eb madh Python, dijeni se tani \u00ebsht\u00eb nj\u00eb moment shum\u00eb i p\u00ebrshtatsh\u00ebm p\u00ebr t\u00eb filluar kalimin n\u00eb tipizimin statik. Kam biseduar me ata q\u00eb kan\u00eb b\u00ebr\u00eb nj\u00eb kalim t\u00eb till\u00eb. Askush nga ata nuk ka patur pendes\u00eb. Kontrolli i tipeve e b\u00ebn Python nj\u00eb gjuh\u00eb q\u00eb \u00ebsht\u00eb shum\u00eb m\u00eb e mir\u00eb se \"Python-i zakonsh\u00ebm\" p\u00ebr zhvillimin e projekteve t\u00eb m\u00ebdha.<\/p>\n<p><b>T\u00eb nderuar lexues!<\/b> A p\u00ebrdorni kontrollin e tipeve n\u00eb projektet tuaja Python?<\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/ruvds.com\/vps_start\/\"><img decoding=\"async\" alt=\"Rruga drejt kontrollit t\u00eb tipeve t\u00eb 4 milion rreshtave t\u00eb kodit Python. Pjesa 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=\"Rruga drejt kontrollit t\u00eb tipeve t\u00eb 4 milion rreshtave t\u00eb kodit Python. Pjesa 3\" src=\"\/wp-content\/uploads\/2019\/10\/098d481c25b3afaba9534c686e8f943a.png\" style=\"display:block;margin: 0 auto;\" \/><\/a><\/noindex><br \/>\n<br \/>Burimi: <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 4.9.10 - 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. \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,\" \/>\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\/sq\/blog\/administrirovanie\/put-k-proverke-tipov-4-millionov-strok-python-koda-chast-3\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 4.9.10\" \/>\n\t\t<meta property=\"og:locale\" content=\"sq_AL\" \/>\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. \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,\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/sq\/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\udd47Rrug\u00ebtimi p\u00ebr kontrollin e tipeve t\u00eb 4 milion linjave t\u00eb kodit Python. Pjesa 3 | ProHoster","description":"Po ju paraqesim pjes\u00ebn e tret\u00eb t\u00eb p\u00ebrkthimit t\u00eb materialit mbi rrug\u00ebn q\u00eb ka ndjekur kompania Dropbox p\u00ebr t\u00eb zbatuar sistemin e kontrollit t\u00eb tipeve t\u00eb kodit Python. \u2192 Pjes\u00ebt e m\u00ebparshme: e para dhe e dyta Arritja e 4 milion linjave t\u00eb kodit t\u00eb tipizuar Nj\u00eb gjithashtu sfid\u00eb e r\u00ebnd\u00ebsishme (kishte qen\u00eb problemi i dyt\u00eb m\u00eb i popullarizuar q\u00eb shqet\u00ebsonte ata q\u00eb mor\u00ebn pjes\u00eb n\u00eb anketat e brendshme) ishte rritja e volumit t\u00eb kodit n\u00eb Dropbox.","canonical_url":"https:\/\/prohoster.info\/sq\/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":"sq_AL","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. \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,","og:url":"https:\/\/prohoster.info\/sq\/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":null,"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-01-23 22:54:19"},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/posts\/38649","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/comments?post=38649"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/posts\/38649\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/media\/28992"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/media?parent=38649"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/categories?post=38649"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/tags?post=38649"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}