المسار إلى فحص 4 ملايين سطر من كود Python. الجزء 3

نقدم انتباهكم إلى الجزء الثالث من ترجمة المواد حول المسار الذي سلكه Dropbox عند تنفيذ نظام التحقق من النوع لكود Python.

المسار إلى فحص 4 ملايين سطر من كود Python. الجزء 3

→ الأجزاء السابقة: الأول и ثان

الوصول إلى 4 ملايين سطر من التعليمات البرمجية المكتوبة

كان التحدي الرئيسي الآخر (والقلق الثاني الأكثر شيوعًا بين أولئك الذين شملهم الاستطلاع داخليًا) هو زيادة كمية التعليمات البرمجية التي تغطيها عمليات التحقق من النوع في Dropbox. لقد جربنا عدة طرق لحل هذه المشكلة، بدءًا من زيادة حجم قاعدة التعليمات البرمجية المكتوبة بشكل طبيعي إلى تركيز جهود فريق mypy على الاستدلال الآلي الثابت والديناميكي للنوع. في النهاية، بدا الأمر وكأنه لا توجد استراتيجية رابحة بسيطة، لكننا تمكنا من تحقيق نمو سريع في حجم التعليمات البرمجية المشروحة من خلال الجمع بين العديد من الأساليب.

ونتيجة لذلك، فإن أكبر مستودع بايثون لدينا (مع كود الواجهة الخلفية) يحتوي على ما يقرب من 4 ملايين سطر من التعليمات البرمجية المشروحة. تم الانتهاء من العمل على كتابة التعليمات البرمجية الثابتة في حوالي ثلاث سنوات. يدعم Mypy الآن أنواعًا مختلفة من تقارير تغطية التعليمات البرمجية التي تسهل مراقبة تقدم الكتابة. على وجه الخصوص، يمكننا إنشاء تقارير عن التعليمات البرمجية التي تحتوي على غموض في الأنواع، مثل، على سبيل المثال، الاستخدام الصريح للنوع Any في التعليقات التوضيحية التي لا يمكن التحقق منها، أو مع أشياء مثل استيراد مكتبات الجهات الخارجية التي لا تحتوي على تعليقات توضيحية للنوع. كجزء من مشروع لتحسين دقة التحقق من النوع في Dropbox، ساهمنا في تحسين تعريفات النوع (ما يسمى بملفات كعب الروتين) لبعض المكتبات الشهيرة مفتوحة المصدر في مستودع Python المركزي تمت كتابته.

لقد قمنا بتنفيذ (وتوحيدها في PEPs اللاحقة) ميزات جديدة لنظام الكتابة الذي يسمح بأنواع أكثر دقة لبعض أنماط Python المحددة. ومن الأمثلة البارزة على ذلك TypeDict، والذي يوفر أنواعًا للقواميس المشابهة لـ JSON والتي تحتوي على مجموعة ثابتة من مفاتيح السلسلة، ولكل منها قيمة من نوعها. سنستمر في توسيع نظام الكتابة. من المرجح أن تكون خطوتنا التالية هي تحسين الدعم لقدرات بايثون العددية.

المسار إلى فحص 4 ملايين سطر من كود Python. الجزء 3
عدد أسطر التعليمات البرمجية المشروحة: الخادم

المسار إلى فحص 4 ملايين سطر من كود Python. الجزء 3
عدد أسطر التعليمات البرمجية المشروحة: العميل

المسار إلى فحص 4 ملايين سطر من كود Python. الجزء 3
إجمالي عدد أسطر التعليمات البرمجية المشروحة

فيما يلي نظرة عامة على الميزات الرئيسية للأشياء التي قمنا بها لزيادة كمية التعليمات البرمجية المشروحة في Dropbox:

دقة الشرح. لقد قمنا تدريجيًا بزيادة متطلبات دقة التعليقات التوضيحية للكود الجديد. لقد بدأنا بنصائح linter التي تقترح إضافة التعليقات التوضيحية إلى الملفات التي تحتوي بالفعل على بعض التعليقات التوضيحية. نطلب الآن تعليقات توضيحية للكتابة في ملفات Python الجديدة وفي معظم الملفات الموجودة.

كتابة التقارير. نرسل للفرق تقارير أسبوعية عن مستوى الكتابة في الكود الخاص بهم ونقدم النصائح حول ما يجب التعليق عليه أولاً.

تعميم mypy. نتحدث عن mypy في الأحداث ونتحدث مع الفرق لمساعدتهم على البدء في كتابة التعليقات التوضيحية.

