आज हम Instagram में सर्वर-साइड पायथन कोड के बड़े संस्करणों के स्थिर विश्लेषण के लिए समर्पित सामग्री के अनुवाद का दूसरा भाग प्रकाशित करते हैं।

→
पहला भागप्रोग्रामर जो लाइनिंग से थक गए हैं
यह देखते हुए कि हमारे पास अपने स्वयं के सौ नियमों के बारे में है, इन नियमों द्वारा जारी की गई अनुशंसाओं के पांडित्य लेखांकन से डेवलपर्स समय की बर्बादी हो सकती है। बेहतर होगा कि कोड शैली को सीधा करने में या कुछ नया बनाने के लिए और परियोजना को विकसित करने के लिए अप्रचलित पैटर्न से छुटकारा पाने में समय व्यतीत करें।
हमने पाया कि जब प्रोग्रामर लिंटर से बहुत अधिक सूचनाएं देखते हैं, तो वे इन सभी संदेशों को अनदेखा करने लगते हैं। यह महत्वपूर्ण सूचनाओं पर भी लागू होता है।
मान लीजिए कि हम
fn
फ़ंक्शन को अप्रचलित घोषित करने का निर्णय लेते हैं और इसके बजाय, बेहतर नाम के साथ फ़ंक्शन का उपयोग करते हैं। यदि आप डेवलपर्स को इसके बारे में सूचित नहीं करते हैं, तो उन्हें पता नहीं चलेगा कि उन्हें अब
fn
फ़ंक्शन का उपयोग करने की आवश्यकता नहीं है। इससे भी बदतर, वे नहीं जानते कि इस फ़ंक्शन के बजाय क्या उपयोग करना है। इस स्थिति में, आप एक लाइनर नियम बना सकते हैं। लेकिन किसी भी बड़े कोड आधार में पहले से ही कई नियम होंगे। नतीजतन, यह संभावना है कि मामूली बग की सूचनाओं के ढेर में एक महत्वपूर्ण लिंटर अधिसूचना खो जाएगी।
लिंटर बहुत नीपिंग है और "उपयोगी सिग्नल" आसानी से "शोर" में खो सकता हैहम इसके साथ क्या करेंगे?
आप लिंटर द्वारा पाई गई कई समस्याओं को स्वचालित रूप से ठीक कर सकते हैं। यदि लाइनर की तुलना उस दस्तावेज से की जा सकती है जो प्रकट होता है जहां इसकी आवश्यकता होती है, तो ऐसे स्वचालित सुधार कोड का एक सा हो जाता है जिसे निष्पादित किया जाता है जहां इसकी आवश्यकता होती है। इंस्टाग्राम पर काम करने वाले डेवलपर्स की बड़ी संख्या को देखते हुए, उनमें से प्रत्येक को हमारे सर्वश्रेष्ठ कोड लेखन तकनीकों में प्रशिक्षित करना लगभग असंभव है। सिस्टम में स्वचालित कोड सुधार क्षमताओं को जोड़ने से हमें नई तकनीकों पर डेवलपर्स को शिक्षित करने की अनुमति मिलती है जब उन्हें इन तकनीकों के बारे में पता नहीं होता है। यह हमें जल्दी से विकसित होने में मदद करता है। इसके अलावा, स्वचालित सुधारों ने हमें प्रोग्रामर को महत्वपूर्ण चीजों पर ध्यान केंद्रित करने की अनुमति दी, न कि नीरस मामूली कोड परिवर्तनों पर ध्यान केंद्रित करने के लिए। सामान्य तौर पर, यह ध्यान दिया जा सकता है कि सरल लिंटर सूचनाओं की तुलना में प्रशिक्षण डेवलपर्स के संदर्भ में स्वचालित कोड सुधार अधिक प्रभावी और उपयोगी हैं।
तो, स्वचालित कोड सुधार के लिए एक सिस्टम कैसे बनाएं? एक सिंटेक्स ट्री आधारित लिंट हमें एक दुष्क्रियाशील नोड के बारे में जानकारी देता है। नतीजतन, हमें समस्याओं का पता लगाने के लिए तर्क बनाने की आवश्यकता नहीं है, क्योंकि हमारे पास पहले से ही लिंटर के लिए समान नियम हैं! चूंकि हम जानते हैं कि कौन सा विशेष नोड हमें सूट नहीं करता है, और इसके स्रोत कोड के बारे में कहां है, हम कुछ खराब किए बिना, उदाहरण के लिए, फ़ंक्शन
fn
के नाम को
add
साथ बदल
add
। यह नियमों के एकल उल्लंघन को ठीक करने के लिए अच्छी तरह से अनुकूल है जो इस तरह के उल्लंघन का पता लगाया जाता है। लेकिन क्या होगा अगर हम लिंटर के लिए एक नया नियम लागू करते हैं, जिसका अर्थ है कि कोड आधार में सैकड़ों कोड टुकड़े हो सकते हैं जो इस नियम का अनुपालन नहीं करते हैं? क्या इन सभी विसंगतियों को पहले से ठीक किया जा सकता है?
कोड मोड
एक कोडमॉड बस समस्याओं को खोजने और स्रोत कोड में बदलाव करने का एक तरीका है। कोडमोड लिपि आधारित हैं। कोडमोड को "स्टेरॉयड रिफैक्टरिंग" के रूप में माना जा सकता है। कोड मोड द्वारा हल किए गए कार्यों की सीमा अत्यंत व्यापक है: साधारण लोगों से, जैसे कि किसी फ़ंक्शन में चर का नाम बदलना, जटिल लोगों के लिए, जैसे फ़ंक्शन को फिर से लिखना ताकि यह एक नया तर्क ले। कोडमोड के साथ काम करते समय, समान अवधारणाओं का उपयोग लाइनर के संचालन के साथ किया जाता है। लेकिन प्रोग्रामर को समस्या के बारे में सूचित करने के बजाय, जैसा कि लिंटर करता है, कोड मोड स्वचालित रूप से इस समस्या को हल करता है।
कोडमॉड कैसे लिखें? एक उदाहरण पर विचार करें। यहां हम
get_global
का उपयोग बंद करना चाहते हैं। इस स्थिति में, आप लिंटर का उपयोग कर सकते हैं, लेकिन यह ज्ञात नहीं होगा कि पूरे कोड को ठीक करने में कितना समय लगेगा, इसके अलावा, यह कार्य कई डेवलपर्स के बीच वितरित किया जाएगा। उसी समय, भले ही परियोजना स्वचालित कोड सुधार की प्रणाली का उपयोग करती है, लेकिन सभी कोड को संसाधित करने में कुछ समय लग सकता है।
हम get_global का उपयोग करने से बचना चाहते हैं और इसके बजाय उदाहरण चर का उपयोग करेंइस समस्या को हल करने के लिए, हम लिंटर नियम के साथ मिलकर इसका पता लगा सकते हैं, एक कोडेम लिख सकते हैं। हम मानते हैं कि पुराने पैटर्न और एपीआई को धीरे-धीरे कोड छोड़ने की अनुमति देने से डेवलपर्स को विचलित किया जाएगा और कोड की पठनीयता को कम किया जाएगा। हम अप्रचलित कोड को तुरंत निकालना पसंद करते हैं, और यह नहीं देखते हैं कि यह धीरे-धीरे परियोजना से कैसे गायब हो जाता है।
हमारे कोड की मात्रा और सक्रिय डेवलपर्स की संख्या को देखते हुए, इसका मतलब अक्सर अप्रचलित डिजाइनों को समाप्त करना है। यदि हम अप्रचलित पैटर्न से कोड को जल्दी से साफ़ करने में सक्षम हैं, तो इसका मतलब है कि हम सभी Instagram डेवलपर्स की उत्पादकता को बनाए रख सकते हैं।
तो, कैसे एक कोडेम बनाने के लिए? टिप्पणियों, इंडेंटेशन और अन्य सभी चीज़ों को संरक्षित करते हुए, हमें केवल उस कोड के टुकड़े को कैसे बदलना चाहिए जो हमें रुचता है? एक विशिष्ट वाक्यविन्यास वृक्ष पर आधारित उपकरण हैं (जैसे कि LibCST क्या बनाता है) जो आपको सर्जिकल परिशुद्धता के साथ कोड को संशोधित करने और इसमें सभी सहायक निर्माणों को बचाने की अनुमति देता है। नतीजतन, अगर हमें नीचे पेड़ में
add
के लिए फ़ंक्शन का नाम
fn
से बदलने की आवश्यकता है, तो हम
Name
नोड में
fn
बजाय नाम
add
सकते हैं, और फिर पेड़ को डिस्क पर लिख सकते हैं!
कोड मोड नाम fn के बजाय नाम नोड में नाम जोड़कर किया जा सकता है। फिर बदले हुए पेड़ को डिस्क पर लिखा जा सकता है। आप इस बारे में LibCST प्रलेखन में अधिक पढ़ सकते हैं।अब जब हमें कोड मॉड्स के बारे में कुछ पता चल गया है, तो आइए एक व्यावहारिक उदाहरण देखें। इंस्टाग्राम कर्मचारी पूरी तरह से टाइप किए गए प्रोजेक्ट का कोड बेस बनाने के लिए कड़ी मेहनत कर रहे हैं। इस मामले में कोडमोडी गंभीरता से उनकी मदद करते हैं।
यदि हमारे पास कुछ निश्चित प्रकार के अनछुए कार्य हैं, जिन्हें टाइप करने की आवश्यकता है, तो हम उनके द्वारा लौटाए गए प्रकारों को सामान्य प्रकार के अनुमान से उत्पन्न करने का प्रयास कर सकते हैं! उदाहरण के लिए, यदि कोई फ़ंक्शन केवल एक आदिम प्रकार के मान लौटाता है, तो हम फ़ंक्शन को केवल इस प्रकार का रिटर्न मान प्रदान करते हैं। यदि फ़ंक्शन तार्किक प्रकार के मान लौटाता है, उदाहरण के लिए, यदि यह किसी चीज़ के साथ किसी चीज़ की तुलना करता है या किसी चीज़ की जाँच करता है, तो हम इसे रिटर्न वैल्यू टाइप
bool
प्रदान कर सकते हैं। हमने पाया कि इंस्टाग्राम कोडबेस के साथ व्यावहारिक काम के दौरान, यह एक बहुत ही सुरक्षित ऑपरेशन है।
फ़ंक्शन द्वारा लौटाए गए मानों के प्रकारों का पता लगानालेकिन क्या होगा यदि फ़ंक्शन स्पष्ट रूप से किसी भी मूल्य को वापस नहीं करता है, या अंतर्निहित रूप से
None
रिटर्न
None
? यदि फ़ंक्शन स्पष्ट रूप से कुछ भी नहीं लौटाता है, तो उसे प्रकार
None
सौंपा जा सकता है।
यह पिछले उदाहरण के विपरीत, डेवलपर्स द्वारा उपयोग किए जाने वाले सामान्य पैटर्न के अस्तित्व के कारण अधिक खतरनाक हो सकता है। उदाहरण के लिए, एक बेस क्लास विधि में, आप एक
NotImplemented
अपवाद फेंक सकते हैं, और इस पद्धति को ओवरराइड करने वाले उपवर्गों में, आप एक स्ट्रिंग वापस कर सकते हैं। यह ध्यान रखना महत्वपूर्ण है कि ये सभी तकनीक विधर्मी हैं, लेकिन उनके आवेदन के परिणाम अक्सर सही हो जाते हैं। नतीजतन, उन्हें उपयोगी माना जा सकता है।
कार्य जो कुछ भी नहीं लौटाते हैंप्यारे के साथ कोड मॉड्यूल का विस्तार करना
एक कदम आगे बढ़ते हैं। इंस्टाग्राम Pyre, mypy के समान एक पूर्ण विकसित स्थिर प्रकार की जाँच प्रणाली का उपयोग करता है। पियरे के उपयोग से हमें कोडबेस में प्रकारों की जांच करने की अनुमति मिलती है। यदि हम कोड्रे की क्षमताओं का विस्तार करने के लिए पियरे द्वारा उत्पन्न डेटा का उपयोग करते हैं तो क्या होगा? निम्नलिखित ऐसे डेटा का एक उदाहरण है। यह देखना आसान है कि स्वचालित रूप से टाइप एनोटेशन को ठीक करने के लिए आपको लगभग हर चीज की आवश्यकता है!
$ pyre ƛ Found 2 type errors! testing/utils.py:7:0 Missing return annotation [3]: Returning `SomeClass` but no return type is specified. testing/utils.py:10:0 Missing return annotation [3]: Returning `testing.other.SomeOtherClass` but no return type is specified.
कार्य के दौरान पियरे प्रत्येक फ़ंक्शन के निष्पादन क्रम का एक विस्तृत विश्लेषण करता है। नतीजतन, यह उपकरण कभी-कभी बहुत अधिक संभावना के साथ एक धारणा बना सकता है कि किसी अननोनॉटेड फ़ंक्शन को वापस लौटना चाहिए। इसका मतलब यह है कि अगर पियरे का मानना है कि फ़ंक्शन एक साधारण प्रकार लौटाता है, तो हम इस फ़ंक्शन को रिटर्न प्रकार प्रदान करते हैं। हालांकि, अब, संभावित रूप से, हमें आयात आदेशों को भी संसाधित करने की आवश्यकता है। इसका मतलब है कि हमें यह जानने की जरूरत है कि क्या कुछ आयात किया गया है या स्थानीय रूप से घोषित किया गया है। बाद में हम इस विषय पर संक्षेप में बात करेंगे।
कोड में आसानी से प्रदर्शित होने वाली जानकारी को स्वचालित रूप से जोड़ने से हमें क्या लाभ मिलते हैं? खैर, प्रकार प्रलेखन हैं! यदि फ़ंक्शन पूरी तरह से टाइप किया गया है, तो डेवलपर को अपने कॉल की सुविधाओं और इसके उपयोग की विशेषताओं का पता लगाने के लिए इसके कोड को नहीं पढ़ना होगा।
def get_description(page: WikiPage) -> Optional[str]: if page.draft: return None return page.metadata["description"]
हम में से कई लोग समान पायथन कोड के साथ आए हैं। इंस्टाग्राम कोडबेस भी कुछ इसी तरह का है। यदि
get_description
फ़ंक्शन
get_description
गया था, तो आपको यह पता लगाने के लिए कई मॉड्यूलों पर गौर करना होगा कि यह क्या रिटर्न देता है। उसी समय, भले ही हम सरल कार्यों के बारे में बात कर रहे हैं, वापसी के प्रकार जिनमें से प्राप्त करना आसान है, उनके टाइप किए गए वेरिएंट अनछुए लोगों की तुलना में अधिक आसानी से माना जाता है।
इसके अलावा, अगर फ़ंक्शन पूरी तरह से एनोटेट नहीं है, तो Pyre फ़ंक्शन बॉडी के सही संचालन को सत्यापित नहीं करता है। निम्नलिखित उदाहरण में,
some_function
कॉल विफल हो जाएगी। कोड उत्पादन में आने से पहले इस बारे में जानना अच्छा होगा।
def some_function(in: int) -> bool: return in > 0 def some_other_function(): if some_function("bla"):
इस मामले में, हम कोड के उत्पादन में चले जाने के बाद एक समान त्रुटि के बारे में अच्छी तरह जान सकते हैं। तथ्य यह है कि
some_other_function
में वापसी प्रकार एनोटेशन नहीं है। यदि हमने अपने हेयुरिस्टिक मैकेनिज्म का उपयोग करके स्वचालित रूप से कम किए गए प्रकारों का उपयोग करके इसे एनोटेट किया है, तो हमें किसी भी समस्या का कारण बनने से पहले प्रकारों के साथ एक समस्या की खोज करनी चाहिए। यह, ज़ाहिर है, एक कृत्रिम उदाहरण है, लेकिन इंस्टाग्राम पर ऐसी समस्याएं गंभीर हैं। यदि आपके पास कोड की लाखों लाइनें हैं, तो आप, कोड समीक्षा प्रक्रिया में, ऐसी चीजों को अच्छी तरह से याद कर सकते हैं जो एक साधारण उदाहरण में पूरी तरह से स्पष्ट लगती हैं।
इंस्टाग्राम में, स्वचालित रूप से कम किए गए प्रकारों के आधार पर उपरोक्त विधियों में लगभग 10% फ़ंक्शन टाइप करने की अनुमति है। परिणामस्वरूप, लोगों को अब मैन्युअल रूप से हजारों और हजारों कार्यों को संपादित करना पड़ा। टाइप किए गए कोड के फायदे स्पष्ट हैं, लेकिन यह, हमारी बातचीत के संदर्भ में, एक और महत्वपूर्ण लाभ की ओर जाता है। एक पूरी तरह से टाइप किया गया कोड आधार कोडमोड्स का उपयोग करके प्रसंस्करण कोड के लिए और भी अधिक संभावनाएं खोलता है।
अगर हम टाइप एनोटेशन पर भरोसा करते हैं, तो इसका मतलब है कि प्यारे हमारे लिए अतिरिक्त संभावनाएं खोल सकते हैं। आइए फिर से उस उदाहरण को देखें जहां हमने कार्यों का नाम बदला था। क्या होगा यदि हम जिस इकाई का नाम बदल रहे हैं वह एक वर्ग विधि द्वारा दर्शाया जाता है न कि एक वैश्विक कार्य?
कार्य एक वर्ग विधि हैयदि आप Pyre से प्राप्त प्रकार की जानकारी और फ़ंक्शन मोड का नाम बदलने वाले कोड को जोड़ते हैं, तो आप अनपेक्षित रूप से, फ़ंक्शन को कहां और कहां घोषित किया जाता है, दोनों में सुधार कर सकते हैं! इस उदाहरण में, क्योंकि हम जानते हैं कि
a.fn
निर्माण के बाईं ओर क्या है, हम यह भी जानते हैं कि इस निर्माण को
a.add
बदलना सुरक्षित है।
अधिक उन्नत स्थैतिक विश्लेषण
पायथन में चार प्रकार के स्कोप हैं: वैश्विक गुंजाइश, वर्ग और फ़ंक्शन स्तर का क्षेत्र, नेस्टेड गुंजाइशगुंजाइश का विश्लेषण हमें और भी अधिक शक्तिशाली कोडमोड का उपयोग करने की अनुमति देता है। उपरोक्त उदाहरणों में से एक को याद रखें, जहां हमने इस तथ्य के बारे में बात की थी कि टाइप एनोटेशन को जोड़ने का मतलब आयात कमांड के साथ काम करने की आवश्यकता भी हो सकती है? यदि सिस्टम गुंजाइश का विश्लेषण करता है, तो इसका मतलब है कि हम यह जान सकते हैं कि फ़ाइल में किस प्रकार का उपयोग किया गया है, इसके लिए कमांड आयात करने के लिए धन्यवाद, जो स्थानीय रूप से घोषित किए गए हैं, और जो गायब हैं। इसी तरह, यदि आप जानते हैं कि एक वैश्विक चर एक फ़ंक्शन तर्क द्वारा ओवरलैप किया गया है, तो आप वैश्विक चर का नाम बदलने पर गलती से इस तरह के तर्क का नाम बदलने से बच सकते हैं।
परिणाम
इंस्टाग्राम कोड में सभी त्रुटियों को ठीक करने की हमारी खोज में, हमने एक बात समझी। यह इस तथ्य में समाहित है कि जिस कोड को ठीक करने की आवश्यकता है उसकी खोज अक्सर खुद को ठीक करने की तुलना में अधिक महत्वपूर्ण होती है। प्रोग्रामर को अक्सर सरल कार्यों को हल करना होता है - जैसे कार्यों का नाम बदलना, विधियों में तर्क जोड़ना या मॉड्यूल को भागों में विभाजित करना। यह सब आम बात है, लेकिन हमारे कोड आधार के आकार का अर्थ है कि कोई व्यक्ति हर उस पंक्ति को नहीं खोज पाएगा जिसे बदलने की आवश्यकता है। यही कारण है कि विश्वसनीय स्थैतिक विश्लेषण के साथ कोडमोड की क्षमताओं को संयोजित करना इतना महत्वपूर्ण है। यह हमें कोड के उन हिस्सों को अधिक आत्मविश्वास से खोजने की अनुमति देता है जिन्हें बदलने की आवश्यकता होती है, जिसका अर्थ है कि यह हमें कोड मोड को सुरक्षित और अधिक शक्तिशाली बनाने की अनुमति देता है।
प्रिय पाठकों! क्या आप कोड मॉड का उपयोग करते हैं?