استطلاعات الرأي. نقوم بإجراء استطلاعات دورية للمستخدمين لتحديد المشاكل الرئيسية. نحن على استعداد للذهاب إلى أبعد من ذلك في حل هذه المشكلات (حتى إنشاء لغة جديدة لتسريع عملية mypy!).

أداء. لقد قمنا بتحسين أداء mypy بشكل كبير باستخدام البرنامج الخفي وmypyc. وقد تم ذلك لتخفيف المضايقات التي تنشأ أثناء عملية التعليق التوضيحي، ولكي تكون قادرًا على العمل بكميات كبيرة من التعليمات البرمجية.

التكامل مع المحررين. لقد قمنا ببناء أدوات لدعم تشغيل mypy في المحررين المشهورين على Dropbox. يتضمن ذلك PyCharm وVim وVS Code. أدى هذا إلى تبسيط عملية التعليق على الكود والتحقق من وظائفه إلى حد كبير. هذه الأنواع من الإجراءات شائعة عند إضافة تعليقات توضيحية إلى التعليمات البرمجية الموجودة.

التحليل الساكن. لقد أنشأنا أداة لاستنتاج التوقيعات الوظيفية باستخدام أدوات التحليل الثابتة. لا يمكن لهذه الأداة أن تعمل إلا في مواقف بسيطة نسبيًا، ولكنها ساعدتنا على زيادة تغطية نوع التعليمات البرمجية لدينا دون بذل الكثير من الجهد.

دعم مكتبات الطرف الثالث. تستخدم العديد من مشاريعنا مجموعة أدوات SQLAlchemy. إنه يستفيد من القدرات الديناميكية لـ Python والتي لا تستطيع أنواع PEP 484 تصميمها بشكل مباشر. لقد قمنا، وفقًا لـ PEP 561، بإنشاء ملف كعب الروتين المقابل وكتبنا مكونًا إضافيًا لـ mypy (مفتوح المصدر)، مما يعمل على تحسين دعم SQLAlchemy.

الصعوبات التي واجهناها

لم يكن الطريق إلى 4 ملايين سطر من التعليمات البرمجية المكتوبة سهلاً بالنسبة لنا دائمًا. واجهنا في هذا الطريق العديد من الحفر وارتكبنا العديد من الأخطاء. هذه بعض المشاكل التي واجهناها. نأمل أن يساعد الحديث عنها الآخرين على تجنب مشاكل مماثلة.

الملفات المفقودة. لقد بدأنا عملنا بفحص كمية صغيرة فقط من الملفات. لم يتم فحص أي شيء غير مدرج في هذه الملفات. تمت إضافة الملفات إلى قائمة المسح عند ظهور التعليقات التوضيحية الأولى فيها. إذا تم استيراد شيء ما من وحدة نمطية تقع خارج نطاق التحقق، فإننا نتحدث عن العمل بقيم مثل Any، والتي لم يتم اختبارها على الإطلاق. وأدى ذلك إلى خسارة كبيرة في دقة الكتابة، خاصة في المراحل الأولى من الترحيل. لقد نجح هذا الأسلوب بشكل مدهش حتى الآن، على الرغم من أن الموقف النموذجي هو أن إضافة الملفات إلى نطاق المراجعة يكشف عن مشكلات في أجزاء أخرى من قاعدة التعليمات البرمجية. في أسوأ الحالات، عندما تم دمج منطقتين معزولتين من التعليمات البرمجية، حيث تم بالفعل فحص الأنواع بشكل مستقل عن بعضها البعض، اتضح أن أنواع هذه المناطق كانت غير متوافقة مع بعضها البعض. وأدى ذلك إلى الحاجة إلى إجراء العديد من التغييرات على الشروح. إذا نظرنا إلى الوراء الآن، فإننا ندرك أنه كان ينبغي علينا إضافة وحدات المكتبة الأساسية إلى منطقة التحقق من النوع في mypy عاجلاً. وهذا من شأنه أن يجعل عملنا أكثر قابلية للتنبؤ به.

شرح الكود القديم. عندما بدأنا، كان لدينا حوالي 4 ملايين سطر من كود بايثون الحالي. كان من الواضح أن التعليق على كل هذا الكود لم يكن مهمة سهلة. لقد أنشأنا أداة تسمى PyAnnotate يمكنها جمع معلومات النوع أثناء تشغيل الاختبارات ويمكنها إضافة تعليقات توضيحية للنوع إلى التعليمات البرمجية الخاصة بك بناءً على المعلومات التي تم جمعها. ومع ذلك، لم نلاحظ اعتمادًا واسع النطاق لهذه الأداة بشكل خاص. كان جمع معلومات النوع بطيئًا، وغالبًا ما كانت التعليقات التوضيحية التي تم إنشاؤها تلقائيًا تتطلب العديد من التعديلات اليدوية. لقد فكرنا في تشغيل هذه الأداة تلقائيًا في كل مرة نقوم فيها بمراجعة التعليمات البرمجية، أو في جمع معلومات النوع بناءً على تحليل بعض الحجم الصغير من طلبات الشبكة الفعلية، لكننا قررنا عدم القيام بذلك لأن أيًا من الطريقتين كان محفوفًا بالمخاطر للغاية.

ونتيجة لذلك، يمكن ملاحظة أن معظم التعليمات البرمجية تم شرحها يدويًا بواسطة مالكيها. ومن أجل توجيه هذه العملية في الاتجاه الصحيح، نقوم بإعداد تقارير حول الوحدات والوظائف ذات الأهمية الخاصة التي تحتاج إلى شرح. على سبيل المثال، من المهم توفير تعليقات توضيحية للنوع لوحدة المكتبة المستخدمة في مئات الأماكن. لكن الخدمة القديمة التي يتم استبدالها بخدمة جديدة لم تعد ذات أهمية كبيرة للتعليق عليها. نحن نقوم أيضًا بتجربة استخدام التحليل الثابت لإنشاء تعليقات توضيحية للنوع للتعليمات البرمجية القديمة.

الواردات الدورية. تحدثت أعلاه عن الواردات الدورية ("تشابكات التبعية")، والتي جعل وجودها من الصعب تسريع عملية mypy. كان علينا أيضًا أن نعمل بجد لجعل mypy يدعم جميع أنواع التعابير التي تنتج عن هذه الواردات الدورية. لقد أكملنا مؤخرًا مشروعًا كبيرًا لإعادة تصميم النظام والذي أدى إلى إصلاح معظم مشكلات mypy المتعلقة بالواردات الدائرية. نشأت هذه المشاكل في الواقع من الأيام الأولى للمشروع، من ألور، اللغة التعليمية التي ركز عليها مشروع mypy في الأصل. يُسهل بناء جملة Alore حل المشكلات باستخدام أوامر الاستيراد الدورية. لقد ورث mypy الحديث بعض القيود من تطبيقه السابق البسيط (والذي كان مناسبًا تمامًا لـ Alore). تجعل بايثون العمل مع الواردات الدائرية أمرًا صعبًا، ويرجع ذلك أساسًا إلى أن التعبيرات غامضة. على سبيل المثال، قد تقوم عملية التعيين فعليًا بتعريف اسم مستعار للنوع. لا يتمكن Mypy دائمًا من اكتشاف أشياء مثل هذه حتى تتم معالجة معظم حلقة الاستيراد. لم تكن هناك مثل هذه الغموض في ألور. يمكن أن تشكل القرارات السيئة التي تم اتخاذها في المراحل الأولى من تطوير النظام مفاجأة غير سارة للمبرمج بعد سنوات عديدة.

النتائج: الطريق إلى 5 ملايين سطر من التعليمات البرمجية وآفاق جديدة

لقد قطع مشروع mypy شوطا طويلا - من النماذج الأولية إلى نظام يتحكم في 4 ملايين سطر من أنواع أكواد الإنتاج. مع تطور mypy، تم توحيد تلميحات نوع Python. في هذه الأيام، تم تطوير نظام بيئي قوي حول كتابة كود بايثون. يحتوي على مكان لدعم المكتبة، ويحتوي على أدوات مساعدة لـ IDEs والمحررين، ولديه العديد من أنظمة التحكم في النوع، لكل منها إيجابيات وسلبيات خاصة به.

على الرغم من أن التحقق من النوع أمر معطى بالفعل في Dropbox، أعتقد أننا مازلنا في الأيام الأولى لكتابة كود Python. أعتقد أن تقنيات التحقق من الكتابة ستستمر في التطور والتحسين.

إذا لم تكن قد استخدمت بالفعل التحقق من النوع في مشروع بايثون واسع النطاق الخاص بك، فاعلم أن الآن هو الوقت المناسب جدًا لبدء الانتقال إلى الكتابة الثابتة. لقد تحدثت مع أولئك الذين قاموا بانتقال مماثل. ولم يندم أي منهم على ذلك. التحقق من النوع يجعل من بايثون لغة أكثر ملاءمة لتطوير المشاريع الكبيرة من "بايثون العادية".

القراء الأعزاء! هل تستخدم التحقق من النوع في مشاريع بايثون الخاصة بك؟

المسار إلى فحص 4 ملايين سطر من كود Python. الجزء 3
المسار إلى فحص 4 ملايين سطر من كود Python. الجزء 3

المصدر: www.habr.com

إضافة تعليق